Wiew port for group of mesh in threejs

135 views Asked by At

What is the best way/practice of creating viewport for group of meshes in three js?
In my case I have THREE.Group of a lot THREE.Mesh instances. My goal is to create viewport for this group, where meshes will be visible.
One solution that I see is to use local clipping planes. threejs example
But I'm concerned that I have to assign clipping planes for every THREE.Mesh material rather than set it once for THREE.Group.
Also I need to recalcutate clipping planes when I move or rotate THREE.Group.

1

There are 1 answers

0
pailhead On

You could look into the stencil buffer:

webgl.stencilFunc()

webgl.stencilOp()

With or without threejs, the principle is the same.

  1. disable depth write
  2. disable depth test
  3. disable color write
  4. enable stencil operation (write a value to stencil buffer)
  5. draw an invisible shape that writes to the stencil buffer (you probably want a screen space quad)
  6. enable 1,2,3
  7. change stencil operation (only draw where stencil buffer is 1 for example)
  8. draw your group
  9. depending on when you're doing this, you could change the stencil op here
  10. and then draw the rest of the scene where buffer is 0 (outside of that shape from 5)

Three.js does not have stencil abstractions unless they've been implemented recently. This means that there is no "magical" property of say transparent which manages a bunch of webgl state under the hood, you have to actually manage this yourself. This means that you have to get the webgl context and do webgl operations on it manually.

There are many ways to do this.

var myScreenSpaceQuad = new THREE.Mesh( new THREE.PlaneBufferGeometry(2,2,1,1), myQuadShaderMaterial )

var scene1 = new THREE.Scene()
var scene2 = new THREE.Scene()
var sceneMask = new THREE.Scene()

sceneMask.add(myScreenSpaceQuad)

//...

myRenderFunction(){
  //gl stencil op
  //...
  myRenderer.render(myCamera, sceneMask)
  //more stencil
  //...
  myRenderer.render(myCamera, scene1)
  //some more stencil...
  myRenderer.render(myCamera, scene2)
}

I'll try to write a working example. For screen space quad you can take a look at this.