Using Three.js to generate points from a heightmap

I've been experimenting with sampling from a heightmap to determine the z-coordinate of various points in my scene, but it seems like I'm making a fundamental error somewhere. Let me walk you through what I have so far:

// Creating the Scene
var scene = new THREE.Scene();

// Setting up the Camera
var aspectRatio = window.innerWidth / window.innerHeight;
var camera = new THREE.PerspectiveCamera(75, aspectRatio, 0.001, 10);

// Initializing the Renderer
var renderer = new THREE.WebGLRenderer({antialias: true, alpha: true});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// Adding Ambient Light
var ambientLight = new THREE.AmbientLight(0xeeeeee);
scene.add(ambientLight);

// Implementing Controls
var controls = new THREE.TrackballControls(camera, renderer.domElement);
controls.zoomSpeed = 0.4;
controls.panSpeed = 0.2;

// Rendering Loop
function render() {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
  controls.update();
};

/**
* Obtaining Heightmap Data
**/

function getHeightmap(cb) {
  // Code for fetching and processing heightmap data
}

/**
* Generating Geometry
**/

function addLetters(data) {
  // Code for positioning points based on heightmap data
}

/**
* Helper Functions
**/

// Fetch heightmap data and initiate rendering
getHeightmap(function(data) {
  addLetters(data);
  render();
})
html,
body {
  width: 100%;
  height: 100%;
}
body {
  margin: 0;
  overflow: hidden;
  background: linear-gradient(#585852, #262726);
}
#letter-canvas {
  position: absolute;
  top: 0;
  left: 0;
}
<script src='https://cdnjs.cloudflare.com/ajax/libs/three.js/97/three.min.js'></script>
<script src='https://s3.amazonaws.com/duhaime/blog/visualizations/word-to-viz/trackball-controls.min.js'></script>

// Shader code goes here...

While attempting to set the z-position of each point using the heightmap data, I noticed irregularities in the z-coordinates that don't align with the heightmap itself. It's clear that my sampling method is flawed, but I can't seem to pinpoint the exact issue.

If anyone has any suggestions or insights on where things might be going wrong, I would greatly appreciate your input!

Answer №1

The equation for determining the position of a pixel in a 2D height map image is

idx = (row * 4 * data.width) + (col * 4)

instead of

idx = (row * 4) + (col * 4)

When loading the image to the data array, it is essential to adjust the canvas dimensions to match the size of the height map image:

function getHeightmap(cb) {
    var canvas = document.createElement('canvas'),
        ctx = canvas.getContext('2d'),
        image = new Image();
        image.crossOrigin = 'Anonymous';
    image.onload = function(img) {
        canvas.width = this.width; // <----- set width and height of the canvas
        canvas.height = this.height;
        ctx.drawImage(this, 0, 0, this.width, this.height);
        cb(ctx.getImageData(0,0, this.width, this.height));
    }
    image.src = 'https://s3.amazonaws.com/duhaime/blog/visualizations/word-to-viz/heightmap.jpg';
}

Check out the example below where I've implemented the recommended changes to your code and added a gradient tint from blue to red on the height map:

[...Javascript code continue here]

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Managing the necessary button checkbox with JavaScript

Having an issue with handling a checkbox button in a form using JavaScript. I've created a customer information collection form that includes basic details like first name, last name, email, etc., and at the end of the form, I've added a navigati ...

The dreaded Heroku Node.js error H10 strikes again: "Application crashed"

I recently embarked on my journey to learn NodeJS and attempted to deploy it on Heroku. However, when I used 'heroku open,' the following error log appeared: 2020-10-08T14:19:52.778660+00:00 app[web.1]: at Module.load (internal/modules/cjs/loa ...

Leveraging Flask to pass data to Google Charts with JavaScript

Trying to integrate Google Charts on my website using Flask as the backend. Need help with sending data from Flask to JavaScript. Here's a snippet of where I plan to retrieve data later: @app.route("/") def home(): data = {'Language': &a ...

The error message reads: `'Icon' is not included in the export list of 'antd'`

I have recently developed a React application and I'm incorporating Ant Design (antd) into it. However, I encountered an issue in one of my project files where I am unable to use the Icon tag. It seems like this is a known problem in ANT V4. The impo ...

The Ajax/jQuery output is not showing up in the iframe, but is instead appearing on a separate page

I've scoured various forums and websites, attempting to troubleshoot the issue described below without success. This problem persists in both IE 11 and Firefox 10.0.2. My goal is to submit a form (POST) to a website () and showcase the resulting bri ...

Can we combine JQuery includes with Angular Includes?

I have come across an issue while working on an application that combines both Jquery and AngularJS includes. It seems that Angular does not work properly after Jquery has included a file containing AngularJS markup. Specifically, Jquery is including the " ...

Finding the tab index within an accordion using Jquery UI version 1.10

I'm currently working with a JQuery UI accordion that contains tabs within each fold. My goal is to accurately determine the index of the tab that is currently open within the active accordion fold. In an earlier version of JQuery, I was able to achie ...

Having a hard time implementing a subtracting callback function in a JavaScript reduce function

Currently, I am tackling a code challenge in JavaScript that requires me to develop a function called reduce. This function is responsible for reducing a collection to a value by applying a specific operation on each item in the collection over which it it ...

How can I maintain my login session in geckodriver using selenium in Java?

I am currently automating a website using Selenium. The issue I am facing is that every time the code runs, I have to login again and GeckoDriver opens a new tab in Firefox to fill in the login details. Is there a more efficient way to handle this? Below ...

position a div element at the bottom of its parent container

I am facing a challenge with this issue: I want to position a red div at the bottom of another div. The red div should always stay at the bottom of its parent div. .homepage-wrapper{ max-width: 1028px; margin-left: auto; ...

Utilizing Ajax for submitting a form in Wordpress contact page

I am currently using Wordpress along with the Ninja Form plugin. I am trying to achieve a function where upon submitting a form, the data is posted to a service. <input type="submit" name="_ninja_forms_field_7" class="ninja-forms-field popup-submit" i ...

three.js - Attempted to execute the 'loadTexture' function on an object that is not defined

Apologies for any language barriers. I'm encountering an issue while using Three.js. In all the examples I find for loading a texture, this code is always present: var map = THREE.ImageUtils.loadTexture( "obj/textures/textures38.jpg" ); map.wrapS ...

Tips for testing the website's color modifications?

I recently had the task of replacing 10 specific colors with new ones in my CSS files. I used the find and replace method to make the changes in over 300 places throughout all the files. Now, I need a way to test if all the color replacements were done c ...

"Unfortunately, the Blender JSON export in Three.js (r64) is missing important normals needed for smooth shading

When using Three.js version r64, my goal is to import an animated object from Blender with its smoothing groups. The file is exported as JSON using the Three.js Blender exporter. The animation aspect is functioning properly. Within Blender, the model app ...

What is the best way to incorporate personalized events into an array using JavaScript?

Imagine we have an array called var arr = [1, 2, 3]. I am looking for a way to create a method that can observe any changes made to this array. The idea is something similar to the following: arr.on('change', function () { // perform some ac ...

Adjust the dimensions of the embed code to specify a width and height

Looking to integrate Appreplica on my website for embedding content, but struggling with the length of the embedded window. My Tweets seem to extend beyond the page boundaries. ...

Is there a way to extract a variable's value from the URL and distribute it to all links across the website, excluding those on the homepage?

Recently, I was attempting to achieve something similar to this concept how to retrieve variable values from the URL and pass them to all links on a website? However, I encountered an issue where simply visiting the homepage or any other page without the ...

AngularJS: Issue with Select Click Trigger Not Fired

I am puzzled as to why this code isn't working on Chrome but works perfectly fine on FireFox SelectModel selectModel: [ { value: "asc", htmlText : "A-Z", selected: "" }, ...

Creating a reusable function in AngularJS using the factory method

Currently, I am using the AngularJS factory method to retrieve data and passing that value to controllers. In order to avoid creating separate functions, I would like to create a common function that can be utilized in all controllers. How can I effi ...

How can I use JSON path to extract all the elements within an array from a JSON input?

I want to extract all fields from a JSON array and turn it into a flat JSON file. Here is an example of the input: Array JSON input: { "field1": "ALNT12345", "field2": "ALNT345346", "field3": "2015353423", "field4": "2332124343", "arr ...