我正在计算多个光照和后处理着色器内部的屏幕空间位置的视图空间位置。我当前的代码是使用投影矩阵的反转来恢复位置:
float depth = depthBuffer.Sample(sampler, uv).x;
float4 temp = mul(float4(uv.x * 2 - 1, (1 - uv.y) * 2 - 1, depth, 1), inverseProjectionMatrix);
float3 viewSpacePosition = temp.xyz / temp.w;
作为优化,我想从着色器中删除矩阵乘法,并使用aspect
,near-clip
和far-clip
等变量恢复视图空间位置。
答案 0 :(得分:3)
您没有说明如何创建透视投影矩阵,这是关键信息。我不是D3D专家。相反,我知道OpenGL。
因此,我可以向您展示如何使用OpenGL gluPerspective
生成的矩阵执行此操作。它的格式为:
此矩阵用于OpenGL列向量。你的D3D代码使用行向量,所以我假设转置。为方便起见,重命名非零项并取相反:
用Wolfram Alpha(一种很好的工具)来象征性地反转:
{{a,0,0,0},{0,b,0,0},{0,0,c,-1},{0,0,d,0}}^-1
我们得到:
因此,如果与代码相乘的点是[x y z 1]
,那么您想要的结果是
[x/a y/b -1 (z+c)/d]
这是一个4d同质点。要回到3d,用w:
除以x,y,z[(1/a)ux (1/b)uy -u] where u = d / (z+c)
当然可以预先计算(1 / a)和(1 / b)项。之后,您需要一次加法,一次除法和四次乘法来完成这项工作。
由于我不知道的D3D和OpenGL坐标系之间的差异,这个解释可以取消一些负面的迹象或其他细微的细节。
说完这一切之后,我同意那些认为这不会产生有意义的加速的评论者。