【问题标题】:Using OpenGL instancing for rendering 2D scene with object depths and alpha blending使用 OpenGL 实例化渲染具有对象深度和 Alpha 混合的 2D 场景
【发布时间】:2020-06-23 23:23:57
【问题描述】:

这就是我想要做的:我想渲染一个 2D 场景,它由许多对象(四边形)组成,使用实例化。具有较低 y 值(朝向屏幕底部)的对象需要在具有较高 y 值的对象之前渲染。 Alpha 混合也需要发挥作用。

所以我的第一个想法是使用 Z 值作为深度,但我很快意识到除非以正确的顺序绘制对象,否则 Alpha 混合将不起作用。但我不是为每个四边形发出一个调用,而是使用单个实例调用来渲染整个场景。将实例数据按正确的排序顺序排列似乎对我有用,但我怀疑这是我可以依赖的东西,因为 GPU 应该尽可能地并行运行这些计算。

所以问题是,有没有办法让它工作?我现在能想到的最好的事情是为每个单独的 y 值发出一个实例调用(并按顺序发出它们,从后到前)。有没有更好的方法来做到这一点?

【问题讨论】:

    标签: opengl


    【解决方案1】:

    实例化最适用于每个实例为中等大小的情况:数百甚至数千个三角形。 Quads 不适合实例化。

    只需构建和渲染一系列三角形。在现代 OpenGL 中甚至有efficiently get around the lack of a GL_QUADS primitive type 的方法。

    以正确的排序顺序放置实例数据似乎对我有用,但我怀疑这是我可以依赖的东西,因为 GPU 应该尽可能并行地运行这些计算。

    GPU 不是这样工作的。

    当您发出渲染命令时,您(最终)得到的是一系列原语。因为给该命令的顶点是有序的(从第一个到最后),并且该命令中的实例是有序的,甚至单个绘制命令中的绘制也是有序的,所以可以为绘制调用中的每个图元分配一个顺序根据顶点、实例和绘制的顺序,相对于所有其他图元。

    这定义了primitive order for a drawing command。 GPU 保证混合(以及逻辑操作和其他可见的post-fragment shader operations)将尊重渲染命令和渲染命令之间的原始顺序。也就是说,如果您在一次调用中绘制了 2 个三角形,并且第一个在第二个之后(关闭了深度测试),那么第二个三角形的混合将尊重第一个写入的数据。

    基本上,如果您按顺序将基元提供给 GPU,GPU 将在混合等方面尊重该顺序。

    同样,只需构建一个有序的三角形流来表示您的四边形并渲染它们。

    【讨论】:

    • 所以我实际上可以在实例调用中依赖绘图顺序吗?我知道这不是你的主要观点,但这很有趣。
    • 关于三角形流,我试图实现的一个主要目标是尽量减少发送到 GPU 的数据量。通过实例化,每个实例都有一组位置/大小/纹理数据,因此每 6 组顶点发送一次这些内容。对于三角形流,我需要为每个顶点传递所有这些。我知道我的用例可能对性能不那么敏感,但我正在努力寻找最好的方法,主要是作为一种实践。
    • @Elektito: "通过实例化,每个实例都有一组位置/大小/纹理数据,因此每 6 组顶点发送一次。 “四个顶点。每个四边形只需要四个顶点。而“位置/大小”只是 4 个顶点中每个顶点位置的一部分,因此您拥有的唯一真实的每个实例数据是“纹理”。
    • 但是我每个四边形需要两个三角形,对吧? (我还没有使用 GL_TRIANGLE_FAN,但我想我可以做到 5)。在我当前的代码中,我为每个顶点发送一个“索引”值,它是从 0 到 3 的整数,并确定这是四边形的哪个顶点(0 表示左下角,1 表示左上角等)。位置、大小和纹理坐标都是每个实例的。
    • @Elektito:“但我每个四边形需要两个三角形,对吗?”这两个三角形共享两个顶点,所以四边形的顶点总数为 4。请参阅我链接到的答案,了解四边形拓扑的工作原理。 “在我当前的代码中,我为每个顶点发送一个“索引”值”您可以更轻松地从 gl_VertexID 计算出来。
    猜你喜欢
    • 2023-03-23
    • 2010-12-09
    • 2012-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多