zoukankan      html  css  js  c++  java
  • Unity3D ShaderLab 模拟精灵动画

    Unity3D ShaderLab 模拟精灵动画

    在上一篇,介绍了通过Shader 模拟纹理运动,那么更深一步讲,我们也可以把帧动画的精灵纹理运动通过shader实现。

    虽然大家都是在游戏脚本中做更高一级的控制。但是有钱就是任性,码代码的也可以码任性啊,我们就来试试做精灵的运动动画,遍历播放每一帧。

     

    首先呢,准备一个精灵的动画序列帧,没有的找度娘要。然后创建一个新的材质球和新的着色器。然后把准备好的序列帧图拖动到材质的纹理上。

    不用多说,_MainTex ("Base (RGB)", 2D) = "white" {},就传递了我们设置好的帧图。

    接下来,还要通过Properties来创建动画的数量 速度等。

    1add>

    Properties {
    
    _MainTex ("Base (RGB)", 2D) = "white" {}
    
    _TexWidht("Image Width",float)=0
    
    _SpriteSize("Sprite Size",float)=0
    
    _Speed("Sprite Speed",Range(0.01,30))=0
    
    }

    上面声明的3个对象,同时也要在SubShaderCGPROGRAM下原样申明;

    2add>

    sampler2D _MainTex;
    
    float _TexWidht;
    
    float _SpriteSize;
    
    float _Speed;

    然后我们要把输入的uv值存入独立的变量,保证在代码中的使用。

    3add>

    void surf (Input IN, inout SurfaceOutput o) {
    
    //uv值存入spriteuv;
    
    float2 spriteUV = IN.uv_MainTex;
    
    //计算单元格的百分比;
    
    float pixeWidth = _TexWidht/_SpriteSize;
    
    float uvPercentage = pixeWidth/_TexWidht;
    
    float timeVal = fmod(_Time.y*_Speed,_SpriteSize);
    
    timeVal = ceil(timeVal);
    
    //计算sprite x方向上的偏移;
    
    float xValue = spriteUV.x;
    
    xValue+=uvPercentage*timeVal*_SpriteSize;
    
    xValue*=uvPercentage;
    
    //刷新uv值;
    
    spriteUV = float2(xValue,spriteUV.y);
    
    //传递新的uv值;
    
    half4 c = tex2D (_MainTex, spriteUV);
    
    o.Albedo = c.rgb;
    
    o.Alpha = c.a;
    
    }

    保存代码,回到编辑器中预览吧。

     

    通过上面的逻辑实现,我们不难看出我们首先从input结构体中获得到了uv值,把他存入到变量spriteUV 中,这个变量同时包含了uvxy坐标。

    接下来,我们获得在gui面板中传入的纹理宽度TexWidht和精灵数量SpriteSize,通过这两个纹理的参数获得了每一个sprite的宽度和每一个spriteuv中所占的比例值,

    这个比例值uvPercentage 表示我们的sprite从上一个精灵单元格到下一个精灵单元格的uv偏移量。

    最后,我们通过计算时间递增获得了最新的偏移值,在计算过程中用到了fmod()ceil()函数。

    最终我们得到了当前的uv值,传递给tex2D()函数,这样我们的sprite就像播放动画一样动起来;

    fmod(x,y):返回x/y的余数,符号同xy不可为0

    ceil(x):对输入参数向上取整,直到其值等于SpriteSize他就从新归0

    上面我们使用了x方向上的uv偏移,同理也可以加入y方向的uv偏移。从而满足更大的精灵表单循环。

     

    code start-------------------------------------------------

     

     

    Shader "91YGame/BasicSpriteAni" {
        Properties {
            _MainTex ("Base (RGB)", 2D) = "white" {}
            _TexWidht("Image Width",float)=0
            _SpriteSize("Sprite Size",float)=0
            _Speed("Sprite Speed",Range(0.01,30))=0
        }
        SubShader {
            Tags { "RenderType"="Opaque" }
            LOD 200
            
            CGPROGRAM
            #pragma surface surf Lambert
    
            sampler2D _MainTex;
            float _TexWidht;
            float _SpriteSize;
            float _Speed;
    
            struct Input {
                float2 uv_MainTex;
            };
    
            void surf (Input IN, inout SurfaceOutput o) {
                //uv值存入spriteuv;
                float2 spriteUV = IN.uv_MainTex;
                //计算单元格的百分比;
                float pixeWidth = _TexWidht/_SpriteSize;
                float uvPercentage = pixeWidth/_TexWidht;
    
                float timeVal = fmod(_Time.y*_Speed,_SpriteSize);
                timeVal = ceil(timeVal);
                //计算sprite x方向上的偏移;
                float xValue = spriteUV.x;
                xValue+=uvPercentage*timeVal*_SpriteSize;
                xValue*=uvPercentage;
                //刷新uv值;
                spriteUV = float2(xValue,spriteUV.y);
                //传递新的uv值;
                half4 c = tex2D (_MainTex, spriteUV);
                o.Albedo = c.rgb;
                o.Alpha = c.a;
            }
            ENDCG
        }
        FallBack "Diffuse"
    }

     



     

    code end---------------------------------------------------

  • 相关阅读:
    支付宝接口对接常见问题
    Myeclipse中配置安卓环境
    算法精解概述
    使用Eclipse开始Java编程
    Windows使用SSH管理Ubuntu
    大臣的旅费
    剪格子
    波动数列
    买不到的数目
    逆波兰表达式
  • 原文地址:https://www.cnblogs.com/2Yous/p/4209658.html
Copyright © 2011-2022 走看看