Ios 具有深度测试的OpenGL点精灵-混合问题?

Ios 具有深度测试的OpenGL点精灵-混合问题?,ios,opengl-es-2.0,blending,depth-buffer,point-sprites,Ios,Opengl Es 2.0,Blending,Depth Buffer,Point Sprites,我正在渲染点精灵(在iOS上使用OpenGL ES 2.0)作为用户的绘图笔划。我将这些点存储在顶点缓冲区对象中,因此我需要执行深度测试,以便精灵在提交绘制时以正确的顺序显示 在渲染这些绘图笔划时,我看到一种奇怪的效果,如以下屏幕截图所示: 请注意蓝色笔划边缘周围的背景色“边框”,该边框绘制在绿色上。用户在绿色笔划之后绘制蓝色笔划,但是当VBO被重新绘制时,蓝色笔划首先被绘制。当要画绿色笔划时,深度测试开始了,并且看到它应该在蓝色笔划后面,这也做了,取得了一些成功。在我看来,这似乎是某种混合问

我正在渲染点精灵(在iOS上使用OpenGL ES 2.0)作为用户的绘图笔划。我将这些点存储在顶点缓冲区对象中,因此我需要执行深度测试,以便精灵在提交绘制时以正确的顺序显示

在渲染这些绘图笔划时,我看到一种奇怪的效果,如以下屏幕截图所示:

请注意蓝色笔划边缘周围的背景色“边框”,该边框绘制在绿色上。用户在绿色笔划之后绘制蓝色笔划,但是当VBO被重新绘制时,蓝色笔划首先被绘制。当要画绿色笔划时,深度测试开始了,并且看到它应该在蓝色笔划后面,这也做了,取得了一些成功。在我看来,这似乎是某种混合问题,或者与不正确地计算片段着色器中的颜色有关?所有笔划的边缘都应该是透明的,但是在处理这些片段时,片段着色器似乎将其与背景纹理相结合

在我的应用程序中,我创建了一个深度渲染缓冲区,并使用
glDepthFunc(GL\u LEQUAL)
调用了
glEnable(GL\u depth\u TEST)
。我尝试了
glDepthMask()
,但没有效果。混合设置为
glBlendFunc(GL\u ONE,GL\u ONE\u减去SRC\u ALPHA)
,点精灵颜色使用预乘的ALPHA值。绘图例程非常简单:

  • 将渲染绑定到纹理FBO
  • 绘制背景纹理
  • 绘制点精灵(来自多个VBO)
  • 将此FBO的纹理绘制到主帧缓冲区
  • 显示主帧缓冲区

编辑

下面是绘图例程中的一些代码

绘图前的设置状态:

glDisable(GL_DITHER);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
绘图程序:

[drawingView setFramebuffer:drawingView.scratchFramebuffer andClear:YES];
glUseProgram(programs[PROGRAM_TEXTURE]);
[self drawTexture:[self textureForBackgroundType:self.backgroundType]];

glUseProgram(programs[PROGRAM_POINT_SPRITE]);

// ...
// Draw all VBOs containing point sprite data
// ...

[drawingView setFramebuffer:drawingView.defaultFramebuffer andClear:YES];
glUseProgram(programs[PROGRAM_TEXTURE]);
[self drawTexture:drawingView.scratchTexture];

[drawingView presentFramebuffer:drawingView.defaultFramebuffer];

谢谢您的帮助。

如果您想绘制非不透明几何图形,您必须从后到前对其进行z排序。多年来,这是获得适当混合的唯一方法。现在有一些与订单无关的透明算法,比如双深度剥离,但它们不适用于iOS。

Gah,这是我不希望看到的答案!谢谢你的回复。Z排序我的精灵可能有点棘手,因为笔划使用不同的纹理(如截图所示)。我希望将VBO的数量保持在最低限度,但如果它们需要保持正确的顺序,我会看看我能做些什么。我想象不同的笔划在不同的VBO中。这里你要做的就是对VBO排序,而不是点精灵。。。除非您想再次使用绿色绘制,并将第一个笔划与第三个笔划合并,因为它们将使用相同的纹理。这看起来像是大量的粒子。我不确定最好的办法是每一帧都画出来。如果你制作一个绘图类型的应用程序,你应该考虑绘制渲染目标中的旧图层,然后在顶部绘制当前的图层。然后,如果你有撤消类型的操作,你将不得不从第一层重新绘制它们。是的,它们存储在VBOs中,问题就像你描述的那样-如果我将一个特定纹理的所有笔划存储在一个VBO中,然后在两者之间绘制不同的纹理,当我绘制所有VBO时,它们将无序。我已经修复了这一部分,并在用户每次更改笔划纹理时创建一个新的VBO,否则我会尽可能多地填充点。我不是每一帧都画VBOs,我使用渲染到纹理的方法来绘制,这很容易达到60帧/秒。我需要VBOs来支持橡皮擦和撤消/重做操作。这是一个令人失望的答案,但在这种情况下,笔划不是通过绘制过程自然地从前到后排列,从而减少了排序的需要吗?