javascript - Three.js 的累积着色器

标签 javascript opengl-es three.js webgl

我正在尝试使用 THREE.js 实现路径跟踪器。我基本上是在渲染全屏四边形,路径跟踪发生在像素着色器中。

我想要更高的采样率,一种方法是为每个像素采样一个路径并累积生成的图像。 (即对每个着色器 channel 获得的图像进行平均)

事实上,我能够生成我需要的图像,但我不知道如何积累它们。我的猜测是我必须使用两个渲染目标;一个将包含“最新”采样图像,一个将包含迄今为止显示的所有图像的平均值。

我只是不知道如何从 WebGLRenderTarget 获取数据并使用它来操作另一个渲染目标中包含的数据。这甚至是 Three.js 可能实现的事情吗?我一直在研究 FrameBuffer 对象,这似乎是一条很有前途的道路,我正在梳理 MrDoob 的 FBO 示例 (http://www.mrdoob.com/lab/javascript/webgl/particles/particles_zz85.html),它看起来很有希望,但我不确定我是否走上了正确的道路。

最佳答案

我认为问题是您不能从同一个缓冲区读取和写入。假设您渲染一帧内容,您需要一个输出到累积缓冲区的 channel 。下一帧,你需要做你的计算,并保存到同一个缓冲区,但如果我理解正确的话,这在目前的 WebGL 中是不可能的。

你可以做的是有两个缓冲区。在将内容输出到缓冲区并进行计算的着色器中,只需添加另一个纹理采样器,从上一帧读取一个,保存到下一帧,然后交替。您将始终拥有累加值,您可以使用任何您想要的数学来进行加法运算,但您需要确保在正确的帧读取正确的缓冲区。

three.js 有一个用于后期处理的插件,这对于做这样的事情应该非常方便。

var flipFlop = true;
var buffer1 = THREE.WebGLRenderTarget(BUFFERSIZE, BUFFERSIZE, {minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat, type: THREE.FloatType});
var buffer2 = THREE.WebGLRenderTarget(BUFFERSIZE, BUFFERSIZE, {minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat, type: THREE.FloatType});


function render() {
    // If we are in frame1 read buffer from frame0 and add it to whatever you compute
    yourComputeShaderMaterial.uniforms._accumulationBuffer.value = flipFlop ? buffer2 : buffer1;

    if (flipFlop) // Frame 0
        renderer.render(scene, camera, buffer1);
    else // Frame 1
        renderer.render(scene, camera, buffer2); 

    // Get whatever just renderered in this frame and use it
    yourEndShader.uniforms._accumulationBuffer.value = !flipFlop ? buffer2 : buffer1;

    // Switch frame
    flipFlop = !flipFlop;
}

关于javascript - Three.js 的累积着色器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22670630/

相关文章:

javascript - Javascript如何使用Fetch API跨域加载文本或JSON数据?

Swift OpenGL 类型转换

c++ - 将 OpenGL 1.x 代码移植到 WebGL

three.js - 三JS : is it possible to simplify an object/reduce the number of vertexes?

javascript - 优化 Durandal 的构建过程

javascript - 使用 HTML 将文件上传到 Node.js

c++ - 在 OpenGL ES 2 应用程序/进程之间共享渲染表面(FrameBuffer、Pbuffers 等)

javascript - 使用 Three.js 实现逼真的 Chrome 效果

javascript - 在 Oculus 浏览器中通过 GamePad API 访问 Oculus Go Controller ?

javascript - 将字符串转换为实时日期时间