Bootstrap

Unity Shader URP 学习 《Built-in和URP中Unlit Shader的区别》

刚刚从Built-in过来看URP一脸懵逼,接下来开始总结两者的区别达到二脸懵逼

Built-in ——>Unlit

Shader "Unlit/NewUnlitShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            sampler2D _MainTex;
            float4 _MainTex_ST;

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

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

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
               
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
               
                fixed4 col = tex2D(_MainTex, i.uv);               
                return col;
            }
            ENDCG
        }
    }
}

 URP——>Unlit

Shader "Universal Render Pipeline/Unlit"
{
    Properties
    {
        _BaseMap("Texture", 2D) = "white" {}
        _BaseColor("Color", Color) = (1, 1, 1, 1)
        _Cutoff("AlphaCutout", Range(0.0, 1.0)) = 0.5
    }
    SubShader
    { 
        Tags { "RenderType" = "Opaque" "IgnoreProjector" = "True" "RenderPipeline" = "UniversalPipeline" }
        LOD 100

        Pass
        {
            Name "Unlit"
            HLSLPROGRAM
            // Required to compile gles 2.0 with standard srp library
            #pragma prefer_hlslcc gles
            #pragma exclude_renderers d3d11_9x

            #pragma vertex vert
            #pragma fragment frag
            #pragma shader_feature _ALPHATEST_ON
            #pragma shader_feature _ALPHAPREMULTIPLY_ON

            // -------------------------------------
            // Unity defined keywords     
            #pragma multi_compile_instancing

            #include "UnlitInput.hlsl"

            struct Attributes
            {
                float4 positionOS       : POSITION;
                float2 uv               : TEXCOORD0;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            struct Varyings
            {
                float2 uv        : TEXCOORD0;       
                float4 vertex : SV_POSITION;

                UNITY_VERTEX_INPUT_INSTANCE_ID
                UNITY_VERTEX_OUTPUT_STEREO
            };

            Varyings vert(Attributes input)
            {
                Varyings output = (Varyings)0;

                UNITY_SETUP_INSTANCE_ID(input);
                UNITY_TRANSFER_INSTANCE_ID(input, output);
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);

                VertexPositionInputs vertexInput =             
                GetVertexPositionInputs(input.positionOS.xyz);
                output.vertex = vertexInput.positionCS;
                output.uv = TRANSFORM_TEX(input.uv, _BaseMap);
               
                return output;
            }

            half4 frag(Varyings input) : SV_Target
            {
                UNITY_SETUP_INSTANCE_ID(input);
                UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);

                half2 uv = input.uv;
                half4 texColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv);
                half3 color = texColor.rgb * _BaseColor.rgb;
                half alpha = texColor.a * _BaseColor.a;
                AlphaDiscard(alpha, _Cutoff);

                #ifdef _ALPHAPREMULTIPLY_ON
                color *= alpha;
                #endif    

                return half4(color, alpha);
            }
            ENDHLSL
        }
      
    }
    FallBack "Hidden/Universal Render Pipeline/FallbackError"
    CustomEditor "UnityEditor.Rendering.Universal.ShaderGUI.UnlitShader"
}

标签部分有了一个"RenderPipeline" = "UniversalPipeline"

还有一个 Tags { "LightMode" = "UniversalForward" }是不能少的,这是unity的renderpass,默认我们可以使用这个单pass进行自定义,想要其他pass协同就需要在Assetrenderer中配置对应pass名称并修改lightMode

多了各种#pragma 其中一些是库代码中的开关。

prefer_hlslcc gles 在OpenGL ES 2.0中使用HLSLcc编译器,目前除了OpenGL ES 2.0全都默认使用HLSLcc编译器

exclude_renderers d3d11_9x 在Direct3D 11 9.x功能级别的渲染平台中不编译Shader

 

# include "UnityCG.cginc"没了取而代之的是#include "Packages/xxx/ShaderLibrary/xxx.hlsl",

Lighting.hlsl——>Core.hlsl...(开始套娃)

 

CGPROGRAM——>HLSLPROGRAM

ENDCG——>ENDHLSL

 

                                                             float4 _MainTex_ST;

UnilitInput.hlsl中定义好了名称,BaseMap,如果直接用只能相同名字,如果自己定义名称就声明在自己的pass里

不使用这一input.hlsl也可以需要自己include 对应代码库和自定义下面buffer中

CBUFFER_START(UnityPerMaterial)

//TODO放置Properties中的变量,Tex一般只放_Name_ST,其他两个仍在外面即可
CBUFFER_END

正确的话你会在编辑器shader属性界面看到

 

 下面两图直观上来看名字变了意思依然一样,UNITY_VERTEX_INPUT_INSTANCE_ID是instance宏

首先映入眼帘的是

 VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);

这东西是Core.hlsl中定义的,可以方便的使用worldSpace、ViewSpace、ClipSpace的空间坐标。

同样的还有一套Normal的

这里出现了一个新的浮点数变量定义 real,real的定义在Common.hlsl中。当函数可以同时用half,float来定义就用real。

当函数需要half , float 同时支持精度时 需要显式定义两者。

sampler2D _MainTex; ——> TEXTURE2D(_MainTex);SAMPLER(sampler_MainTex);// 采样器每个shader有数量上限可以定义一个共用统一当做采样器设置

tex2D(_MainTex, i.uv);  ——> SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv);

 AlphaDiscard(alpha, _Cutoff);其实就是做了  clip(alpha - cutoff + offset);
 

;