TANotes

💡 学点儿丨URP Shader编辑指北[1] - URP Shader Structure

by ERIN.Z, 2022-05-27


说来惭愧,最近也做了不少把built-in shader转URP/HDRP的工作...但一直在很没出息地用Shader Graph.....趁这几天闲,好好掰扯掰扯URP和HDRP的Shader区别。

本篇引擎版本为Unity 2021.3.3f1c1 Universal RP 12.1.6

从Built-In到URP

PASS可用差别

之前Built-in管线写前向渲染时,使用一个pass计算主光,再用多个其他pass叠加光照。但URP中不支持多个渲染Pass。 URP提供的几个默认Shader中包含多个Pass,但是只能有一个渲染Pass:

  • 渲染Pass

    "LightMode" = "UniversalForward"

    输出到帧缓存,只能有一个

  • 投影Pass

    "LightMode" = "ShadowCaster"
  • 深度Pass

    "LightMode" = "DepthOnly"
  • 其他Pass 专门用于烘焙的Pass,专门用于2D渲染的Pass等

通过Render Feature可以实现之前多Pass的描边等效果。

为了使URP认识并能渲染所需的pass,要记得在SubShader中加上tag:

"RenderPipeline"="UniversalPipeline"

CG to HLSL

URP和HDRP都使用了HLSL,包含Shader语言的代码块要改为:

HLSLPROGRAME
    ...
ENDHLSL

头文件变化

包含的头文件也需要从"UnityCG.cginc"改为

 #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

Lighting相关的头文件为

 #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"

对应的一些函数名称也会有变化。

CBUFFER

为使用SRP Batcher,所有贴图外的暴露参数需要用CBUFFER_START(UnityPerMaterial)与CBUFFER_END包裹,并置于Pass之前。

CBUFFER_START(UnityPerMaterial)
    float4 _BaseMap_ST;
    float _Color;
CBUFFER_END

Basic Shader Structure

以下是一个可以有URP编译的基础Shader:

// This shader fills the mesh shape with a color predefined in the code.
Shader "Example/URPUnlitShaderBasic"
{
    // The properties block of the Unity shader. In this example this block is empty
    // because the output color is predefined in the fragment shader code.
    Properties
    { }

    // The SubShader block containing the Shader code.
    SubShader
    {
        // SubShader Tags define when and under which conditions a SubShader block or
        // a pass is executed.
        Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }

        Pass
        {
            // The HLSL code block. Unity SRP uses the HLSL language.
            HLSLPROGRAM
            // This line defines the name of the vertex shader.
            #pragma vertex vert
            // This line defines the name of the fragment shader.
            #pragma fragment frag

            // The Core.hlsl file contains definitions of frequently used HLSL
            // macros and functions, and also contains #include references to other
            // HLSL files (for example, Common.hlsl, SpaceTransforms.hlsl, etc.).
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

            // The structure definition defines which variables it contains.
            // This example uses the Attributes structure as an input structure in
            // the vertex shader.
            struct Attributes
            {
                // The positionOS variable contains the vertex positions in object
                // space.
                float4 positionOS   : POSITION;
            };

            struct Varyings
            {
                // The positions in this struct must have the SV_POSITION semantic.
                float4 positionHCS  : SV_POSITION;
            };

            // The vertex shader definition with properties defined in the Varyings
            // structure. The type of the vert function must match the type (struct)
            // that it returns.
            Varyings vert(Attributes IN)
            {
                // Declaring the output object (OUT) with the Varyings struct.
                Varyings OUT;
                // The TransformObjectToHClip function transforms vertex positions
                // from object space to homogenous clip space.
                OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
                // Returning the output.
                return OUT;
            }

            // The fragment shader definition.
            half4 frag() : SV_Target
            {
                // Defining the color variable and returning it.
                half4 customColor = half4(0.5, 0, 0, 1);
                return customColor;
            }
            ENDHLSL
        }
    }
}

by ERIN.Z

2024 © typecho & elise