【從UnityURP開始探索游戲渲染】專欄-直達
前情提要
【渲染流水線】主線索引-從數據到圖像以UnityURP為例-CSDN博客
- 圖元裝配負責將離散頂點組裝成完整幾何圖元(如點、線、三角形、三角形條帶)
(對渲染的探索是個持續不斷完善的過程,記錄這個過程將零散的內容整理起來,其中肯定會有理解偏差和問題,如果哪里有問題,歡迎在評論區探討和指出)
輸入數據?
接收?頂點著色器輸出的離散頂點數據?,包括:
- 變換后的空間坐標(如裁剪空間位置)
- 頂點屬性(顏色、法線、紋理坐標等
輸出數據?
生成?完整幾何圖元?(Primitive),例如:
- 三角形(
GL_TRIANGLES
) - 線段(
GL_LINES
) - 點(
GL_POINTS
)?
在Unity中,圖元裝配的實現
主要通過?**網格拓撲(Mesh Topology)?和?索引緩沖區(Index Buffer)**?完成。
頂點分組模式?
-
?索引分組模式?通過索引數組(如
Mesh.triangles
或Mesh.GetIndices()
)定義頂點連接順序,每個索引指向頂點緩沖區中的位置,按預設拓撲規則分組?。例如:text 索引數組 [0,1,2,3,4,5] 三角形拓撲 → 分組為△(0,1,2)和△(3,4,5)
-
?順序分組模式?無索引時直接按頂點提交順序分組(如連續3頂點構成一個三角形)?。
?Unity支持的圖元類型?
?圖元類型? | ?描述? |
---|---|
三角形(Triangles ) | 每3個獨立頂點構成一個三角形,默認用于3D模型渲染?。 |
三角形條帶(TriangleStrip ) | 復用前2頂點與當前頂點生成新三角形,減少頂點重復提交?。 |
四邊形(Quads ) | 每4頂點構成一個四邊形(實際渲染時拆分為2個三角形)。 |
線段(Lines ) | 每2頂點構成一條線段,用于線框渲染?。 |
點(Points ) | 每個頂點獨立渲染為屏幕上的點?。 |
?拓撲連接規則?
- ?纏繞順序(Winding Order)?Unity默認使用?順時針順序?判定三角形正面,逆時針面會被剔除?。例如:
- 頂點順序
(v1,v2,v3)
為順時針 → 可見 - 順序
(v1,v3,v2)
為逆時針 → 剔除?。
- 頂點順序
- ?共享頂點優化?索引數組可復用頂點(如
[0,1,2,1,2,3]
生成兩個共享邊(1,2)
的三角形)。
?關鍵實現接口?
- ?設置拓撲類型?通過
MeshTopology
枚舉指定圖元類型(如MeshTopology.Triangles
)?。 - ?索引緩沖區操作?
Mesh.SetIndices()
:自定義索引分組規則Mesh.triangles
:直接設置三角形索引(舊API,效率較低)?
URP中對圖元裝配的調用位置與示例
在Unity URP (Universal Render Pipeline) 中,幾何階段的圖元裝配是由底層渲染管線自動處理的,主要通過ScriptableRenderContext
和CommandBuffer
系統完成。
?核心類與調用流程?
- ?UniversalRenderPipeline.RenderSingleCamera?入口點,通過
ScriptableRenderContext
提交繪制命令 - ?ScriptableRenderContext.DrawRenderers?觸發幾何處理,最終調用底層圖形API (如OpenGL/D3D)
- ?CommandBuffer.DrawProcedural?直接控制圖元裝配(手動模式)
圖元裝配示例代碼?
以下是不同圖元類型的裝配方式示例:
三角形 (Triangles)?
csharp
// 通過MeshFilter自動裝配var meshFilter = GetComponent<MeshFilter>();
Graphics.DrawMesh(meshFilter.sharedMesh, transform.position, transform.rotation, material, 0);
三角形帶 (Triangle Strip)?
csharp
// 手動通過CommandBuffer裝配
CommandBuffer cmd = new CommandBuffer();
cmd.DrawProcedural(Matrix4x4.identity,material,0,MeshTopology.TriangleStrip,vertexCount: 4// 需要至少4個頂點形成2個三角形
);
context.ExecuteCommandBuffer(cmd);
四邊形 (Quads)?
csharp
// URP中四邊形會被拆分為三角形處理
Mesh quadMesh = new Mesh();
quadMesh.vertices = new Vector3[] {/* 4個頂點 */ };
quadMesh.SetIndices(new int[] {0,1,2, 0,2,3}, MeshTopology.Triangles, 0);
Graphics.DrawMesh(quadMesh, Matrix4x4.identity, material, 0);
線段 (Lines)?
csharp
// 使用GL.LINES或LineRenderer組件
CommandBuffer cmd = new CommandBuffer();
cmd.DrawProcedural(Matrix4x4.identity,lineMaterial,0,MeshTopology.Lines,vertexCount: 2
);
點 (Points)?
csharp
// 使用MeshTopology.Points
CommandBuffer cmd = new CommandBuffer();
cmd.DrawProcedural(Matrix4x4.identity,pointMaterial,0,MeshTopology.Points,vertexCount: 1
);
底層實現位置?
- ?URP源碼關鍵文件?:
UniversalRenderPipelineCore.cs
?→?ExecuteRenderPass
方法ScriptableRenderer.cs
?→?EnqueuePass
提交繪制命令 - ?Shader支持?:在Shader中需聲明正確的
#pragma target
和幾何著色器(如需要)
調試
- 使用
Frame Debugger
查看實際提交的圖元類型 - 在URP設置中啟用
Native Rendering Debugger
- 檢查材質的
Render Queue
和Shader Pass
設置
更深入的管線定制,可繼承ScriptableRendererFeature
實現自定義幾何處理。
接下來:【渲染流水線】[幾何階段]-[歸一化NDC]以UnityURP為例-CSDN博客
【從UnityURP開始探索游戲渲染】專欄-直達
(歡迎點贊留言探討,更多人加入進來能更加完善這個探索的過程,🙏)