【转载】URP 中 Shader 与 Built-In 的区别

442 阅读2分钟

原文链接

版权声明:本文为CSDN博主「Rain哗啦啦」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:blog.csdn.net/qq_26916435…

正文

1、SRP 中特殊的 Tag —— RenderPipeline

指定用哪个管线渲染

  • URP: UniversalRenderPipeline
  • HDRP: HDRenderPipeline
  • SRP: 你自定义的标签

2、Pass 中首选语言为 HLSL 语言

Pass
{
    HLSLPROGRAM
    ENDHLSL
}

URP 也支持 CG 语言。如果给 Shader 添加了 CGPROGRAM/ENDCGPROGRAM 块,Unity 会自动 include 内置渲染管线 的代码库,此时如果你再 include SRP shader 代码库,可能会有一些宏或者函数和内置渲染管线代码库 冲突。此外,使用 CG 语言编写无法支持 SRP Batcher

如果用了 HLSLPROGRAM/ENDHLSL ,那么 UnityCG.cginc 已经不再适用,取而代之的是 Core.hlsl ,在引用时注明 #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" 即可。

3、CBUFFER

如果想要 Shader 和 SRP Batcher 兼容,需要将材质的所有属性定义在一个名为 UnityPerMaterialCBUFFER 块中

写在顶点着色器之前

CBUFFER_START(UnityPerMaterial)

half4_BaseColor;

CBUFFER_END

对于变量是 单个材质独有 的时候建议放在这里面,以提高性能。CBUFFER(常量缓冲区)的空间较小,不适合 存放纹理贴图这种大量数据的数据类型,适合 存放 floathalf 之类的不占空间的数据,

关于它使用请看 参考2 的详细说明(动态批处理GPU 实例化)。

4、URP 中可以引用 URP 特殊的库

Shader "MyShader/Unlit"
{
  Properties
  {
    _Color("Base Color",Color)=(1,1,1,1)
  }
  SubShader
  {
    Tags
    {
        "RenderType"="Opaque" 
        "RenderPipeline"="UniversalPipeline"
    }
    Pass
    {
         HLSLPROGRAM
         #pragma vertex vert
         #pragma fragment frag
         #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
         struct Attributes
         {
            // OS object space
            float4 positionOS:POSITION;
         };
         struct Varying
         {
            // 这个结构体必须包含 SV_POSITION, 
            // HCS 是 Homgeneous Clipping Space 齐次裁剪空间
            float4 positionHCS:SV_POSITION;
         };

         /// @note 重点
         CBUFFER_START(UnityPerMaterial)
         half4 _Color;
         CBUFFER_END

         Varyings vert(Attributes IN)
         {
            Varyings OUT;
            OUT.positionHCS=TransformObjectToHClip(IN.positionOS.xyz);
            return OUT;
         }
         half4 frag(Varyings IN):SV_Target
         {
            return Base
         }
         ENDHLSL
    }
  }
}

5、贴图采样

新的 DXD11 HLSL 贴图的 采样函数采样器函数TEXTURE2D (_MainTex)SAMPLER(sampler_MainTex),用来定义 采样贴图采样状态 代替原来 DXD9 的 sampler2D,在不同的平台有不同的变化,在 GLcore 库函数里定义,具体的原理未知,如有大佬了解望给予评论和指出。

image.png

贴图的采用输出函数采用 DXD11 HLSL 下的 SAMPLE_TEXTURE2D(textureName, samplerName, coord2) ,具有三个变量

image.png

分别是

  • TEXTURE2D (_MainTex) 的变量: 贴图的名字
  • SAMPLER(sampler_MainTex) 的变量: 贴图数据
  • uv: UV 信息

结构体

代码阶段 需要 注意 的是把模型传入的 UV 信息改为以下这样区分。

image.png

顶点阶段

顶点着色器阶段,使用的函数也是不一样的,TransformObjectToHClip(v.positionOS.xyz) 替换掉原来的。

image.png

参考