代码之家  ›  专栏  ›  技术社区  ›  mudin mike.bronner

如何在三个对象中显示网格?

  •  8
  • mudin mike.bronner  · 技术社区  · 6 年前

    我在场景中有水平网格助手和多边形。

    有没有任何方法可以像下面的图片一样将网格隐藏在多边形之外?

    enter image description here

    这里是 JSFiddle

    var camera, scene, renderer, controls, geometry, material, mesh, gridHelper, polygon;
    var edges = [{
      "x": -204.87113421108512,
      "y": -150,
      "z": 350.73338884671745
    }, {
      "x": -204.87113421108535,
      "y": -150,
      "z": -38.02713383973953
    }, {
      "x": -83.08211641046344,
      "y": -150,
      "z": -39.62530388610881
    }, {
      "x": -78.88807649109879,
      "y": -150,
      "z": -538.3155247201529
    }, {
      "x": 220.63777329601388,
      "y": -150,
      "z": -535.796479191672
    }, {
      "x": 220.63777329601444,
      "y": -150,
      "z": 176.94968924487634
    }, {
      "x": -53.07402331399715,
      "y": -150,
      "z": 176.9496892448766
    }, {
      "x": -53.07402331399726,
      "y": -150,
      "z": 350.41591086077415
    }];
    
    init();
    animate();
    
    function init() {
    
      scene = new THREE.Scene();
      
      renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
    	renderer.setPixelRatio(window.devicePixelRatio);
      renderer.setSize(window.innerWidth, window.innerHeight);
      renderer.setClearColor(0x555555, 1);
      renderer.sortObjects = true;
      
      document.body.appendChild(renderer.domElement);
    
      camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000);
      scene.add(camera);
      
      camera.position.x =  1000;
     	camera.position.y =  2000;
    	camera.position.z =  -1000;
      
    	controls = new THREE.OrbitControls( camera );
    
    
      gridHelper = new THREE.GridHelper(1500, 30);
      gridHelper.position.y = -150;
      scene.add(gridHelper);
    
    
      var shape = new THREE.Shape();
      let firstEdge = edges[0];
      shape.moveTo(firstEdge.x, -firstEdge.z);
      const len = edges.length;
      for (let i = 1; i < len; i++) {
        shape.lineTo(edges[i].x, -edges[i].z);
      }
    
      shape.lineTo(firstEdge.x, -firstEdge.z);
      
      var material = new THREE.MeshBasicMaterial({
          color:0x00aa00,
          opacity:0.5,
          side:THREE.DoubleSide,
          transparent:true,
          depthTest:false
        });
    
      var polygonGeometry = new THREE.ShapeGeometry(shape);
      polygon = new THREE.Mesh(polygonGeometry, material);
      polygon.position.y = firstEdge.y;
      polygon.rotation.x = -Math.PI / 2.;
      polygon.name = this.name;
      scene.add(polygon);
    
    }
    
    function animate() {
    		controls.update();
      window.requestAnimationFrame(animate);
      render();
    
    }
    
    function render() {
    
      renderer.render(scene, camera);
    
    };
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/100/three.js"></script>
          <script type="text/javascript" src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

    任何建议都将不胜感激!

    1 回复  |  直到 6 年前
        1
  •  6
  •   Alex Khoroshylov    6 年前

    我用模板缓冲区得到的结果是: https://jsfiddle.net/mmalex/g3hf4zxc/

    Stencil buffer clipping threejs Grid by Mesh

    const gl = renderer.getContext();
    polygon.onBeforeRender = function () {
        gl.enable(gl.STENCIL_TEST)
        gl.stencilFunc(gl.ALWAYS, 1, 0xFF);
        gl.stencilMask(0xFF);
        gl.stencilOp(gl.KEEP, gl.KEEP, gl.INCR);
    }
    polygon.onAfterRender = function() {
        gl.disable(gl.DEPTH_TEST);
    }
    polygon.renderOrder = 999;
    
    gridHelper.onBeforeRender = function() {
        gl.enable(gl.STENCIL_TEST)
        gl.stencilMask(0x00);
        gl.stencilFunc(gl.EQUAL, 1, 0xFF);
    }
    gridHelper.onAfterRender = function() {
        gl.disable(gl.STENCIL_TEST)
    }
    gridHelper.renderOrder = 1000
    

    不幸的是,我牺牲了网格不透明度,因为threejs独立地对不透明和透明对象进行排序:

    .renderOrder:编号 该值允许覆盖场景图对象的默认渲染顺序,尽管不透明和透明对象保持独立排序。排序是从最低到最高的renderder。默认值为0。

    https://threejs.org/docs/#api/en/core/Object3D.renderOrder