gpt4 book ai didi

opengl - 从clipspace.xyz和(inv)投影矩阵计算clipspace.w

转载 作者:行者123 更新时间:2023-12-04 13:52:12 24 4
gpt4 key购买 nike

我正在使用对数深度算法,该算法导致someFunc(clipspace.z)被写入深度缓冲区,并且没有隐式透视划分。

我正在执行RTT/后处理,因此稍后在片段着色器中,我想重新计算eyespace.xyz,给定ndc.xy(来自片段坐标)和clipspace.z(来自someFuncInv(),存储在深度缓冲区中的值) 。

请注意,我没有clipspace.w,并且存储的值不是clipspace.z/clipspace.w(就像使用固定函数深度时那样)-沿...

float clip_z = ...; /* [-1 .. +1] */
vec2 ndc = vec2(FragCoord.xy / viewport * 2.0 - 1.0);
vec4 clipspace = InvProjMatrix * vec4(ndc, clip_z, 1.0));
clipspace /= clipspace.w;

...在这里不起作用。

那么,给定投影矩阵或逆矩阵,有没有一种方法可以从clipspace.xyz中计算出clipspace.w呢?

最佳答案

clipspace.xy = FragCoord.xy / viewport * 2.0 - 1.0;

就术语而言,这是错误的。 “剪辑空间”是顶点着色器(或最后一个“顶点处理”阶段所输出的)空间。剪辑空间和窗口空间之间是归一化设备坐标(NDC)空间。 NDC空间是剪辑空间除以剪辑空间W坐标:
vec3 ndcspace = clipspace.xyz / clipspace.w;

因此,第一步是获取我们的窗口空间坐标并获取NDC空间坐标。这很简单:
vec3 ndcspace = vec3(FragCoord.xy / viewport * 2.0 - 1.0, depth);

现在,我将假设您的 depth值是正确的NDC空间深度。我假设您从深度纹理中获取值,然后使用深度范围的近/远值渲染该深度值,以将其映射到[-1,1]范围。如果没有,那应该。

那么,既然我们有了 ndcspace,我们如何计算 clipspace?好吧,这很明显:
vec4 clipspace = vec4(ndcspace * clipspace.w, clipspace.w);

很明显,...没有帮助,因为我们没有 clipspace.w。那么我们如何得到它呢?

为此,我们需要看看第一次计算 clipspace的方式:
vec4 clipspace = Proj * cameraspace;

这意味着 clipspace.w是通过获取 cameraspace并将其乘以 Proj的第四行乘积产生的。

好吧,这不是很有帮助。如果我们实际查看 Proj的第四行,它将变得更有帮助。当然,您可以使用任何投影矩阵,并且,如果您不使用典型的投影矩阵,则此计算将变得更加困难(可能无法实现)。
Proj的第四行使用典型的投影矩阵,实际上就是这样:
[0, 0, -1, 0]

这意味着 clipspace.w实际上只是 -cameraspace.z。这对我们有什么帮助?

记住以下内容会有所帮助:
ndcspace.z = clipspace.z / clipspace.w;
ndcspace.z = clipspace.z / -cameraspace.z;

好吧,那很好,但是它只是将一个未知数换成另一个。我们仍然有两个未知数( clipspace.zcameraspace.z)的方程。但是,我们确实知道一些其他信息: clipspace.z来自投影矩阵第三行的点乘 cameraspace。传统投影矩阵的第三行如下所示:
[0, 0, T1, T2]

其中T1和T2是非零数字。我们暂时将忽略这些数字。因此, clipspace.z实际上只是 T1 * cameraspace.z + T2 * cameraspace.w。如果我们知道 cameraspace.w是1.0(通常是),则可以将其删除:
ndcspace.z = (T1 * cameraspace.z + T2) / -cameraspace.z;

因此,我们仍然有一个问题。实际上,我们没有。为什么?因为在这个方程中只有一个未知数。请记住:我们已经知道 ndcspace.z。因此,我们可以使用ndcspace.z来计算 cameraspace.z:
ndcspace.z = -T1 + (-T2 / cameraspace.z);
ndcspace.z + T1 = -T2 / cameraspace.z;
cameraspace.z = -T2 / (ndcspace.z + T1);
T1T2来自我们的投影矩阵(场景最初用于渲染的矩阵)。而且我们已经有了 ndcspace.z。这样我们就可以计算 cameraspace.z。而且我们知道:
clispace.w = -cameraspace.z;

因此,我们可以这样做:
vec4 clipspace = vec4(ndcspace * clipspace.w, clipspace.w);

显然,您需要为 clipspace.w而不是文字代码添加浮点数,但是您明白我的意思。一旦有了 clipspace,就可以获取相机空间,然后乘以反投影矩阵:
vec4 cameraspace = InvProj * clipspace;

关于opengl - 从clipspace.xyz和(inv)投影矩阵计算clipspace.w,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14523588/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com