我正在从多个灯光和后处理着色器内的屏幕空间位置计算 View 空间位置。我当前的代码是使用投影矩阵的逆来恢复位置:
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
这样的变量恢复 View 空间位置。 , near-clip
和 far-clip
.
最佳答案
你没有说你是如何创建透视投影矩阵的,这是关键信息。我不是 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,将 x,y,z 除以 w:
[(1/a)ux (1/b)uy -u] where u = d / (z+c)
(1/a) 和 (1/b) 项当然可以预先计算。之后,您需要进行一次加法、一次除法和四次乘法来完成这项工作。
由于我不知道的 D3D 和 OpenGL 坐标系之间的差异,这种解释可能会偏离一些负号或其他小细节的模数。
说了这么多,我同意评论者的看法,他们认为这不会产生有意义的加速。
关于shader - 如何在没有矩阵乘法的情况下从屏幕空间位置计算 View 空间位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23540799/