6

i've been tinkering around with three.js and i have a canvas i'd like to use as kind of a GUI. for that i have to check if an object is in the camera frustum.

my current code:

camera.updateMatrix(); 
camera.updateMatrixWorld(); 
        
var frustum = new THREE.Frustum();
var projScreenMatrix = new THREE.Matrix4();
projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
        
frustum.setFromProjectionMatrix( camera.projectionMatrix );
        
if(frustum.containsPoint( mesh.position )){
    //stuff happens...
};

frustum.containsPoint()keeps returning false. what am i doing wrong here?

larsmoa
  • 12,604
  • 8
  • 62
  • 85
Kevin Kuyl
  • 1,215
  • 1
  • 17
  • 31
  • A `Frustum` takes 6 `Plane`s as arguments, you're not providing anything. That's probably why it doesn't work. – Leeft Jul 22 '14 at 07:10
  • So how would i go about cloning the camera frustum? – Kevin Kuyl Jul 22 '14 at 07:40
  • An example of that is in this answer: http://stackoverflow.com/questions/10858599/how-to-determine-if-plane-is-in-three-js-camera-frustum – Leeft Jul 22 '14 at 07:56

3 Answers3

9

Your code is using

frustum.setFromMatrix( camera.projectionMatrix );

But that isn't the matrix you want. Instead use:

frustum.setFromMatrix( new THREE.Matrix4().multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ) );

as answered in How to determine if plane is in Three.js camera Frustum

larsmoa
  • 12,604
  • 8
  • 62
  • 85
Leeft
  • 3,827
  • 1
  • 17
  • 25
0

Three.js is doing view frustum Culling internally and only rendering when in camera frustum. Assuming that your Boundig Volumes are calculated correct, you can track weather a renderable Object3D is inside the camera view frustum when Object3D.onBeforeRender callback is called in your current frame

air5
  • 140
  • 2
  • 10
0

Here is what I did to find if a mesh is in camera view (within 100ms):

mesh.onBeforeRender = function() {
    if (mesh.userData.inViewID) clearTimeout(mesh.userData.inViewID);
    mesh.userData.inViewID = setTimeout(()=>{
        mesh.userData.inView = false;
        console.log("out of view");
    }, 100);
    if (!mesh.userData.inView) { 
        mesh.userData.inView = true;
        console.log("in view");
    }
}
Dan Zen
  • 480
  • 3
  • 10