当前位置: 首页 > news >正文

【渲染流水线】[应用阶段]-[裁剪]以UnityURP为例

前情提要

【渲染流水线】主线索引-从数据到图像以UnityURP为例-CSDN博客

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或模板缓冲)属于特定情境的实现,非全局几何裁剪。

下面讨论包围盒裁剪算法的原理与实现

基础算法:AABB与视锥体相交测试

Unity URP在应用阶段(CPU端)的裁剪核心是轴对齐包围盒(AABB)与视锥体的相交检测。具体流程如下:

  • AABB生成:每个GameObject的Renderer组件会自动计算其AABB,包含centersize属性,定义物体在局部空间的边界。
  • 视锥体平面方程:摄像机视锥体由6个平面(近、远、左、右、上、下)定义,每个平面通过法线向量和距离原点参数表示。Unity通过GeometryUtility.CalculateFrustumPlanes获取这些平面。
  • 相交测试:对每个AABB的8个顶点,检查是否所有顶点均在任一视锥体平面的外侧。若存在至少一个顶点在所有平面内侧,则物体可见;否则被剔除。

优化策略:层次化与空间分区

为提高效率,Unity引擎采用以下优化:

  • 层级包围盒(BVH):对复杂场景构建层次化包围盒树,优先测试父节点AABB,快速剔除整组不可见物体。
  • 动态更新机制:仅对位置或旋转变化的物体重新计算AABB,静态物体通过预计算缓存结果。

URP的定制化扩展

URP在C#层通过以下方式增强裁剪:

  • 光照剔除集成:结合Tile-based分块(如16x16像素区块),将光源AABB与区块边界比对,仅保留影响当前区块的光源。
  • 动态分辨率适配:根据目标渲染分辨率动态调整视锥体参数,确保裁剪精度与性能平衡。

数学原理与代码实现

关键数学逻辑包括:

  • 平面测试公式:对平面方程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; 
    }
    

性能与局限性

  • 优势: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的裁剪是多阶段流水线,应用阶段为核心起点:

视锥体剔除(应用程序阶段)

  • Unity引擎在CPU端遍历场景对象,使用包围盒算法测试每个对象的AABB与摄像机视锥体的相交性。可见对象进入渲染队列,不可见对象被剔除。
  • 优化机制:zBinning将视锥体深度(Z轴)划分为多个bin,结合Tile-based空间分区(XY平面),加速光源影响计算。例如,在URP的PreSetup方法中,为每个区块生成位图标记潜在受影响光源,减少冗余光照计算。

后续裁剪阶段‌(后面会讨论的阶段):

  • 视口裁剪(几何阶段):在GPU端执行,裁剪超出视口的三角形图元,确保只渲染可见像素区域。
  • 背面裁剪与遮挡剔除(光栅化阶段):GPU处理背面剔除(基于法线方向)和遮挡测试(如Early-Z技术),后者使用深度缓冲优化像素级渲染。

URP定制流程‌:

  • 光照剔除‌:URP在C#中实现forward+算法,通过Tile和zBinning分块光源,仅计算影响当前区块的光源。例如,点光源和聚光灯的AABB与区块边界比较,标记影响位图。
  • UI裁切‌:独立于几何裁剪,使用ClipRect坐标或模板缓冲实现像素级遮罩,适用于Canvas元素。

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

接下来:【渲染流水线】[应用阶段]-[遮挡剔除]以UnityURP为例-CSDN博客


(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,🙏)

http://www.dtcms.com/a/318494.html

相关文章:

  • GeoTools 结合 OpenLayers 实现缓冲区分析
  • LINQ 要点
  • 92、【OS】【Nuttx】【构建】cmake 支持构建的目标
  • SOD-YOLO:增强基于YOLO的无人机影像小目标检测
  • Product Hunt 每日热榜 | 2025-08-06
  • GoogLeNet训练
  • FastDeploy2.0:Error reading file: SafeTensorError::MetadataIncompleteBuffer
  • chdir系统调用及示例
  • 【C/C++】形参、实参相关内容整理
  • 零基础-动手学深度学习-8.7. 通过时间反向传播
  • Spring_事务
  • 国产3D大型装配设计新突破①:图纸打开设计双加速 | 中望3D 2026
  • C语言的数组与字符串练习题2
  • 如何快速翻译PPT中的文字(或简繁体转换)
  • 【51单片机2个独立按键2个独立数码管静态显示内容自定】2022-10-22
  • Perforce P4 Plan - DevOps实时规划工具
  • 指挥中心自动化的演变
  • 无人机遥控器波特率技术解析
  • 前端开发_怎么禁止用户复制内容
  • 计算机网络:如何判断B或者C类IP地址是否划分了子网
  • 设备 AI 知识库如何提升管理效率?实测分享
  • 【STM32U385RG 测评】基于VSCode的STM32开发环境搭建
  • 认识河豚毒素!剧毒神经毒素详解!
  • 向量数据库基础夯实:相关概念的详细介绍
  • 淘宝/天猫商品详情API详解(tb.item_get)
  • 一文读懂:什么是CLIP
  • 分布式存储 Ceph 的演进经验 · SOSP 2019
  • 【Web安全】csrf、ssrf和xxe的区别
  • GPT-OSS-20B vs Qwen3-14B 全面对比测试
  • 【大模型系列】gpt-oss系列模型初探