[Unity3D]Shader编程之扫描显示

版权声明:本文为博主原创文章,转载请注明 http://blog.csdn.net/u012741077 https://blog.csdn.net/u012741077/article/details/53386209

通过Shader实现,从左向右的扫描显示,可自定义扫描颜色、宽度、速度。

效果图如下
这里写图片描述

编辑器界面如下
这里写图片描述

Shader源码如下

Shader "XM/ScanEffect"
{
    Properties
    {
        _MainTex("Main Tex", 2D) = "white"{}
        _lineColor("Line Color", Color) = (0,0,0,0)
        _lineWidth("Line width", Range(0, 1.0)) = 0.1
        _rangeX("Range X", Range(0,1.0)) = 1.0
    }

    SubShader
    {
        Tags {
            "Queue" = "Transparent"
        }

        ZWrite Off
        Blend SrcAlpha OneMinusSrcAlpha
        Cull back

        Pass
        {
            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag

            #include "Lighting.cginc"

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float4 _lineColor;
            float _lineWidth;
            float _rangeX;

            struct a2v
            {
                float4 vertex : POSITION;
                float4 texcoord : TEXCOORD0;
            };

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

            v2f vert(a2v v)
            {
                v2f o;
                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
                return o;
            }

            fixed4 frag(v2f i) : SV_TARGET
            {
                fixed4 col = tex2D(_MainTex, i.uv);

                if(i.uv.x > _rangeX)
                {
                    clip(-1);
                }
                else if (i.uv.x > _rangeX - _lineWidth)
                {
                    float offsetX = i.uv.x - _rangeX +_lineWidth;
                    fixed xAlpha = offsetX / _lineWidth;
                    col = col * (1 - xAlpha) + _lineColor * xAlpha;
                }


                return col;
            }

            ENDCG
        }
    }

    FallBack "Diffuse"
}

代码调用如下

using UnityEngine;
using System.Collections;
public class ScanEffect : MonoBehaviour
{
    //默认扫描线的宽
    [Range(0,1)]
    public float _defaultLineW = 0.2f;
    //扫描的速度
    [Range(0, 1)]
    public float _showSpeed = 0.02f;

    private MeshRenderer _render;

    private void Awake()
    {
        _render = GetComponent<MeshRenderer>();
        SetX(0);
        SetLineWidth(0);
    }

    public void SetLineWidth(float val)
    {
        _render.material.SetFloat("_lineWidth", val);
    }
    public void SetX(float val)
    {
        _render.material.SetFloat("_rangeX", val);
    }

    public void Show()
    {
        StopCoroutine("Showing");
        StartCoroutine("Showing");
    }
    public void Hide()
    {
        StopCoroutine("Showing");

        SetX(0);
        SetLineWidth(0);
    }

    private IEnumerator Showing()
    {
        float deltaX = 0;
        float deltaWidth = _defaultLineW;

        SetX(deltaX);
        SetLineWidth(deltaWidth);

        while (true)
        {
            if (deltaX != 1)
            {
                deltaX = Mathf.Clamp01(deltaX + _showSpeed);
                SetX(deltaX);
            }
            else
            {
                if (deltaWidth != 0)
                {
                    deltaWidth = Mathf.Clamp01(deltaWidth - _showSpeed);
                    SetLineWidth(deltaWidth);
                }
                else
                {
                    break;
                }
            }
            yield return new WaitForEndOfFrame();
        }
    }


    public void OnGUI()
    {
        if (GUILayout.Button("Show"))
        {
            Show();
        }
        if (GUILayout.Button("Hide"))
        {
            Hide();
        }
    }
}

这里写图片描述

猜你喜欢

转载自blog.csdn.net/u012741077/article/details/53386209