2017-09-14 36 views
0

我试图制作一个复杂的场景节点,这会导致几次绘制调用和状态之间的变化,当遇到三个WebGLRenderer.render()调用时。管理webgl状态并用three.js发出顺序绘制调用

具体而言,我想使用模板缓冲区,它不作为更高级别的API公开。

如果我有

var mesh = new THREE.Mesh(someGeom, someMaterial) 

我需要有这种情况发生它被绘制之前:

mesh.onBeforeRender = (renderer , scene , camera)=>{ 
    //because there is no someMaterial.stencilOp = THREE.SomeStencilOp 
    //i need to work with the gl context 

    _gl.enable(_gl.STENCIL_TEST) 
    _gl.clearStencil(0) 
    _gl.clear(_gl.STENCIL_BUFFER_BIT) 
    _gl.stencilFunc(_gl.ALWAYS , 1 , 1) 
    _gl.stencilOp(_gl.REPLACE , _gl.REPLACE , _gl.REPLACE) 
    //... 

} 

随后更抽奖电话:

mesh.onAfterRender = (renderer , scene , camera)=>{ 

    //more state 
    _gl.stencilFunc(_gl.EQUAL , 1 , 1) 
    _gl.stencilOp(_gl.KEEP , _gl.KEEP , _gl.INCR) 

    //renderer.render(someOtherMesh , camera) //this doesn't really work 
    renderer.render(anotherSceneWithOtherMesh, camera) //this is nightmarish 

    //more state for yet another call 
    _gl.stencilFunc(_gl.EQUAL, 0 ,1) 
    _gl.stencilOp(_gl.KEEP , _gl.KEEP , _gl.KEEP) 

    //renderer.render(mesh , camera) //not a scene so it doesnt work 
    renderer.render(proxySceneForThisMeshWithThisMesh, camera) // :(i need to either bake the transformation, or somehow sync a copy of the scene graph down to this node 

    _gl.disable(_gl.STENCIL_TEST) 

} 

我可以做什么三,就像,R87以最少的头痛达到这个目标?

我希望我能叫某种renderGeometryDirect方法,将使用该onBeforeRenderonAfterRender被调用同一个节点只画几何形状,并通过其已经在顶级render(scene, camera)呼叫使用相同的camera

或者它只是在render(myObject3D, camera)上被调用。

取而代之的是,我正在考虑创建这些可与render()配合使用的阴影图,但我不确定最佳的行动方案是什么。

+0

我可能没有看到的东西在这里,但你为什么不能只是做在同一水平三个渲染调用和模版缓冲控制着这个外?像1)preapre模板2)渲染场景与对象写入模具缓冲区3)渲染anotherSceneWithOtherMesh 4)渲染proxySceneForThisMeshWithThisMesh 5)禁用模具 –

+0

我不知道如何最好地解决创建这些不同的场景,以及如何同步它们如果如果这有意义,我想要移动原始节点?我需要有一种管理系统来创建这些场景中的每一个,对于这些“多遍”节点中的每一个我都有。 – pailhead

+0

或者更方便的渲染调用。 – pailhead

回答

1

只是一个想法,也许你可以使用图层来实现这样的事情(见herehere)?这至少应该允许您指定场景图的子集以在渲染调用中渲染。

因此,像这样:

_gl.enable(_gl.STENCIL_TEST) 
_gl.clearStencil(0) 
_gl.clear(_gl.STENCIL_BUFFER_BIT) 
_gl.stencilFunc(_gl.ALWAYS , 1 , 1) 
_gl.stencilOp(_gl.REPLACE , _gl.REPLACE , _gl.REPLACE) 

camera.layers.set(1);  
renderer.render(scene, camera); 


_gl.stencilFunc(_gl.EQUAL , 1 , 1) 
_gl.stencilOp(_gl.KEEP , _gl.KEEP , _gl.INCR) 

camera.layers.set(2); 
renderer.render(scene, camera); 


_gl.stencilFunc(_gl.EQUAL, 0 ,1) 
_gl.stencilOp(_gl.KEEP , _gl.KEEP , _gl.KEEP) 

camera.layers.enable(1); 
camera.layers.enable(2); 
renderer.render(scene, camera); 
+0

我喜欢这个想法,但我担心频道数可能会受到限制:(看来这样我就不得不为这些节点分配一个不同的层?也许'.renderOrder'可以做类似这样的事情,也许每个parentNode的范围从1000到3000例如,然后在N0 + 1,N0 + 2 ...? – pailhead

+0

这些其他绘制调用中的每个我认为更像每个传递一个,但是然后我不是完全确定我知道你想实现什么,模板缓冲区的中间状态是什么等等,目前它只限于32层,但也许可以对这些层进行猴子修补 - 如果你真的需要更多它只是通过它的方法iirc来使用) –

+0

更新了这个,它实际上起作用了!我很担心场景遍历每个渲染,但是如果不更新矩阵,我认为它可能非常有用。 – pailhead