Unity学习笔记(六)——顶点动画

1.流动的河流

        声明所需要的属性:

    Properties
    {
        _MainTex       ("Main Tex", 2D)    = "white"{}
        _Color         ("Color",    Color) = (1.0, 1.0, 1.0, 1.0)
        _Speed         ("Speed",    float) = 0.5        
        _Magnitude     ("Distortion Magnitude", float) = 1
        _Frequency     ("Distortion Frequency", float) = 1
        _InvWaveLength ("Distortion Inverse Wave Length", float) = 10
    }
    

        确定子着色器标签:

Tags { "RenderType"="Transparent" 
       "Queue"="Transparent"        
       "IgnoreProjector"="Ture"         //是否收到投影影响
       "DisableBatching"="True"         //阻止 Unity 将动态批处理应用于使用此子着色器的几何体,动态批处理会将几何体转换至世界空间
                                        //从而导致无法访问物体的模型空间,顶点动画需要对模型空间下的顶点偏移,所以需要关闭。
             }

在标签中涉及到两个新的标签的声明:

1.IgnoreProjector

 2.DisableBatching

        pass实现:

Pass
        {
            Tags{ "LightMode"="ForwardBase" }

            ZWrite Off
            Blend SrcAlpha OneMinusSrcAlpha     //正常混合
            Cull Off                            //禁止剔除

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag


            #include "UnityCG.cginc"

            sampler2D _MainTex;     float4 _MainTex_ST;
            fixed4 _Color;
            float _Speed;
            float _Magnitude;
            float _Frequency;
            float _InvWaveLength;

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

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 pos : SV_POSITION;
            };


            v2f vert (appdata v)
            {
                v2f o;
                
                float4 Offset;
                Offset.yzw = float3 (0.0, 0.0, 0.0);       //只对x值进行偏移,所以其他分量取零
                Offset.x = sin(_Frequency * _Time.y + _InvWaveLength * (v.vertex.x  + v.vertex.y  + v.vertex.z )) * _Magnitude;
                // 利用_Frequency * _Time.y控制正弦函数的频率,为了不同位置有不同位移,加上模型空间的位置分量,并乘以_InvWaveLength控制波长
                // 最后对结果值乘以_Magnitude来控制波动幅度。
                o.pos = UnityObjectToClipPos(v.vertex + Offset);

                o.uv  = TRANSFORM_TEX(v.uv, _MainTex);
                o.uv += float2(0.0, _Time.y * _Speed);      //因为贴图是竖放

                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 c = tex2D (_MainTex, i.uv);
                c.rgb *= _Color.rgb;

                return c;
            }
            ENDCG
        }
    }

2.广告牌技术

        主要实现:

v2f vert (appdata v)
            {
                v2f o;                                                                  //此时还是在模型空间当中
                float3 center = float3(0, 0, 0);                                        //选择模型空间下的原点作为锚点
                float3 viewer = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos,1));     //获得模型空间下的视向量

                float3 normalDir = viewer - center;               //视向量减去原点,获得物体的法线
                //法线的Y为1时,意味着法线方向固定为视角方向,
                //法线的Y为0时,意味着法线在面上,则向上方向固定为(0, 1, 0),朝向视角
                normalDir.y = normalDir.y * _VerticalBillboarding;
                normalDir   = normalize(normalDir);                 //向量归一化

                float3 upDir    = abs(normalDir.y) > 0.999 ? float3(0, 0, 1) : float3(0, 1, 0); //通过法线向量不同的Y值获得粗略的向上方向
                float3 rightDir = normalize( cross( upDir, normalDir));                        //利用叉乘获得向右方向
                upDir = normalize( cross( normalDir, rightDir));                               //重新叉乘获得向上方向

                float3 centerOffs = v.vertex.xyz - center;          //获得原始位置相对于锚点的偏移量
                float3 localPos   = center + rightDir * centerOffs.x + upDir * centerOffs.y + normalDir * centerOffs.z;

                o.pos = UnityObjectToClipPos(float4(localPos, 1));
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值