H.B*_*.B. 5 javascript webgl webvr
曾经有过视野信息VREyeParameters,但已被弃用.所以现在我想知道:有可能使用提供的视图/投影矩阵来计算VRFrameData吗?
投影矩阵描述了从场景的3D点到视口的2D点的映射.投影矩阵从视图空间变换到剪辑空间.剪辑空间坐标是同构坐标.通过用w剪辑坐标的分量划分,剪辑空间中的坐标被变换为范围(-1,-1,-1)到(1,1,1)范围内的归一化设备坐标(NDC).
在透视投影中,投影矩阵描述了从针孔相机到视口的2D点看世界中3D点的映射.
相机平截头体(截头金字塔)中的眼睛空间坐标被映射到立方体(标准化设备坐标).
如果你想知道视图空间中相机平截头体的角,那么你必须转换标准化设备空间(-1,-1,-1),...,(1,1,1)的角.所述逆投影矩阵.要获得笛卡尔坐标,结果的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]];
Run Code Online (Sandbox Code Playgroud)
可以通过逆视图矩阵完成变换视图坐标到世界坐标.
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 );
Run Code Online (Sandbox Code Playgroud)
注意,左投影矩阵和右投影矩阵不对称.这意味着视线不在视锥体的中心,并且它们对于左眼和右眼是不同的.
另请注意,透视投影矩阵如下所示:
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
Run Code Online (Sandbox Code Playgroud)
其中:
a = w / h
ta = tan( fov_y / 2 );
2 * n / (r-l) = 1 / (ta * a)
2 * n / (t-b) = 1 / ta
Run Code Online (Sandbox Code Playgroud)
如果投影是对称的,其中视线位于视口的中心并且视场不移位,则矩阵可以简化:
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
Run Code Online (Sandbox Code Playgroud)
这意味着视角可以通过以下公式计算:
fov_y = Math.atan( 1/prjMat[5] ) * 2; // prjMat[5] is prjMat[1][1]
Run Code Online (Sandbox Code Playgroud)
和纵横比:
aspect = prjMat[5] / prjMat[0];
Run Code Online (Sandbox Code Playgroud)
如果投影矩阵仅沿水平方向对称,则视场角的计算也有效.这意味着如果-bottom等于top.对于2只眼睛的投影矩阵,应该是这种情况.
此外:
z_ndc = 2.0 * depth - 1.0;
z_eye = 2.0 * n * f / (f + n - z_ndc * (f - n));
Run Code Online (Sandbox Code Playgroud)
通过替换投影矩阵的字段,这是:
A = prj_mat[2][2]
B = prj_mat[3][2]
z_eye = B / (A + z_ndc)
Run Code Online (Sandbox Code Playgroud)
这意味着到近平面和远平面的距离可以通过以下公式计算:
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);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
363 次 |
| 最近记录: |