three.js:如何判断Vector3是否在摄像机视图内?

时间:2022-06-05 05:50:05

Using three.js, Is there a quick and inexpensive way to check if a point/Vector3 is within a camera's field of view?

使用three.js,是否有一种快速而廉价的方法来检查点/ Vector3是否在摄像机的视野范围内?

I'm hoping to create a grid of boxes to fill the "floor" of a scene, but only to the edges of the visible area that will not pan or rotate (or at least the origin point of each box being in the visible area with leftovers hanging out of view). As a bonus, it may also be good to limit the depth from the camera position that boxes can "live" in.

我希望创建一个盒子网格来填充场景的“地板”,但仅限于可见区域的边缘不会平移或旋转(或者至少每个盒子的原点位于可见区域内)剩下的东西挂在视线外)。作为奖励,限制盒子可以“居住”的相机位置的深度也可能是好的。

While I'm unable to find a clear answer at this time, it may just be due to missing the correct terminology needed to find the correct answer. Clarification and a quick example is welcome.

虽然我目前无法找到明确的答案,但可能只是因为错过了找到正确答案所需的正确术语。欢迎澄清和快速举例。

Starter code:

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

var vec = new THREE.Vector3(0, 0, 10);
          
//??? How to tell if Vector3 is within camera's view?

var renderer = new THREE.WebGLRenderer();
document.body.appendChild( renderer.domElement );

console.log('Yes it is just a black/blank screen at this point.');
body { margin: 0; }
canvas { width: 100%; height: 100% }
<html>
<head>
<meta charset=utf-8>
<title>Spot the Vector</title>
</head>
<body>
<script src="https://raw.githubusercontent.com/mrdoob/three.js/master/build/three.min.js"></script>
</body>
</html>

1 个解决方案

#1


2  

Take the camera frustrum as stated in this answer

按照本答案中的说明拍摄相机截止日期

then, call

if(frustum.containsPoint( vec ))  
    { ...

EDIT: Full updated example based on question above:

编辑:基于以上问题的完整更新示例:

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

//var vec = new THREE.Vector3(0, 0, 10); //behind camera
var vec = new THREE.Vector3(0, 0, -10); //in front of camera

//check if within camera's view:
camera.updateMatrix(); // make sure camera's local matrix is updated
camera.updateMatrixWorld(); // make sure camera's world matrix is updated
camera.matrixWorldInverse.getInverse( camera.matrixWorld );

var frustum = new THREE.Frustum();
frustum.setFromMatrix( new THREE.Matrix4().multiply( camera.projectionMatrix, camera.matrixWorldInverse ) );

if(frustum.containsPoint(vec)) {
  console.log('within camera view');
} else {
  console.log('outside camera view');
}

var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
body { margin: 0; }
canvas { width: 100%; height: 100% }
<html>
  <head>
    <meta charset=utf-8>
    <title>Spot the Vector</title>
  </head>
  <body>
    <script src="https://raw.githubusercontent.com/mrdoob/three.js/master/build/three.min.js"></script>
  </body>
</html>

#1


2  

Take the camera frustrum as stated in this answer

按照本答案中的说明拍摄相机截止日期

then, call

if(frustum.containsPoint( vec ))  
    { ...

EDIT: Full updated example based on question above:

编辑:基于以上问题的完整更新示例:

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

//var vec = new THREE.Vector3(0, 0, 10); //behind camera
var vec = new THREE.Vector3(0, 0, -10); //in front of camera

//check if within camera's view:
camera.updateMatrix(); // make sure camera's local matrix is updated
camera.updateMatrixWorld(); // make sure camera's world matrix is updated
camera.matrixWorldInverse.getInverse( camera.matrixWorld );

var frustum = new THREE.Frustum();
frustum.setFromMatrix( new THREE.Matrix4().multiply( camera.projectionMatrix, camera.matrixWorldInverse ) );

if(frustum.containsPoint(vec)) {
  console.log('within camera view');
} else {
  console.log('outside camera view');
}

var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
body { margin: 0; }
canvas { width: 100%; height: 100% }
<html>
  <head>
    <meta charset=utf-8>
    <title>Spot the Vector</title>
  </head>
  <body>
    <script src="https://raw.githubusercontent.com/mrdoob/three.js/master/build/three.min.js"></script>
  </body>
</html>