角色和武器Shader特效开发

角色Shader的动效需求

角Shader的开发不知要实现最基础光照等功能, 可能还要在角色武器的Shader增加多种动效, 比如因武器品质区分的流光特效, 被技能击中时的冻结效果.
这类动效的实现方式有多种, 以下以Shader的方式实现下列三种:

  • 流光
  • 溶解

开发思路

具体效果

  • 流光

    两层
    Alpha控制范围
  • matcap实现
  • 溶解

    支持溶解边缘亮边
    step(fixed2(noise, noise+edge), _Dissolve)

对需要实现的效果进行排序

实现这些需求的过程上来说, 肯定是一层一层在基础效果只上叠加上去的,相互之间是有"覆盖"关系的, 于是我们将以上需求排列整理如下:

  • 光照
  • 流光
  • 溶解

2. Shader代码的实现

1. 封装

#ifndef MESH_FX_CORE_INCLUDED
    #define MESH_FX_CORE_INCLUDED

    #ifdef MESH_FX_ON
        uniform float4 _EdgeColor;
        uniform sampler2D _DissolveNoiseTex;
        uniform float4 _DissolveNoiseTex_ST;
        uniform float _DissolveWidth;
        uniform float _Dissolve;

        uniform sampler2D   _MatcapTex      ;
        uniform float       _MatcapIntensity;

        uniform float4      _FlowColor;
        uniform sampler2D   _FlowTex        ;
        uniform float4      _FlowTexTiling  ;
        uniform float4      _Flow1Color;
        uniform sampler2D   _FlowTex1       ;
        uniform float4      _FlowSpeed      ;
        uniform float       _FlowIntensity  ;

        struct MeshFXData
        {
            float2 UV0;
            float3 normalWorld;
            fixed3 BaseColor;
        };

        fixed4 FX_Dissolve(MeshFXData fx)
        {
            float2 uv_DissolveNoiseTex = fx.UV0 * _DissolveNoiseTex_ST.xy + _DissolveNoiseTex_ST.zw;
            float4 dissolveTexCol = tex2D(_DissolveNoiseTex, uv_DissolveNoiseTex);
            float2 twoLayer = float2(dissolveTexCol.r, saturate(dissolveTexCol.r + _DissolveWidth));
            float2 dissolveResult = step(twoLayer, _Dissolve.xx);
            float4 finalCol = _EdgeColor * (dissolveResult.x - dissolveResult.y) * dissolveTexCol.r;
            finalCol.a = saturate(dissolveResult.x);
            return finalCol;
        }

        fixed4 FX_Frozen(MeshFXData fx)
        {
            float2 matCapUV = ((mul(UNITY_MATRIX_V, float4(fx.normalWorld, 0.0)).xyz * 0.5) + 0.5).xy;
            float4 finalCol = tex2D(_MatcapTex, matCapUV);
            finalCol.a = _MatcapIntensity;
            return finalCol;
        }

        fixed4 FX_LightFlow(MeshFXData fx)
        {
            float2 uv0 = fx.UV0 * _FlowTexTiling.xy + (_Time.y * _FlowSpeed.xy);
            fixed4 flowCol1 = tex2D(_FlowTex, uv0);
            fixed mask1 = tex2D(_FlowTex, fx.UV0.xy).a; //

            float2 uv1 = fx.UV0 * _FlowTexTiling.zw + (_Time.y * _FlowSpeed.zw);
            fixed4 flowCol2 = tex2D(_FlowTex1, uv1);
            fixed mask2 = tex2D(_FlowTex1, fx.UV0.xy).a;

            fixed4 layer1 = flowCol1 *  mask1 * _FlowColor;
            fixed4 layer2 = flowCol2 * mask2 * _Flow1Color;
            fixed4 col = (layer1 + layer2) * _FlowIntensity;
            col.a = max(flowCol1.a, flowCol2.a);
            return col;
        }

        fixed4 MeshFXInternal(MeshFXData fx)
        {
            fixed4 finalColor = fixed4(0, 0, 0, 0);

            fixed4 Dissolve = FX_Dissolve(fx);
            fixed4 Frozen = FX_Frozen(fx);
            fixed4 LightFlow = FX_LightFlow(fx);

            // lightflow -> frozen -> dissolve

            //lightflow
            finalColor.rgb = fx.BaseColor + LightFlow.rgb * fx.BaseColor * 2;

            //matcap frozen
            finalColor.rgb = lerp(finalColor.rgb, Frozen.rgb, Frozen.a);

            //dissolve
            finalColor.rgb = finalColor + Dissolve.rgb;
            finalColor.a = Dissolve.a;
            return finalColor;
        }
    #endif
#endif

2. 调用

#if defined(MESH_FX_ON)
    MeshFXData fx = (MeshFXData)0;
    fx.UV0 = i.tex.xy;
    fx.normalWorld = s.normalWorld;
    fx.BaseColor = Color.rgb;
    Color = MeshFXInternal(fx);
#endif

3. ShaderGUI的实现

体力活
角色和武器Shader特效开发_第1张图片

 
 
 
 

转载于:https://www.cnblogs.com/CloudLiu/p/10442301.html

你可能感兴趣的:(角色和武器Shader特效开发)