【问题标题】:[GLSL]How to compare the z value of all the vertices in world coordinate?[GLSL]如何比较世界坐标中所有顶点的z值?
【发布时间】:2011-09-22 15:35:24
【问题描述】:

这可能是一个简单的问题。作为 GLSL 的新手,我宁愿在这里问。 现在,在顶点着色器中,我可以通过以下方式获取世界坐标系中的位置:

    gl_Position = ftransform();
    posWorld = gl_ModelViewMatrix * gl_Vertex;

问题是:现在我可以得到所有顶点中 posWorld 的最大值/最小值吗?这样我就可以得到顶点深度的范围,而不是深度缓冲区的范围。

如果这不可能,我如何获得世界坐标系中近/远平面的z值?

致以最诚挚的问候,

简

【问题讨论】:

  • gl_ModelViewMatrix 进入 view 空间,而不是世界空间。这就是为什么它被称为“模型视图”:它从模型到视图。

标签: glsl depth vertex-shader zbuffer


【解决方案1】:

是的,使用 OpenGL 是可能的。我正在使用类似的技术来计算 GPU 上对象的边界框。步骤如下:

  1. 在自己的 FBO 中安排大小为 1x1 类型 RGBA_32F 的渲染缓冲区。设置为渲染目标(没有深度/模板,只有一个颜色平面)。它可以是更大纹理的像素,在这种情况下,您需要正确设置视口。
  2. 用基本值清除。 'min' 是一个巨大的数字,'max' 是负数。
  3. 根据系数 (1,1) 设置混合函数“min”或“max”。
  4. 使用生成具有 (0,0,0,1) 坐标的点的着色器绘制网格。输出包含原始顶点世界位置的颜色。

您可以从这里进一步优化。例如,您可以通过使用几何着色器并否定输出像素之一的位置,在一次绘制调用中同时获得“最小”和“最大”。

【讨论】:

  • 感谢您的回答 :D 我试图在着色器中执行此操作...但我没有完全理解您..:(
  • 我逐步解释了您最初要求的内容以及@Cristobal 认为不可能的内容。如前所述,此方案在我的引擎中适用于更新边界框。关键是:它有效。如果您不理解,请提出更具体的问题(如果仍然感兴趣)。
  • 我正在使用 xip builder,我可以做的是通过加载我自己的着色器文件(顶点着色器和片段着色器)来替换标准着色器。我正在处理体积数据而不是网格。那有可能让你的方法在着色器中工作吗?谢谢:D
  • 是的,当然,我是在着色器中做的。无论是一些数据还是网格 - 都无所谓。这是我用于 BBox 更新的几何着色器:“code.google.com/p/kri/source/browse/gpu/cull/box_g.glsl”。很基础,主要动作是在客户端OpenGL状态设置上完成的。
  • 对我来说只有顶点/片段着色器可用...几何着色器不在框架中:(
【解决方案2】:

据我所知,我认为这需要使用基于并行缩减的算法手动完成。我希望有人确认是否存在已经执行此操作的 OpenGL 或 GLSL 函数。

另一方面,您可以在片段着色器中访问归一化的近/远平面, http://www.opengl.org/wiki/GLSL_Predefined_Variables#Fragment_shader_uniforms.
在一些统一变量的帮助下,您可以让世界远近。

【讨论】:

  • 感谢您的回答。您能否给我一个关于使用哪些统一变量来从标准化的近/远到世界近/远的转换的提示?
  • @superpanda 那里只列出了 3 个统一值,您可以使用其中的 all。问题是,如果你想去查看空间,你需要的还不止这些。对于初学者(或者更确切地说,它的倒数),您需要投影矩阵。老实说,直接传递它会容易得多。那些近和远值来自您使用glFrustum 或gluPerspective 使用的视图空间近值和远值。
  • 是的,按照 Nicol 的建议传递投影矩阵。
  • 谢谢,通过投影矩阵!我通过参考这个博客页面解决了这个问题:olivers.posterous.com/linear-depth-in-glsl-for-real
猜你喜欢
  • 2021-06-13
  • 1970-01-01
  • 2013-12-16
  • 2017-11-30
  • 2011-06-21
  • 1970-01-01
  • 1970-01-01
  • 2020-03-25
  • 2020-09-12
相关资源
最近更新 更多