Mic*_*aël 4 javascript camera three.js
我想在动画过程中修改相机的 FOV 值。不幸的是,一旦我实现了 FOV 值,我就可以观察到我的场景变得更小。
所以我一直想知道,FOV 值和透视相机的距离位置之间的数学联系是什么?
这个想法是在 FOV 值发生变化时拥有相同的场景(通过修改相机位置来实现相同的大小)。
非常感谢。
编辑1:
这是说明我的问题的片段:当我实现相机的 FOV 值(从 4 到 45)时,我的方块和相机之间的距离发生了变化。我该如何预防呢?
let W = window.innerWidth, H = window.innerHeight;
let renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( W, H );
document.body.appendChild( renderer.domElement );
let camera = new THREE.PerspectiveCamera( 4, W/H, 1, 100 );
let scene = new THREE.Scene();
camera.position.set(0,0,14);
camera.lookAt(0,0,0);
let geo = new THREE.BoxGeometry(0.5, 0.5, 0.5);
let mat = new THREE.MeshNormalMaterial();
let mesh = new THREE.Mesh(geo, mat);
mesh.rotation.set(0.2,0.4,-0.1);
scene.add(mesh);
renderer.render(scene, camera);
let progress = {};
progress.fov = 4;
TweenMax.to(progress, 2,{
fov:45,
onUpdate:function(){
camera.lookAt(0,0,0);
camera.updateProjectionMatrix();
camera.fov = progress.fov;
renderer.render(scene, camera);
},
repeat:-1,
ease:Power3.easeInOut
});
Run Code Online (Sandbox Code Playgroud)
body{margin:0;padding:0;overflow:hidden;background: #666;}Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/108/three.js"></script>Run Code Online (Sandbox Code Playgroud)
Rab*_*d76 10
透视投影描述了从针孔相机看到的世界上的 3D 点到视口的 2D 点的映射。这意味着投影在视口上的对象因其深度而变小。
视图空间中的投影面积与视图空间的 Z 坐标之间的关系是线性的。这取决于视角和纵横比。
另请参见THREE.js PerspectiveCamera focusLength 关闭两倍,与 FOV 不一致。
透视投影时, Z 距离与视野大小之间的关系fov_y为:
depht_s = Math.tan(fov_y/2.0 * Math.PI/180.0) * 2.0;
Run Code Online (Sandbox Code Playgroud)
对象在视口上的投影尺寸取决于视野和深度。这导致当视野改变时,3维物体永远不会“看起来”相同。您可以在一定距离(深度)内定义一个平面并找到一个新距离,以便在该深度上,对象的投影大小不会发生变化。当然,该特定距离“之前”和“之后”的物体的投影尺寸将会(至少轻微地)改变。另请参阅如何在透视相机和正交相机之间切换,分别保持所需对象的大小,在 Three.js 中将 z 位置从透视相机转置为正交相机。
请参阅插图。当物体靠近相机时,从相机看不到立方体的顶点,但当物体远离相机时,可以看到它:
初始视野为4.0。所以 Z 距离和尺寸之间的比率是:
let init_depht_s = Math.tan(4.0/2.0 * Math.PI/180.0) * 2.0;
Run Code Online (Sandbox Code Playgroud)
当视野动画化时,Z 距离和大小之间的当前比率为:
let current_depht_s = Math.tan(progress.fov/2.0 * Math.PI/180.0) * 2.0;
Run Code Online (Sandbox Code Playgroud)
现在您必须定义一个距离,该距离必须“保持尺寸”。到立方体中心的初始距离是 14.0,所以我将选择它作为参考距离。该距离必须按 ration 进行缩放init_depht_s / current_depht_s,然后立方体的投影(恰好在该距离处)保持其大小:
camera.position.set(0, 0, 14 * init_depht_s / current_depht_s);
Run Code Online (Sandbox Code Playgroud)
请参阅示例,该示例基于您的原始代码(我已将近平面更改为 0.1,否则立方体将被剪裁,因为最终距离低于 1.0):
let W = window.innerWidth, H = window.innerHeight;
let renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( W, H );
document.body.appendChild( renderer.domElement );
let camera = new THREE.PerspectiveCamera( 4, W/H, 0.1, 100 );
let scene = new THREE.Scene();
camera.position.set(0,0,14);
camera.lookAt(0,0,0);
let geo = new THREE.BoxGeometry(0.5, 0.5, 0.5);
let mat = new THREE.MeshNormalMaterial();
let mesh = new THREE.Mesh(geo, mat);
mesh.rotation.set(0.2,0.4,-0.1);
scene.add(mesh);
renderer.render(scene, camera);
let progress = {};
progress.fov = 4;
TweenMax.to(progress, 2,{
fov:45,
onUpdate:function(){
let init_depht_s = Math.tan(4.0/2.0 * Math.PI/180.0) * 2.0;
let current_depht_s = Math.tan(progress.fov/2.0 * Math.PI/180.0) * 2.0;
camera.position.set(0, 0, 14 * init_depht_s / current_depht_s);
camera.lookAt(0,0,0);
camera.updateProjectionMatrix();
camera.fov = progress.fov;
renderer.render(scene, camera);
},
repeat:-1,
ease:Power3.easeInOut
});Run Code Online (Sandbox Code Playgroud)
body{margin:0;padding:0;overflow:hidden;background: #666;}Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/108/three.js"></script>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6706 次 |
| 最近记录: |