全部专题

Shadertoy 的 Buffer A 怎么迁移?用两张纹理保存上一帧

Buffer A 经常读取自身上一帧的结果。WebGL 不允许采样正在写入的纹理,因此需要分开的读取目标和写入目标。每次更新后交换两者,再让显示阶段读取刚完成的纹理。

先固定问题

Buffer A 的核心是让一个渲染通道读取自己的上一帧结果。WebGL 不允许把正在写的纹理同时当作输入,所以要分开读目标和写目标。一次更新完成后交换两者,最终显示通道只读取刚写完的纹理。

关键代码

const readTarget=new THREE.WebGLRenderTarget(width,height);
const writeTarget=new THREE.WebGLRenderTarget(width,height);
let read=readTarget,write=writeTarget;
// Initialize both once; the simulation shader samples uniforms.previous.
renderer.setRenderTarget(read);renderer.clear();
renderer.setRenderTarget(write);renderer.clear();
function update(){
  simulationMaterial.uniforms.previous.value=read.texture;
  renderer.setRenderTarget(write);
  renderer.render(simulationScene,simulationCamera);
  [read,write]=[write,read];
  displayMaterial.uniforms.state.value=read.texture;
  renderer.setRenderTarget(null);
  renderer.render(displayScene,displayCamera);
}

按顺序验证

先打开轨迹示例检查单通道反馈:新亮点加入,旧颜色逐帧衰减。再看水波案例的双时刻高度。调试时直接显示状态通道,分清模拟坏了还是显示映射坏了。

适用范围和常见错误

模拟 shader、显示 shader、uniform、场景与相机仍需按各自用途创建。调整分辨率时要同时重建或 resize 两张状态纹理,并明确是否重置历史。

继续实验

参考

官方文档

运行相关示例