在着色器中可以轻松进行裁剪。使用一些计算,您甚至可以拥有例如球形的裁剪区域。垂直于坐标系的平面裁剪最简单。在顶点着色器中计算像素的世界位置:
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 剪裁平面,因为为了让这个演示工作,我必须使用一个着色器来渲染模板缓冲区,确定剪裁平面是否朝向远离相机的方向,并只在那些朝向相机的平面上进行剪裁。
现在支持剪裁。
这是要遵循的模式。根据您的用例进行适应。
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
} );
查看这些three.js示例:
https://threejs.org/examples/webgl_clipping.html https://threejs.org/examples/webgl_clipping_advanced.html
three.js r.85
render.localClippingEnabled
被设置为false:/ - Jacksonkr