使用OpenGL实例渲染具有对象深度和alpha混合的2D场景

使用OpenGL实例渲染具有对象深度和alpha混合的2D场景,opengl,Opengl,下面是我要做的:我想使用实例渲染一个2D场景,它由许多对象(四边形)组成。y值较低(朝向屏幕底部)的对象需要在y值较高的对象之前渲染。阿尔法混合也需要发挥作用 因此,我的第一个想法是使用Z值表示深度,但我很快意识到,除非以正确的顺序绘制对象,否则alpha混合将不起作用。但我不是对每个四边形发出一个调用,而是使用一个实例调用来渲染整个场景。将实例数据按正确的排序顺序排列似乎对我有效,但我怀疑这是我可以依赖的,因为GPU应该尽可能并行地运行这些计算 所以问题是,有没有一种方法可以让它发挥作用?我现

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

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


所以问题是,有没有一种方法可以让它发挥作用?我现在能想到的最好的办法是为每个单独的y值发出一个实例化调用(并按顺序从后向前发出)。有更好的方法吗?

实例最好用于每个实例都是中等大小的情况:数百个或数千个三角形。四边形不是实例化的好候选对象

只需构建并渲染一系列三角形。在现代OpenGL中,甚至还有一些方法可以使用

将实例数据按正确的排序顺序排列似乎对我有效,但我怀疑这是我可以依赖的,因为GPU应该尽可能并行地运行这些计算

GPU不是这样工作的

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

这定义了。GPU保证混合(以及逻辑操作和其他可见操作)将遵守渲染命令和渲染命令之间的基本顺序。也就是说,如果在一次调用中绘制两个三角形,且第一个三角形在第二个三角形之后(深度测试已关闭),则第二个三角形的混合将考虑第一个三角形写入的数据

基本上,如果您按顺序向GPU提供原语,GPU将在混合等方面遵守该顺序


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

这样我就可以在实例调用中真正依赖于绘制顺序了?我知道这不是你的主要观点,但很有趣。关于三角形流,我试图实现的一个主要目标是最小化发送到GPU的数据量。对于实例,我为每个实例都有一组位置/大小/纹理数据,因此每6组顶点发送一次这些数据。对于三角形流,我需要传递每个顶点的所有三角形。我知道我的用例可能对性能不太敏感,但我正在努力找到最好的方法,主要是作为一种实践。@Elektito:“通过实例,我每个实例都有一组位置/大小/纹理数据,因此每6组顶点发送一次这些数据。”四个顶点。每个四边形只需要四个顶点。“位置/大小”只是4个顶点中每个顶点位置的一部分,所以每个实例的唯一真实数据是“纹理”。但我需要每个四边形两个三角形,对吗?(我还没有用过GL_三角形_风扇,但我想用它我可以做到5)。在我当前的代码中,我为每个顶点发送一个“索引”值,它是一个从0到3的整数,并确定这是四边形的哪个顶点(0表示左下角,1表示左上角,等等)。位置、大小和纹理坐标都是每个实例的。@Elektito:“但我需要每个四边形两个三角形,对吗?”这两个三角形共享两个顶点,因此四边形的顶点总数为4。请参阅我链接的关于四边形拓扑如何工作的答案。在我当前的代码中,我为每个顶点发送一个“索引”值“你可以更容易地从
gl\u VertexID
计算它。