【Shader】热扭曲实现刀光特效

来源:互联网 发布:怎么投诉淘宝网 编辑:程序博客网 时间:2024/04/24 06:04

第一种方式:

// 用于刀光的空气扭曲特效Shader "Custom/SimpleHeatDistortion" {    Properties {        _NoiseTex ("Noise Texture (RG)", 2D) = "white" {}        _MainTex ("Alpha (A)", 2D) = "white" {}        _HeatTime  ("Heat Time", range (0,1.5)) = 1        _HeatForce  ("Heat Force", range (0,1)) = 1    }    Category {        Tags { "Queue"="Transparent+1" "RenderType"="Transparent" }        Blend SrcAlpha OneMinusSrcAlpha        AlphaTest Greater .01        Cull Off Lighting Off ZWrite Off        SubShader {            GrabPass { Name "BASE" Tags { "LightMode" = "Always" } }            Pass {                Name "BASE"                Tags { "LightMode" = "Always" }                CGPROGRAM                #pragma vertex vert                #pragma fragment frag                #pragma fragmentoption ARB_precision_hint_fastest                #include "UnityCG.cginc"                struct appdata_t {                    float4 vertex : POSITION;                    fixed4 color : COLOR;                    float2 texcoord: TEXCOORD0;                };                struct v2f {                    float4 vertex : POSITION;                    float4 uvgrab : TEXCOORD0;                    float2 uvmain : TEXCOORD1;                };                float _HeatForce;                float _HeatTime;                float4 _MainTex_ST;                float4 _NoiseTex_ST;                sampler2D _NoiseTex;                sampler2D _MainTex;                v2f vert (appdata_t v)                {                    v2f o;                    o.vertex = UnityObjectToClipPos(v.vertex);                    #if UNITY_UV_STARTS_AT_TOP                        float scale = -1.0;                    #else                        float scale = 1.0;                    #endif                    o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;                    o.uvgrab.zw = o.vertex.zw;                    o.uvmain = TRANSFORM_TEX( v.texcoord, _MainTex );                    return o;                }                sampler2D _GrabTexture;                half4 frag( v2f i ) : COLOR                {                    half4 offsetColor1 = tex2D(_NoiseTex, i.uvmain + _Time.xz*_HeatTime);                    half4 offsetColor2 = tex2D(_NoiseTex, i.uvmain - _Time.yx*_HeatTime);                    i.uvgrab.x += ((offsetColor1.r + offsetColor2.r) - 1) * _HeatForce;                    i.uvgrab.y += ((offsetColor1.g + offsetColor2.g) - 1) * _HeatForce;                    half4 col = tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(i.uvgrab));                    col.a = 1.0f;                    half4 tint = tex2D( _MainTex, i.uvmain);                    return col*tint;                }                ENDCG            }// End Pass        }// End SubShader        // Fallback for older cards and Unity non-Pro        SubShader {            Blend DstColor Zero            Pass {                Name "BASE"                SetTexture [_MainTex] { combine texture }            }        }    }}

第二种方式:

头文件

