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