shader - 如何在没有矩阵乘法的情况下从屏幕空间位置计算 View 空间位置

标签 shader hlsl

我正在从多个灯光和后处理着色器内的屏幕空间位置计算 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-clipfar-clip .

最佳答案

你没有说你是如何创建透视投影矩阵的,这是关键信息。我不是 D3D 专家。相反,我知道 OpenGL。

所以我可以向你展示如何使用 OpenGL gluPerspective 的矩阵来做到这一点。产生。它具有以下形式:

gluPerspective matrix

该矩阵用于 OpenGL 列向量。您的 D3D 代码使用行向量,因此我将假设转置。为方便起见,重命名非零项并取逆:

gluPerspective simplified and inverted

Wolfram Alpha 象征性地反转(这种事情的一个很好的工具):

{{a,0,0,0},{0,b,0,0},{0,0,c,-1},{0,0,d,0}}^-1

我们得到:

inverse matrix expression

所以如果乘以的点是 [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/

相关文章:

c# - 使用 Kinect 深度 View 显示人体内部的物体

wpf - 像素着色器将纹理投影到任意四边形

opengl-es - WebGL - 在平面上显示球体

directx - 如何使用着色器常量缓冲区?

unity-game-engine - 像素化照明着色器

shader - HLSL : multi pass shader?

c++ - 如何填充常量着色器以避免 E_INVALIDARG?

c++ - 将纹理数组发送到 DirectX 11 中的着色器

angular - 在 Angular nx 项目中导入 glsl 文件

树莓派上的 JavaFX : Error loading stock shader