Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/430.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何计算给定坐标下相机可见的矩形的大小?_Javascript_Three.js_Perspectivecamera_Frustum - Fatal编程技术网

Javascript 如何计算给定坐标下相机可见的矩形的大小?

Javascript 如何计算给定坐标下相机可见的矩形的大小?,javascript,three.js,perspectivecamera,frustum,Javascript,Three.js,Perspectivecamera,Frustum,我制作了一个小的three.js应用程序,可以将一组圆圈从画布底部移动到顶部: let渲染器、场景、灯光、圆、摄影机; 初始化(); 制作动画(); 函数初始化(){ renderer=new THREE.WebGLRenderer({alpha:true,antialas:true}); renderer.setSize(window.innerWidth、window.innerHeight); document.body.appendChild(renderer.doElement);

我制作了一个小的three.js应用程序,可以将一组圆圈从画布底部移动到顶部:

let渲染器、场景、灯光、圆、摄影机;
初始化();
制作动画();
函数初始化(){
renderer=new THREE.WebGLRenderer({alpha:true,antialas:true});
renderer.setSize(window.innerWidth、window.innerHeight);
document.body.appendChild(renderer.doElement);
场景=新的三个。场景();
灯光=新的三个。环境灯光();
场景。添加(灯光);
圆圈=新的三个。组();
场景。添加(圆圈);
摄像头=新的三个透视摄像头(45,renderer.domElement.clientWidth/renderer.domElement.clientHeight,1);
camera.position.z=圆.position.z+500;
}
函数animate(){
//更新每个圆圈。
Array.from(circles.children).forEach(circle=>{
if(圆位置y<可视框(圆位置z).最大y){
圆位置y+=4;
}否则{
圆圈。删除(圆圈);
}
});
//创建一个新的圆。
设circle=new THREE.Mesh();
圆几何=新的三圆几何(30,30);
circle.material=new THREE.MeshToonMaterial({color:randomColor(),transparent:true,opacity:0.5});
circle.position.z=u.random(camera.position.z-camera.far,camera.position.z-(camera.far/10));
circle.position.x=uu.random(visibleBox(circle.position.z).min.x,visibleBox(circle.position.z).max.x);
圆.position.y=可视框(圆.position.z).min.y;
圆。添加(圆);
//渲染场景。
渲染器。渲染(场景、摄影机);
请求动画帧(动画);
}
函数可视框(z){
返回新的3.Box2(
新的三矢量2(-1000,-1000),
新三个矢量2(10001000)
);
}
函数randomColor(){
返回“#${.sampleSize”(“abcdef0123456789”,6).join(“”)}”;
}
正文{
宽度:100%;
身高:100%;
溢出:隐藏;
}

如下更改功能:

function visibleBox(z) {
    var t = Math.tan( THREE.Math.degToRad( camera.fov ) / 2 )
    var h = t * 2 * z;
    var w = h * camera.aspect;
    return new THREE.Box2(new THREE.Vector2(-w, h), new THREE.Vector2(w, -h));
}
circle.position.z = _.random(-camera.near, -camera.far);
var visBox = visibleBox(circle.position.z)
circle.position.x = _.random(visBox.min.x, visBox.max.x);
circle.position.y = visBox.min.y;
然后设置圆的位置,如下所示:

function visibleBox(z) {
    var t = Math.tan( THREE.Math.degToRad( camera.fov ) / 2 )
    var h = t * 2 * z;
    var w = h * camera.aspect;
    return new THREE.Box2(new THREE.Vector2(-w, h), new THREE.Vector2(w, -h));
}
circle.position.z = _.random(-camera.near, -camera.far);
var visBox = visibleBox(circle.position.z)
circle.position.x = _.random(visBox.min.x, visBox.max.x);
circle.position.y = visBox.min.y;
代码演示:

let渲染器、场景、灯光、圆、摄影机;
初始化();
制作动画();
函数初始化(){
renderer=new THREE.WebGLRenderer({alpha:true,antialas:true});
renderer.setSize(window.innerWidth、window.innerHeight);
document.body.appendChild(renderer.doElement);
场景=新的三个。场景();
灯光=新的三个。环境灯光();
场景。添加(灯光);
圆圈=新的三个。组();
场景。添加(圆圈);
摄像头=新的三个透视摄像头(45,renderer.domElement.clientWidth/renderer.domElement.clientHeight,1);
camera.position.z=圆.position.z+500;
}
函数animate(){
//更新每个圆圈。
Array.from(circles.children).forEach(circle=>{
if(圆位置y<可视框(圆位置z).最大y){
圆位置y+=4;
}否则{
圆圈。删除(圆圈);
}
});
//创建一个新的圆。
设circle=new THREE.Mesh();
圆几何=新的三圆几何(30,30);
circle.material=new THREE.MeshToonMaterial({color:randomColor(),transparent:true,opacity:0.5});
圆.position.z=u0.random(-(camera.near+(camera.far camera.near)/5)、-camera.far);
var visBox=可视框(圆圈位置z)
圆.position.x=uu0.random(visBox.min.x,visBox.max.x);
圆.position.y=visBox.min.y;
圆。添加(圆);
//渲染场景。
渲染器。渲染(场景、摄影机);
请求动画帧(动画);
}
函数可视框(z){
var t=Math.tan(三个Math.degToRad(camera.fov)/2)
var h=t*2*z;
var w=h*camera.aspect;
返回新的THREE.Box2(新的THREE.Vector2(-w,h),新的THREE.Vector2(w,-h));
}
函数randomColor(){
返回“#${.sampleSize”(“abcdef0123456789”,6).join(“”)}”;
}


作为一个选项。您知道摄像机到圆的视场和距离,因此可以计算上下点(y轴)。你知道视场、纵横比和从相机到圆的距离,所以你可以计算左右限制(x轴)的边界。我对此进行了改进,但对于用户的想法来说,这似乎有点GLSL重?至少这个问题没有用GLSL标记,而且很多three.js用户甚至没有编写任何着色器逻辑。@pailhead它或多或少是伪代码。我想解释一下算法。但是如果你用javascript/three.js编码来写一个答案,我会投赞成票。