使用加法混合渲染粒子效果 无需渲染到纹理解决亮背景失效问题
解决方案
你遇到的问题本质是纯加法混合GL_SRC_ALPHA, GL_ONE的计算逻辑为 最终色 = 粒子色 * 粒子alpha + 背景色 * 1,当背景为白色(各通道值为1)时,叠加任何颜色都会被截断为1,自然看不到粒子。不需要渲染到纹理的可行方案如下:
方案1:双Pass混合(最贴合预期效果)
通过两次绘制粒子先压暗背景区域再叠加发光,完美适配明暗背景:
// 先绘制完其他场景物体 renderOtherObjects(); // 第一Pass:压暗粒子区域背景 glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); glBlendFunc(GL_SRC_ALPHA, GL_ONE); renderParticles(); // 第二Pass:叠加粒子发光 glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_SRC_ALPHA, GL_ONE); renderParticles(); // 恢复默认混合设置 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
你可以在粒子着色器中调整第一Pass输出的压暗程度,匹配你需要的发光对比度。
方案2:单Pass混合(性能最优)
改用预乘alpha的混合模式,不需要额外绘制Pass:
- 粒子着色器输出前先做预乘:
fragColor.rgb *= fragColor.a; - 更换混合函数:
renderOtherObjects(); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); renderParticles(); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
该模式暗背景下接近纯加法的发光效果,亮背景下会保留粒子颜色不会被白色覆盖,调试成本更低。
内容的提问来源于stack exchange,提问作者Joezzz
相关产品推荐
相关产品推荐

