图元装配负责将离散顶点组装成完整几何图元(如点、线、三角形、三角形条带)
【从UnityURP开始探索游戏渲染】专栏-直达
输入数据
接收顶点着色器输出的离散顶点数据,包括:
- 变换后的空间坐标(如裁剪空间位置)
- 顶点属性(颜色、法线、纹理坐标等
输出数据
生成完整几何图元(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实现自定义几何处理。
【从UnityURP开始探索游戏渲染】专栏-直达
(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |