3

UPDATE: Issue was that texData object was recreated each time and thus reference for DataTexture was lost. Solution by WestLangley was to overwrite the data in texData instead of recreating texData object.

I have a simple threejs scene with a DataTexture in a ShaderMaterial. The data array passed to it once during initialization is updated on mouse events. However the DataTexture does not seem to update.

Did i assign uniforms or texture data wrongly? Or using the needsUpdate flags wrongly? It does work when deleting and recreating the texture, material, mesh and scene objects each time, but this shouldnt really be necessary as i have seen from many examples which i could however not reproduce.

Note that the data itself is updated nicely, just not the DataTexture.

// mouse event triggers request to server
// server then replies and this code here is called
// NOTE: this code **is** indeed called on every mouse update!

// this is the updated data from the msg received
// NOTE: texData **does** contain the correct updated data on each event
texData = new Float32Array(evt.data.slice(0, msgByteLength));

// init should happen only once
if (!drawContextInitialized) {

    // init data texture
    dataTexture = new THREE.DataTexture(texData, texWidth, texHeight, THREE.LuminanceFormat, THREE.FloatType);
    dataTexture.needsUpdate = true;

    // shader material
    material = new THREE.ShaderMaterial({
        vertexShader: document.querySelector('#vertexShader').textContent.trim(),
        fragmentShader: document.querySelector('#fragmentShader').textContent.trim(),
        uniforms: {
            dataTexture: { value: dataTexture }
        }
    });

    // mesh with quad geometry and material
    geometry = new THREE.PlaneGeometry(width, height, 1, 1);
    mesh = new THREE.Mesh(geometry, material);

    // scene
    scene = new THREE.Scene();
    scene.add(mesh);

    // camera + renderer setup
    // [...]

    drawContextInitialized = true;

}

// these lines seem to have no effect
dataTexture.needsUpdate = true;    
material.needsUpdate = true;
mesh.needsUpdate = true;
scene.needsUpdate = true;

renderer.render(scene, camera);
4

2 回答 2

4

When updating the DataTexture data, do not instantiate a new array. Instead, update the array elements like so:

texData.set( javascript_array );

Also, the only flag you need to set when you update the texture data is:

dataTexture.needsUpdate = true;

three.js r.83

于 2017-01-16T02:50:53.297 回答
-1

I had a real hard time for some reason seeing any change to modifactions . In desperation i just made a new DataTexture . Its important to set needsUpdate to true

imgData.set(updatedData)
var newDataTex = new THREE.DataTexture( imgData,...     
var newDataTex.needsUpdate = true

renderMesh.material.uniforms.texture.value = newDataTex
于 2018-09-08T02:22:58.280 回答