亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

【渲染流水線】[應用階段]-[裁剪]以UnityURP為例

標簽:
Unity 3D C#

Unity URP中的裁剪过程涉及多个阶段和算法,尤其在应用阶段(CPU端)主要通过视锥体剔除实现,核心算法包括包围盒测试和空间分区优化。裁剪过程主要发生在引擎的C++层面,但URP在C#端提供了定制化扩展点,例如光照剔除的优化。以下详细分析裁剪过程。

一、应用阶段的裁剪算法

  • 包围盒裁剪算法‌:视锥体剔除使用轴对齐包围盒(AABB)测试对象是否在视锥体内,Unity引擎默认采用此算法快速筛选可见对象。引擎会计算一个模型的包围盒,包围盒信息存放在U3D的Mesh.bounds中。包围盒是长方体,称之为AABB盒。盒子有8个点定,有任意一个顶点在摄像机范围内(视锥体或正交范围内)就不会被剔除,否则直接剔除。例如,每个GameObject的包围盒与摄像机视锥体进行相交检测,剔除不可见物体以提高渲染效率。
  • 其他算法‌:
    • 空间分区算法‌:如zBinning和Tile-based划分,将场景划分为多个区块(Tile),用于光源剔除(例如forward+算法中的光照影响范围测试),这虽然不是直接几何裁剪,但优化了后续渲染阶段的负载。
    • 层次结构加速‌:Unity引擎底层可能使用Bounding Volume Hierarchy(BVH)或四叉树加速包围盒测试,尤其在复杂场景中减少计算量,但这些实现细节未完全公开。
    • 遮挡剔除算法(如软件光栅化或Early-Z技术)主要在光栅化阶段执行,非应用阶段焦点。

包围盒裁剪是应用阶段的核心,但结合空间分区可提升效率;其他如UI裁切(如RectMask2D或模板缓冲)属于特定情境的实现,非全局几何裁剪。

  • 下面讨论包围盒裁剪算法的原理与实现
    1. 基础算法:AABB与视锥体相交测试
      Unity URP在应用阶段(CPU端)的裁剪核心是轴对齐包围盒(AABB)与视锥体的相交检测。具体流程如下:
    • AABB生成:每个GameObject的Renderer组件会自动计算其AABB,包含centersize属性,定义物体在局部空间的边界。
    • 视锥体平面方程:摄像机视锥体由6个平面(近、远、左、右、上、下)定义,每个平面通过法线向量和距离原点参数表示。Unity通过GeometryUtility.CalculateFrustumPlanes获取这些平面。
    • 相交测试:对每个AABB的8个顶点,检查是否所有顶点均在任一视锥体平面的外侧。若存在至少一个顶点在所有平面内侧,则物体可见;否则被剔除。
    1. 优化策略:层次化与空间分区
      为提高效率,Unity引擎采用以下优化:
    • 层级包围盒(BVH):对复杂场景构建层次化包围盒树,优先测试父节点AABB,快速剔除整组不可见物体。
    • 动态更新机制:仅对位置或旋转变化的物体重新计算AABB,静态物体通过预计算缓存结果。
    1. URP的定制化扩展
      URP在C#层通过以下方式增强裁剪:
    • 光照剔除集成:结合Tile-based分块(如16x16像素区块),将光源AABB与区块边界比对,仅保留影响当前区块的光源。
    • 动态分辨率适配:根据目标渲染分辨率动态调整视锥体参数,确保裁剪精度与性能平衡。
    1. 数学原理与代码实现
      关键数学逻辑包括:
    • 平面测试公式:对平面方程Ax + By + Cz + D = 0,顶点(x,y,z)代入后若结果大于0则位于外侧。
    • AABB顶点计算:通过center ± size/2生成8个顶点,转换到世界空间后测试。
      示例代码片段(简化版):
    bool IsVisible(Bounds bounds, Plane[] frustumPlanes) {
        foreach (var plane in frustumPlanes) {
             if (plane.GetDistanceToPoint(bounds.ClosestPoint(plane.normal * -1)) < 0)
                          return false; // 完全在平面外侧
             }
    		return true;
    }
    
    1. 性能与局限性
    • 优势:AABB计算简单,适合快速剔除;层级结构减少测试次数。
    • 局限:旋转物体会导致AABB膨胀(需使用OBB优化,但URP默认未采用)。

二、裁剪过程的位置:C++引擎层与URP C#定制

  • 主要位于C++引擎层‌:视锥体剔除由Unity引擎核心C++代码处理,实现高效、低层的包围盒测试和视锥计算,确保平台兼容性和性能。URP作为上层框架,依赖此基础剔除机制。
  • URP C#端定制‌:
    • URP在C#中扩展了裁剪相关逻辑,例如通过ForwardsLights.cs等脚本实现光照专用的剔除算法(如zBinning)。用户可通过URP源代码定制Tile划分规则或光源影响测试,但这些定制聚焦于优化光照而非几何裁剪本身。
    • UI裁切组件(如Mask或ClipRect)完全在C#端实现,通过Shader参数控制裁剪区域,适用于UI渲染管线的特定需求。

裁剪过程以C++引擎层为主,URP的C#定制用于补充优化(如光源管理),而非取代核心几何剔除。

三、Unity URP裁剪过程详细分析

Unity URP的裁剪是多阶段流水线,应用阶段为核心起点:

  1. ‌**视锥体剔除(应用程序阶段)**‌:
    • Unity引擎在CPU端遍历场景对象,使用包围盒算法测试每个对象的AABB与摄像机视锥体的相交性。可见对象进入渲染队列,不可见对象被剔除。
    • 优化机制:zBinning将视锥体深度(Z轴)划分为多个bin,结合Tile-based空间分区(XY平面),加速光源影响计算。例如,在URP的PreSetup方法中,为每个区块生成位图标记潜在受影响光源,减少冗余光照计算。
  2. 后续裁剪阶段‌(后面会讨论的阶段):
    • ‌**视口裁剪(几何阶段)**‌:在GPU端执行,裁剪超出视口的三角形图元,确保只渲染可见像素区域。
    • ‌**背面裁剪与遮挡剔除(光栅化阶段)**‌:GPU处理背面剔除(基于法线方向)和遮挡测试(如Early-Z技术),后者使用深度缓冲优化像素级渲染。
  3. URP定制流程‌:
    • 光照剔除‌:URP在C#中实现forward+算法,通过Tile和zBinning分块光源,仅计算影响当前区块的光源。例如,点光源和聚光灯的AABB与区块边界比较,标记影响位图。
    • UI裁切‌:独立于几何裁剪,使用ClipRect坐标或模板缓冲实现像素级遮罩,适用于Canvas元素。

整个过程以视锥体剔除为起点,URP的光照优化增强性能,但核心裁剪依赖引擎层


【从UnityURP开始探索游戏渲染】专栏-直达
(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,🙏)

點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消