仅显示重叠部分
Displaying only overlapping parts
我想这是基本问题,但找不到任何解决方案。比如说,我有 2 个对象并且只想显示它们重叠的部分(即它们的交集)。有什么提示吗?
看看:构造实体几何。介绍在这里:
http://learningthreejs.com/blog/2011/12/10/constructive-solid-geometry-with-csg-js/
一种方法是打开模板。绘制第一个对象,更新模板缓冲区,然后使用模板测试集绘制第二个对象,以仅绘制第一个对象设置模板缓冲区的位置。
var camera, scene1, scene2, scene3, renderer, container;
var mesh1, mesh2, mesh3, mesh4;
init();
animate();
function init() {
container = document.body;
renderer = new THREE.WebGLRenderer();
renderer.setSize( container.clientWidth, container.clientHeight );
container.appendChild( renderer.domElement );
renderer.autoClear = false;
//
camera = new THREE.PerspectiveCamera( 70, container.clientWidth / container.clientHeight, 1, 1000 );
camera.position.z = 400;
// we have to make 2 scenes AFAICT because three has no way to render portions
// of scene. I suppose we could hide one object, render, the hide the other object and un hide
// the first. Or we could remove objects from the scene and add them back.
scene1 = new THREE.Scene();
scene2 = new THREE.Scene();
var geometry1 = new THREE.BoxGeometry( 200, 200, 200 );
var geometry2 = new THREE.IcosahedronGeometry ( 200, 0 );
var material1 = new THREE.MeshBasicMaterial( { color: 0xFF8040 } );
var material2 = new THREE.MeshBasicMaterial( { color: 0x8080FF, wireframe: true } );
// put the box in scene1
mesh1 = new THREE.Mesh( geometry1, material1 );
mesh1.position.x = -75;
scene1.add( mesh1 );
// put the icoahedron in scene2
mesh2 = new THREE.Mesh( geometry2, material1 );
mesh2.position.x = 75;
scene2.add( mesh2 );
// just for visualization lets draw a 3rd scene with both objects so we can
// where they would be if drawn
scene3 = new THREE.Scene();
mesh3 = new THREE.Mesh( geometry1, material2 );
scene3.add( mesh3 );
// put the icoahedron in scene2
mesh4 = new THREE.Mesh( geometry2, material2 );
scene3.add( mesh4 );
}
function animate() {
mesh1.rotation.x += 0.005;
mesh1.rotation.y += 0.01;
mesh2.rotation.x -= 0.003;
mesh2.rotation.y -= 0.007;
// Clear color, depth, and stencil
renderer.clear(true, true, true);
// Turn on stenciling, Set it up so that as we draw scene1 it will put
// a 1 in the stencil for ever pixel drawn
var gl = renderer.context;
gl.enable(gl.STENCIL_TEST);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
gl.stencilFunc(gl.ALWAYS, 1, 0xFF);
// renderer scene1
renderer.render( scene1, camera );
// Clear the color and depth but NOT the stencil
renderer.clear(true, true, false);
// Set the stencil up so we'll only draw if there's a 1 in the stencil buffer.
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);// sfail, spassdfail, spassdepthpass);
gl.stencilFunc(gl.EQUAL, 1, 0xFF); //func, ref, mask)
// renderer scene2
renderer.render( scene2, camera );
// this part is just so we can see both shapes since it's hard to see otherwise
gl.disable(gl.STENCIL_TEST);
mesh3.position.x = mesh1.position.x;
mesh3.rotation.x = mesh1.rotation.x;
mesh3.rotation.y = mesh1.rotation.y;
mesh4.position.x = mesh2.position.x;
mesh4.rotation.x = mesh2.rotation.x;
mesh4.rotation.y = mesh2.rotation.y;
renderer.render( scene3, camera );
requestAnimationFrame( animate );
}
html, body {
width: 100%;
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/three.js/r69/three.min.js"></script>
嗯,这实际上只适用于 2D 而不是 3D(交叉点在 2d 中)。卫生署!
作为@gman 提到的模板的替代方法,您可以通过巧妙地在 depth functions or blend functions.
之间切换来实现这一点
我想这是基本问题,但找不到任何解决方案。比如说,我有 2 个对象并且只想显示它们重叠的部分(即它们的交集)。有什么提示吗?
看看:构造实体几何。介绍在这里: http://learningthreejs.com/blog/2011/12/10/constructive-solid-geometry-with-csg-js/
一种方法是打开模板。绘制第一个对象,更新模板缓冲区,然后使用模板测试集绘制第二个对象,以仅绘制第一个对象设置模板缓冲区的位置。
var camera, scene1, scene2, scene3, renderer, container;
var mesh1, mesh2, mesh3, mesh4;
init();
animate();
function init() {
container = document.body;
renderer = new THREE.WebGLRenderer();
renderer.setSize( container.clientWidth, container.clientHeight );
container.appendChild( renderer.domElement );
renderer.autoClear = false;
//
camera = new THREE.PerspectiveCamera( 70, container.clientWidth / container.clientHeight, 1, 1000 );
camera.position.z = 400;
// we have to make 2 scenes AFAICT because three has no way to render portions
// of scene. I suppose we could hide one object, render, the hide the other object and un hide
// the first. Or we could remove objects from the scene and add them back.
scene1 = new THREE.Scene();
scene2 = new THREE.Scene();
var geometry1 = new THREE.BoxGeometry( 200, 200, 200 );
var geometry2 = new THREE.IcosahedronGeometry ( 200, 0 );
var material1 = new THREE.MeshBasicMaterial( { color: 0xFF8040 } );
var material2 = new THREE.MeshBasicMaterial( { color: 0x8080FF, wireframe: true } );
// put the box in scene1
mesh1 = new THREE.Mesh( geometry1, material1 );
mesh1.position.x = -75;
scene1.add( mesh1 );
// put the icoahedron in scene2
mesh2 = new THREE.Mesh( geometry2, material1 );
mesh2.position.x = 75;
scene2.add( mesh2 );
// just for visualization lets draw a 3rd scene with both objects so we can
// where they would be if drawn
scene3 = new THREE.Scene();
mesh3 = new THREE.Mesh( geometry1, material2 );
scene3.add( mesh3 );
// put the icoahedron in scene2
mesh4 = new THREE.Mesh( geometry2, material2 );
scene3.add( mesh4 );
}
function animate() {
mesh1.rotation.x += 0.005;
mesh1.rotation.y += 0.01;
mesh2.rotation.x -= 0.003;
mesh2.rotation.y -= 0.007;
// Clear color, depth, and stencil
renderer.clear(true, true, true);
// Turn on stenciling, Set it up so that as we draw scene1 it will put
// a 1 in the stencil for ever pixel drawn
var gl = renderer.context;
gl.enable(gl.STENCIL_TEST);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
gl.stencilFunc(gl.ALWAYS, 1, 0xFF);
// renderer scene1
renderer.render( scene1, camera );
// Clear the color and depth but NOT the stencil
renderer.clear(true, true, false);
// Set the stencil up so we'll only draw if there's a 1 in the stencil buffer.
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);// sfail, spassdfail, spassdepthpass);
gl.stencilFunc(gl.EQUAL, 1, 0xFF); //func, ref, mask)
// renderer scene2
renderer.render( scene2, camera );
// this part is just so we can see both shapes since it's hard to see otherwise
gl.disable(gl.STENCIL_TEST);
mesh3.position.x = mesh1.position.x;
mesh3.rotation.x = mesh1.rotation.x;
mesh3.rotation.y = mesh1.rotation.y;
mesh4.position.x = mesh2.position.x;
mesh4.rotation.x = mesh2.rotation.x;
mesh4.rotation.y = mesh2.rotation.y;
renderer.render( scene3, camera );
requestAnimationFrame( animate );
}
html, body {
width: 100%;
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/three.js/r69/three.min.js"></script>
嗯,这实际上只适用于 2D 而不是 3D(交叉点在 2d 中)。卫生署!
作为@gman 提到的模板的替代方法,您可以通过巧妙地在 depth functions or blend functions.
之间切换来实现这一点