【URP】Unity[内置Shader]粒子光照ParticlesLit
【从UnityURP开始探索游戏渲染】专栏-直达Unity URP内置的Particles Lit着色器是专为粒子系统设计的高质量光照模型,其核心作用是为火焰、烟雾、雨雪等动态粒子效果提供逼真的光照交互。该着色器采用URP的物理光照计算模型,支持透明混合、深度碰撞检测等高级特性,但会带来较高的性能开销。
原理与特性
[*]光照模型:基于URP的PBR光照计算,支持方向光、点光源和聚光灯的实时交互,通过表面法线计算高光反射
[*]混合模式:提供Alpha、Premultiply、Additive和Multiply四种混合模式,分别适用于云雾(Alpha)、玻璃反射(Premultiply)、全息效果(Additive)等场景
[*]深度交互:可与深度纹理比对实现粒子碰撞效果,通过CS脚本在渲染管线中同步深度数据
发展沿革
[*]2019年:随URP 7.x版本首次推出,最初仅支持基础光照模型
[*]2021年:URP 12.x加入深度纹理交互支持,实现粒子碰撞效果
[*]2023年:优化移动端性能,在URP 14.x中成为粒子系统默认推荐着色器
Particles Lit 对比 Lit
渲染模式选择
ParticlesLit专为粒子系统设计,提供更灵活的混合模式(如Additive、Multiply等),适合处理透明粒子的叠加效果,而Lit通常用于不透明或标准透明物体渲染。ParticlesLit支持通过Color Mode控制粒子颜色与材质颜色的混合方式(如Multiply、Additive等),可减少过度混合导致的性能损耗。
性能敏感功能裁剪
ParticlesLit默认关闭了Lit中部分高消耗特性(如复杂光照计算),采用简化的光照模型。例如,它避免使用完整PBR计算,转而使用预乘混合(Premultiply)保留高光的同时降低透明渲染开销。此外,粒子系统通常禁用碰撞检测和物理交互,进一步降低CPU负载。
资源复用与批处理
ParticlesLit鼓励材质共享和纹理图集化,通过减少DrawCall提升性能。建议多个粒子系统共用同一材质,且纹理尺寸不超过256x256。相比之下,Lit可能涉及更多独立材质实例,尤其在复杂场景中。
渲染参数优化
ParticlesLit提供针对粒子的特定参数控制:
[*]通过Alpha Clipping实现硬边透明(如草叶效果),避免全透明混合的计算开销
[*]推荐小尺寸粒子去除Alpha通道,改用Opaque渲染以减少Overdraw
[*]限制粒子数量(单发射器 Lit
[*]设置Surface Type为Transparent,Blending Mode为Additive
[*]绑定粒子贴图并调整颜色参数:
[*]_MainTex: 火焰序列帧贴图
_Color: RGBA(1,0.5,0,0.8)
_Emission: 2.0
雨打到地上和物体上碰撞产生水花
[*]雨水粒子基础配置:
[*]使用Rectangle发射器形状并旋转90度使粒子垂直下落
[*]设置Velocity over Lifetime的World空间模式确保雨滴始终朝Y轴降落
[*]通过Linear参数添加XYZ方向偏移模拟风力效果
[*]碰撞检测模块:
[*]启用粒子系统的Collision模块,选择World碰撞模式
[*]设置Dampen参数为1使碰撞后粒子完全停止
[*]调整Bounce参数控制水花溅射力度
[*]水花效果生成:
[*]使用Sub Emitters模块在粒子消亡时触发子发射器
[*]子粒子系统采用Horizontal Billboard渲染模式保持水平显示
[*]通过Size over Lifetime曲线控制水花扩散动画
[*]RainCollisionController.cs
using UnityEngine;
public class RainCollisionController : MonoBehaviour {
private ParticleSystem _mainSystem;
private ParticleSystem _splashSystem;
void Start() {
_mainSystem = GetComponent<ParticleSystem>();
var collision = _mainSystem.collision;
collision.enabled = true;
collision.type = ParticleSystemCollisionType.World;
// 获取子发射器系统
_splashSystem = transform.GetChild(0).GetComponent<ParticleSystem>();
}
void Update() {
// 动态调整粒子发射速率
var emission = _mainSystem.emission;
emission.rateOverTime = Mathf.Lerp(50, 500, WeatherManager.Instance.RainIntensity);
}
}
[*]RainCollisionController.cs
Shader "Custom/Ripple" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_Speed ("Animation Speed", Range(0,5)) = 1.0
}
SubShader {
Tags { "Queue"="Transparent" }
Blend SrcAlpha OneMinusSrcAlpha
Pass {
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
// 着色器代码...
ENDHLSL
}
}
}
[*]性能优化
[*]纹理数组替代:使用Texture2DArray将多张纹理合并为单一资源,通过索引值(存储在SplatMap的R/G通道)选择纹理,减少采样次数。例如:
hlsl
half4 var_Main = SAMPLE_TEXTURE2D_ARRAY(_TexArray, sampler_TexArray, uv, splat.r * 255) * splat.b;
half4 var_Sec = SAMPLE_TEXTURE2D_ARRAY(_TexArray, sampler_TexArray, uv, splat.g * 255) * (1 - splat.b);
half4 finalRGB = var_Main + var_Sec;
[*]高度混合增强:结合高度图(存储在SplatMap的B通道)实现更自然的过渡效果,通过比较各层高度值动态调整权重
Shader Graph应用
实现雨滴效果:
[*]创建新的Shader Graph,选择URP Particle Lit模板
[*]添加Texture Sample节点连接Main Texture输入口
[*]使用Custom Function节点实现法线扰动:
hlsl
void RainDistortion_float(float2 uv, out float3 normal){
normal = float3(frac(uv.x * 10), frac(uv.y * 5), 1);
}
[*]输出口连接Normal和Base Color通道
[*]RainParticle.shadergraph
{
"m_Nodes": [
{
"m_Type": "UnityEditor.ShaderGraph.Texture2DNode",
"m_Outputs": [{ "m_Name": "Out" }],
"m_Inputs": [{ "m_Name": "Texture", "m_DefaultValue": "Assets/Textures/RainDrop.png" }]
},
{
"m_Type": "UnityEditor.ShaderGraph.CustomFunctionNode",
"m_Outputs": [{ "m_Name": "normal" }],
"m_Code": "RainDistortion_float"
}
],
"m_Edges": [
{ "m_OutputSlot": 0, "m_InputSlot": "BaseColor" },
{ "m_OutputSlot": 1, "m_InputSlot": "Normal" }
]
}
该示例通过Shader Graph创建动态雨滴效果,包含纹理采样和法线扰动功能,需配合粒子系统使用
<blockquote>
【从UnityURP开始探索游戏渲染】专栏-直达
(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! 感谢分享,下载保存了,貌似很强大
页:
[1]