【问题标题】:Efficiently rendering a transparent terrain in OpenGL在 OpenGL 中高效渲染透明地形
【发布时间】:2014-07-11 18:41:10
【问题描述】:

我正在编写一个可视化洞穴的 OpenGL 程序,所以当我可视化地表地形时,我想让它透明,这样你就可以看到下面的洞穴。我假设我可以将来自数字高程模型的数据标准化为与 X/Z 轴对齐且间距规则的网格,并将每个网格单元呈现为两个三角形。使用对齐的网格,我可以在应用画家算法时避免排序成本(以确保适当的透明度效果);相反,我可以逐行渲染单元格,从最远的行和每行最远的单元格开始。

这一切都很好,但我对 OpenGL 专家的问题是,我怎样才能使用 OpenGL 最有效地绘制地形(并且以一种可以缩放到高分辨率地形的方式)?必须有比为每个网格单元调用一次glDrawElements() 更好的方法。以下是我正在考虑的一些方法(它们涉及我尚未尝试过的功能,这就是我问专家的原因):

glMultiDrawElements创意

  • 将所有地形坐标放入顶点缓冲区
  • 将所有坐标索引放入元素缓冲区中
  • 要进行绘制,请将每个单元格的起始索引按所需顺序写入一个数组,并使用该数组调用 glMultiDrawElements

这看起来不错,但我想知道是否有什么方法可以避免每帧将一组索引传输到显卡,所以我想出了以下想法:

统一缓冲区理念

这似乎是使用 OpenGL 的一种落后方式,但只是把它放在那里......

  • 将地形坐标放入统一缓冲区中的二维数组中
  • 将坐标索引偏移量 0..5 放入顶点缓冲区(我知道它们必须是浮点数)
  • 调用glDrawArraysInstanced - 每个实例都是一个网格单元
  • 顶点着色器检查相机相对于地形的位置并确定如何对单元格进行排序,将gl_instanceId映射到统一缓冲区中单元格的第一个坐标的索引,并将gl_Position设置为该索引处的坐标 + 索引偏移属性

我认为可能有一些我不知道的闪亮的新 OpenGL 4.0 功能会比这两种方法中的任何一种更优雅。我会很感激任何提示!

【问题讨论】:

    标签: performance opengl transparency terrain


    【解决方案1】:

    glMultiDrawElements() 方法听起来很合理。我将首先实现它,并将其用作您可以比较的基准,如果您尝试更复杂的方法。

    如果你有机会让它更快将取决于绘制调用的处理是否是你渲染中的一个重要瓶颈。除非您渲染的三角形非常小,和/或您的片段着色器非常简单,否则您很有可能会受到片段处理的限制。如果您拥有可让您收集数据和识别瓶颈的分析工具,那么您的优化工作就会更有针对性。当然,总是有低技术含量的方法:如果缩小窗口可以提高性能,那么很可能你主要是片段受限。

    回到您的问题:既然您询问了闪亮的新 GL4 功能,您可以检查的另一种方法是使用 glDrawElementsIndirect() 的间接渲染。除了更灵活之外,glMultiDrawElements() 的主要区别在于每次绘制使用的参数(例如您的情况下的开始索引)可以来自缓冲区。如果您映射此缓冲区并将开始索引直接写入缓冲区,这可能会阻止一份副本。您甚至可以将它与持久缓冲区映射(查找 GL_MAP_PERSISTENT_BIT)结合起来,这样您就不必每次都映射和取消映射缓冲区。

    您的统一缓冲区想法听起来很有趣。我有点怀疑它会表现得更好,但这只是一种感觉,而不是基于任何数据或直接经验。所以我认为你绝对应该尝试一下,然后报告它的效果!

    进一步扩大您的问题范围,如果您尚未考虑并拒绝它们,您还可以研究与订单无关的透明度渲染方法。例如,alpha-to-coverage 非常容易实现,而且如果您仍然使用 MSAA,它几乎是免费的。根据我有限的尝试,它不会产生非常高质量的透明效果,但如果它为您的用例完成这项工作,它可能会非常有吸引力。另一种与顺序无关的透明度技术是深度剥离。

    如果可以接受一些自我宣传,我在此处的较早答案中写了一些透明度渲染方法的概述:OpenGL ES2 Alpha test problems

    【讨论】:

    • 酷,你提到了很多我不知道的技术(感谢指向glDrawElementsIndirect() 的指针。深度剥离和覆盖范围的阿尔法很好,但我想我应该坚持下去到基于排序的方法。
    • 所以,我还没有测试统一缓冲区的想法。我得到了glMultiDrawElements() 的工作方法,并且没有明显的性能问题。如果我有时间我会尝试统一缓冲区的方法......
    猜你喜欢
    • 2012-01-16
    • 1970-01-01
    • 2011-12-26
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 2011-12-08
    相关资源
    最近更新 更多