如何计算与 3D 空间中的对象(本例中为图像)的相机距离,以使图像处于其原始像素宽度。
考虑到相机的纵横比、fov 和图像的原始宽度/高度(以像素为单位),我是否正确地假设这是可能的?
(如果相关,我在这个特定实例中使用 THREE.js)。
感谢任何可以帮助或引导我走向正确方向的人!
如何计算与 3D 空间中的对象(本例中为图像)的相机距离,以使图像处于其原始像素宽度。
考虑到相机的纵横比、fov 和图像的原始宽度/高度(以像素为单位),我是否正确地假设这是可能的?
(如果相关,我在这个特定实例中使用 THREE.js)。
感谢任何可以帮助或引导我走向正确方向的人!
感谢大家的所有投入!
在进行了一些挖掘,然后弄清楚这一切如何适合我试图用 THREE.js 解决的确切问题之后,这是我在 JavaScript 中提出的答案,作为以原始比例显示事物的目标 Z 距离:
var vFOV = this.camera.fov * (Math.PI / 180), // convert VERTICAL fov to radians
var targetZ = window.innerHeight / (2 * Math.tan(vFOV / 2) );
我试图找出将哪一个标记为答案,但我将所有这些都组合到了这个解决方案中。
三角函数:
一条长度为 l 的线段与视图平面成直角,并且垂直于它的距离为 n 将在相机上对角 arctan(l/n) 度。您可以通过简单的三角函数得出该结果。
因此,如果您在直线方向上的视野是 q,相当于 p 个像素,那么您最终将占据p*arctan(l/n)/q
像素。
因此,使用 y 作为输出像素数:
y = p*arctan(l/n)/q
y*q/p = arctan(l/n)
l/tan(y*q/p) = n
线性代数:
在具有 90 度视野和 2w 像素宽的视口的相机中,投影到屏幕空间中相当于:
x' = w - w*x/z
当垂直时,屏幕上一条线的长度是两个这样的 x 之间的差,因此根据正常的关联性和交换性规则:
l' = w - w*l/z
因此:
w - l' = w*l/z
z = (w - l') / (w*l)
如果您的视野实际上是 q 度而不是 90 度,那么您可以使用余切来适当地缩放。
在您最初的问题中,您说您正在使用 css3D。我建议您执行以下操作:
设置一个 fov = 1..179 度的正交相机,其中left = screenWidth / 2,right = screenWidth / - 2,top = screenHeight / 2,bottom = screenHeight / - 2。近平面和远平面不影响CSS3D渲染据我所知,经验。
camera = new THREE.OrthographicCamera(left, right, top, bottom, near, far);
camera.fov = 75;
现在您需要计算相机和物体之间的距离,这样当使用上述设置的相机投影物体时,物体在屏幕上具有 1:1 的坐标对应关系。这可以通过以下方式完成:
var camscale = Math.tan(( camera.fov / 2 ) / 180 * Math.PI);
var camfix = screenHeight / 2 / camscale;
这应该为您提供与渲染结果和 css / div 样式中的像素值的 1:1 坐标对应关系。请记住,原点在中心,对象的位置是对象的中心,因此您需要进行调整以实现例如左上角的坐标规格
object.x = ( screenWidth - objectWidth ) / 2 + positionLeft
object.y = ( screenHeight - objectHeight ) / 2 + positionTop
object.z = 0
我希望这会有所帮助,我一直在为同样的事情苦苦挣扎(精确控制 css3d 场景),但设法弄清楚正交相机 + 视口大小调整到对象的距离起到了作用。不要改变相机旋转或其 x 和 y 坐标,只需调整 z 即可。