Math 如何计算摄影机的z距离,以便在3D空间中以原始比例的100%查看图像

Math 如何计算摄影机的z距离,以便在3D空间中以原始比例的100%查看图像,math,3d,three.js,linear-algebra,Math,3d,Three.js,Linear Algebra,如何计算3D空间(本例中为图像)中相机与对象的距离,从而使图像保持其原始像素宽度 我假设这是可能的,假设相机的纵横比、fov和图像的原始宽度/高度(以像素为单位)正确吗 (如果相关的话,我在这个特定的实例中使用THREE.js) 感谢所有能帮助我或带领我走向正确方向的人 三角: 长度为l的线段与视图平面成直角,且与视图平面垂直的距离为n,该线段将对摄影机上的arctan(l/n)度。你可以通过简单的三角法得到这个结果 因此,如果直线方向上的视野为q,相当于p个像素,那么最终将占据p*arctan

如何计算3D空间(本例中为图像)中相机与对象的距离,从而使图像保持其原始像素宽度

我假设这是可能的,假设相机的纵横比、fov和图像的原始宽度/高度(以像素为单位)正确吗

(如果相关的话,我在这个特定的实例中使用THREE.js)

感谢所有能帮助我或带领我走向正确方向的人

三角:

长度为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度的正交摄像机,其中左=屏幕宽度/2,右=屏幕宽度/-2,上=屏幕高度/2,下=屏幕高度/-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;
  • 将div置于位置:x,y,z
  • 将相机的位置设置为0,0,z+camfix
  • 这将为您提供与渲染结果和css/div样式中的像素值的1:1坐标对应关系。请记住,原点位于中心,对象的位置位于对象的中心,因此需要进行调整,以便从左上角获得坐标等级库

    object.x = ( screenWidth - objectWidth ) / 2 + positionLeft
    object.y = ( screenHeight - objectHeight ) / 2 + positionTop
    object.z = 0
    

    我希望这能有所帮助,我也在努力做同样的事情(精确控制css3d场景),但我设法找到了正交摄影机+视口大小调整后的与对象的距离才是关键。不要改变相机的旋转或其x和y坐标,只要拨动z就可以了。

    谢谢大家的输入

    在做了一些挖掘之后,我找到了这一切如何与我试图用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) );
    

    我试图找出哪一个作为答案,但我把它们都组合到了这个解决方案中。

    谢谢!我会试试这个。在这种情况下,我的视野实际上是45。在第一个三角函数版本中,如果我有一个视野为45,屏幕分辨率为1024x768,图像大小为120x115像素的相机,我会在你的方程中用45的余切来缩放z,最终得到q=45,p=1024*768,l=115,y=120*115?还是我完全偏离了基准?不,这都是一维的;如果你向下看,直角三角形的底面长度不是斜边。所以我估计如果你的几何体是115个单位,那么在1024 px=45度的视窗中,它离摄像机大约1300个单位,屏幕上115 px方程式看起来它对于1024倍的屏幕宽度来说是完美的,但是超过这个宽度,它会变得比原来的宽度越来越小。这个看起来对吗<代码>var targetZ=原始图像宽度/(数学tan(degToRadian(原始图像宽度*(45/window.innerWidth)))对于普通2D世界,我想知道是否有一个“默认值”来初始化场景,使用z值渲染“真实像素”。据我所知,这就是它的作用,但我觉得它可以/应该是这样default@Ben我们在初始化摄影机时必须进行此计算,还是使用render()函数?