当前位置: 首页 > 知识库问答 >
问题:

在OpenGL中高效绘制透明地形

贺君浩
2023-03-14

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

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

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

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

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

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

我想可能会有一些新的OpenGL4.0特性,我不知道它们会比这两种方法更优雅。我很感激你给我的提示!

共有1个答案

羊煜
2023-03-14

glmultidrawelements()方法听起来非常合理。我将首先实现它,并使用它作为一个基线,如果您尝试更复杂的方法,您可以与之进行比较。

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

回到您的问题:既然您询问了闪亮的GL4新特性,那么您可以查看的另一种方法是间接呈现,使用gldrawelementsindirection()。除了更灵活之外,GLMultiDrawElements()的主要区别在于,用于每个绘制的参数(如您的示例中的起始索引)可以从缓冲区中获取。如果映射此缓冲区并将开始索引直接写入缓冲区,则可能会阻止一次复制。您甚至可以将它与持久缓冲区映射(查找gl_map_persistent_bit)结合起来,这样就不必每次都映射和取消映射缓冲区。

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

如果您还没有考虑并拒绝那些与顺序无关的透明度呈现方法,那么您可以进一步扩展您的问题的范围。例如,alpha-to-coverage非常容易实现,如果您使用MSAA,几乎是免费的。根据我有限的尝试,它不会产生很高质量的透明效果,但如果它能为您的用例提供服务,它可能会非常吸引人。另一种与顺序无关的透明度技术是深度剥离。

如果一些自我提升是可以接受的,我在这里前面的一个回答中写了一些透明度渲染方法的概述:OpenGL ES2阿尔法测试问题。

 类似资料:
  • 我正在尝试脚本创建视频使用ImageMagick创建一些覆盖,然后放在一个视频的顶部。 如果我尝试直接使用ImageMagick创建的图像,透明度会被绘制为不透明。 我已经使用ImageMagick绘制命令创建了一个透明的PNG。当加载到GIMP中并进行检查时,PNG具有alpha通道,并且每个透明像素看起来具有透明度:RGBA=0,0,0,0 我可以通过获取覆盖图像,在GIMP中加载它,然后选择

  • 对于需要图形分层的应用,经常需要处理透明度。本节,我们将学习如何使用全局透明度设置图形的透明度。 图2-5 绘制透明图形 绘制步骤 按照以下步骤,在一个不透明的矩形之上,绘制一个透明的圆: 1. 定义2D画布上下文: window.onload  = function(){ var canvas  = document.getElementById("myCanvas"); var co

  • 问题内容: 如何绘制具有Alpha颜色的矩形?我有: 但是我希望白色矩形的透明度为50%,但是Alpha值似乎没有起作用。 问题答案: 函数将不使用Alpha绘制。该文件说: 大多数参数接受RGB三元组的color参数。这些也可以接受RGBA四联体。如果Alpha值包含像素Alpha,则它将直接写入Surface,但是draw函数不会透明地绘制。 您可以做的是创建第二个曲面,然后将其调高到屏幕上。

  • 问题内容: 我想在另一幅图像上绘制部分透明的图像(在物体上形成阴影)。我目前正在使用Java的Graphics2D类进行渲染,有人告诉我将合成设置为AlphaComposite,但这仅将其设置为完全透明。 我可以使用当前设置进行此操作吗?我必须怎么做才能解决此问题? 这是我被告知可以使其部分透明的代码: (顺便说一句,我正在使用png图像) 这是您的sscce(它们都在不同的类中,但是为了简单起见

  • 问题内容: 我想在PDFBox中用透明线绘制线条和多边形。这是一些有关如何绘制蓝线的示例代码,但是我无法弄清楚更改颜色的Alpha值。 问题答案: 您不能使用的alpha值,因为PDFBox仅使用RGB值。根据它的javadoc 只是: 设置描边颜色,指定为RGB。 一种选择是将背景色设置为描边色,以使线条不可见。 注意- 不可见!=透明(因此您不会获得透视效果)

  • 我们有一个TextView,其中包含应用程序资源中的可抽屉-左和可抽屉-右。在一些设备上 运行Android 4.1.2的索尼Xperia L, 三星Galaxy Young或 三星Galaxy SII 我们正面临一个奇怪的问题。可拉拔件将显示为半透明/透明。在其他设备上,如 三星Galaxy S4(4.4.2)或 HTC ONE V(4.0.3) 可抽屉将正确显示。 这是布局定义的剪裁: 在HT