gpt4 book ai didi

javascript - 如何从 VRFrameData 计算 FOV?

转载 作者:数据小太阳 更新时间:2023-10-29 06:04:46 25 4
gpt4 key购买 nike

VREyeParameters里面曾经有视野信息,但这已被弃用。所以现在我想知道:是否可以使用 VRFrameData 提供的 View /投影矩阵来计算它?

最佳答案

投影矩阵描述了从场景的 3D 点到视口(viewport)的 2D 点的映射。投影矩阵从 View 空间变换到裁剪空间。剪辑空间坐标为 Homogeneous coordinates .通过除以 w 组件,将剪辑空间中的坐标转换为 (-1, -1, -1) 到 (1, 1, 1) 范围内的归一化设备坐标 (NDC)剪辑坐标。

在透视投影中,投影矩阵描述了从针孔相机看到的世界中的 3D 点到视口(viewport)的 2D 点的映射。
相机平截头体(截棱锥)中的眼空间坐标映射到立方体(归一化设备坐标)。

enter image description here

如果你想知道视空间中相机平截头体的 Angular 点,那么你必须变换标准化设备空间的 Angular 点 (-1, -1, -1), ..., (1, 1, 1) 通过逆投影矩阵。获取cartesian coordinates ,结果的 X、Y 和 Z 分量必须除以结果的 W(第 4)分量。
glMatrix是一个提供矩阵运算和数据类型的库,例如 mat4vec4:

projection  = mat4.clone( VRFrameData.leftProjectionMatrix );
inverse_prj = mat4.create();
mat4.invert( inverse_prj, projection );

pt_ndc = [-1, -1, -1];
v4_ndc = vec4.fromValues( pt_ndc[0], pt_ndc[1], pt_ndc[2], 1 );

v4_view = vec4.create();
vec4.transformMat4( v4_view, v4_ndc, inverse_prj );
pt_view = [v4_view[0]/v4_view[3], v4_view[1]/v4_view[3], v4_view[2]/v4_view[3]];

View 坐标到世界坐标的转换可以通过逆 View 矩阵来完成。

view         = mat4.clone( VRFrameData.leftViewMatrix );
inverse_view = mat4.create();
mat4.invert( inverse_view, view );

v3_view = vec3.clone( pt_view );
v3_world = vec3.create();
mat4.transformMat4( v3_world, v3_view, inverse_view );

注意,左右投影矩阵不是对称的。这意味着视线不在平截头体的中心,并且左右眼的视线不同。


进一步注意,透视投影矩阵如下所示:

r = right, l = left, b = bottom, t = top, n = near, f = far

2*n/(r-l) 0 0 0
0 2*n/(t-b) 0 0
(r+l)/(r-l) (t+b)/(t-b) -(f+n)/(f-n) -1
0 0 -2*f*n/(f-n) 0

哪里:

a = w / h
ta = tan( fov_y / 2 );

2 * n / (r-l) = 1 / (ta * a)
2 * n / (t-b) = 1 / ta

如果投影是对称的,视线在视口(viewport)的中心,视野没有位移,那么矩阵可以简化:

1/(ta*a)  0     0              0
0 1/ta 0 0
0 0 -(f+n)/(f-n) -1
0 0 -2*f*n/(f-n) 0

这意味着视野 Angular 可以通过以下方式计算:

fov_y = Math.atan( 1/prjMat[5] ) * 2; // prjMat[5] is prjMat[1][1] 

和纵横比:

aspect = prjMat[5] / prjMat[0];


如果投影矩阵仅沿水平方向对称,则视野 Angular 的计算也有效。这意味着如果 -bottom 等于 top。 2只眼睛的投影矩阵应该是这样的。

此外:

z_ndc = 2.0 * depth - 1.0;
z_eye = 2.0 * n * f / (f + n - z_ndc * (f - n));

通过替换投影矩阵的字段,这是:

A = prj_mat[2][2]
B = prj_mat[3][2]
z_eye = B / (A + z_ndc)

这意味着到近平面和远平面的距离可以通过以下方式计算:

A = prj_mat[10]; // prj_mat[10] is prj_mat[2][2]
B = prj_mat[14]; // prj_mat[14] is prj_mat[3][2]

near = - B / (A - 1);
far = - B / (A + 1);

关于javascript - 如何从 VRFrameData 计算 FOV?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48443671/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com