【问题标题】:All points go to 0,0 when updating a data texture uniform更新数据纹理制服时,所有点都变为 0,0
【发布时间】:2017-05-21 17:40:09
【问题描述】:

当用户点击时,我正在交换新的位置数据以塑造点云(在高云和宽云之间交替)。我已经制作了这个fiddle,到目前为止,我可以让云第一次正确渲染(高大的云),但是在点击事件中,所有点位置似乎都变成了 0,0 而不是变成了宽云。我在这里错过了什么?

这里有几个 sn-ps 供检查:

function makeCloud() {

    var cloudWidth, cloudHeight;

    if ( isTallCloud ) {
        cloudHeight = 100;
        cloudWidth = 25;
    } else {
        cloudHeight = 25;
        cloudWidth = 100;
    }

    isTallCloud = !isTallCloud;

    var positions = new Float32Array( particles * 4 );
    var offsets = new Float32Array( particles * 4 );

    for ( var i = 0, i4 = 0; i < particles; i ++, i4 +=4 ) {

        positions[ i4 + 0 ] = ( Math.random() * 2 - 1 ) * cloudWidth; // x
        positions[ i4 + 1 ] = ( Math.random() * 2 - 1 ) * cloudHeight; // y
        positions[ i4 + 2 ] = 0.0; // velocity
        positions[ i4 + 3 ] = 0.0; // velocity

        offsets[ i4 + 0 ] = positions[ i4 + 0 ]; // width offset
        offsets[ i4 + 1 ] = positions[ i4 + 1 ]; // height offset
        offsets[ i4 + 2 ] = stateChange; // this will hold the change state ( 0.0 or 1.0 )
        offsets[ i4 + 3 ] = 0.0; // not used

    }

    cloudData = {
        "positions" : positions,
        "offsets" : offsets
    }
}

function updateStateChange() {

    for ( var i = 0, i4 = 0; i < particles; i ++, i4 +=4 ) {
        cloudData.offsets[ i4 + 2 ] = stateChange; // this will hold the change state ( 0.0 or 1.0 )
    }
}

function updateOffsets() {
    offsetsTexture = new THREE.DataTexture( cloudData.offsets, width, height, THREE.RGBAFormat, THREE.FloatType );
    positionUniforms.tOffsets.value = offsetsTexture;
    positionUniforms.tOffsets.needsUpdate = true;
}

function onDocumentClick() {
    event.preventDefault();
    stateChange = 1.0;
    makeCloud();
    updateOffsets();
}

function animate() {
    requestAnimationFrame( animate );
    update();
    render(); 
}

function render() {
    renderer.render( scene, camera );
}

function update() {
    positionUniforms.uTime.value += 0.01;
    gpuCompute.compute();

    particleUniforms.tPositions.value = gpuCompute.getCurrentRenderTarget( positionVariable ).texture;

    if ( stateChange === 1.0 ) {
        stateChange = 0.0;
        console.log("swapped state!");
        updateStateChange();
        updateOffsets();
    }
}

来自着色器代码的 sn-p:

vec4 offsets = texture2D( tOffsets, uv ).xyzw;
float swapState = offsets.z;
vec4 nowPos;
vec2 velocity;

if ( swapState == 0.0 ) {
    nowPos = texture2D( tPositions, uv ).xyzw;
    velocity = vec2(nowPos.z, nowPos.w);
} else { // if swapState == 1.0
    nowPos = vec4( offsets.x, offsets.y, 0.0, 0.0 );
    velocity = vec2(0.0, 0.0);
}

背景:

我意识到只需单击一下即可交换所有数据并获得我正在寻找的结果就很容易了;但是,我试图通过在纹理中传递这些偏移值来更新的原因是,在我的较大程序中有更多的点云,我只想更改选定的云(如着色器中的 swapState 所示),同时让物理着色器继续控制其余未选中的着色器。更新所有云会扰乱着色器控制的物理连续性。

【问题讨论】:

    标签: javascript three.js textures shader


    【解决方案1】:

    我在我的代码中发现了错误——错误在于我如何为DataTexture 设置needsUpdate 属性。请参阅固定小提琴here。这是使它最终按预期工作的修订:

    function updateOffsets() {
        offsetsTexture = new THREE.DataTexture( cloudData.offsets, width, height, THREE.RGBAFormat, THREE.FloatType );
        offsetsTexture.needsUpdate = true; // **using this way of updating the texture produced the behavior I expected
        positionUniforms.tOffsets.value = offsetsTexture;
        // positionUniforms.tOffsets.needsUpdate = true; **this form of updating caused the faulty behavior
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-16
      • 1970-01-01
      • 1970-01-01
      • 2023-02-26
      • 1970-01-01
      • 1970-01-01
      • 2014-09-08
      相关资源
      最近更新 更多