• UnityShader 序列帧动画效果


    实现原理:主要思想是设置显示uv纹理的大小,并逐帧修改图片的uv坐标。

    实现步骤

    1、我们首先用_Time.y和速度属性_Speed相乘得到模拟的时间。

    2、然后我们用time除以_HorizontalAmount的结果值作为当前的行索引,除法结果的余数则是列索引。

    3、接下来,我们根据行索引和列索引来构建真正的采样坐标。由于序列帧图像包含了很多张关键帧图像,这意味着采样坐标需要映射到关键帧图像的坐标范围。

    4、我们可以把原纹理坐标i.uv按行数和列数进行等分,得到每个子图像的纹理坐标范围。

    5、映射到对应的行列数后,再对纹理坐标进行偏移。

    注意:Unity的纹理坐标竖直方向的顺序和序列帧纹理中竖直方向上的顺序是相反的。

     1 Shader "unilt/SceneRainSplash" {
     2     Properties {
     3         _MainTex ("Base (RGB)", 2D) = "white" {}               //序列帧动画纹理  
     4         _Color("Color Tint", Color) = (1, 1, 1, 1)            //颜色
     5         _HorizontalAmount("Horizontal Amount", float) = 6        // 行数
     6         _VerticalAmount("Vertical Amount", float) = 1            // 列数 
     7         _Speed("Speed", Range(1, 100)) = 7                     // 播放速度 
     8     }
     9     
    10     CGINCLUDE
    11 
    12         #include "UnityCG.cginc"
    13 
    14         sampler2D _MainTex;
    15         
    16         uniform half4 _MainTex_ST;
    17         uniform fixed4 _Color;
    18         uniform float _HorizontalAmount;
    19         uniform float _VerticalAmount;
    20         uniform float _Speed;
    21 
    22         struct appdata
    23         {
    24             float4 vertex : POSITION;   //从形似寄存器中读取顶点坐标
    25             float2 uv : TEXCOORD0;      //从形似寄存器中读取uv坐标信息
    26         };
    27         
    28 
    29         struct v2f
    30         {
    31             float2 uv : TEXCOORD0;
    32             float4 vertex : SV_POSITION;
    33         };
    34 
    35         v2f vert(appdata v)
    36         {
    37             v2f o;
    38             
    39             //mul(UNITY_MATRIX_MVP,*)' == 'UnityObjectToClipPos(*) 
    40             //(物体的模型到世界矩阵 * 从世界到摄像机的矩阵 * 投影的矩阵 )
    41             o.vertex = UnityObjectToClipPos(v.vertex);
    42             
    43             //TRANSFORM_TEX,就是将模型顶点的uv和Tiling、offset两个变量进行计算得出实际显示用的定点uv
    44             o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    45             
    46             return o; 
    47         }
    48         
    49         fixed4 frag(v2f i) : SV_Target
    50         {    
    51             //所经过的时间,Unity内置变量_Timefloat4 _Time : Time (t/20, t, t*2, t*3)
    52             float time = floor(_Time.y * _Speed);
    53             //该时间渲染序列帧动画指定的行列
    54             float row = floor(time / _HorizontalAmount);
    55             float col = time - row * _HorizontalAmount;
    56 
    57             //将所显示的单张图片缩放到应有的大小区域
    58             half2 uv = float2(i.uv.x / _HorizontalAmount, i.uv.y / _VerticalAmount);
    59             //移动到对应缩放后的区域位置
    60             uv.x += col / _HorizontalAmount;
    61             uv.y -= row / _VerticalAmount;
    62             fixed4 color = tex2D(_MainTex, uv);
    63             color.rgb *= _Color.rgb;
    64             return color;
    65         }
    66     
    67     ENDCG
    68     
    69     SubShader {
    70         Tags { "Queue" = "Transparent" }
    71         Cull Off
    72         ZWrite Off
    73         Blend One OneMinusSrcColor
    74 
    75     Pass {
    76     
    77         CGPROGRAM
    78         
    79         #pragma vertex vert
    80         #pragma fragment frag
    81         #pragma fragmentoption ARB_precision_hint_fastest 
    82         
    83         ENDCG
    84          
    85         }
    86                 
    87     } 
    88     FallBack Off
    89 }

    序列帧图像:

  • 相关阅读:
    C 实战练习题目20 – 小球自由下落
    C 实战练习题目19
    C 实战练习题目18
    C 实战练习题目17
    C 实战练习题目16 -最大公约数和最小公倍数
    C 实战练习题目15
    C 实战练习题目14 -将一个正整数分解质因数
    C 实战练习题目13 -水仙花数
    C 实战练习题目12
    C 实战练习题目11
  • 原文地址:https://www.cnblogs.com/kane0526/p/9216580.html
Copyright © 2020-2023  润新知