如何在three.js中不延伸前景而增加透视

Spl*_*iFF 5 javascript three.js

我有一个带有纹理地板平面的three.js场景,需要一个非常特定的视角来与静态2D叠加层对齐

图像在这里

我的问题是,我越多地增加相机FOV以获得我需要的视角,前景延伸越多,我不希望这样.我似乎需要一个非常高的FOV(~120-150)来使纹理跟随墙壁,这是如此之高,以至于相机正在将物体定位在它后面.我需要将相机几乎移动到场景的中心,以显示整个楼层,这只是感觉不对.如何调整此场景,以便在没有失真的情况下获得正确的视角?

实例:http://warriorhut.net/testing/shapes/backend/room/view.basic.php

相关的相机设置是:

var WIDTH = 1024;
var HEIGHT = 683;
var FOV = 140; // Increases perspective as it goes higher but also distortion

camera =  new THREE.PerspectiveCamera(FOV, WIDTH/HEIGHT, .1, 3000);

camera.position.x = 0;
camera.position.y = 200;
camera.position.z = 0;  
//camera.lookAt(scene.position);
camera.lookAt(new THREE.Vector3( 0, 100, -400 )); // look at the back of the room
camera.updateProjectionMatrix();
Run Code Online (Sandbox Code Playgroud)

rha*_*oto 10

将虚拟对象添加到现有图像需要尽可能地匹配原始相机参数.在这种情况下,因为图像是合成的,理想情况下,您可以从生成它的人那里获取这些参数.否则,我们可以尝试通过对图像进行测量来推断一些参数.

我将做出针孔相机的标准假设,并进一步假设光轴位于图像的中心.场景中的平行线将在消失点处相遇.在此图像中,我们只能确定一个具有任何精度的消失点:

在此输入图像描述

这里的平行线也与地平面平行,这意味着消失点在地平线上.因此,地平线略低于该图像的中心,这意味着相机略微向上倾斜.

向上多少钱?消失点在图像中心下方约为0.022个图像高度(15个像素).我们可以根据垂直视场表达指示的摄像机俯仰:

pitch = arctan(2 * tan(vfov/2) * 0.022)
Run Code Online (Sandbox Code Playgroud)

我们可以类似地确定相对于平行线的相机的偏航.消失点位于中心右侧约0.010像素高度,因此相机略微向左偏转.

yaw = arctan(2 * tan(vfov/2) * -0.010)
Run Code Online (Sandbox Code Playgroud)

为了在three.js应用程序中表达这一点,我修改了代码的相机配置部分,如下所示:

var FOV = 75;

[...]

camera.position.x = 0;
camera.position.y = 200;
camera.position.z = 512;

var lookTarget = new THREE.Vector3().copy(camera.position);
var tanScale = 2 * Math.tan(FOV/2 * Math.PI/180);
lookTarget.x += -0.010 * tanScale;
lookTarget.y +=  0.022 * tanScale;
lookTarget.z += -1;
camera.lookAt(lookTarget);

camera.updateProjectionMatrix();
Run Code Online (Sandbox Code Playgroud)

我将相机向后移动(朝向正Z)以使大部分地板几何体可见(这不会改变渲染几何体的消失点).然后我改为FOV75度(仍然是一个很宽的角度视图),纹理图案现在自动收敛于消失点,透视失真更小:

在此输入图像描述

请注意,您现在可以看到地板几何体的末端,因为假设较小的视野会增加图像的假定深度,因此您可能需要增加地板的大小.您可以修改视野以调整纹理缩短,相机代码应将消失点保持在同一位置.我不相信这个特定图像中有足够的特征让我们估计它的实际焦距,但它可能在其他图像中 - 在这种情况下我们也可以推断出视场.