【URP】Shader繪制棋盤格對比內置管線
以繪制棋盤格為例,對比內置管線和URP中的Shader異同。
【從UnityURP開始探索游戲渲染】專欄-直達
異同簡述
- 面板屬性定義Properties一樣的
- Tags主要區別在于RenderPipeline的聲明
- 這里沒涉及到的渲染命令也是一樣的。
- 主要區別在Pass中使用CG還是HLSL
- 其中引用的內置變量的庫不同,內置引用UnityCG.cginc,而URP中引用URP包中的core.hlsl
- 再有HLSL中定義變量 用靜態緩沖宏定義包裹 ,CBUFFER_START(UnityPerMaterial),CBUFFER_END。內置中直接定義變量。
內置渲染管線與URP的基本概念對比
?內置渲染管線(Built-in Render Pipeline)
- Unity的默認渲染管線,采用固定架構設計
- 基于傳統的前向渲染和延遲渲染模式,代碼高度耦合
- 自定義選項有限,修改渲染流程需直接修改Unity源碼
- 使用CG語言編寫Shader,支持Standard Shader等內置著色器
?通用渲染管線(URP)
- 基于可編程渲染管線(SRP)框架的模塊化設計
- 核心邏輯通過C#腳本控制,如RenderPipeline和RenderPass
- 輕量且可擴展,專注于跨平臺性能優化
- 使用HLSL語言編寫Shader,支持Shader Graph可視化編輯
Shader的具體差異對比
| 對比維度 | 內置渲染管線 | URP |
|---|---|---|
| ?編程語言? | 主要使用CG | 主要使用HLSL |
| ?SubShader標簽? | 無特殊要求 | 需添加"RenderPipeline"="UniversalPipeline" |
| ?光照處理? | 內置光照模型 | 基于物理渲染(PBS)系統 |
| ?合批流程? | 傳統合批 | 支持SRP Batcher |
| ?數據類型? | 支持fixed類型 | 僅支持half/float類型 |
| ?著色器庫? | UnityCG.cginc | Packages/com.unity.render-pipelines.universal/ShaderLibrary |
| ?后處理支持? | 有限支持 | 更強大的后處理系統 |
Shader遷移到URP的步驟
?基礎修改?
- 在SubShader的Tags中添加
"RenderPipeline"="UniversalPipeline" - 將
CGPROGRAM/ENDCG替換為HLSLPROGRAM/ENDHLSL - 替換包含文件:
#include "UnityCG.cginc"→#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
?數據類型和函數調整?
- 將
fixed類型改為half或float - 更新光照計算函數,使用URP提供的API
- 將屬性定義在
CBUFFER_START(UnityPerMaterial)塊中以提高兼容性
?使用遷移工具?
- Unity官方提供Render Pipeline Converter工具
- 可自動轉換大部分標準Shader
- 對于自定義Shader,需要手動調整
?驗證和優化?
- 檢查材質在URP下的渲染效果
- 優化性能,利用URP特性如SRP Batcher
- 測試不同平臺的表現
遷移注意事項
?不兼容功能處理?
- 某些高級特效(如曲面細分)在URP中可能不支持
- 需要尋找替代方案或使用HDRP
?性能優化?
- URP更注重移動端性能,可減少不必要的計算
- 使用URP的批處理功能提高渲染效率
棋盤格Shader實現
內置Checkerboard.shader
Shader "Custom/Checkerboard"
{
Properties
{
_GridSize ("Grid Size", Range(1, 100)) = 10
_Color1 ("Color 1", Color) = (1,1,1,1)
_Color2 ("Color 2", Color) = (0,0,0,1)
_HighlightColor ("Highlight Color", Color) = (1,0,0,1)
_HighlightCoord ("Highlight Coordinate", Vector) = (0,0,0,0)
}
SubShader
{
Tags { "RenderType"="Opaque" }
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
float _GridSize;
fixed4 _Color1;
fixed4 _Color2;
fixed4 _HighlightColor;
float2 _HighlightCoord;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv * _GridSize;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
float2 gridPos = floor(i.uv);
float pattern = fmod(gridPos.x + gridPos.y, 2.0);
// 檢查是否是高亮坐標
if (gridPos.x == _HighlightCoord.x && gridPos.y == _HighlightCoord.y)
{
return _HighlightColor;
}
return pattern < 1.0 ? _Color1 : _Color2;
}
ENDCG
}
}
}
URP Checkerboard.shader
Shader "Universal Render Pipeline/Checkerboard"
{
Properties
{
_GridSize("Grid Size", Float) = 10
_Color1("Color 1", Color) = (1,1,1,1)
_Color2("Color 2", Color) = (0,0,0,1)
_HighlightColor("Highlight Color", Color) = (1,0,0,1)
_HighlightCoord("Highlight Coordinate", Vector) = (0,0,0,0)
}
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
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
};
struct Varyings
{
float2 uv : TEXCOORD0;
float4 positionHCS : SV_POSITION;
};
CBUFFER_START(UnityPerMaterial)
float _GridSize;
float4 _Color1;
float4 _Color2;
float4 _HighlightColor;
float2 _HighlightCoord;
CBUFFER_END
Varyings vert(Attributes IN)
{
Varyings OUT;
OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
OUT.uv = IN.uv * _GridSize;
return OUT;
}
half4 frag(Varyings IN) : SV_Target
{
float2 gridPos = floor(IN.uv);
float pattern = fmod(gridPos.x + gridPos.y, 2.0);
if (gridPos.x == _HighlightCoord.x && gridPos.y == _HighlightCoord.y)
{
return _HighlightColor;
}
return pattern < 1.0 ? _Color1 : _Color2;
}
ENDHLSL
}
}
}
【從UnityURP開始探索游戲渲染】專欄-直達
(歡迎點贊留言探討,更多人加入進來能更加完善這個探索的過程,??)

Unity內置渲染管線和URP在Shader編寫上的主要區別:1)URP使用HLSL而非CG語言;2)URP需添加RenderPipeline=UniversalPipeline標簽;3)URP使用CBUFFER宏封裝材質屬性;4)包含文件路徑不同。以棋盤格Shader為例,URP版本需要修改語言標簽、變量聲明方式和著色器庫引用。相比內置管線,URP更模塊化,支持跨平臺優化,但需注意部分高級功能可能不兼容。遷移時需替換代碼結構并利用URP特有功能如SRPBat
浙公網安備 33010602011771號