渲染混合点精灵和3D对象的最佳方法是什么?
比方说,我想建模"太空尘埃"粒子作为点精灵。在太空中,我可能有大型小行星物体(简单的立方体),空间尘埃粒子可能位于小行星立方体的前面或后面。
我遇到了两种情况:
gl_DepthMask(GL_TRUE)
然后渲染小行星立方体(太空尘埃总是在小行星后面)gl_DepthMask(GL_FALSE)
,渲染空间尘点精灵并设置gl_DepthMask(GL_TRUE)
(空间尘埃总是出现在小行星前面)我目前正在使用单个粒子发射器顶点着色器,它在随机(x,y,z)位置绘制带有gl_DrawArrays()
的粒子负载。
如何渲染一堆粒子,使它们出现在小行星立方体的前面和后面?
如果我的粒子是单独的四边形,那么我可以对Z渲染的顺序进行排序,但我不知道如何使用gl_DrawArrays()
,GL_POINT
和我的顶点着色器来实现这种行为。
我是否应该将粒子分成几组数组 - 例如我是否必须这样做:
如果我有很多小行星,这不是非常低效吗?
当然,OpenGL有一种更好的方法来达到这个目的吗?
更新:尝试托马斯'建议:
我的立方体和粒子使用以下混合/深度调用进行渲染:
// First render opaque object(s)
glEnable( GL_DEPTH_TEST );
glDepthMask( true );
g_ObjCube1.Render();
// Now render sprites with particle emitter - sprites should appear
// behind and in front of above cube
glEnable( GL_POINT_SPRITE );
// Stop overlapping particles from interfering with each other
//glDisable( GL_DEPTH_TEST ); <- NO! Must leave depth test enabled
glDepthMask( false );
glEnable( GL_BLEND );
//glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glBlendFunc( GL_SRC_ALPHA, GL_ONE ); // Doing the same as above
glBlendEquation( GL_FUNC_ADD );
...
glDrawArrays( GL_POINTS, 0, NUM_PARTICLES );
...
glDepthMask( true );
答案 0 :(得分:1)
我假设你的粒子有一定的透明度,否则不会有问题。
然后答案与所有透明对象的答案相同。首先渲染不透明物体(小行星)(使用深度缓冲,以任何顺序)。然后按照从前到后的顺序渲染所有透明对象。这个排序(据我所知)需要在CPU上完成。
或者,根据您的目标效果,您可以对粒子使用添加剂混合(glBlendFunc(GL_SRC_ALPHA, GL_ONE)
)。然后渲染顺序无关紧要,因为加法是可交换的。请务必禁用此深度书写。
作为另一种选择,使用alpha测试(true / false)而不是alpha混合可以让你以任何顺序渲染粒子。在这种情况下,完全透明的像素不会写入深度缓冲区。使用此技术时,您不能拥有部分透明的区域。
This article是一个很好的参考。