Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to show grid in object in threejs?

I have horizontal grid Helper and polygon in scene.

Is there any way of hiding grid out of the polygon like below image?

enter image description here

Here is the 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>

Any suggestion would be appreciated!

like image 679
mudin Avatar asked Jan 16 '19 02:01

mudin


1 Answers

This result I achieved with stencil buffer: 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

Unfortunately I sacrificed mesh opacity, as threejs sorts opaque and transparent objects independently:

.renderOrder : Number This value allows the default rendering order of scene graph objects to be overridden although opaque and transparent objects remain sorted independently. Sorting is from lowest to highest renderOrder. Default value is 0.

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

like image 86
Alex Khoroshylov Avatar answered Oct 31 '22 19:10

Alex Khoroshylov