2014-03-26 151 views
2

我試圖使用THREE.js實現路徑跟蹤器。我基本上是渲染一個全屏四邊形,並且路徑追蹤發生在像素着色器中。與Three.js的積累着色器

我想要一個更高的採樣率,一種方法是爲每個像素採樣一個路徑並累加生成的圖像。 (即平均每個着色器通道獲得的圖像)

因爲它是我能夠生成我需要的圖像,但我不知道如何積累它們。我的猜測是我必須使用兩個渲染目標;一個會包含「最新」的採樣圖像,一個會包含目前顯示的所有圖像的平均值。

我只是不知道如何從WebGLRenderTarget獲取數據並使用它來操縱另一個渲染目標中包含的數據。這甚至有可能是Three.js可能的嗎?我一直在研究FrameBuffer Objects,這看起來像是一個很有前途的路徑,我正在梳理MrDoob的FBO例子(http://www.mrdoob.com/lab/javascript/webgl/particles/particles_zz85.html),它看起來很有前途,但我不確定我是否走向了正確的道路。

+0

請參閱http://threejs.org/examples/webgl_gpgpu_birds.html。它展示了兩個渲染目標之間乒乓球的例子。 – WestLangley

回答

2

我認爲問題是你不能從同一個緩衝區讀寫。假設你渲染一幀圖像,你需要一個輸出到累積緩衝區的通道。下一幀,你需要做你的計算,並保存到同一個緩衝區,但如果我理解正確,這對目前的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; 
} 
+0

感謝您的好評。最後我用純WebGL重新實現了整個事物,你可以在http://tinyurl.com/k7adpb6看到結果! – XenoChrist

+0

甜蜜的演示,這是從一個特定的教程? – pailhead

+0

不是真的,只是基於簡單的路徑跟蹤算法和其他教程/示例,我可以找到網絡。整個事情是相當徹底的評論,所以不要猶豫,通過源頭看! – XenoChrist