Question

I'm currently working on a web-based height map generator with Three.js. I use one canvas to show the actual generated height map, several others for displaying the separate octaves the height map consists of and another one for demonstrating the height map 'in action' where it is applied directly to a plane mesh.

So far so good. The whole stuff also renders perfectly fine with all the predefined parameters (wavelength, etc.). The actual problem is, that the canvasses aren't updating after the initial render pass which makes my program completely useless since the purpose of my program is to be able to manipulate the several parameters of the height map with sliders and see the effects in real time.

Sadly the only canvas that updates at all is the one with the 'real' 3D scene with the plane mesh. But also here it kind of seems like the data from the first render pass never got cleared, but at least it seems the uniforms for the noise parameters are updated correctly - this is obviously not the case for all the other canvasses.

Before I finally render a scene, I always set the needsUpdate field of the meshes material to true, but it only seems to work for that one canvas that got initialized last. I'm completely lost here and also wasn't able to find any information about that issue.

Was it helpful?

Solution

I finally found the solution myself. There was no issue with three.js at all, the actual problem was that I accidentially added several planes into one scene instead of just one. That was because my initScene() method got called more than just once since I didn't check the case when all the shaders etc. are still loading (I'm loading my shaders via an async AJAX request). I just checked for 'isn't loaded at all' and 'is completely loaded and ready to use'.

This is working now:

/**
 * Adds geometry to the scene and attaches previously loaded material.
 * 
 * @param {Number} wavelength of the first octave of the height map
 * @param {Number} frequency of the first octave of the height map
 * @param {Number} number of octaves (has to be an integer)
 */
HeightMap.prototype.initScene = function(wavelength, frequency, lacunarity, persistency, octaves) {
    this.material = HeightMap.settings.templateMaterial.clone();

    this.updateUniforms(wavelength, frequency, lacunarity, persistency, octaves);
    HeightMapOctave.prototype.addPlane.call(this);

    this.initialized = true;
};

/**
 * Updates values for HeightMap.
 * 
 * @param {Number} wavelength of the first octave of the height map
 * @param {Number} frequency of the first octave of the height map
 * @param {Number} number of octaves (has to be an integer)
 */
HeightMap.prototype.updateScene = function(wavelength, frequency, lacunarity, persistency, octaves) {
    if (this.initialized) {
        this.updateUniforms(wavelength, frequency, lacunarity, persistency, octaves);
        Canvas3D.prototype.render.call(this);
    } else if (!this.initializing) {
        this.initializing = true;
        this.loadShaders(function() {
            this.initScene(wavelength, frequency, lacunarity, persistency, octaves);
            Canvas3D.prototype.render.call(this);
        });
    }
};

I know this was a very specific problem, but maybe this post might still be helpful for others who make the same mistake. It took me basically a week to track this bug down...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top