我正在编写一个可视化洞穴的OpenGL程序,因此当我想象表面地形时,我想让它透明,所以你可以看到下面的洞穴。我假设我可以将数字高程模型中的数据标准化为以规则间距对齐到X / Z轴的网格,并将每个网格单元渲染为两个三角形。使用对齐的网格,我可以避免在应用画家算法时进行排序的成本(以确保适当的透明效果);相反,我可以逐行渲染单元格,从最远的行和每行的最远单元格开始。
这一切都很好,但我对OpenGL专家的问题是,我怎样才能使用OpenGL最有效地绘制地形(以及可以扩展到高分辨率地形的方式)?必须有一个比为每个网格单元调用glDrawElements()
一次更好的方法。以下是我正在考虑做的一些方法(它们涉及我尚未尝试过的功能,这就是我问专家的原因):
glMultiDrawElements
想法glMultiDrawElements
。这看起来还不错,但我想知道是否有任何方法可以避免每帧都将索引数组转移到显卡中,所以我提出了以下想法:
这似乎是使用OpenGL的一种落后方式,但只是把它放在那里......
glDrawArraysInstanced
- 每个实例都是一个网格单元格gl_instanceId
映射到统一缓冲区中单元格的第一个坐标的索引,并设置{{1到此索引的坐标+索引偏移属性我认为可能会有一些闪亮的新OpenGL 4.0功能,我不知道它会比这些方法更优雅。我很感激任何提示!
答案 0 :(得分:1)
glMultiDrawElements()
方法听起来很合理。我会首先实现它,并将其用作基线,如果您尝试更复杂的方法,可以将其与之比较。
如果你有机会让它更快将取决于绘制调用的处理是否是渲染中的一个重要瓶颈。除非您渲染的三角形非常小,和/或您的片段着色器非常简单,否则您很可能会受到片段处理的限制。如果您拥有可以收集数据并识别瓶颈的分析工具,那么您可以更加有针对性地进行优化工作。当然,总有一种低技术方法:如果让窗口变小可以改善你的表现,那么你很可能只是片段限制。
回到你的问题:由于你询问了有关闪亮的新GL4功能的问题,你可以检查的另一种方法是间接渲染,使用glDrawElementsIndirect()
。除了更灵活之外,与glMultiDrawElements()
的主要区别在于,每个绘制所使用的参数(如您的情况下的起始索引)可以来自缓冲区。如果映射此缓冲区,则可能会阻止一个副本,并将起始索引直接写入缓冲区。您甚至可以将它与持久缓冲区映射(查找GL_MAP_PERSISTENT_BIT
)结合使用,这样您就不必每次都映射和取消映射缓冲区。
你的统一缓冲区理念听起来很有趣。我有点怀疑它会表现得更好,但这只是一种感觉,而不是基于任何数据或直接经验。所以我认为你绝对应该尝试一下,并报告它的运作情况!
如果您还没有考虑并拒绝它们,您还可以查看与顺序无关的透明度渲染的方法。例如,alpha-to-coverage非常容易实现,如果您仍然使用MSAA,几乎是免费的。基于我的有限尝试,它不会产生非常高质量的透明效果,但如果它能够满足您的使用需求,它可能会非常有吸引力。另一种与顺序无关的透明度技术是深度剥离。
如果某些自我推销是可以接受的,我在前面的答案中写了一些透明度渲染方法的概述:OpenGL ES2 Alpha test problems。