You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PixiJS Godrays滤镜优化:仅提亮区域不暗化透明背景

解决方案:透明舞台下的Godrays滤镜提亮效果修复

问题根源分析

当前滤镜的核心问题在于:

  • 透明区域(原像素alpha=0)叠加了mist(alpha=1),导致无光源处出现黑色,破坏了背景的透明性
  • 直接使用gl_FragColor += mist的叠加方式,可能在某些情况下让原像素颜色溢出或出现不必要的暗化
  • mist的alpha通道未与原像素的透明度关联,导致透明区域被填充了颜色

你的猜测中,noise函数本身没有问题,clamp语句也不是核心问题,核心是叠加逻辑没有考虑透明背景和仅提亮的需求。

修改方案

我们需要调整shader的最终颜色计算逻辑,确保:

  1. 仅在原像素非透明的区域应用提亮效果
  2. 透明区域保持完全透明,不生成任何颜色
  3. 只做提亮操作,不暗化原像素

修改后的片段着色器核心部分如下(仅展示修改的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 03:21:06