PixiJS Godrays滤镜优化:仅提亮区域不暗化透明背景
解决方案:透明舞台下的Godrays滤镜提亮效果修复
问题根源分析
当前滤镜的核心问题在于:
- 透明区域(原像素alpha=0)叠加了
mist(alpha=1),导致无光源处出现黑色,破坏了背景的透明性 - 直接使用
gl_FragColor += mist的叠加方式,可能在某些情况下让原像素颜色溢出或出现不必要的暗化 mist的alpha通道未与原像素的透明度关联,导致透明区域被填充了颜色
你的猜测中,noise函数本身没有问题,clamp语句也不是核心问题,核心是叠加逻辑没有考虑透明背景和仅提亮的需求。
修改方案
我们需要调整shader的最终颜色计算逻辑,确保:
- 仅在原像素非透明的区域应用提亮效果
- 透明区域保持完全透明,不生成任何颜色
- 只做提亮操作,不暗化原像素
修改后的片段着色器核心部分如下(仅展示修改的main函数):
void main(void) { vec4 source = texture2D(uSampler, vTextureCoord); float d = 0.0; vec2 coord = vTextureCoord; if (parallel) { float _cos = light.x; float _sin = light.y; d = (_cos * coord.x) + (_sin * coord.y * aspect); } else { float dx = coord.x - light.x / dimensions.x; float dy = (coord.y - light.y / dimensions.y) * aspect; float dis = sqrt(dx * dx + dy * dy) + 0.00001; d = dy / dis; } vec2 dir = vec2(d, d); float noise = turb(vec3(dir, 0.0) + vec3(time, 0.0, 62.1 + time) * 0.1, lacunarity, gain); // 调整mist的alpha,仅作用于原像素非透明区域 vec4 mist = vec4(noise, noise, noise, source.a); noise = mix(noise, 0.0, 0.3); mist *= 1.0 - coord.y; mist = clamp(mist, 0.0, 1.0); // 使用混合而非直接叠加,确保只提亮,不暗化 gl_FragColor = source + mist * source.a; // 确保最终alpha和原像素一致,保持透明性 gl_FragColor.a = source.a; }
关键修改点说明
- 将原像素存储为
source变量,方便后续引用 - 修改
mist的alpha通道为source.a,确保mist只在原像素有颜色的区域生效 - 最终颜色计算使用
source + mist * source.a,避免透明区域被填充颜色 - 强制设置最终alpha等于原像素alpha,严格保持背景透明性
- 保留了原有的noise和turb逻辑,不破坏Godrays的视觉效果
额外优化建议
如果需要更细腻的提亮效果,可以把叠加逻辑改为乘法提亮:
// 替换原有的gl_FragColor计算 float boost = 1.0 + mist.r * 0.5; // 控制提亮幅度 gl_FragColor.rgb = source.rgb * boost; gl_FragColor.a = source.a;
这样可以实现更自然的“提亮”效果,而不是直接叠加白色雾效。
内容的提问来源于stack exchange,提问作者Serious Angel
相关产品推荐
相关产品推荐

