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

标签 opengl matrix-inverse projection-matrix frustum volume-rendering

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

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

将切片渲染为 3D 模型并使用顶点位置作为世界空间坐标,效果非常好:

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

结果:

然而,在视锥体空间中渲染切片并尝试对世界空间坐标进行逆向工程并不能给出预期的结果。我得到的最接近的是:

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

结果:

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

最佳答案

嗯,“截锥体空间”的含义并不是 100% 清楚。我假设它确实引用了 OpenGL 中的标准化设备坐标,其中视锥体(默认情况下)是轴对齐的立方体 -1 <= x,y,z <= 1 。我还将假设一个透视投影,以便 NDC z坐标实际上是眼睛空间的双曲函数 z .

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)时眼睛空间向量,您将获得同质剪辑坐标。仅考虑 矩阵的最后两行作为单独的方程:

z_clip = A * z_eye + B
w_clip = -z_eye

因为我们将透视除以 w_clip为了从剪辑空间到 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

关于OpenGL如何从平截头体对齐向量计算世界空间坐标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53728282/

相关文章:

concurrency - 大矩阵求逆

Three.js:在场景角落显示世界坐标轴

iphone - 如何从“顶点缓冲对象”绘制单个三角形并设置其颜色?

c++ - 使用 OpenSceneGraph 创建和导出球体

c++ - OpenGL GL_TEXTURE1 不显示

performance - 矩阵求逆的最快方法

java - 物体不旋转

c++ - 单应性投影矩阵

java - 将 Tango 3D 点投影到屏幕 Google Project Tango

webgl - 伪圆柱投影的投影矩阵