zoukankan      html  css  js  c++  java
  • 角色和武器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的实现

    体力活

    <wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">

  • 相关阅读:
    一个体验好的Windows 任务栏缩略图开发心得
    扫脸动画
    ShimmerTextView
    201512-2 消除类游戏 (水题,暴力)
    CCF 201512-1 数位之和 (水题)
    UVa 557 Burger (概率+递推)
    CCF 201604-2 俄罗斯方块 (模拟)
    CCF 201604-1 折点计数 (水题,暴力)
    UVa 10213 How Many Pieces of Land ? (计算几何+大数)
    UVa 1641 ASCII Area (计算几何,水题)
  • 原文地址:https://www.cnblogs.com/CloudLiu/p/10442301.html
Copyright © 2011-2022 走看看