chore: checkpoint current workspace changes
This commit is contained in:
@@ -2,42 +2,42 @@
|
||||
|
||||
## 1.1 课题背景
|
||||
|
||||
随着实时渲染技术的发展,渲染引擎所面对的应用场景已经逐步扩展到游戏、虚拟现实、数字内容生产和交互式可视化等多个方向,逐渐演变为集图形接口抽象、资源导入与管理、场景组织、材质与光照、脚本运行时以及编辑器工作流于一体的综合软件系统。围绕渲染引擎整体架构开展设计与实现,也更便于将运行时系统、工具链以及后续渲染扩展放在统一平台中加以组织。
|
||||
随着实时渲染技术的发展,渲染引擎的应用场景已经逐步扩展至游戏、虚拟现实、数字内容生产和交互式可视化等多个方向,逐渐演变为集图形硬件接口、资源导入与管理、场景组织、材质与光照、脚本运行时以及编辑器工作流于一体的综合软件系统。围绕渲染引擎整体架构开展设计与实现,更便于将运行时系统、工具链以及后续渲染扩展放在统一平台中加以组织。
|
||||
|
||||
在现代实时渲染中,云、雾、烟、火等体积特效已经成为常见而重要的视觉元素。与基于表面的传统渲染不同,体积渲染需要处理光线在参与介质中的吸收、散射和透射率累积过程,通常伴随着大量采样和较高的计算开销。特别是在实时应用环境下,如何在有限的帧长内兼顾体积效果的空间层次感、光照表现和运行效率是极具价值的技术问题。也正因如此,体积渲染既具有较强的理论背景,也具有较高的工程实现价值。
|
||||
在现代实时渲染中,云、雾、烟、火等体积特效已经成为常见且重要的视觉元素。与基于表面的传统渲染不同,体积渲染需要处理光线在参与介质中的吸收、散射和透射率累积过程,通常伴随着大量采样和较高的计算开销。特别是在实时应用场景下,如何在有限的帧长中兼顾体积特效的空间层次感、光照表现和运行效率是极具价值的技术问题。也正因如此,体积渲染既具有较强的理论背景,也具有较高的工程实现价值。
|
||||
|
||||
在体数据表达方面,OpenVDB 为稀疏体积数据组织提供了成熟思路,而 NanoVDB 通过线性化数据结构进一步提升了 GPU 访问友好性,使其更适合实时渲染场景。与此同时,DirectX 12 提供了较底层的资源、命令和同步控制能力,便于开发者更直接地组织 GPU 数据上传、状态切换与渲染调度流程。将 NanoVDB 稀疏体数据组织方式与 DirectX 12 图形接口结合起来,不仅适合开展体积特效的实现研究,也能够作为扩展渲染引擎高级渲染能力的一条现实技术路径。
|
||||
在体数据表达方面,OpenVDB 为稀疏体积数据组织提供了成熟思路,而 NanoVDB 通过线性化数据结构进一步提升了 GPU 访问友好性,使其更适合实时渲染场景。与此同时,DirectX 12 提供了较底层的渲染资源、命令和同步控制能力,便于开发者更直接地组织 GPU 数据上传、状态切换与渲染调度流程。将 NanoVDB 稀疏体数据组织方式与 DirectX 12 图形接口结合起来,不仅适合开展体积渲染的理论研究,也能够作为扩展渲染引擎高级渲染特性的技术路径。
|
||||
|
||||
## 1.2 课题意义
|
||||
|
||||
从体积渲染理论与实现的角度看,本课题围绕 NanoVDB 稀疏体数据在 DirectX 12 环境下的实时渲染展开,重点关注体数据加载、GPU 访问、光线步进、空域跳过和体积阴影等关键问题。相关工作的完成,有助于为云、雾、烟等体积特效的实时工程实现提供一条较清晰的技术路径,也有助于加深对参与介质渲染、体绘制方程简化以及性能优化方法的理解。
|
||||
从体积渲染理论与实现的角度看,本课题围绕 NanoVDB 稀疏体数据在 DirectX 12 环境下的实时渲染展开,重点关注体数据加载、GPU 访问、光线步进、空域跳过和体积阴影等关键问题。相关工作的完成,有助于为云、雾、烟等体积特效实时渲染的工程实现提供一条较清晰的技术路径,也有助于加深对参与介质渲染、体渲染方程数值化以及性能优化方法的理解。
|
||||
|
||||
从系统设计与工程实践的角度看,本课题在体积渲染实现之外,还涵盖了渲染引擎主体架构、运行时模块和编辑器工作流的设计与实现。当前项目已经形成了包含 RHI 抽象、资源系统、场景与组件系统、渲染主链、材质与光照、C# 脚本系统以及编辑器工具链在内的主体框架,体积渲染是在这一基础上的重要高级扩展。这体现了渲染引擎开发中的模块协同关系,同时满足了系统性、完整性和可扩展性的要求。
|
||||
从系统设计与工程实践的角度看,本课题在体积渲染实现之外,还涵盖了渲染引擎主体架构、运行时模块和编辑器工作流的设计与实现。当前项目已经形成了包含 RHI 抽象、资源缓存系统、场景与组件系统、渲染主链、材质与光照、C# 脚本系统以及编辑器工具链在内的主体框架,体积渲染是在这一基础上的重要高级扩展。这体现了渲染引擎开发中的模块协同关系,同时满足了系统性、完整性和可扩展性的要求。
|
||||
|
||||
## 1.3 本课题的主要内容
|
||||
|
||||
结合当前项目的实际进展,本文的研究与实现内容主要由渲染引擎主体部分和体积渲染扩展部分两方面构成。
|
||||
本文的研究与实现内容主要由渲染引擎主体部分和体积渲染扩展部分两方面构成。
|
||||
|
||||
渲染引擎主体部分围绕运行时系统与编辑器工作流展开。在运行时层面,项目已经建立起平台层、图形接口抽象层、资源系统、场景与组件系统、渲染主链、模型与材质系统、多光源与简单阴影、C# 脚本运行时等核心模块,能够支持基础场景的组织、加载与实时渲染。在编辑器层面,项目已经形成 Scene 视口、Game 视口、Hierarchy、Inspector、Project、Console 等主要界面,并提供对象拾取、轮廓高亮、网格显示、变换 Gizmo 以及脚本构建与重载等辅助能力,具备较完整的开发与调试闭环。
|
||||
渲染引擎主体部分围绕运行时系统与编辑器工作流展开。在运行时层面,项目已经建立起平台层、图形接口抽象层、资源缓存系统、场景与组件系统、渲染主链、模型与材质系统、多光源与简单阴影、C# 脚本运行时等核心模块,能够支持基础场景的组织、加载与实时渲染。在编辑器层面,项目已经形成 Scene 视口、Game 视口、Hierarchy、Inspector、Project、Console 等主要界面,并提供对象拾取、轮廓高亮、网格显示、变换 Gizmo 以及脚本构建与重载等辅助能力,具备较完整的开发与调试闭环。
|
||||
|
||||
体积渲染扩展部分建立在现有引擎主体之上,重点研究参与介质渲染的基本理论以及 NanoVDB 稀疏体数据在 DirectX 12 环境下的工程实现方式。其核心内容包括体积渲染基本物理量分析、体绘制方程的简化理解、光线步进流程、稀疏体数据加载与 GPU 上传、Shader 侧体数据访问、空域跳过优化和体积阴影等。
|
||||
体积渲染扩展部分建立在现有引擎主体之上,重点研究参与介质渲染的基本理论以及 NanoVDB 稀疏体数据在 DirectX 12 环境下的工程实现方式。其核心内容包括体积渲染基本物理量分析、体绘制方程的简化理解、光线步进流程、稀疏体数据加载与 GPU 上传、Shader 侧体数据访问、空域跳过优化和体积阴影等。成功完成了基于 NanoVDB 的体积渲染管线,支持了云、雾、烟等体积特效的实时渲染。
|
||||
|
||||
## 1.4 本文的主要工作
|
||||
|
||||
围绕上述目标,本文已开展并完成的主要工作如下。
|
||||
|
||||
1. 完成了渲染引擎总体架构的设计与模块划分,构建了平台层、RHI 层、资源与场景层、渲染层、脚本层和编辑器层之间的基本组织关系。
|
||||
2. 实现了渲染引擎运行时主体能力,完成了缓冲、纹理、资源视图、管线状态、交换链等核心图形对象封装,并在此基础上建立了渲染请求规划、场景提取和相机执行等主链流程。
|
||||
3. 实现了资源导入与管理、场景与组件组织、OBJ 模型渲染、材质系统、多光源和简单阴影等基础渲染能力,使引擎具备了较完整的场景渲染闭环。
|
||||
2. 实现了渲染引擎运行时主体能力,完成了图形缓冲、纹理、资源视图、管线状态、交换链等核心图形对象封装,并在此基础上建立了渲染请求规划、场景提取和相机执行等主链流程。
|
||||
3. 实现了资源导入与缓存管理、场景与组件组织、OBJ 模型渲染、材质系统、多光源和简单阴影等基础渲染能力,使引擎具备了较完整的场景渲染闭环。
|
||||
4. 实现了基于 Mono 的 C# 脚本系统以及编辑器工作界面,支持脚本程序集构建、脚本运行时装载、Scene/Game 视口显示、Hierarchy 与 Inspector 联动、Project 资源浏览和 Console 调试输出等功能。
|
||||
5. 完成了基于 NanoVDB 的体积渲染管线,实现 `.nvdb` 数据加载、GPU Buffer 上传、HLSL 侧 PNanoVDB 访问、光线步进、HDDA 跳空和体积阴影等流程。
|
||||
5. 完成了基于 NanoVDB 的体积渲染管线,实现 .nvdb 数据加载、GPU Buffer 上传、HLSL 侧 PNanoVDB 访问、光线步进、HDDA 跳空和体积阴影等流程。
|
||||
|
||||
## 1.5 论文结构安排
|
||||
|
||||
全文共分为九章,各章安排如下。
|
||||
|
||||
1. 第1章为绪论,主要说明课题背景、课题意义、本文的主要内容、已完成的主要工作以及全文结构安排。
|
||||
2. 第2章介绍渲染引擎相关技术基础,为后续引擎架构设计与核心模块实现提供技术铺垫。
|
||||
2. 第2章介绍渲染引擎发展历程、当前主流实时渲染引擎特点以及本课题渲染引擎概况,为后续引擎架构设计与核心模块实现做铺垫。
|
||||
3. 第3章介绍体积渲染理论基础,重点说明参与介质、透射率、体绘制方程、光线步进和稀疏体数据等内容。
|
||||
4. 第4章对渲染引擎总体架构进行设计说明,给出系统分层、模块划分、数据流关系以及体积渲染模块在整体架构中的位置。
|
||||
5. 第5章围绕渲染引擎核心模块展开,说明 RHI、资源系统、场景与组件系统、渲染主链、材质光照和脚本系统等关键内容的设计与实现。
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 第三章 体积渲染理论基础
|
||||
|
||||
第二章已经从渲染引擎角度说明了运行时系统、资源系统、场景组织和编辑器工作流等基础内容。本章进一步转入体积渲染本身的理论部分,重点讨论参与介质、光在介质中的衰减与散射、体绘制方程、光线步进以及稀疏体数据与空域跳过等关键概念,为后续基于 NanoVDB 的体积渲染管线设计与实现提供充足的理论基础。
|
||||
第二章已经对实时渲染引擎进行了详细的介绍,包括渲染引擎发展历程、当前主流实时渲染引擎特点以及本课题渲染引擎概况等。本章进一步转入体积渲染本身的理论部分,重点讨论参与介质、光在介质中的衰减与散射、体绘制方程、光线步进以及稀疏体数据与空域跳过等关键概念,为后续基于 NanoVDB 的体积渲染管线设计与实现提供充足的理论基础。
|
||||
|
||||
## 3.1 参与介质与体积渲染基本概念
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
传统表面渲染主要关心光线在物体表面处发生的反射与折射,而体积渲染关注的对象则是空间中的参与介质(Participating Media)。所谓参与介质,是指光在传播过程中会与其内部粒子持续发生相互作用的介质,例如云、雾、烟、火焰、水汽等。这类介质并不像三角形网格那样只在边界上发生光学变化,而是会在体积内部对光线产生吸收、散射甚至发射作用,因此它们的成像过程天然具有空间累积特征。
|
||||
|
||||
从工程角度看,参与介质通常可以分为均匀介质和非均匀介质两类。均匀介质在空间中的光学参数保持不变,便于分析和推导;非均匀介质的密度或光学参数随位置变化,更接近真实云层和烟雾的外观,也是实际应用中更常见的情况。在本文项目后续的体积渲染实现中,体数据本质上就是对这种空间变化进行离散表达,因此理解参与介质的基本性质是后续实现的前提。
|
||||
从工程角度看,参与介质通常可以分为均匀介质和非均匀介质两类。均匀介质在空间中的光学参数保持不变,便于分析和推导;非均匀介质的密度或光学参数随位置变化,更接近真实云层和烟雾的外观,也是实际应用中更常见的情况。在本文项目后续的体积渲染实现中,稀疏体数据本质上就是对这种空间变化进行离散表达,因此理解参与介质的基本性质是后续实现的前提。
|
||||
|
||||
### 3.1.2 吸收、散射与透射率
|
||||
|
||||
@@ -18,15 +18,13 @@ $$
|
||||
\sigma_t = \sigma_a + \sigma_s
|
||||
$$
|
||||
|
||||
在很多实时体积渲染实现中,密度场会被用来调制这些系数,使介质在空间上的不透明度和亮度分布发生变化。也就是说,密度并不是与吸收、散射并列的第三类光学现象,而更像是对局部光学参数的空间缩放。密度越大,局部吸收和散射通常也越强;密度越小,介质对光的影响则越弱。
|
||||
在很多实时体积渲染实现中,密度场会被用来调制这些系数,使介质在空间上的不透明度和亮度分布发生变化。密度值是对局部光学参数的空间缩放,密度越大,局部吸收和散射通常也越强;密度越小,介质对光的影响则越弱。
|
||||
|
||||
透射率(Transmittance)描述的是光线在介质中传播一段距离后仍然保留下来的比例,其取值范围在 0 到 1 之间。透射率越接近 1,说明光几乎未被削弱;透射率越接近 0,说明光在介质中已被显著衰减。透射率是体积渲染中极为核心的量,因为无论是背景光穿过体积后的结果,还是光源传播到采样点的有效光照,最终都要依赖透射率来表达。
|
||||
|
||||
### 3.1.3 体积颜色形成的基本原因
|
||||
### 3.1.3 体积颜色的形成原因
|
||||
|
||||
体积图像的形成并不是单纯“给体素上色”,而是光在介质中传播、衰减与散射共同作用的结果。从观察者方向看,体积颜色主要来自两个来源。其一是背景或后方物体发出的光在穿过介质时被衰减后剩余的部分;其二是来自光源的入射光在介质内部发生散射后,被重新导向观察方向所产生的内散射贡献。当前项目后续实现的重点主要也集中在这两部分,即背景透射与单次散射近似。
|
||||
|
||||
如果介质本身还会主动发光,例如火焰、高温气体等,则还需要考虑发射项。不过从本文当前项目的体积模块实现状态来看,重点仍然放在云、烟等主要受吸收和散射影响的体数据渲染上,因此本章后续分析将以吸收、散射和透射率累积为主。
|
||||
体积图像的形成是光在介质中传播、衰减与散射共同作用的结果。从观察者方向看,体积颜色主要来自两个来源。其一是背景或体积后方物体发出的光在穿过介质时被衰减后剩余的部分;其二是来自光源的入射光在介质内部发生散射后,被重新导向观察方向所产生的内散射贡献。如果介质本身还会主动发光,例如火焰、高温气体等,则还需要考虑发射项。
|
||||
|
||||
## 3.2 比尔-朗伯定律与光线透射
|
||||
|
||||
@@ -104,39 +102,33 @@ $$
|
||||
|
||||
其中 $g \in [-1,1]$ 为非对称因子。当 $g=0$ 时退化为各向同性散射;当 $g>0$ 时表现为前向散射;当 $g<0$ 时表现为后向散射。后续第7章的工程实现虽然会采用简化形式,但相位函数这一思想仍然是构成单次散射项的理论基础。
|
||||
|
||||
### 3.3.4 为什么在实时系统中常采用简化模型
|
||||
|
||||
如果严格考虑多次散射、复杂相位函数、多个动态光源和高精度体数据积分,那么体积渲染的计算量会迅速增大,很难满足实时应用对帧率的要求。因此,实时系统通常会在若干环节上做简化:例如只考虑单次散射、采用固定步长或分层步进、使用简化相位函数、对阴影进行近似积分,或者在必要时对空区域进行跳过。
|
||||
|
||||
这种简化并不意味着理论被放弃,而是意味着在已知完整物理模型的前提下,有选择地保留最影响画面结果的部分。对于工程设计类项目而言,这种从完整理论到可实时实现之间的取舍非常重要。后续章节的体积模块实现也正是在这一原则下,选择了适合当前项目阶段的实时方案。
|
||||
|
||||
## 3.4 光线步进算法原理
|
||||
|
||||
### 3.4.1 Ray Marching 的基本思想
|
||||
|
||||
由于体绘制方程通常难以直接求得解析解,实际实现中往往采用数值积分近似,而光线步进(Ray Marching)就是其中最典型的方法。其基本思想是:先求出相机光线与体积包围区域的进入点和离开点,再把这段区间划分为若干个小步长,在每个采样点处估计局部密度、局部消光、局部散射贡献与透射率,最后将这些局部结果累积起来,近似连续积分。
|
||||
|
||||
若步长足够小,则每个小区间都可以视作局部均匀,这样就能用离散求和逼近连续积分。也正因为这一思想简单直接,光线步进非常适合作为体积渲染的工程实现起点。本文后续的 NanoVDB 体积原型同样以相机光线与体积边界求交为起点,然后在体积内部做离散采样累积。
|
||||
若步长足够小,则每个小区间都可以视作局部均匀,这样就能用离散求和逼近连续积分。也正因为这一思想简单直接,光线步进算法非常适合作为体积渲染的工程实现起点。本文后续的 NanoVDB 体积渲染同样以相机光线与体积边界求交为起点,然后在体积内部做离散采样累积。
|
||||
|
||||
### 3.4.2 正向步进与反向步进
|
||||
|
||||
按观察方向组织时,光线步进通常可以分为正向步进和反向步进两种。正向步进一般指从靠近相机的一侧向远处推进,也可理解为前向累积(front-to-back);反向步进则从远处向近处积分,也可理解为后向累积(back-to-front)。
|
||||
按观察方向分类,光线步进通常可以分为正向步进和反向步进两种。正向步进一般指从靠近相机的一侧向远处步进,也可理解为前向累积(front-to-back);反向步进则从远处向近处积分,也可理解为后向累积(back-to-front)。
|
||||
|
||||
从数值结果上看,两者都可以逼近同一个积分目标,但在工程实现上,正向步进往往更适合实时系统。原因在于,正向步进可以显式维护“当前剩余透射率”,当透射率已经很低时,后续更远处的采样贡献可以近似忽略,从而支持提前终止优化。反向步进虽然在某些推导上较直观,但不如正向步进方便做前端遮挡裁剪。当前项目后续的体积实现也更接近前向累积方式。
|
||||
从数值结果上看,两者都可以逼近同一个积分目标,但在工程实现上,正向步进往往更适合实时系统。原因在于,正向步进支持提前终止优化。反向步进虽然在推导上较直观,但不如正向步进方便做前端遮挡裁剪。本课题采用前向累积方式。
|
||||
|
||||
### 3.4.3 步长、最大步数与误差控制
|
||||
|
||||
步长是光线步进中的关键参数。步长越小,离散积分越接近连续积分,画面通常越平滑,细节也越稳定;但采样次数随之增加,运行开销也会显著变大。步长过大时,则容易出现条带感、细节丢失和阴影估计不稳定等问题。与步长相对应的另一个参数是最大步数,它决定了一条光线最多允许采样多少次,用于限制最坏情况下的开销。
|
||||
步长是光线步进中的关键参数。步长越小,离散累积越接近连续积分,画面通常越平滑,细节也越稳定;但采样次数随之增加,运行开销也会显著变大。步长过大时,则容易出现条带感、细节丢失和阴影估计不稳定等问题。与步长相对应的另一个参数是最大步数,它决定了一条光线最多允许采样多少次,用于限制最坏情况下的开销。
|
||||
|
||||
因此,实时体积渲染本质上是在“精度”和“性能”之间寻找平衡。工程上通常会根据体素分辨率、包围盒大小、屏幕分辨率以及目标帧率来选择合适步长,并在必要时为主光线和阴影光线设置不同的采样密度。这种参数平衡在后续测试章节中也会体现出来。
|
||||
|
||||
### 3.4.4 提前终止、抖动等常见优化
|
||||
### 3.4.4 提前终止和采样抖动优化
|
||||
|
||||
在体积积分过程中,并不是每一个采样点都同样重要,因此常会配合若干优化策略。最常见的一类是提前终止(Early Termination):当累计透射率已经低于某个阈值时,说明后续更远区域的贡献非常有限,此时可以直接结束当前光线步进。对于较浓的烟雾或高密度区域,这类优化能节省大量无效计算。
|
||||
|
||||
另一类常见方法是采样抖动(Jitter)。固定步长加固定采样起点容易带来规则性的条纹或分层感,而在初始采样位置上引入轻微随机偏移,可以打散这种结构化误差,使图像在视觉上更平滑。除此之外,还可以通过多分辨率步进、阴影光线使用更粗步长、分层包围盒裁剪等方式进一步优化。对于本文后续实现而言,提前终止和空域跳过具有更直接的工程意义。
|
||||
|
||||
## 3.5 稀疏体数据与空域跳过思想
|
||||
## 3.5 稀疏体数据与空域跳过
|
||||
|
||||
### 3.5.1 稠密体素网格的问题
|
||||
|
||||
@@ -146,11 +138,11 @@ $$
|
||||
|
||||
### 3.5.2 稀疏体数据结构的意义
|
||||
|
||||
稀疏体数据结构的核心思想,是只为真正包含有效信息的区域分配更细粒度的存储,而对大量空区域或均匀区域采用更粗层级的表示。OpenVDB 及其面向 GPU 的 NanoVDB 就属于这一类思路。它们通过层级化节点结构组织体数据,使得体素值访问不再局限于简单的三维数组索引,而是能够根据当前区域是否活跃、当前层级分辨率以及节点类型进行更有选择性的访问。
|
||||
稀疏体数据结构的核心思想是只为真正包含有效信息的区域分配更细粒度的存储,而对大量空区域或均匀区域采用更粗层级的表示。OpenVDB 及其面向 GPU 的 NanoVDB 就属于这一思路。它们通过层级化节点结构组织体数据,使得体素值访问不再局限于简单的三维数组索引,而是能够根据当前区域是否活跃、当前层级分辨率以及节点类型进行选择性访问。
|
||||
|
||||
对于实时渲染而言,NanoVDB 的价值尤其明显。它在保留 VDB 层级稀疏表达思想的基础上,对数据进行了线性化组织,使 GPU 更容易访问。这样一来,体数据不但可以以更紧凑的形式存储在显存中,还能够在 Shader 中配合层级遍历或辅助访问器实现更高效的采样与判断。后续第7章的工程实现,正是建立在这种 GPU 友好的稀疏表示之上。
|
||||
|
||||
### 3.5.3 空区域跳过对实时性的作用
|
||||
### 3.5.3 空区域跳的实时性优化
|
||||
|
||||
空域跳过(Empty Space Skipping)的目标,是尽量避免在无效区域上进行逐步长采样。其基本思想不是改变体绘制方程,而是在数值积分过程中快速定位“哪些区域值得细采样,哪些区域可以直接跳过”。如果能在光线进入空区域时一次跨过较长距离,而不是继续做多个低价值采样,那么体积渲染的实时性就会明显提升。
|
||||
|
||||
|
||||
@@ -1,24 +1,30 @@
|
||||
# 第五章 渲染引擎核心模块设计与实现
|
||||
|
||||
上一章已经对渲染引擎的总体分层、模块划分和数据流关系进行了说明。本章进一步下沉到运行时主体,围绕当前项目中已经形成的几个核心模块展开分析,重点说明这些模块在工程实现中的职责边界、关键数据结构和协同方式。结合现有代码实现,本章主要讨论 RHI 抽象层、资源系统、场景与组件系统、渲染主链、模型材质与着色器系统、多光源与简单阴影,以及 C# 脚本系统。它们共同构成了当前渲染引擎的主体能力,也是后续编辑器工作流和体积渲染模块接入的基础。
|
||||
上一章已经对渲染引擎的总体分层、模块划分和数据流关系进行了说明。本章进一步围绕当前项目的几个核心模块展开分析,重点说明这些模块在工程实现中的职责边界、关键数据结构和协同方式。结合现有代码实现,本章主要讨论 RHI 抽象层、资源系统、场景与组件系统、渲染主链、模型材质与着色器系统、多光源与简单阴影,以及 C# 脚本系统。它们共同构成了当前渲染引擎的主体能力,也是后续编辑器工作流和体积渲染模块接入的基础。
|
||||
|
||||
## 5.1 RHI 抽象层设计与实现
|
||||
|
||||
### 5.1.1 抽象目标与接口边界
|
||||
### 5.1.1 设计目标与总体思路
|
||||
|
||||
渲染引擎的底层必须直接面对图形后端差异。不同图形 API 在资源创建方式、命令提交模型、描述符组织形式以及状态切换机制上均存在明显区别。如果上层渲染模块直接依赖某一个后端实现,那么渲染主链、资源绑定和管线状态组织都将与具体平台高度耦合,不利于后续扩展和维护。因此,本项目在底层建立了 RHI(Rendering Hardware Interface)抽象层,将图形设备能力统一为一组稳定接口,使上层模块更多围绕“渲染什么”和“如何组织渲染阶段”来展开,而不是反复处理后端 API 细节。
|
||||
RHI 的设计目标主要有两个。其一,是在 `D3D12`、`OpenGL` 和 `Vulkan` 三套后端之上建立统一接口,使上层渲染模块不再直接依赖具体图形 API;其二,是为资源系统、材质系统、渲染主链和后续高级渲染特性的接入提供一致的底层语义,屏蔽不同后端的差异。
|
||||
|
||||
从当前实现看,`RHIDevice` 是这一抽象层的核心入口。它统一提供缓冲、纹理、交换链、命令列表、命令队列、着色器、管线状态、管线布局、同步栅栏、采样器、渲染通道、帧缓冲、描述符池、描述符集以及各类资源视图的创建接口。这样一来,渲染层在组织离屏纹理、深度表面、阴影图、材质资源绑定和绘制命令时,都可以基于统一对象模型展开。
|
||||
从设计思路看,当前 RHI 遵循“求同存异、分层抽象、特性降级、底层逃逸”的原则。所谓求同存异,是优先提取不同图形 API 在资源、命令、状态与同步层面的共性能力,并把差异控制在后端内部;所谓分层抽象,是把上层渲染流程与底层 API 实现隔开,使渲染管线层只面向统一接口编写;所谓特性降级,是通过硬件能力查询接口把不同后端与设备的能力差异转化为上层可判断、可选择的运行条件;所谓底层逃逸,则是保留原生设备或原生句柄访问入口,以便在调试、扩展或特殊场景下直接调用底层对象。这样设计后,RHI 既不会因为过度抽象而失去实际可用性,也不会因为直接暴露底层细节而破坏整个引擎的模块边界。
|
||||
|
||||
### 5.1.2 多后端统一封装方式
|
||||
### 5.1.2 统一控制模型
|
||||
|
||||
当前项目的 RHI 已经形成了多后端组织结构。在工程构建层面,`engine/CMakeLists.txt` 中已经纳入了 `D3D12`、`OpenGL` 和 `Vulkan` 三套后端实现,以及与之对应的缓冲、纹理、资源视图、交换链、命令队列、命令列表、描述符、管线状态和截图支持等对象。对应地,`RHIFactory` 负责根据 `RHIType` 或字符串名称创建目标后端设备,从而将设备实例化过程与上层运行逻辑解耦。
|
||||
当前项目中的 RHI 抽象并不是把不同后端的接口简单套上一层统一名称,而是围绕一套完整的显式控制模型展开。其起点是统一的资源描述方式。无论是缓冲、纹理、交换链,还是着色器、管线状态和资源视图,上层都先通过统一描述结构表达“需要什么样的 GPU 对象”,然后再交由具体后端完成实例化。这样做的意义在于,把资源需求先从具体 API 中抽离出来,使资源系统、材质系统和渲染主链在进入底层之前就能围绕同一种对象语义组织数据,而不是在不同后端之间来回切换思维方式。
|
||||
|
||||
这种设计并不是简单追求“支持多个 API”,更重要的是建立统一的资源语义。例如,上层不再分别讨论 D3D12 的描述符堆、OpenGL 的纹理单元或 Vulkan 的描述符集布局,而是通过统一的缓冲、纹理、采样器、描述符集和资源视图概念组织资源绑定;同样,上层也不直接处理各后端的原生命令对象,而是通过命令队列和命令列表接口完成绘制、状态切换与结果提交。当前项目的体积渲染研究阶段以 D3D12 为重点推进,但从引擎主体架构看,多后端 RHI 已经为引擎保留了较好的平台弹性。
|
||||
在资源被创建出来之后,RHI 进一步把资源状态、描述符绑定、管线布局、命令录制与提交、渲染通道与帧缓冲组织成一条连续的控制链。资源状态解决的是“当前资源处于什么用途、下一步将被怎样访问”的问题;描述符绑定与管线布局解决的是“资源如何进入着色器、以什么绑定关系参与绘制或计算”的问题;命令列表与命令队列解决的是“这些状态和资源按什么顺序被提交给 GPU 执行”的问题;渲染通道与帧缓冲则进一步规定“本次执行向哪些目标输出、怎样装载和保存结果”。经过这层整理,场景绘制、阴影贴图、对象 ID 输出、离屏渲染和后处理就不再是零散的 API 调用,而是可以被统一组织和复用的阶段化流程。
|
||||
|
||||
### 5.1.3 RHI 对上层模块的支撑作用
|
||||
这套控制模型本质上更接近 `D3D12` 和 `Vulkan` 这类高级图形 API 的设计取向,因为它们天然强调资源、状态、绑定、命令和同步的显式管理。与此同时,RHI 还通过能力查询把不同硬件和后端的差异转化为上层可判断的运行条件,使某些高级特性能够根据实际能力选择启用、降级或关闭。也正因为如此,RHI 在当前引擎中承担的并不是单纯的“后端适配”职责,而是为整个渲染系统建立一套统一、可控、可扩展的底层执行模型。
|
||||
|
||||
RHI 抽象层在整个引擎中承担的是“运行时图形基础设施”的角色。资源系统最终生成的网格、纹理、材质常量和着色器变体,都需要落到 RHI 对象上;渲染主链中的主场景绘制、阴影绘制、对象 ID 绘制、后处理和最终输出,也都依赖 RHI 提供的离屏表面、命令提交和资源状态切换能力;编辑器视口同样是通过对渲染表面的申请和复用接入渲染主链的。可以说,RHI 为整个渲染引擎提供了统一而稳定的底层执行面,是后续所有高层模块成立的前提。
|
||||
### 5.1.3 显式控制模型的后端落地
|
||||
|
||||
从实际实现看,当前 RHI 的整体结构明显以 `D3D12` 和 `Vulkan` 这类显式图形 API 为主干。无论是资源描述到对象创建的转换,还是资源状态切换、描述符绑定、管线布局、命令列表录制、命令队列提交以及渲染通道组织,这些抽象都天然更贴近显式 API 的工作方式。换句话说,这套 RHI 并不是先从三个后端求一个平均值,再拼出一层抽象;它首先确立的是一种偏高级 API 的控制模式,再让不同后端向这套模式靠拢。
|
||||
|
||||
在这种前提下,`D3D12` 和 `Vulkan` 的接入相对直接,因为它们本身就具备较强的显式控制特征。相比之下,`OpenGL` 属于典型的隐式状态机 API,本身并不天然提供与描述符集、管线布局、显式同步和阶段化渲染通道完全对应的机制。如果直接按照 OpenGL 的原生使用方式暴露给上层,那么整个 RHI 统一抽象就会迅速失去约束力。为了解决这一问题,当前项目在 OpenGL 后端中做了较多模拟实现,把原本分散在上下文状态中的绑定、同步和资源使用过程重新整理为接近显式 API 的形式。例如,在资源绑定层,通过绑定点映射、纹理单元分配和统一缓冲管理来模拟描述符集与管线布局;在同步层,通过 `GLsync` 配合 CPU 侧计数方式适配统一的 Fence 语义;在渲染输出层,则通过帧缓冲和渲染通道封装,把 OpenGL 的输出过程纳入与其他后端一致的阶段化组织方式。
|
||||
|
||||
因此,三套后端虽然共同服务于同一套 RHI 接口,但它们在这套模型中的角色并不完全对称。`D3D12` 和 `Vulkan` 更像是这套显式控制模型的直接承载者,`OpenGL` 则是在保留自身底层实现的同时,通过模拟与适配被收束到同一框架之中。对上层模块而言,这种差异被有效屏蔽,资源系统、渲染主链、材质绑定和编辑器视口都可以围绕统一的执行语义工作;而对底层实现而言,这又允许不同后端保留各自的实现特点。RHI 的真正价值也正体现在这里,即以统一的显式控制模型支撑整个渲染引擎,同时把后端差异压缩在可管理的范围之内。
|
||||
|
||||
## 5.2 资源系统设计与实现
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# 第六章 编辑器与引擎工作流设计与实现
|
||||
|
||||
上一章已经围绕渲染引擎运行时的核心模块展开分析,说明了底层图形抽象、资源管理、场景组织、渲染主链以及脚本系统的实现方式。在此基础上,本章进一步转向引擎的可视化界面与工作流部分,重点说明当前项目中的编辑器如何围绕场景编辑、资源浏览、参数调整、脚本运行和调试输出等功能组织起来。对于本课题而言,编辑器是连接资源系统、场景系统、渲染系统和脚本系统的直接入口,也是展示整个系统功能的重要部分。
|
||||
上一章已经围绕渲染引擎运行时的核心模块展开分析,说明了各个模块的实现方式。在此基础上,本章进一步转向引擎的可视化界面与工作流部分,重点说明当前项目中的编辑器如何围绕场景编辑、资源浏览、参数调整、脚本运行和调试输出等功能组织起来。对于本课题而言,编辑器是连接资源系统、场景系统、渲染系统和脚本系统的直接入口,也是展示整个系统功能的重要部分。
|
||||
|
||||
## 6.1 编辑器在引擎中的定位
|
||||
|
||||
当前项目中的编辑器由 `Application`、`EditorLayer`、`EditorWorkspace` 以及各类面板共同构成,其初始化过程直接建立在现有引擎能力之上。编辑器启动后,会依次完成窗口渲染器初始化、项目根目录设置、`ResourceManager` 与脚本运行时初始化、ImGui 后端桥接以及视口离屏渲染资源接管,随后进入逐帧更新与绘制阶段。从系统定位看,编辑器并不是独立于引擎主体之外的附加程序,而是直接复用资源系统、渲染链路、场景数据和脚本运行时能力的可视化工作界面。它承担的核心任务包括场景编辑、资源管理、渲染结果验证以及脚本与调试支撑,并通过 `Scene`、`Game`、`Hierarchy`、`Inspector`、`Project` 和 `Console` 等主要界面组织这些工作。
|
||||
当前项目中的编辑器由 `Application`、`EditorLayer`、`EditorWorkspace` 以及各类面板共同构成,其初始化过程直接建立在现有引擎能力之上。编辑器启动后,会依次完成窗口渲染器初始化、项目根目录设置、`ResourceManager` 与脚本运行时初始化、ImGui 后端桥接以及视口离屏渲染资源接管,随后进入逐帧更新与绘制阶段。编辑器是直接复用资源系统、渲染链路、场景数据和脚本运行时能力的可视化工作界面,它承担的核心任务包括场景编辑、资源管理、渲染结果验证以及脚本与调试支撑,并通过 `Scene`、`Game`、`Hierarchy`、`Inspector`、`Project` 和 `Console` 等主要面板组织这些工作。
|
||||
|
||||
编辑器与运行时之间的关系并不是简单的界面展示关系,而是围绕统一上下文形成了完整闭环。`EditorContext` 负责组织事件总线、选择管理器、场景管理器、项目管理器、撤销管理器和视口宿主服务,使不同面板之间的数据与事件能够保持联动;`EditorWorkspace` 负责在运行阶段组织菜单栏、停靠布局和各类面板的更新与绘制;`PlaySessionController` 则负责连接编辑态与运行态,在进入播放模式前保存场景快照、停止播放后恢复快照。这样一来,编辑器既能够把 `Game` 视口中的脚本逻辑和运行时场景更新真实执行出来,又能够在退出运行后回到稳定的编辑状态,因此它构成了当前渲染引擎工作流中的核心组织层。
|
||||
|
||||
|
||||
@@ -1,22 +1,20 @@
|
||||
# 第四章 渲染引擎总体架构设计
|
||||
|
||||
前两章已经分别给出了渲染引擎概述和体积渲染理论基础。在此基础上,本章从系统设计层面对当前项目中的渲染引擎进行说明,重点讨论引擎设计目标、总体架构与模块划分、模块之间的协同关系,以及体积渲染模块在整体架构中的位置。本章的任务是把整个系统的组织方式讲清楚,为后续第5章、第6章和第7章的具体实现分析建立统一框架。
|
||||
前两章已经分别给出了渲染引擎概述和体积渲染理论基础。在此基础上,本章从系统设计层面对当前项目中的渲染引擎进行说明,重点讨论引擎设计目标、总体架构与模块划分、模块之间的协同关系,以及体积渲染模块在整体架构中的位置。本章的任务是说明整个系统的组织方式,为后续第5章、第6章和第7章的具体实现分析建立统一框架。
|
||||
|
||||
## 4.1 引擎设计目标
|
||||
|
||||
本项目的架构设计以渲染引擎为主体展开,目标是在统一框架下组织图形接口、资源管理、场景组织、渲染执行、脚本扩展和编辑器工作流等能力。这样的架构安排使系统能够围绕同一套运行时基础持续扩展,并将图形绘制、资源处理和工具能力组织在同一体系中。当前项目不仅包含运行时系统,也包含围绕资源浏览、场景编辑、参数调整和结果验证构建的编辑器工作流。
|
||||
|
||||
渲染引擎的架构设计不仅服务于当前已完成的基础能力,也需要为后续扩展保留空间。体积渲染作为当前项目中最重要的高级渲染扩展,需要依附既有资源系统、渲染主链和编辑器验证能力接入系统。因此,在总体架构层面,需要预留新资源类型、新渲染阶段和新调试入口能够自然接入的位置,使扩展能够沿既有资源、渲染和验证链路进入系统。
|
||||
本项目的架构设计以渲染引擎为主体展开,目标是在统一框架下组织图形硬件接口、资源管理、场景组织、渲染执行、脚本扩展和编辑器工作流等基础功能。同时体积渲染作为当前项目中最重要的高级渲染扩展,需要依附既有资源系统、渲染主链和编辑器验证能力接入系统。因此,在总体架构层面,需要兼顾基础功能完善和可扩展性。
|
||||
|
||||
## 4.2 引擎总体架构与模块划分
|
||||
|
||||
结合当前项目的代码结构和功能组织方式,本文将渲染引擎总体概括为平台层、图形接口抽象层、资源与场景层、渲染组织层以及脚本与编辑器层五个主要层级。在此之外,系统中还存在内存、线程、调试、音频和 UI 等支撑模块,但从论文主体展开角度看,上述五层构成了最核心的结构主线。围绕这一分层结构,引擎主体的核心模块可以进一步归纳为 `RHI`、`Resources / Assets`、`Scene / Components`、`Rendering`、`Scripting` 和 `Editor` 六个部分,它们分别落在不同层次上,共同构成当前系统的主体架构。
|
||||
本文将渲染引擎总体概括为平台层、图形接口抽象层、资源与场景层、渲染组织层以及脚本与编辑器层五个主要层级。在此之外,系统中还存在内存、线程、调试和 UI 等支撑模块,但从论文主体展开角度看,上述五层构成了最核心的结构主线。围绕这一分层结构,引擎主体的核心模块可以进一步归纳为 `RHI`、`Resources / Assets`、`Scene / Components`、`Rendering`、`Scripting` 和 `Editor` 六个部分,它们分别落在不同层次上,共同构成当前系统的主体架构。
|
||||
|
||||
【插图:渲染引擎总体分层架构】
|
||||
|
||||
### 平台层
|
||||
|
||||
平台层位于整个系统的底部,负责窗口、消息循环、输入处理、时间管理和文件系统访问等基础运行环境。它决定了主循环如何驱动系统运行,也决定了渲染结果最终如何呈现到设备屏幕上。平台层本身不直接组织场景和资源,但它为上层所有模块提供统一的执行环境。
|
||||
平台层位于整个系统的底部,负责窗口、消息循环、输入处理、时间管理和文件系统访问等基础运行环境。它决定了主循环如何驱动系统运行,也决定了渲染结果最终如何呈现到设备屏幕上。平台层本身不直接组织场景和资源,但它为上层所有模块提供统一的执行环境。本课题项目主要建立在 Windows 平台上,同时也考虑到了跨平台的扩展性。
|
||||
|
||||
### 图形接口抽象层
|
||||
|
||||
@@ -40,7 +38,7 @@
|
||||
|
||||
### 4.3.1 资源从工程目录进入运行时的路径
|
||||
|
||||
工程目录中的模型、纹理、材质、着色器和场景文件首先经过资源系统的扫描、导入和缓存,随后被装载为运行时可直接使用的资源对象。这些资源再进一步被场景中的对象和组件引用,最终参与渲染和逻辑更新。由此形成从工程资源到运行时内容的第一条主线。
|
||||
工程目录中的模型、纹理、材质、着色器、稀疏体积数据和场景文件首先经过资源系统的扫描、导入和缓存,随后被装载为运行时可直接使用的资源对象。这些资源再进一步被场景中的对象和组件引用,最终参与渲染和逻辑更新。由此形成从工程资源到运行时内容的第一条主线。
|
||||
|
||||
### 4.3.2 场景状态到渲染数据的转换关系
|
||||
|
||||
@@ -62,6 +60,6 @@
|
||||
|
||||
## 4.5 本章小结
|
||||
|
||||
本章从系统设计层面对当前项目中的渲染引擎进行了分析,明确了引擎架构的主要目标,包括形成完整工作框架、建立基础场景渲染闭环、兼顾运行时能力与编辑器工作流,以及为高级渲染特性扩展预留空间。在此基础上,将系统概括为平台层、图形接口抽象层、资源与场景层、渲染组织层以及脚本与编辑器层五个主要层级,并在同一结构下说明了 `RHI`、`Resources / Assets`、`Scene / Components`、`Rendering`、`Scripting` 和 `Editor` 六个核心模块在整体架构中的归属关系。
|
||||
本章从系统设计层面对本课题的渲染引擎进行了分析,明确了引擎架构的主要目标,并将系统概括为平台层、图形接口抽象层、资源与场景层、渲染组织层以及脚本与编辑器层五个主要层级,并在同一结构下说明了 `RHI`、`Resources / Assets`、`Scene / Components`、`Rendering`、`Scripting` 和 `Editor` 六个核心模块在整体架构中的归属关系。
|
||||
|
||||
同时,本章还从资源进入运行时、场景状态转化为渲染数据、编辑器视口接入渲染主链以及脚本驱动场景与渲染结果联动四个角度说明了模块之间的协同关系,并明确了体积渲染模块在总体架构中的位置。基于这一总体架构,下一章将进一步转入渲染引擎核心模块设计与实现的具体分析。
|
||||
|
||||
Reference in New Issue
Block a user