Unity3d之流光效果

所谓流光效果,如一个图片上一条刀光从左闪到右边,以下为实现代码:

c#代码:

using System;
using UnityEngine;

public class WalkLightEffect : MonoBehaviour
{
    public Texture MainTex;
    public Texture LightTex;
    public float Duration;
    public float LightULen;
    public Vector2 Size;

    bool m_play;
    float m_timer;
    float m_t1;

    void Awake()
    {
        if (MainTex == null)
            throw new ArgumentNullException("MainTex");
        if (LightTex == null)
            throw new ArgumentNullException("LightTex");
        if (Duration <= 0)
            throw new ArgumentException("Duration");
        if (LightULen <= 0 || LightULen >= 1)
            throw new ArgumentException("LightULen <= 0 || LightULen >= 1");
        if (Size.x <= 0 || Size.y <= 0)
            throw new ArgumentException("Size.x <= 0 || Size.y <= 0");

        GenerateRenderer();

        m_t1 = (1 - LightULen) * Duration;
    }

    void GenerateRenderer()
    {
        // Mesh
        Mesh mesh = new Mesh();
        mesh.vertices = new Vector3[4] 
            { 
                new Vector2(-Size.x/2,Size.y/2),
                new Vector2(Size.x/2,Size.y/2),
                new Vector2(-Size.x/2,-Size.y/2),
                new Vector2(Size.x/2,-Size.y/2),
            };
        mesh.triangles = new int[6] { 0, 1, 2, 2, 1, 3 };
        mesh.uv = new Vector2[4] 
            { 
                new Vector2(0,1),
                new Vector2(1,1),
                new Vector2(0,0),
                new Vector2(1,0),
            };

        mesh.Optimize();

        var mf = gameObject.AddComponent<MeshFilter>();
        mf.mesh = mesh;

        // Material
        var mat = new Material(Shader.Find("Bleach/WalkLight"));
        mat.SetTexture("_MainTex", MainTex);
        mat.SetFloat("_LightLen", LightULen);

        var mr = gameObject.AddComponent<MeshRenderer>();
        mr.sharedMaterial = mat;
    }

    void Update()
    {
        if (m_play)
        {
            renderer.material.SetFloat("_TimeRate", m_timer / Duration);

            m_timer += Time.deltaTime;

            if (m_timer > Duration)
                m_timer = 0;
            else if (m_timer > m_t1)
                renderer.material.SetFloat("_ReachBoundary", 1);
            else
                renderer.material.SetFloat("_ReachBoundary", -1);
        }
    }

    public bool Play
    {
        set
        {
            renderer.material.SetTexture("_LightTex", value ? LightTex : null);
            m_timer = 0;
            m_play = value;
        }
    }
}

shader代码:

Shader "Bleach/WalkLight"
{
    Properties
    {
        _MainTex ("Main", 2D) = "white" {}
        _LightTex("Light", 2D) = "black" {}
        _LightLen("Light Length", float) = 0
    }
    
    SubShader
    {
        Pass
        {
            Tags { "RenderType"="Opaque" }
            LOD 200
            
            Cull Off
                                                
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            uniform sampler2D _MainTex;
            uniform sampler2D _LightTex;
            uniform    fixed _LightLen;
            
            uniform fixed _ReachBoundary;     // 小于0表示未到边界,大于0表示到达边界
            uniform fixed _TimeRate;        // 时间/周期
            
            struct Data
            {
                fixed4 vertex:POSITION;
                fixed2 texcoord:TEXCOORD0;
            };
            
            struct V2F
            {
                fixed4 pos:SV_POSITION;
                fixed2 uv:TEXCOORD0;
            };
            
            V2F vert(Data v)
            {
                V2F o;
                o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
                o.uv=v.texcoord;
                return o;
            }    
            
            fixed4 frag(V2F i):COLOR 
            {
                fixed4 main = tex2D(_MainTex,i.uv);
                fixed x = _ReachBoundary>0 && i.uv.x<_LightLen? i.uv.x+1 : i.uv.x;
                fixed lightU = (x - _TimeRate)/_LightLen;            // u=(x-timer/Duration)/_LightLen;
                fixed4 light = tex2D(_LightTex,float2(lightU,i.uv.y));
                
                return lerp(main,light,light.a);
            }
                            
            ENDCG
        }
    }
    
    FallBack "Diffuse"
}

 

转载请注明出处:http://www.cnblogs.com/jietian331/p/4748644.html

posted @ 2015-08-21 18:06  孤独の巡礼  阅读(2107)  评论(0编辑  收藏  举报