Three.JS对象剪辑?

时间:2016-04-11 19:23:59

标签: javascript three.js

我试图以类似于Unity的方式使用three.js来划分我的3D模型: enter image description here

我一直在玩相机控制器,当然我可以调整近/远场以剪切相机的方向,但是如果我想在X或Y平面上剪辑怎么办?我看了可能添加一个可以在该轴上滑动的大透明块,然后使用二进制操作来合并/减去它与对象相交的位置,但是这些工具最终会在新平面上创建一个新网格,而不是实际沿着该平面移除所有内容。轴。

我是否需要使用多个视口,或者是否有更简单的方法?

2 个答案:

答案 0 :(得分:16)

剪切可以在着色器中轻松完成。使用一些计算你甚至可以有像剪裁区域这样的球体。在垂直于坐标系的平面处剪切是最容易的。在顶点着色器中计算像素的世界位置:

worldPosition = modelMatrix * vec4( position, 1.0 );

在片段着色器中,如果超出裁剪限制,则丢弃像素的绘制:

if ( worldPosition.x > clippingLimitX ) {
    discard;
}

然而,这将使网格在裁剪边缘处打开。要关闭它,请使用模板缓冲区。用显示背面的场景减少模板。然后使用显示剪裁正面的场景增加模板。 这些场景中使用的材料不应该是可见的,因此禁用它们的颜色和深度写:

new THREE.ShaderMaterial( { colorWrite: false, depthWrite: false, ... } );

使用模板渲染位于剪裁平面位置的平面。禁用模板后,渲染剪切的正面。

renderer.autoClear = false;
renderer.clear();

var gl = renderer.context;

renderer.state.setStencilTest( true );

renderer.state.setStencilFunc( gl.ALWAYS, 1, 0xff );
renderer.state.setStencilOp( gl.KEEP, gl.KEEP, gl.INCR );
renderer.render( backStencilScene, camera );

renderer.state.setStencilFunc( gl.ALWAYS, 1, 0xff );
renderer.state.setStencilOp( gl.KEEP, gl.KEEP, gl.DECR );
renderer.render( frontStencilScene, camera );

renderer.state.setStencilFunc( gl.EQUAL, 1, 0xff );
renderer.state.setStencilOp( gl.KEEP, gl.KEEP, gl.KEEP );
renderer.render( capsScene, camera );

renderer.state.setStencilTest( false );

renderer.render( scene, camera );

我做了一个演示,展示了如何同时在多个平面上剪辑:

http://daign.github.io/clipping-with-caps/

我没有使用内置的three.js剪裁平面,因为要使这个演示工作,我必须使用着色器渲染模板,该着色器确定剪裁平面是否背对着相机,以及只能在那些面向相机的平面上剪辑。

答案 1 :(得分:15)

现在支持剪辑。

以下是要遵循的模式。根据您的使用情况进行调整。

var localPlane = new THREE.Plane( new THREE.Vector3( 0, - 1, 0 ), 1 );

var globalPlane = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), 1 );

renderer.clippingPlanes = [ globalPlane ];

renderer.localClippingEnabled = true;

var material = new THREE.MeshPhongMaterial( {
    clippingPlanes: [ localPlane ],
    clipShadows: true
} );

请参阅以下三个例子:

https://threejs.org/examples/webgl_clipping.html https://threejs.org/examples/webgl_clipping_advanced.html

three.js r.85