Unity Shader入门(一)——宝可梦战斗切屏特效

注:本文介绍的Shader来自于油管视频,有条件、听得懂的童鞋建议点下链接去给原po点个赞

前言

本文介绍的Shader来自于油管视频——Shaders Case Study - Pokémon Battle Transitions
有条件、听得懂的童鞋建议去给原po点个赞
最近看了大半本书,还在跟阴影光照纠缠不清,一个Shader都写不出来
这个视频7分钟介绍了N种宝可梦的战斗切屏动画
照搬思路,一些简单动画就成型了

效果

切屏动画
看起来很好像有点复杂有木有
换做以前,我只能让美术做个全屏的Spine动画盖上去,或者拿几个黑色色块写一连串动画
这样对做法一来麻烦(尤其上自己写动画),二来不够灵活,换个表现就要重新做
那,换成Shader呢?
几行代码即可实现上面的效果。并且一句代码都不用改,就可以换成下面的效果
切屏动画2
切屏动画3
很神奇有木有

原理

屏幕后处理

所谓屏幕后处理,可以理解成,整个场景渲染完毕,还未绘制到显卡被用户看到前,介入其中,对渲染的结果做处理

因为切屏特效要覆盖整个屏幕,采用屏幕后处理自然再适合不过
Unity中要使用屏幕后处理只需要在Camera上挂个脚本,并添加如下代码

1
2
3
4
5
void OnRenderImage(RenderTexture src, RenderTexture dst)
{
    if (TransitionMaterial != null)
        Graphics.Blit(src, dst, transitionMaterial);
}

纹理

秘密就在下面这张图上

这张图上RGB值的变化与上面的切屏动画的变化是一致的
在Shader中,对这张图进行采样,比较R通道,如果小于当前阀值,则用指定颜色覆盖,否则正常渲染

1
2
3
4
5
6
7
8
9
10
11
12
fixed4 frag (v2f i) : SV_Target
{
    fixed4 transit = tex2D(_TransitionTex, i.uv);
    if (transit.b < _Cutoff)
    {
        return _Color;
    }
   
    // sample the texture
    fixed4 col = tex2D(_MainTex, i.uv);
    return col;
}

完整Shader代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
Shader "Custom/TransitionByTexture"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _TransitionTex ("Transition Texture", 2D) = "white" {}
        _Color("Screen Color", Color) = (1,1,1,1)
        _Cutoff ("Cutoff", range(0, 1)) = 0
    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float2 uv1 : TEXCOORD1;
                float4 vertex : SV_POSITION;
            };

            float4 _MainTex_TexelSize;
            sampler2D _MainTex;
            sampler2D _TransitionTex;
            float4 _MainTex_ST;
            fixed4 _Color;
            float _Cutoff;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                o.uv1 = v.uv;
               
                // Flip sampling of the Texture:
                // The main Texture
                // texel size will have negative Y).
                #if UNITY_UV_STARTS_AT_TOP
                if (_MainTex_TexelSize.y < 0)
                {
                    o.uv1.y = 1 - o.uv1.y;
                }
                #endif
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 transit = tex2D(_TransitionTex, i.uv);
                if (transit.b < _Cutoff)
                {
                    return _Color;
                }
               
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv);
                return col;
            }
            ENDCG
        }
    }
}

demo下载
提取码: mcq4
第一次写,不会搞下载,暂时先放网盘

抱歉,有点卡壳了,暂时留个坑。
感觉如果完全零基础,需要讲的东西好像比预想的多,一时不知道如何下手
麻烦看官们暂且自己看一下回头再来填坑