OpenGL 如何从平截头体对齐向量计算世界空间坐标?

OpenGL How to calculate worldspace coordinates from frustum aligned vectors?

我是一名图形编程初学者,在我自己的引擎上工作并尝试实现平截头体对齐的体积渲染。

我们的想法是将多个平面渲染为视锥体的垂直切片,然后将这些平面的世界坐标用于程序体积。

将切片渲染为 3d 模型并将顶点位置用作世界坐标 space 效果非常好:

//Vertex Shader  
gl_Position = P*V*vec4(vertexPosition_worldspace,1);
coordinates_worldspace = vertexPosition_worldspace;

结果:

但是在截锥体-space 中渲染切片并尝试对世界 space 坐标进行逆向工程并没有给出预期的结果。我得到的最接近的是:

//Vertex Shader
gl_Position = vec4(vertexPosition_worldspace,1);
coordinates_worldspace = (inverse(V) * inverse(P) * vec4(vertexPosition_worldspace,1)).xyz;

结果:

我的猜测是,标准投影矩阵以某种方式摆脱了一些关键的深度信息,但除此之外我不知道我做错了什么以及如何解决它。

嗯,"frustum space" 不是 100% 清楚你的意思。我将假设它确实引用了 OpenGL 中的 标准化设备坐标 ,其中视锥体是(默认情况下)轴对齐的立方体 -1 <= x,y,z <= 1。我还将假设透视投影,因此 NDC z 坐标实际上是眼睛 space z.[=] 的 双曲线 函数30=]

My guess is, that the standard projection matrix somehow gets rid of some crucial depth information, but other than that i have no clue what i am doing wrong and how to fix it.

不,OpenGL 中的标准透视矩阵看起来像

( sx   0   tx   0  ) 
(  0  sy   ty   0  )
(  0   0    A   B  )
(  0   0   -1   0  )

当您将其乘以 (x,y,z,1) 眼睛 space 向量时,您将得到同质剪辑坐标。只考虑 矩阵的最后两行作为单独的方程式:

z_clip = A * z_eye + B
w_clip = -z_eye

由于我们将透视除以 w_clip 从剪辑 space 到 NDC,我们最终得到

z_ndc = - A - B/z_eye

这实际上是双曲线重新映射的深度信息 - 因此信息被完全保留。 (另请注意,我们还对 xy 进行除法)。

当你计算inverse(P)时,你只是反转了4D -> 4D同构映射。但是你会得到一个 w 而不是 1 的结果,所以这里:

coordinates_worldspace = (inverse(V) * inverse(P) * vec4(vertexPosition_worldspace,1)).xyz;
                                                                                       ^^^

谎言你的信息丢失。您只需跳过生成的 w 并使用 xyz 组件,就好像它是笛卡尔 3D 坐标一样,但它们是表示某些 3D 点的 4D 齐次坐标。

正确的方法是除以 w:

vec4 coordinates_worldspace = (inverse(V) * inverse(P) * vec4(vertexPosition_worldspace,1));
coordinates_worldspace /= coordinates_worldspace.w