Unity Shader 噪声消融特效 - 剑灵死亡特效
Posted Sooda
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity Shader 噪声消融特效 - 剑灵死亡特效相关的知识,希望对你有一定的参考价值。
噪声是个很神奇的东西,以前接触的时候就是在自动生成地图上,因为噪声本来就近自然所以,很多特效也是基于噪声的。
前几篇文章介绍了纹理和光照,这回其实也就是用这么多。就是光照加一个噪声的法线纹理。
你可能就玩过一款游戏,剑灵,游戏中怪物死亡的时候会有一种消融的效果。让我们来看一看是怎么实现的。
下面三个图片分别是BurnAmount = 0、BurnAmount = 0.25、BurnAmount = 0.5时的效果。
这里我们用两个Pass来处理这个效果
- 第一个Pass:渲染模型的正常颜色和消融的混合颜色
- 第二个Pass:处理消融的阴影,如不特殊处理则影子不会有消融效果。
下面给出代码(有必要的注释)
1 Shader "Shader/Shader" 2 { 3 Properties 4 { 5 _MainTex ("Main Tex", 2D) = "white" {} 6 // 法线贴图 7 _BumpMap ("Bump Map", 2D) = "bump" {} 8 // 噪声贴图 9 _BurnMap ("Burn Map", 2D) = "white" {} 10 // 控制消融程度 11 _BurnAmount ("Burn Amount", Range(0, 1)) = 0 12 // 控制模型烧焦效果的线宽 13 _LineWidth ("Burn Line Width", Range(0.0, 0.2)) = 0.1 14 // 烧焦边缘的颜色 15 _BurnColor ("Burn Color", Color) = (1, 0, 0, 1) 16 } 17 SubShader 18 { 19 Tags { "RenderType"="Opaque" "Queue"="Geometry" } 20 21 Pass 22 { 23 Tags { "LightMode"="ForwardBase" } 24 25 // 所有面都不被剔除,因为消融的时候应该可以看到物体的内部。 26 Cull Off 27 28 CGPROGRAM 29 #pragma vertex vert 30 #pragma fragment frag 31 // 为得到正确的光照设置的编译指令 32 #pragma multi_compile_fwdbase 33 34 #include "Lighting.cginc" 35 #include "AutoLight.cginc" 36 37 sampler2D _MainTex; 38 sampler2D _BumpMap; 39 sampler2D _BurnMap; 40 float4 _MainTex_ST; 41 float4 _BumpMap_ST; 42 float4 _BurnMap_ST; 43 fixed _BurnAmount; 44 fixed _LineWidth; 45 fixed4 _BurnColor; 46 47 struct a2v 48 { 49 float4 vertex : POSITION; 50 float3 normal : NORMAL; 51 float2 texcoord : TEXCOORD0; 52 fixed4 tangent : TANGENT; 53 }; 54 55 struct v2f 56 { 57 float4 pos : SV_POSITION; 58 float2 uvMainTex : TEXCOORD0; 59 float2 uvBumpMap : TEXCOORD1; 60 float2 uvBurnMap : TEXCOORD2; 61 // 切线视图的光照方向 62 float3 lightDir : TEXCOORD3; 63 float3 worldPos : TEXCOORD4; 64 // Shader 阴影宏:用于对阴影纹理采样的坐标 65 // 参数:一个可用的差值寄存器的索引值,用世界的顶点坐标。即5(从0开始) 66 SHADOW_COORDS(5) 67 }; 68 69 v2f vert(a2v v) 70 { 71 v2f o; 72 73 o.pos = UnityObjectToClipPos(v.vertex); 74 75 o.uvMainTex = TRANSFORM_TEX(v.texcoord, _MainTex); 76 o.uvBumpMap = TRANSFORM_TEX(v.texcoord, _BumpMap); 77 o.uvBurnMap = TRANSFORM_TEX(v.texcoord, _BurnMap); 78 79 TANGENT_SPACE_ROTATION; 80 o.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex)); 81 o.worldPos = UnityObjectToWorldDir(v.vertex); 82 83 // 阴影宏:在顶点着色器中计算上一步中声明的阴影纹理坐标 84 TRANSFER_SHADOW(o); 85 86 return o; 87 } 88 89 fixed4 frag(v2f i) : SV_Target 90 { 91 // 取噪声贴图进行采样 92 fixed3 burn = tex2D(_BurnMap, i.uvBurnMap); 93 // 用于剔除像素点,if (采样结果-消融程度阀值 > 0) 存留 or 丢弃 94 clip(burn.r - _BurnAmount); 95 96 fixed3 albedo = tex2D(_MainTex, i.uvMainTex).rgb; 97 98 fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo; 99 100 fixed3 tangentLightDir = normalize(i.lightDir); 101 fixed3 tangentNormal = UnpackNormal(tex2D(_BumpMap, i.uvBumpMap)); 102 fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(tangentLightDir, tangentNormal)); 103 104 // 阴影宏:计算阴影值,最后与漫反射的颜色叠加 105 UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos); 106 107 // smoothsetp(e1,e2,x)平滑过度函数 108 // 原理:if (x < e1) 结果 = 0 109 // if (x > e2) 结果 = 1 110 // if (e1 < x < e2) 结果 = 3 * pow(x, 2) - 2 * pow(x, 3) 111 // t = 0时,该像素为正常的模型颜色 112 // t = 1时,该像素位于消融的边界处 113 fixed t = 1 - smoothstep(0.0, _LineWidth, burn.r - _BurnAmount); 114 115 // 最终颜色,在消融和正常中差值,系数为t 116 fixed3 finalColor = lerp(ambient + diffuse * atten, _BurnColor, t); 117 118 return fixed4(finalColor, 1); 119 } 120 ENDCG 121 } 122 123 // 此Pass是处理阴影的,我们需要按照正常的Pass的处理来剔除片元或进行顶点动画。以便阴影可以和物体正常渲染的结果相匹配。 124 Pass 125 { 126 // 光照模式定义为阴影 127 Tags { "LightMode"="ShadowCaster" } 128 129 CGPROGRAM 130 #pragma vertex vert 131 #pragma fragment frag 132 // 处理阴影的编译指令 133 #pragma multi_compile_shadowcaster 134 135 #include "UnityCG.cginc" 136 137 fixed _BurnAmount; 138 sampler2D _BurnMap; 139 float4 _BurnMap_ST; 140 141 struct a2v 142 { 143 float4 vertex : POSITION; 144 float2 texcoord : TEXCOORD0; 145 float3 normal : NORMAL; 146 float4 tangent: TANGENT; 147 }; 148 149 struct v2f 150 { 151 // 定义阴影投射需要定义的变量 152 V2F_SHADOW_CASTER; 153 float2 uvBurnMap : TEXCOORD0; 154 }; 155 156 v2f vert (a2v v) 157 { 158 v2f o; 159 160 // 填充V2F_SHADOW_CASTER定义的变量 161 TRANSFER_SHADOW_CASTER_NORMALOFFSET(o) 162 o.uvBurnMap = TRANSFORM_TEX(v.texcoord, _BurnMap); 163 164 return o; 165 } 166 167 fixed4 frag (v2f i) : SV_Target 168 { 169 fixed3 burn = tex2D(_BurnMap, i.uvBurnMap); 170 171 clip(burn - _BurnAmount); 172 173 // 让Unity完成阴影投射 174 SHADOW_CASTER_FRAGMENT(i) 175 } 176 ENDCG 177 } 178 } 179 }
本文引自Unity Shader 入门精要
以上是关于Unity Shader 噪声消融特效 - 剑灵死亡特效的主要内容,如果未能解决你的问题,请参考以下文章
游戏开发实战教你在Unity中实现模型消融化为灰烬飘散的效果(ShaderGraph | 消融 | 粒子系统 | 特效)
游戏开发实战教你在Unity中实现模型消融化为灰烬飘散的效果(ShaderGraph | 消融 | 粒子系统 | 特效)
游戏开发实战教你在Unity中实现模型消融化为灰烬飘散的效果(ShaderGraph | 消融 | 粒子系统 | 特效)
小功能⭐️Unity2018 Shader Graph——全息影像物体消融