赞
踩
有些时候需要让角色死亡时逐渐燃烧消失,用表面着色器很容易实现。
可以用一张黑白图片控制各部位的消融顺序,比如让该图片的某通道和一个变量相比,小于该变量则舍弃片元。变量从0不断变大,则消融面积逐渐扩大。
燃烧部分的颜色则读取自一张渐变贴图,类似于渐变纹理。可以取代纹理颜色或进行差值,也可以直接当做自发光(Emission)。
代码:
- Shader "Test"
- {
- Properties
- {
- _MainTex ("Albedo (RGB)", 2D) = "white" {} //纹理贴图
- _DisolveTex("DisolveTex",2D) = "white"{}//噪声图,影响哪些位置被消融
- _Threshold("Threshold",Range(0,1)) = 0 //控制消融程度
- _EdgeLength("EdgeLength", Range(0,0.2)) = 0.1 //过渡部分多少大
- _BurnTex("BurnTex", 2D) = "white"{} //渐变图,过渡部分用
- _BurnInstensity("BurnInstensity", Range(0,5)) = 1 //过渡部分的强度
- }
- SubShader
- {
- Tags { "RenderType"="Opaque" }
-
- CGPROGRAM
-
- #pragma surface surf Standard fullforwardshadows
-
- #pragma target 3.0
-
- sampler2D _MainTex;
- sampler2D _DisolveTex;
- half _Threshold;
- sampler2D _BurnTex;
- half _EdgeLength;
- half _BurnInstensity;
-
- struct Input
- {
- float2 uv_MainTex;
- float2 uv_DisolveTex;
- };
-
-
- UNITY_INSTANCING_BUFFER_START(Props)
- UNITY_INSTANCING_BUFFER_END(Props)
-
- void surf (Input IN, inout SurfaceOutputStandard o)
- {
- //读取纹理贴图
- fixed4 c = tex2D (_MainTex, IN.uv_MainTex) ;
- o.Albedo = c.rgb;
-
- //消融
- float cutout = tex2D(_DisolveTex, IN.uv_DisolveTex).r;
- //值小于0时舍弃该片元。
- clip(cutout - _Threshold);
- //temp越接近0的位置越接近消融边界。
- float temp = saturate((cutout - _Threshold) / _EdgeLength);
- //用temp当uv坐标读取渐变纹理。temp越接近0读取位置越靠近左下,temp越接近1读取位置越靠近右上。
- fixed4 edgeColor = tex2D(_BurnTex,float2(temp,temp));
- //将过渡的燃烧颜色作为自发光。temp=1时该片元完全不显示过渡颜色,当小于1时显示过渡颜色。
- fixed4 finalColor = _BurnInstensity * lerp(edgeColor, fixed4(0,0,0,0), temp);
- o.Emission = finalColor.rgb;
-
- o.Alpha = c.a;
- }
- ENDCG
- }
- FallBack "Diffuse"
- }
增大_Threshold值的效果:
如果想要用c#代码控制消融,先获得材质
material = GetComponent<SkinnedMeshRenderer>().materials[0];
之后就可以修改material.SetFloat("_Threshold", 值);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。