- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
VREyeParameters
里面曾经有视野信息,但这已被弃用。所以现在我想知道:是否可以使用 VRFrameData
提供的 View /投影矩阵来计算它?
最佳答案
投影矩阵描述了从场景的 3D 点到视口(viewport)的 2D 点的映射。投影矩阵从 View 空间变换到裁剪空间。剪辑空间坐标为 Homogeneous coordinates .通过除以 w
组件,将剪辑空间中的坐标转换为 (-1, -1, -1) 到 (1, 1, 1) 范围内的归一化设备坐标 (NDC)剪辑坐标。
在透视投影中,投影矩阵描述了从针孔相机看到的世界中的 3D 点到视口(viewport)的 2D 点的映射。
相机平截头体(截棱锥)中的眼空间坐标映射到立方体(归一化设备坐标)。
如果你想知道视空间中相机平截头体的 Angular 点,那么你必须变换标准化设备空间的 Angular 点 (-1, -1, -1), ..., (1, 1, 1) 通过逆投影矩阵。获取cartesian coordinates ,结果的 X、Y 和 Z 分量必须除以结果的 W(第 4)分量。
glMatrix是一个提供矩阵运算和数据类型的库,例如 mat4
和 vec4
:
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/
VREyeParameters里面曾经有视野信息,但这已被弃用。所以现在我想知道:是否可以使用 VRFrameData 提供的 View /投影矩阵来计算它? 最佳答案 投影矩阵描述了从场景的 3D
我是一名优秀的程序员,十分优秀!