仅显示重叠的部分

时间:2015-01-07 20:52:08

标签: javascript three.js webgl

我想这是基本的东西,但找不到任何解决方案。比如说,我有2个物体,只想显示它们的重叠部分(即它们的交点)。任何提示?

3 个答案:

答案 0 :(得分:2)

一种方法是打开模板。绘制第一个对象,更新模板缓冲区,然后使用模板测试集绘制第二个对象,仅绘制第一个对象设置模板缓冲区的位置。



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>
&#13;
&#13;
&#13;

嗯,这实际上只适用于2D而不是3D(交叉点是2d)。 DOH!

答案 1 :(得分:1)

答案 2 :(得分:1)

作为使用模板@gman的替代方法,您可以通过巧妙地在depth functionsblend functions之间切换来实现这一目标。