Unity中Shader Graph实现雨雪效果需设Render Queue=Overlay、关ZWrite、开Alpha混合,UV偏移系数控在0.5–2.0,贴图禁MipMaps;UE5 Niagara需分离参数、归一化合成风速、重映射雨量,天气状态机须插值过渡,移动端应压缩纹理通道、用LUT替代三角函数、动态裁剪粒子数。

Unity 中用 Shader Graph 做雨雪粒子叠加层
动态天气效果里最直观的其实是视觉层——雨滴划过镜头、雪花在风中飘散,这些不能靠逻辑模拟,得用渲染管线叠加。Shader Graph 是最快落地的方式,尤其适合不需要物理交互的氛围型天气。
常见错误是直接在主摄像机上套全屏雨效材质,结果 UI 也被淋湿、UI 文字边缘出现透明噪点。这是因为没正确处理 ZWrite 和 Blend 模式。
- 把雨/雪图层的 Shader 设置为
Render Queue = Overlay(值 4000+),确保它永远在 UI 之上、场景之后 - 关闭
ZWrite,开启Blend SrcAlpha OneMinusSrcAlpha,避免遮挡后方物体深度 - 用
_Time.y驱动粒子 UV 偏移,但别直接乘大系数——建议控制在0.5–2.0范围内,否则高速移动时会“抽帧” - 如果用 Sprite Atlas 存雨滴贴图,记得在 Texture Import Settings 里关掉
Generate Mip Maps,否则远距离会出现模糊水痕
Unreal Engine 5 的 Niagara 系统控制风向与降水强度联动
Niagara 本身不存“天气状态”,它只响应参数。想让风一变、雨就斜着下,就得把逻辑拆到 Blueprint 或 Data Asset 里驱动 Niagara System。
容易踩的坑是把所有参数都塞进一个 Vector3 动态输入:比如用 X 控制风速、Y 控制雨量、Z 控制湿度——结果改风速时雨滴突然缩成针尖大小,因为没做归一化约束。
- 用独立的
Float参数传入 Niagara:如RainIntensity、WindDirection、WindStrength - 在 Niagara 的
Update模块里,用Normalize+Multiply把WindDirection和WindStrength合成真实速度向量 -
RainIntensity别直接当发射率——先过一个RemapFloat(0→1 映射到 50→300),再喂给Spawn Rate,防止低值时粒子完全消失 - 若需跨关卡持久化天气,别存 Niagara 系统实例,改用
Gameplay Ability System或自定义WeatherDataAsset管理参数
天气状态机如何避免“晴转多云再转雷暴”的跳变感
状态切换生硬,本质是没做插值过渡。纯用 if-else 切换天气类型,会导致光照突变、音效断掉、粒子系统重置——玩家会觉得世界“卡了一下”。
关键不是写多少状态,而是每个状态之间有没有共享变量和缓动接口。
- 所有天气状态共用一套
WeatherParameters结构体:含CloudCoverage、LightIntensity、AmbientColor、WindSpeed等浮点字段 - 切换时不用销毁重建,而是调用
StartTransitionTo(NewState, duration: 8.0f),内部对每个字段做Lerp插值 - 音效别用“播放新 Clip”,改用
Audio Mixer的Volume和Pitch参数实时调节已有轨道 - 粒子系统用
SetFloat动态改Scale和Velocity,而不是 Stop/Play——避免发射器重置导致粒子消失
移动端性能敏感点:别让天气吃光 GPU 带宽
手机上一个 1024×1024 的全屏雨效 Shader,可能吃掉 30% 的帧时间——尤其在低端 Android 设备上,SampleTexture2D 多采两次,GPU 就开始掉帧。
最容易被忽略的是“透明通道滥用”:雨滴贴图带 Alpha,但实际只需要灰度信息;雪花图用 RGBA 存旋转+大小,其实 RGB 就够了。
- 把雨/雪贴图导出为单通道
R8_UNORM格式(Unity 里设 Texture Type = Default,Alpha Source = From Gray Scale) - 在 Shader 中用
tex2D(_RainTex, uv).r取值,比.a更快,且省一半采样带宽 - 避免在片元 Shader 里做
sin/cos运算——用预生成的 256 点LUT纹理替代,查表比计算快 3–5 倍 - 粒子数量按屏幕分辨率动态裁剪:
MaxParticles = Screen.width * Screen.height / 120000,防低端机爆内存
天气系统最难的从来不是加特效,而是让所有模块——光照、音频、粒子、物理——共享同一套时间尺度和参数空间。漏掉任意一层插值或异步更新,玩家就会觉得“这雨是贴图,不是天上下下来的”。











