Unity中Shader序列帧动画(总结篇)

文章目录

  • 前言
  • 一、半透明混合自定义调整
    • 1、属性面板
    • 2、SubShader中
    • 3、在片元着色器(可选)
    • 3、根据纹理情况自己调节
  • 二、适配Build In Render Pipeline
  • 三、最终代码


前言

在前几篇文章中,我们依次解决了实现Shader序列帧动画所遇到的问题。

  • Unity中Shader序列图动画(UV流动的通用起始点)
  • Unity中Shader序列帧动画(U、V方向的走格)
  • Unity中Shader的_Time精度问题

我们在这篇文章中,对其进行优化、适配BRP 和 总结。


一、半透明混合自定义调整

1、属性面板

[Enum(UnityEngine.Rendering.BlendMode)]_SrcFactor(“SrcFactor”,int) = 0
[Enum(UnityEngine.Rendering.BlendMode)]_DstFactor(“DstFactor”,int) = 0

2、SubShader中

Blend [_SrcFactor] [_DstFactor]

3、在片元着色器(可选)

  • 使用返回颜色的rgb值与alpha值相乘输出,防止雾效影响透明度

col.rgb = col.rgb * col.a;

3、根据纹理情况自己调节

  • Unity中Shader的混合模式Blend
    Unity中Shader序列帧动画(总结篇)_第1张图片

二、适配Build In Render Pipeline

SubShader
    {
        Tags
        {
            //渲染类型
            "RenderType"="Transparent"
            //渲染队列
            "Queue"="Transparent"
        }
        Blend [_SrcFactor] [_DstFactor]
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fog
            #include "UnityCG.cginc"

            struct appdata
            {
                float3 vertexOS : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertexCS : SV_POSITION;
                float2 uv : TEXCOORD1;
                UNITY_FOG_COORDS(2)
            };


            float4 _Color;
            sampler2D _MainTex;
            float4 _MainTex_ST;
            half4 _Sequence;


            v2f vert(appdata v)
            {
                v2f o;
                o.vertexCS = UnityObjectToClipPos(v.vertexOS);
                o.uv = float2(v.uv.x / _Sequence.y, v.uv.y / _Sequence.x + (_Sequence.x - 1) / _Sequence.x);
                o.uv.x += frac(floor(_Time.y * _Sequence.y * _Sequence.z) / _Sequence.y);
                o.uv.y -= frac(floor(_Time.y * _Sequence.y * _Sequence.z / _Sequence.y) / _Sequence.x);
                //o.uv.x += floor(_Time.y);
                //o.uv = float2(v.uv.x/4,v.uv.y/4);
                //o.uv = TRANSFORM_TEX(v.uv,_MainTex);
                UNITY_TRANSFER_FOG(o, o.vertex)
                return o;
            }

            half4 frag(v2f i) : SV_Target
            {
                float4 mainTex = tex2D(_MainTex, i.uv);
                float4 col = mainTex * _Color;
                UNITY_APPLY_FOG(i.fogCoord, col)
                col.rgb = col.rgb * col.a;
                return col;
            }
            ENDCG
        }
    }

三、最终代码

Unity中Shader序列帧动画(总结篇)_第2张图片

Shader "MyShader/URP/P3_9"
{
    Properties
    {
        [Enum(UnityEngine.Rendering.BlendMode)]_SrcFactor("SrcFactor",int) = 0
        [Enum(UnityEngine.Rendering.BlendMode)]_DstFactor("DstFactor",int) = 0
        _Color("Color",Color) = (1,1,1,1)
        _MainTex("MainTex",2D) = "white"{}
        _Sequence("Row(X) Column(Y) Speed(Z)",Vector) = (1,1,1,1)
    }
    SubShader
    {
        Tags
        {
            //告诉引擎,该Shader只用于 URP 渲染管线
            "RenderPipeline"="UniversalPipeline"
            //渲染类型
            "RenderType"="Transparent"
            //渲染队列
            "Queue"="Transparent"
        }
        Blend [_SrcFactor] [_DstFactor]
        Pass
        {
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fog
            #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"

            struct Attribute
            {
                float3 vertexOS : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct Varying
            {
                float4 vertexCS : SV_POSITION;
                float2 uv : TEXCOORD1;
                float fogCoord : TEXCOORD2;
            };

            CBUFFER_START(UnityPerMaterial)
                float4 _Color;
                float4 _MainTex_ST;
                half4 _Sequence;
            CBUFFER_END

            TEXTURE2D(_MainTex);
            SAMPLER(sampler_MainTex);

            Varying vert(Attribute v)
            {
                Varying o;
                o.vertexCS = TransformObjectToHClip(v.vertexOS);
                o.uv = float2(v.uv.x / _Sequence.y, v.uv.y / _Sequence.x + (_Sequence.x - 1) / _Sequence.x);
                o.uv.x += frac(floor(_Time.y * _Sequence.y * _Sequence.z) / _Sequence.y);
                o.uv.y -= frac(floor(_Time.y * _Sequence.y * _Sequence.z / _Sequence.y) / _Sequence.x);
                //o.uv.x += floor(_Time.y);
                //o.uv = float2(v.uv.x/4,v.uv.y/4);
                //o.uv = TRANSFORM_TEX(v.uv,_MainTex);
                o.fogCoord = ComputeFogFactor(o.vertexCS.z);
                return o;
            }

            half4 frag(Varying i) : SV_Target
            {
                float4 mainTex = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv);
                float4 col = mainTex * _Color;
                col.rgb = MixFog(col, i.fogCoord);
                col.rgb = col.rgb * col.a;
                return col;
            }
            ENDHLSL
        }
    }
    SubShader
    {
        Tags
        {
            //渲染类型
            "RenderType"="Transparent"
            //渲染队列
            "Queue"="Transparent"
        }
        Blend [_SrcFactor] [_DstFactor]
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fog
            #include "UnityCG.cginc"

            struct appdata
            {
                float3 vertexOS : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertexCS : SV_POSITION;
                float2 uv : TEXCOORD1;
                UNITY_FOG_COORDS(2)
            };


            float4 _Color;
            sampler2D _MainTex;
            float4 _MainTex_ST;
            half4 _Sequence;


            v2f vert(appdata v)
            {
                v2f o;
                o.vertexCS = UnityObjectToClipPos(v.vertexOS);
                o.uv = float2(v.uv.x / _Sequence.y, v.uv.y / _Sequence.x + (_Sequence.x - 1) / _Sequence.x);
                o.uv.x += frac(floor(_Time.y * _Sequence.y * _Sequence.z) / _Sequence.y);
                o.uv.y -= frac(floor(_Time.y * _Sequence.y * _Sequence.z / _Sequence.y) / _Sequence.x);
                //o.uv.x += floor(_Time.y);
                //o.uv = float2(v.uv.x/4,v.uv.y/4);
                //o.uv = TRANSFORM_TEX(v.uv,_MainTex);
                UNITY_TRANSFER_FOG(o, o.vertex)
                return o;
            }

            half4 frag(v2f i) : SV_Target
            {
                float4 mainTex = tex2D(_MainTex, i.uv);
                float4 col = mainTex * _Color;
                UNITY_APPLY_FOG(i.fogCoord, col)
                col.rgb = col.rgb * col.a;
                return col;
            }
            ENDCG
        }
    }
}

你可能感兴趣的:(Unity,unity,游戏引擎)