繁体   English   中英

具有Three.js的累积着色器

[英]Accumulation shader with Three.js

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

我想要更高的采样率,一种方法是为每个像素采样一条路径并累积结果图像。 (即平均每个着色器通过时获得的图像)

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

我只是不知道如何从WebGLRenderTarget获取数据并使用它来操纵另一个渲染目标中包含的数据。 这是否可能与Three.js一起成为可能? 我一直在研究FrameBuffer Objects,这似乎是一条很有希望的道路,我正在通过MrDoob的FBO示例( http://www.mrdoob.com/lab/javascript/webgl/particles/particles_zz85.html )进行梳理,看起来很有希望但我不确定自己是走在正确的道路上。

我认为问题是你不能从同一个缓冲区读写。 假设你渲染了一个帧,你需要一个输出到accum缓冲区的传递。 下一帧,您需要进行计算,并保存到相同的缓冲区,但如果我理解正确,目前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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM