GLSL 粒子的渲染(premult)

Posted

技术标签:

【中文标题】GLSL 粒子的渲染(premult)【英文标题】:GLSL particle's rendering (premult) 【发布时间】:2012-08-13 11:23:43 【问题描述】:

我一直在尝试让粒子渲染库与我的着色器一起使用。它与固定功能完美结合,我知道我的目标是什么。我只是不确定如何进行最后的混合。

它将这样的粒子生命打包到 DWORD 中,并将 dword 设置为顶点属性之一。一个四边形有 4 个这样的顶点。 3 个浮动位置,3 个浮动正常,4 个字节漫反射,2 个浮动 uv。 我应该如何处理 4byte 属性,在我的 glsl 着色器中将其用作 vec4 还是 float 属性? 另外,由于这个库使用预乘 alpha,我应该使用什么样的混合方程?库是pyro粒子库。

int ir = (int) (r * 255.0f + 0.5f);
int ig = (int) (g * 255.0f + 0.5f);
int ib = (int) (b * 255.0f + 0.5f);
int ia = (int) (a * Particle.Visibility * 255.0f + 0.5f);
DWORD diffuse;

#ifdef __BIG_ENDIAN__
if (GetLibrary()->GetGraphicsDevice()->IsRGBA())
diffuse = (ir << 24) | (ig << 16) | (ib << 8) | ia;
else diffuse = (ib << 24) | (ig << 16) | (ir << 8) | ia;
#else
if (GetLibrary()->GetGraphicsDevice()->IsRGBA())
diffuse = ir | (ig << 8) | (ib << 16) | (ia << 24);
else diffuse = ib | (ig << 8) | (ir << 16) | (ia << 24);
#endif /* __BIG_ENDIAN__ */

【问题讨论】:

我应该如何处理 4byte 属性你如何将此属性传递给着色器? glVertexAttribPointer(LocDiff, 4, GL_UNSIGNED_BYTE, GL_FALSE, VertexSize, pVertex); 【参考方案1】:

您的 4x 无符号字节将转换为 vec4(浮点类型)。 glVertexAttribPointer 始终将任何输入类型转换为着色器中的浮点数。

如果您选择normalize == GL_FALSE,它们的值的范围是0-255,否则如果您选择normalize == GL_TRUE,它们的范围是0-1(byte/255.f)

关于您关于预乘 alpha 的问题,如果您不想在混合操作中将源数据乘以 alpha,则只需使用:

glBlendFunc(GL_ONE,                 //multiply source value by 1
            GL_ONE_MINUS_SRC_ALPHA  //multiply destination value by (1-src_alpha)
            )

【讨论】:

以上是关于GLSL 粒子的渲染(premult)的主要内容,如果未能解决你的问题,请参考以下文章

Cocos 3.0 使用UIMeshRenderer将3D模型或粒子渲染到2D

粒子效果不渲染

在 openGL 中渲染粒子的问题

Horde3D 粒子系统不在 Qt OpenGL 中渲染

realflow缓存模拟可以提高渲染速度吗

OpenGL ES - 如何批量渲染 500 多个带有不同 alpha、旋转和缩放的粒子?