// 来自博客:http://console-dev.de/#ifndef GRABPASSDISTORTION_GCINC#define GRABPASSDISTORTION_GCINC// _MainTex is the distortion texture and should use "Bypass sRGB Sampling" import setting.sampler2D _MainTex;// _MainTex tiling and offset properties.float4 _MainTex_ST;// _GrabTexture contains the contents of the screen where the object is about to be drawn.sampler2D _GrabTexture;// x=horizontal intensity, y=vertical intensity// z=horizontal scrolling speed, w=vertical scrolling speedfloat4 _IntensityAndScrolling;// x=near distance at which distortions have full intensity// y=far distance at which distortions have zero intensityhalf2 _DistanceFade;#if ENABLE_TINT// Tinting the distorted areahalf3 _Tint;#endifstruct appdata_t{    float4 vertex  : POSITION;    half2 texcoord : TEXCOORD0;    fixed4 color   : COLOR;};struct v2f{    float4 vertex  : SV_POSITION;    fixed4 color   : COLOR;     // a=distortion intensity multiplier    half4 texcoord : TEXCOORD0; // xy=distort uv, zw=mask uv    half4 screenuv : TEXCOORD1; // xy=screenuv, z=distance dependend intensity, w=depth};// ----------------------------------------------------------------------------// Helper Functions// ----------------------------------------------------------------------------inline float2 Repeat(float2 t, float2 length){    return t - floor(t / length) * length;}inline float2 PingPong(float2 t, float2 length){    t = Repeat(t, length * 2);    return length - abs(t - length);}// ----------------------------------------------------------------------------// Vertex Shader// ----------------------------------------------------------------------------v2f vert (appdata_t v){    v2f o = (v2f)0;    o.vertex = UnityObjectToClipPos(v.vertex);    o.color  = v.color;    // texcoord.xy stores the distortion texture coordinates.    o.texcoord.xy = TRANSFORM_TEX(v.texcoord, _MainTex); // Apply texture tiling and offset.    o.texcoord.xy += _Time.gg * _IntensityAndScrolling.zw; // Apply texture scrolling.    // texcoord.zw stores the distortion mask texture coordinates.    // We don't want to scroll the mask, so we just use the original texture coords.    o.texcoord.zw = v.texcoord;    half4 screenpos = ComputeGrabScreenPos(o.vertex);    o.screenuv.xy = screenpos.xy / screenpos.w;    // Calculate distance dependend intensity.    // Blend intensity linearily between near to far params.    half depth = length(mul(UNITY_MATRIX_MV, v.vertex));    o.screenuv.z = saturate((_DistanceFade.y - depth) / (_DistanceFade.y - _DistanceFade.x));    o.screenuv.w = depth;    return o;}// ----------------------------------------------------------------------------// Pixel Shader// ----------------------------------------------------------------------------fixed4 frag (v2f i) : COLOR{    half2 distort = tex2D(_MainTex, i.texcoord.xy).xy;    // distort*2-1 transforms range from 0..1 to -1..1.    // negative values move to the left, positive to the right.    half2 offset = (distort.xy * 2 - 1) * _IntensityAndScrolling.xy * i.screenuv.z * i.color.a;#if ENABLE_TINT    half3 tint = _Tint;#endif#if MASK    // _MainTex stores in the blue channel the mask.    // The mask intensity represents how strong the distortion should be for this pixel.    // black=no distortion, white=full distortion    half  mask = tex2D(_MainTex, i.texcoord.zw).b;                  offset *= mask;    #if ENABLE_TINT    // Push tint towards white where distortions are not applied.    // This makes the tint fade out using the mask.    tint = lerp(tint, half3(0.5,0.5,0.5), 1-mask);    #endif#endif                          #if ENABLE_CLIP                 // Clip pixel if offset is really small. This makes masked particle    // distortions blend together slightly better.    clip(dot(offset,1) - 0.0001);                   #endif                      // get screen space position of current pixel    half2 uv = i.screenuv.xy + offset;#if MIRROR_EDGE    // Mirror uv's when it goes out of the screen.    // This avoids streched seams at screen borders by introducing    // these kind of mirroring artifacts. It looks less disturbing than the border seams though.    uv = PingPong(uv, 1);#endif    half4 color = tex2D(_GrabTexture, uv);#if ENABLE_TINT    color.rgb *= tint * 2;#endif    UNITY_OPAQUE_ALPHA(color.a);#if DEBUGUV    color.rg = uv;    color.b = 0;#endif#if DEBUGDISTANCEFADE    color.rgb = lerp(half3(1,0,0), half3(0,1,0), i.screenuv.z);#endif    //color.rgb = float3(fade,fade,fade)*15;    return color;}#endif // GRABPASSDISTORTION_GCINC

Shader 文件

// 热扭曲 —— GrabPass 实现方式Shader "Custom/GrabPass Distortion (Layer)"{    Properties    {        _MainTex ("Texture (R,G=X,Y Distortion; B=Mask; A=Unused)", 2D) = "white" {}        _Tint ("Tint (RGB)", Color) = (0.5,0.5,0.5,1)        _IntensityAndScrolling ("Intensity (XY); Scrolling (ZW)", Vector) = (0.1,0.1,1,1)        _DistanceFade ("Distance Fade (X=Near, Y=Far, ZW=Unused)", Float) = (20, 50, 0, 0)        [Toggle(MASK)] _MASK ("Texture Blue channel is Mask", Float) = 0        [Toggle(MIRROR_EDGE)] _MIRROR_EDGE ("Mirror screen borders", Float) = 0        [Enum(UnityEngine.Rendering.CullMode)] _CullMode ("Culling", Float) = 0        [Toggle(DEBUGUV)] _DEBUGUV ("Debug Texture Coordinates", Float) = 0        [Toggle(DEBUGDISTANCEFADE)] _DEBUGDISTANCEFADE ("Debug Distance Fade", Float) = 0    }    SubShader    {        Tags {"Queue" = "Transparent" "IgnoreProjector" = "True"}        Blend One Zero        Lighting Off        Fog { Mode Off }        ZWrite Off        LOD 200        Cull [_CullMode]        // 文档 http://docs.unity3d.com/Manual/SL-GrabPass.html        // Note: this form of grab pass (not specifying a texture name) will do the        // expensive screen grabbing operation for each object that uses it!        GrabPass{ }        Pass        {              CGPROGRAM                #pragma vertex vert                #pragma fragment frag                #pragma shader_feature MASK                #pragma shader_feature MIRROR_EDGE                #pragma shader_feature DEBUGUV                #pragma shader_feature DEBUGDISTANCEFADE                #define ENABLE_TINT 1                #include "UnityCG.cginc"                #include "GrabPassDistortion.cginc"            ENDCG        }    }}