Writing Shader Code for the Universal RP

URP中,RenderType可能不太重要了,在内置管线中,是用来做 Replacement Shaders 用的
但是在 URP 中不支持Replacement Shader,尽管有个 ForwardRenderer 的 overrideMaterail
每个Pass标签都需要标记特定的 LightMode,URP使用 single-pass forward renderer
所有只有一个 “UniversalFoward” 的 Pass,也不能同时渲染多个对象
也可以不加Tag,但是会破坏 SRP Batcher
建议在单独的 MeshRender 上使用独立的 Shader 或者材质
或者使用 Forward Renderer 上 overrideMaterial 的 Render Objects 特性

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Unity想弃用CG,推荐使用 HLSL(High level shading language)
不再有 fixed 类型,只有half 和 float
Cg 和 HLSL 被视为相同的语言
如果在 URP 中使用 CG 的标签,将与 URPShaderLibrary 冲突
因为变量和函数会被重复定义
现在请使用 HLSLPROGRAM, HLSLINCLUDE, ENDHLSL
不推荐用CGPROGRAM, ENDCG, CGINCLUDE

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
URP LightMode Tags:
Tags{“LightMode” = “XXX”}
UniversalForward:前向渲染物件之用
ShadowCaster: 投射阴影之用
DepthOnly:只用来产生深度图
Mata:来用烘焙光照图之用
Universal2D :做2D游戏用的,用来替代前向渲染
UniversalGBuffer : 貌似与延迟渲染相关

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Pass 的 Name,应该全大写
可以用 UsePass 来引用
例如:UsePass “Custom/UnlitShaderExample/MyShader”
为了与 SPRBatcher 兼容,所有传递必须共享相同的 UnityPerMaterial CBUFFER
如果不匹配,则出错

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
HLSL 数据类型
bool - true / false.
float - 32位浮点数,用在比如世界坐标,纹理坐标,复杂的函数计算
half - 16位浮点数,用于短向量、方向、颜色,模型空间位置
double - 64位浮点数,不能用于输入输出,要使用double,得声明为一对unit再用asuint把double打包到uint对中,再用asdouble函数解包
fixed - 只能用于内建管线,URP不支持,用half替代
real - 好像只用于URP,如果平台指定了用half(#define PREFER_HALF 0),否则就是float类型
int - 32位有符号整形
uint - 32位无符号整形(GLES2不支持,会用int替代)

vector - 类型可以直接在基础数据后添加维度
例如:float4, half3, int2
访问可以用xyzw或者rgba访问

HLSL数据类型3 – 矩阵
matrix类型可以直接在基础数据后添加 维度 x 维度
例如:float4x4, int4x3, half2x1
即表达 4行4列的float,4行3列的int,2行1列的half
float3x3 m = { 0, 1, 2, 3, 4, 5, 6, 7, 8};
float3 row0 = m[0]; // 0, 1, 2
float r1c2 = m[1][2]; // 5
乘法,使用mul进行
mul(m, row0)
第1个列数必须与第2个行数相同

HLSL数据类型4 – 数组
ShaderLab 材质属性面板 Properties 不支持数组,只能从C#中设置
必须在 Shader 中指定数组的大小,例如
float array[10];
float4x4 array2[10];

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
纹理和采样
定义:
TEXTURE2D(textureName);
SAMPLER(sampler_textureName);
缓存区:
从C#中使用material.SetBuffer 或者 Shader.SetGlobalBuffer
例如:StructuredBuffer buffer;

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
宏(macro)
define MUL2(x,y) ((x)(y))
可以做一些语法糖,例如:
define TRANSFORM_TEX(tex, name) (tex.xy
name##_ST.xy + name##_ST.zw)
o.uv = TRANSFORM_TEX(in.uv, _MainTex) =>
o.uv = (in.uv.xy * _MainTex_ST.xy + _MainTex.ST_zw)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
每个 Pass, UnityPerMaterial CBUFFER 都是相同的
CBUFFER需要包含所有公用的属性(即与ShaderLab中的Properties相同)
它不能包含其它未公开的属性以及纹理采样器
虽然不需要通过C# material.SetColor/SetFloat等
但多 Material 实例具有不同的值,这会产生问题,SRP Batcher会将他们一起批处理
1、如果您有未公开的变量,请始终使用Shader.SetGlobalColor / Float
以使它们在所有材质实例中保持不变。
2、如果每个材料都不同,则通过Shaderlab属性块将它们公开,然后将它们添加到 CBUFFER 中

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
HLSLINCLUDE
#include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl”
CBUFFER_START(UnityPerMaterial) float4 _BaseMap_ST; float4 _BaseColor; CBUFFER_END
ENDHLSL
Core.hlsl文件是URP的内置核心文件
比如如果要使用灯光,则添加 Lighting.hlsl文件

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Vertex Shader 阶段
在内置 Shader 中,使用 UnityObjectToClipPos 将模型空间转换到裁剪空间
URP 中使用 TransformObjectToHClip 函数(在 SpaceTransforms.hlsl 中有定义)
URP 中也可以使用 GetVertexPositionInputs 函数(在Core.hlsh中有定义)
得到的 VertexPositionInputs 结构体包含以下内容
positionWS = positionWorldSpace
positionVS = positionViewSpace
positionCS = positionClipSpace
positionNDC = position in Normalised Device Coordinates
我们可以直接使用上述代码,即便含有未使用到的变量
因为 Shader 编译器会自动对上述代码进行优化
法线 & 切线
VertexNormalInputs normalInputs = GetVertexNormalInputs(IN.normalOS, IN.tangentOS);
GetVertexNormalInputs 将模型空间法线和切线转换为世界空间
包含 normalWS, tangentWS, bitangetWS

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Fragment Shader 阶段
可以使用 SAMPLE_TEXTURE2D 宏进行采样
URP 不支持 Surface Shader
URP 的一些光照文件在 Lighting.hlsl 中
可以用来处理例如 UniversalFragmentPBR

以下代码展示了阴影相关的宏
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE
#pragma multi_compile _ _SHADOWS_SOFT
#include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl”

原文链接

王小兵 /
Published under (CC) BY-NC-SA in categories Unity  tagged with Unity