2017-01-06 1 views
0

Я обмениваюсь данными новой позиции, чтобы сформировать облако точек (чередующееся между высоким облаком и широким облаком), когда пользователь делает клик. Я сделал это fiddle, и до сих пор я могу получить облако для рендеринга в первый раз (высокое облако), но в событии click все точки позиции кажутся 0,0 вместо того, чтобы стать широким облаком. Что я пропустил здесь?Все точки идут до 0,0 при обновлении однородности текстуры данных

Вот несколько фрагментов для проверки:

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(); 
    } 
} 

Отрывок из кода шейдера:

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 в шейдере) позволяя физическому шейдеру продолжать контролировать оставшиеся невыбранные. Обновление всех облаков будет связано с непрерывностью физики, контролируемой шейдером.

ответ

1

Я нашел ошибку в своем коде - недостаток был в том, как я устанавливал атрибут needsUpdate для DataTexture. См. Фиксированную скрипку 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 
} 
Смежные вопросы