refactor: reorganize docs into plan/ and add skills/
This commit is contained in:
1612
docs/plan/D3D12后端测试设计.md
Normal file
1612
docs/plan/D3D12后端测试设计.md
Normal file
File diff suppressed because it is too large
Load Diff
1186
docs/plan/OpenGL后端测试设计.md
Normal file
1186
docs/plan/OpenGL后端测试设计.md
Normal file
File diff suppressed because it is too large
Load Diff
410
docs/plan/OpenGL测试实施计划.md
Normal file
410
docs/plan/OpenGL测试实施计划.md
Normal file
@@ -0,0 +1,410 @@
|
||||
# OpenGL 测试实施计划
|
||||
|
||||
## 1. 概述
|
||||
|
||||
本文档是 `docs/OpenGL后端测试设计.md` 的实施细化计划,基于设计文档中的 5 阶段实现优先级,结合 D3D12 测试经验(54 个测试)制定。
|
||||
|
||||
### 1.1 目标
|
||||
|
||||
- 搭建完整的 OpenGL 后端测试框架
|
||||
- 实现与 D3D12 对齐的 54+ 个测试用例
|
||||
- 确保 CI 环境可用
|
||||
- 支持无头渲染(headless)测试
|
||||
|
||||
### 1.2 测试组件总览
|
||||
|
||||
| # | 组件 | 测试数量 | 文件 | 优先级 |
|
||||
|---|------|:--------:|------|:------:|
|
||||
| 1 | OpenGLDevice | 6 | test_device.cpp | Phase 1 |
|
||||
| 2 | OpenGLBuffer | 6 | test_buffer.cpp | Phase 1 |
|
||||
| 3 | OpenGLFence | 5 | test_fence.cpp | Phase 1 |
|
||||
| 4 | OpenGLTexture | 5 | test_texture.cpp | Phase 2 |
|
||||
| 5 | OpenGLSampler | 4 | test_sampler.cpp | Phase 2 |
|
||||
| 6 | OpenGLShader | 4 | test_shader.cpp | Phase 3 |
|
||||
| 7 | OpenGLPipelineState | 3 | test_pipeline_state.cpp | Phase 3 |
|
||||
| 8 | OpenGLVertexArray | 4 | test_vertex_array.cpp | Phase 3 |
|
||||
| 9 | OpenGLCommandList | 8 | test_command_list.cpp | Phase 4 |
|
||||
| 10 | OpenGLRenderTargetView | 4 | test_render_target_view.cpp | Phase 4 |
|
||||
| 11 | OpenGLDepthStencilView | 4 | test_depth_stencil_view.cpp | Phase 4 |
|
||||
| 12 | OpenGLSwapChain | 3 | test_swap_chain.cpp | Phase 5 |
|
||||
| **总计** | | **56** | | |
|
||||
|
||||
---
|
||||
|
||||
## 2. 实施阶段
|
||||
|
||||
### Phase 1: 核心基础设施(约 1 天)
|
||||
|
||||
#### 2.1 创建目录结构
|
||||
|
||||
```
|
||||
tests/RHI/OpenGL/
|
||||
├── CMakeLists.txt
|
||||
├── fixtures/
|
||||
│ ├── OpenGLTestFixture.h
|
||||
│ └── OpenGLTestFixture.cpp
|
||||
└── Res/
|
||||
├── Shader/
|
||||
├── Texture/
|
||||
└── Data/
|
||||
```
|
||||
|
||||
#### 2.2 实现测试夹具
|
||||
|
||||
**OpenGLTestFixture** 是所有测试的基础:
|
||||
|
||||
| 功能 | 描述 |
|
||||
|------|------|
|
||||
| `SetUpTestSuite()` | 创建隐藏 GLFW 窗口和 GL 上下文 |
|
||||
| `TearDownTestSuite()` | 销毁窗口,终止 GLFW |
|
||||
| `SetUp()` | 确保上下文激活,清除 GL 错误 |
|
||||
| `TearDown()` | 重置 GL 状态,检查泄漏 |
|
||||
| `CheckGLError()` | 检查并报告 GL 错误 |
|
||||
|
||||
**GL 错误检查宏**:
|
||||
|
||||
```cpp
|
||||
#define GL_CLEAR_ERRORS() do { while (glGetError() != GL_NO_ERROR); } while(0)
|
||||
#define GL_CHECK(call) do { call; ASSERT_TRUE(CheckGLError(__FILE__, __LINE__)); } while(0)
|
||||
#define GL_EXPECT_SUCCESS(call) do { call; EXPECT_EQ(glGetError(), GL_NO_ERROR); } while(0)
|
||||
```
|
||||
|
||||
#### 2.3 OpenGLDevice 测试(6 个)
|
||||
|
||||
| 测试用例 | 验证内容 |
|
||||
|----------|----------|
|
||||
| `CreateRenderWindow_ValidParams` | 窗口创建成功 |
|
||||
| `CreateRenderWindow_DebugMode` | 调试模式创建 |
|
||||
| `InitializeWithExistingWindow` | 现有窗口初始化 |
|
||||
| `GetDeviceInfo_ReturnsValid` | 供应商/渲染器/版本信息 |
|
||||
| `SwapBuffers_NoErrors` | 交换缓冲区无错误 |
|
||||
| `PollEvents_ReturnsTrue` | 事件轮询正常 |
|
||||
|
||||
#### 2.4 OpenGLBuffer 测试(6 个)
|
||||
|
||||
| 测试用例 | 验证内容 |
|
||||
|----------|----------|
|
||||
| `Initialize_VertexBuffer` | 顶点缓冲创建 |
|
||||
| `Initialize_IndexBuffer` | 索引缓冲创建 |
|
||||
| `Initialize_UniformBuffer` | Uniform 缓冲创建 |
|
||||
| `Initialize_Dynamic` | 动态缓冲创建 |
|
||||
| `Bind_Unbind` | 缓冲绑定/解绑 |
|
||||
| `Map_Unmap` | 数据映射操作 |
|
||||
|
||||
#### 2.5 OpenGLFence 测试(5 个)
|
||||
|
||||
| 测试用例 | 验证内容 |
|
||||
|----------|----------|
|
||||
| `Initialize_Unsignaled` | 未 signaled 状态创建 |
|
||||
| `Initialize_Signaled` | signaled 状态创建 |
|
||||
| `Signal_SetsValue` | Signal 设置值 |
|
||||
| `Wait_Blocks` | Wait 阻塞等待 |
|
||||
| `IsSignaled_ReturnsState` | signaled 状态查询 |
|
||||
|
||||
#### 2.6 验证步骤
|
||||
|
||||
```bash
|
||||
# 构建
|
||||
cmake --build build --config Debug
|
||||
|
||||
# 运行测试
|
||||
./build/tests/RHI/OpenGL/Debug/opengl_tests.exe --gtest_filter=OpenGLTestFixture.Device*:OpenGLTestFixture.Buffer*:OpenGLTestFixture.Fence*
|
||||
|
||||
# 预期结果
|
||||
[==========] 17 tests from OpenGLTestFixture
|
||||
[ PASSED ] 17 tests
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Phase 2: 资源管理(约 1 天)
|
||||
|
||||
#### 2.7 OpenGLTexture 测试(5 个)
|
||||
|
||||
| 测试用例 | 验证内容 |
|
||||
|----------|----------|
|
||||
| `Initialize_2DTexture` | 2D 纹理创建 |
|
||||
| `Initialize_CubeMap` | 立方体纹理创建 |
|
||||
| `Bind_Unbind` | 纹理绑定/解绑 |
|
||||
| `GenerateMipmap` | Mipmap 生成 |
|
||||
| `SetFiltering_SetWrapping` | 过滤/环绕参数 |
|
||||
|
||||
#### 2.8 OpenGLSampler 测试(4 个)
|
||||
|
||||
| 测试用例 | 验证内容 |
|
||||
|----------|----------|
|
||||
| `Initialize_Default` | 默认采样器创建 |
|
||||
| `Initialize_Custom` | 自定义采样器创建 |
|
||||
| `Bind_Unbind` | 采样器绑定/解绑 |
|
||||
| `GetID_ReturnsValid` | 采样器 ID 有效 |
|
||||
|
||||
#### 2.9 验证步骤
|
||||
|
||||
```bash
|
||||
# 运行资源管理测试
|
||||
./build/tests/RHI/OpenGL/Debug/opengl_tests.exe --gtest_filter=OpenGLTestFixture.Texture*:OpenGLTestFixture.Sampler*
|
||||
|
||||
# 预期结果
|
||||
[==========] 9 tests from OpenGLTestFixture
|
||||
[ PASSED ] 9 tests
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Phase 3: 渲染管线(约 1.5 天)
|
||||
|
||||
#### 2.10 OpenGLShader 测试(4 个)
|
||||
|
||||
| 测试用例 | 验证内容 |
|
||||
|----------|----------|
|
||||
| `Compile_VertexFragment` | 顶点和片段着色器编译 |
|
||||
| `Compile_WithGeometry` | 几何着色器编译 |
|
||||
| `Compile_InvalidSource` | 无效源码编译失败 |
|
||||
| `SetUniforms` | Uniform 设置 (int/float/vec3/mat4) |
|
||||
|
||||
#### 2.11 OpenGLPipelineState 测试(3 个)
|
||||
|
||||
| 测试用例 | 验证内容 |
|
||||
|----------|----------|
|
||||
| `SetDepthStencilState` | 深度/模板状态设置 |
|
||||
| `SetBlendState` | 混合状态设置 |
|
||||
| `SetViewport_SetScissor` | 视口/裁剪矩形 |
|
||||
|
||||
#### 2.12 OpenGLVertexArray 测试(4 个)
|
||||
|
||||
| 测试用例 | 验证内容 |
|
||||
|----------|----------|
|
||||
| `Initialize_CreatesVAO` | VAO 创建 |
|
||||
| `AddVertexBuffer` | 顶点缓冲添加 |
|
||||
| `SetIndexBuffer` | 索引缓冲设置 |
|
||||
| `Bind_Unbind` | VAO 绑定/解绑 |
|
||||
|
||||
#### 2.13 验证步骤
|
||||
|
||||
```bash
|
||||
# 运行渲染管线测试
|
||||
./build/tests/RHI/OpenGL/Debug/opengl_tests.exe --gtest_filter=OpenGLTestFixture.Shader*:OpenGLTestFixture.PipelineState*:OpenGLTestFixture.VertexArray*
|
||||
|
||||
# 预期结果
|
||||
[==========] 11 tests from OpenGLTestFixture
|
||||
[ PASSED ] 11 tests
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Phase 4: 命令与视图(约 1.5 天)
|
||||
|
||||
#### 2.14 OpenGLCommandList 测试(8 个)
|
||||
|
||||
| 测试用例 | 验证内容 |
|
||||
|----------|----------|
|
||||
| `Clear_ColorBuffer` | 清除颜色缓冲 |
|
||||
| `Clear_DepthStencil` | 清除深度/模板 |
|
||||
| `SetVertexBuffer` | 设置顶点缓冲 |
|
||||
| `SetIndexBuffer` | 设置索引缓冲 |
|
||||
| `Draw_Triangles` | 绘制三角形 |
|
||||
| `DrawIndexed_Indices` | 索引绘制 |
|
||||
| `DrawInstanced` | 实例化绘制 |
|
||||
| `Dispatch_ComputeShader` | 计算着色器分发 |
|
||||
|
||||
#### 2.15 OpenGLRenderTargetView 测试(4 个)
|
||||
|
||||
| 测试用例 | 验证内容 |
|
||||
|----------|----------|
|
||||
| `Initialize_Texture2D` | 2D 纹理 RTV 创建 |
|
||||
| `Initialize_Default` | 默认帧缓冲 RTV |
|
||||
| `Bind_Unbind` | RTV 绑定/解绑 |
|
||||
| `Clear_Color` | 清除颜色 |
|
||||
|
||||
#### 2.16 OpenGLDepthStencilView 测试(4 个)
|
||||
|
||||
| 测试用例 | 验证内容 |
|
||||
|----------|----------|
|
||||
| `Initialize_Texture2D` | 2D 纹理 DSV 创建 |
|
||||
| `Initialize_DepthOnly` | 仅深度 DSV |
|
||||
| `Bind_Unbind` | DSV 绑定/解绑 |
|
||||
| `ClearDepthStencil` | 清除深度/模板 |
|
||||
|
||||
#### 2.17 验证步骤
|
||||
|
||||
```bash
|
||||
# 运行命令与视图测试
|
||||
./build/tests/RHI/OpenGL/Debug/opengl_tests.exe --gtest_filter=OpenGLTestFixture.CommandList*:OpenGLTestFixture.RenderTargetView*:OpenGLTestFixture.DepthStencilView*
|
||||
|
||||
# 预期结果
|
||||
[==========] 16 tests from OpenGLTestFixture
|
||||
[ PASSED ] 16 tests
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Phase 5: 窗口管理(约 0.5 天)
|
||||
|
||||
#### 2.18 OpenGLSwapChain 测试(3 个)
|
||||
|
||||
| 测试用例 | 验证内容 |
|
||||
|----------|----------|
|
||||
| `Initialize_Window` | 交换链初始化 |
|
||||
| `Present_VSync` | 垂直同步显示 |
|
||||
| `Resize_ChangesSize` | 调整大小 |
|
||||
|
||||
#### 2.19 验证步骤
|
||||
|
||||
```bash
|
||||
# 运行窗口管理测试
|
||||
./build/tests/RHI/OpenGL/Debug/opengl_tests.exe --gtest_filter=OpenGLTestFixture.SwapChain*
|
||||
|
||||
# 预期结果
|
||||
[==========] 3 tests from OpenGLTestFixture
|
||||
[ PASSED ] 3 tests
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 完整验证
|
||||
|
||||
### 3.1 运行所有测试
|
||||
|
||||
```bash
|
||||
# 完整测试
|
||||
cmake --build build --config Debug
|
||||
ctest --test-dir build -C Debug --output-on-failure
|
||||
|
||||
# 预期结果
|
||||
[==========] 56 tests from 1 test suite.
|
||||
[ PASSED ] 56 tests
|
||||
```
|
||||
|
||||
### 3.2 测试分类统计
|
||||
|
||||
| 分类 | 数量 | 占比 |
|
||||
|------|:----:|:----:|
|
||||
| 初始化测试 | 18 | 32% |
|
||||
| 绑定/解绑测试 | 10 | 18% |
|
||||
| 数据操作测试 | 8 | 14% |
|
||||
| 状态设置测试 | 10 | 18% |
|
||||
| 绘制/执行测试 | 10 | 18% |
|
||||
|
||||
---
|
||||
|
||||
## 4. CI 配置
|
||||
|
||||
### 4.1 GitHub Actions
|
||||
|
||||
```yaml
|
||||
# .github/workflows/opengl-tests.yml
|
||||
name: OpenGL Tests
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Configure
|
||||
run: cmake -B build -S . -G "Visual Studio 17 2022"
|
||||
|
||||
- name: Build
|
||||
run: cmake --build build --config Debug
|
||||
|
||||
- name: Run Tests
|
||||
run: ctest --test-dir build -C Debug --output-on-failure
|
||||
```
|
||||
|
||||
### 4.2 Linux CI(可选)
|
||||
|
||||
Linux 下需要配置 Mesa 软件渲染:
|
||||
|
||||
```yaml
|
||||
- name: Run Tests
|
||||
env:
|
||||
MESA_GL_VERSION_OVERRIDE: 4.6
|
||||
MESA_GALLIUM_DRIVER: llvmpipe
|
||||
run: ctest --test-dir build -C Debug --output-on-failure
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 任务清单
|
||||
|
||||
### 阶段 1:基础设施
|
||||
|
||||
- [ ] 1.1 创建 `tests/RHI/OpenGL/CMakeLists.txt`
|
||||
- [ ] 1.2 创建 `tests/RHI/OpenGL/fixtures/OpenGLTestFixture.h`
|
||||
- [ ] 1.3 创建 `tests/RHI/OpenGL/fixtures/OpenGLTestFixture.cpp`
|
||||
- [ ] 1.4 实现 `test_device.cpp`(6 个测试)
|
||||
- [ ] 1.5 实现 `test_buffer.cpp`(6 个测试)
|
||||
- [ ] 1.6 实现 `test_fence.cpp`(5 个测试)
|
||||
- [ ] 1.7 构建验证(17 个测试)
|
||||
|
||||
### 阶段 2:资源管理
|
||||
|
||||
- [ ] 2.1 实现 `test_texture.cpp`(5 个测试)
|
||||
- [ ] 2.2 实现 `test_sampler.cpp`(4 个测试)
|
||||
- [ ] 2.3 构建验证(9 个测试)
|
||||
|
||||
### 阶段 3:渲染管线
|
||||
|
||||
- [ ] 3.1 实现 `test_shader.cpp`(4 个测试)
|
||||
- [ ] 3.2 实现 `test_pipeline_state.cpp`(3 个测试)
|
||||
- [ ] 3.3 实现 `test_vertex_array.cpp`(4 个测试)
|
||||
- [ ] 3.4 构建验证(11 个测试)
|
||||
|
||||
### 阶段 4:命令与视图
|
||||
|
||||
- [ ] 4.1 实现 `test_command_list.cpp`(8 个测试)
|
||||
- [ ] 4.2 实现 `test_render_target_view.cpp`(4 个测试)
|
||||
- [ ] 4.3 实现 `test_depth_stencil_view.cpp`(4 个测试)
|
||||
- [ ] 4.4 构建验证(16 个测试)
|
||||
|
||||
### 阶段 5:窗口管理
|
||||
|
||||
- [ ] 5.1 实现 `test_swap_chain.cpp`(3 个测试)
|
||||
- [ ] 5.2 完整测试验证(56 个测试)
|
||||
- [ ] 5.3 提交并推送
|
||||
|
||||
---
|
||||
|
||||
## 6. 关键注意事项
|
||||
|
||||
### 6.1 窗口依赖
|
||||
|
||||
- OpenGL 必须有 GLFW 窗口上下文
|
||||
- 使用 `GLFW_VISIBLE = GLFW_FALSE` 创建隐藏窗口
|
||||
- 每个测试前 `glfwMakeContextCurrent()`
|
||||
|
||||
### 6.2 GL 状态污染
|
||||
|
||||
- OpenGL 状态是全局的,必须隔离
|
||||
- `TearDown()` 中重置所有 GL 状态
|
||||
- 测试结束后 `glBindBuffer(..., 0)` 等
|
||||
|
||||
### 6.3 错误检查
|
||||
|
||||
- 使用 `GL_CHECK()` 宏验证每个 GL 调用
|
||||
- 测试开始时 `GL_CLEAR_ERRORS()`
|
||||
- 捕获 GL 错误并转换为测试失败
|
||||
|
||||
### 6.4 与 D3D12 对齐
|
||||
|
||||
- 保持相同的测试数量级(54+)
|
||||
- 使用相同的 TEST_F 宏
|
||||
- 遵循相同的命名约定
|
||||
|
||||
---
|
||||
|
||||
## 7. 后续工作
|
||||
|
||||
- [ ] 资源泄漏检测工具
|
||||
- [ ] 性能基准测试
|
||||
- [ ] 截图对比测试
|
||||
- [ ] Linux CI 配置
|
||||
- [ ] macOS 支持
|
||||
|
||||
---
|
||||
|
||||
**文档版本**:1.0
|
||||
**创建日期**:2026年3月17日
|
||||
**基于文档**:`docs/OpenGL后端测试设计.md`、`tests/RHI/D3D12/`
|
||||
1069
docs/plan/RHI抽象层设计与实现.md
Normal file
1069
docs/plan/RHI抽象层设计与实现.md
Normal file
File diff suppressed because it is too large
Load Diff
285
docs/plan/TESTING.md
Normal file
285
docs/plan/TESTING.md
Normal file
@@ -0,0 +1,285 @@
|
||||
# XCEngine 测试体系文档
|
||||
|
||||
> **版本**: 1.0
|
||||
> **日期**: 2026-03-13
|
||||
|
||||
---
|
||||
|
||||
## 1. 测试架构
|
||||
|
||||
```
|
||||
tests/
|
||||
├── CMakeLists.txt # 测试构建配置
|
||||
├── run_tests.cmake # 测试运行脚本
|
||||
├── fixtures/ # 测试夹具
|
||||
│ └── MathFixtures.h
|
||||
├── math/ # Math 单元测试
|
||||
│ ├── CMakeLists.txt
|
||||
│ ├── test_vector.cpp
|
||||
│ ├── test_matrix.cpp
|
||||
│ ├── test_quaternion.cpp
|
||||
│ └── test_geometry.cpp
|
||||
├── core/ # Core 测试
|
||||
├── threading/ # 线程测试
|
||||
├── memory/ # 内存测试
|
||||
├── containers/ # 容器测试
|
||||
└── rendering/ # 渲染测试
|
||||
├── unit/ # 单元测试
|
||||
├── integration/ # 集成测试
|
||||
└── screenshots/ # 参考图
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 测试分类
|
||||
|
||||
| 类型 | 目录 | 目的 | 运行频率 |
|
||||
|------|------|------|---------|
|
||||
| **Unit Test** | `tests/*/` | 验证单个函数/类 | 每次提交 |
|
||||
| **Integration Test** | `tests/rendering/integration/` | 验证多模块协作 | 每次提交 |
|
||||
| **Benchmark** | `tests/benchmark/` | 性能回归检测 | 每日/每周 |
|
||||
| **Screenshot Test** | `tests/rendering/screenshots/` | 渲染正确性 | 每次提交 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 测试命名规范
|
||||
|
||||
```cpp
|
||||
// 格式: test_<模块>_<功能>_<场景>
|
||||
TEST(Math_Vector3, Dot_TwoVectors_ReturnsCorrectValue) { }
|
||||
TEST(Math_Vector3, Normalize_ZeroVector_ReturnsZeroVector) { }
|
||||
TEST(Math_Matrix4, Inverse_Identity_ReturnsIdentity) { }
|
||||
TEST(Math_Matrix4, TRS_Decompose_RecoversOriginalValues) { }
|
||||
TEST(Math_Quaternion, Slerp_ShortestPath_InterpolatesCorrectly) { }
|
||||
|
||||
// 边界情况
|
||||
TEST(Math_Vector3, Normalize_ZeroVector_DoesNotCrash) { }
|
||||
TEST(Math_Matrix4, Inverse_SingularMatrix_ReturnsIdentity) { }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 断言规范
|
||||
|
||||
### 4.1 浮点数比较
|
||||
|
||||
```cpp
|
||||
// 必须使用容差
|
||||
EXPECT_NEAR(actual, expected, 1e-5f);
|
||||
ASSERT_FLOAT_EQ(actual, expected); // gtest 内部有容差
|
||||
|
||||
// 数组比较
|
||||
for (int i = 0; i < 4; i++) {
|
||||
EXPECT_NEAR(actual.m[i], expected.m[i], 1e-5f);
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2 常用断言
|
||||
|
||||
```cpp
|
||||
EXPECT_TRUE(condition);
|
||||
EXPECT_FALSE(condition);
|
||||
EXPECT_EQ(actual, expected);
|
||||
EXPECT_NE(actual, expected);
|
||||
EXPECT_STREQ(actual, expected);
|
||||
EXPECT_THROW(expression, exception_type);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 测试夹具 (Fixture)
|
||||
|
||||
```cpp
|
||||
class MathFixture : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
v1 = Vector3(1, 0, 0);
|
||||
v2 = Vector3(0, 1, 0);
|
||||
v3 = Vector3(1, 1, 1);
|
||||
|
||||
m1 = Matrix4x4::Identity();
|
||||
m2 = Matrix4x4::Translation(Vector3(1, 2, 3));
|
||||
}
|
||||
|
||||
Vector3 v1, v2, v3;
|
||||
Matrix4x4 m1, m2;
|
||||
const float epsilon = 1e-5f;
|
||||
};
|
||||
|
||||
TEST_F(MathFixture, Dot_OrthogonalVectors_ReturnsZero) {
|
||||
EXPECT_FLOAT_EQ(Vector3::Dot(v1, v2), 0.0f);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 参数化测试
|
||||
|
||||
```cpp
|
||||
class MatrixInverseTest : public ::testing::TestWithParam<Matrix4x4> {};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
InverseCases,
|
||||
MatrixInverseTest,
|
||||
testing::Values(
|
||||
Matrix4x4::Identity(),
|
||||
Matrix4x4::Translation(Vector3(1,2,3)),
|
||||
Matrix4x4::Scale(Vector3(2,2,2))
|
||||
)
|
||||
);
|
||||
|
||||
TEST_P(MatrixInverseTest, InverseOfInverse_EqualsOriginal) {
|
||||
Matrix4x4 original = GetParam();
|
||||
Matrix4x4 inverted = original.Inverse();
|
||||
Matrix4x4 recovered = inverted.Inverse();
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
EXPECT_NEAR(original.m[i][j], recovered.m[i][j], 1e-4f);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Math 测试用例
|
||||
|
||||
### 7.1 Vector2/3/4 测试
|
||||
|
||||
| 测试类别 | 测试用例 |
|
||||
|---------|---------|
|
||||
| **构造** | 默认构造、参数构造、从 Vector3 构造 |
|
||||
| **运算** | 加、减、乘、除、点积、叉积 |
|
||||
| **归一化** | Normalize、Normalized、Magnitude、SqrMagnitude |
|
||||
| **插值** | Lerp、MoveTowards |
|
||||
| **投影** | Project、ProjectOnPlane |
|
||||
| **角度** | Angle、Reflect |
|
||||
|
||||
### 7.2 Matrix 测试
|
||||
|
||||
| 测试类别 | 测试用例 |
|
||||
|---------|---------|
|
||||
| **构造** | Identity、Zero |
|
||||
| **变换** | Translation、Rotation、Scale、TRS |
|
||||
| **相机** | LookAt、Perspective、Orthographic |
|
||||
| **运算** | 乘法、点乘、叉乘 |
|
||||
| **分解** | Inverse、Transpose、Determinant、Decompose |
|
||||
|
||||
### 7.3 Quaternion 测试
|
||||
|
||||
| 测试类别 | 测试用例 |
|
||||
|---------|---------|
|
||||
| **构造** | Identity、FromAxisAngle、FromEulerAngles |
|
||||
| **转换** | ToEulerAngles、ToMatrix4x4、FromRotationMatrix |
|
||||
| **插值** | Slerp |
|
||||
| **运算** | 乘法和逆 |
|
||||
|
||||
### 7.4 几何测试
|
||||
|
||||
| 测试类型 | 测试用例 |
|
||||
|---------|---------|
|
||||
| **Ray** | GetPoint、Intersects(Sphere/Box/Plane) |
|
||||
| **Sphere** | Contains、Intersects |
|
||||
| **Box** | Contains、Intersects |
|
||||
| **Plane** | FromPoints、GetDistanceToPoint、Intersects |
|
||||
| **Frustum** | Contains(Point/Sphere/Bounds)、Intersects |
|
||||
| **Bounds** | GetMinMax、Intersects、Contains、Encapsulate |
|
||||
|
||||
---
|
||||
|
||||
## 8. 构建与运行
|
||||
|
||||
### 8.1 构建测试
|
||||
|
||||
```bash
|
||||
# 创建构建目录
|
||||
mkdir build && cd build
|
||||
|
||||
# 配置 CMake
|
||||
cmake .. -G "Visual Studio 17 2022" -A x64
|
||||
|
||||
# 构建测试
|
||||
cmake --build . --config Debug --target xcengine_math_tests
|
||||
```
|
||||
|
||||
### 8.2 运行测试
|
||||
|
||||
```bash
|
||||
# 运行所有测试
|
||||
ctest --output-on-failure
|
||||
|
||||
# 运行 Math 测试
|
||||
./tests/xcengine_math_tests.exe
|
||||
|
||||
# 运行特定测试
|
||||
./tests/xcengine_math_tests.exe --gtest_filter=Math_Vector3.*
|
||||
|
||||
# 运行测试并显示详细信息
|
||||
./tests/xcengine_math_tests.exe --gtest_also_run_disabled_tests --gtest_print_time=1
|
||||
```
|
||||
|
||||
### 8.3 测试过滤器
|
||||
|
||||
```bash
|
||||
# 运行所有 Vector3 测试
|
||||
--gtest_filter=Math_Vector3.*
|
||||
|
||||
# 运行除某测试外的所有测试
|
||||
--gtest_filter=-Math_Matrix4.SingularMatrix*
|
||||
|
||||
# 运行多个测试
|
||||
--gtest_filter=Math_Vector3.*:Math_Matrix4.*
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. 覆盖率要求
|
||||
|
||||
| 模块 | 最低覆盖率 | 关键测试 |
|
||||
|------|-----------|---------|
|
||||
| Math | 90% | 所有公开 API |
|
||||
| Core | 80% | 智能指针、Event |
|
||||
| Containers | 85% | 边界、迭代器 |
|
||||
| Memory | 90% | 分配/泄漏 |
|
||||
| Threading | 70% | 基本功能 |
|
||||
|
||||
---
|
||||
|
||||
## 10. 持续集成
|
||||
|
||||
```yaml
|
||||
# .github/workflows/test.yml
|
||||
name: Test
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Configure
|
||||
run: cmake -B build -DENABLE_COVERAGE=ON
|
||||
|
||||
- name: Build
|
||||
run: cmake --build build --config Debug
|
||||
|
||||
- name: Test
|
||||
run: ctest --test-dir build --output-on-failure
|
||||
|
||||
- name: Coverage
|
||||
run: cmake --build build --target coverage
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. 注意事项
|
||||
|
||||
1. **浮点数比较** - 必须使用容差 (通常 1e-5 或 1e-6)
|
||||
2. **边界条件** - 必须测试零向量、奇异矩阵等
|
||||
3. **随机性** - 如需固定 seed 保证确定性
|
||||
4. **线程安全** - 线程测试需设置超时
|
||||
5. **内存泄漏** - 使用 Valgrind 或 CRT 检测
|
||||
621
docs/plan/Unity SRP API参考文档.md
Normal file
621
docs/plan/Unity SRP API参考文档.md
Normal file
@@ -0,0 +1,621 @@
|
||||
# Unity SRP (Scriptable Render Pipeline) API 参考文档
|
||||
|
||||
## 1. 概述
|
||||
|
||||
Unity 的可编写脚本渲染管线 (Scriptable Render Pipeline, SRP) 是一项允许通过 C# 脚本控制渲染的功能。SRP 是通用渲染管线 (URP) 和高清渲染管线 (HDRP) 的底层技术基础。
|
||||
|
||||
**命名空间**: `UnityEngine.Rendering`
|
||||
|
||||
---
|
||||
|
||||
## 2. 核心类 API
|
||||
|
||||
### 2.1 RenderPipeline 类
|
||||
|
||||
**命名空间**: `UnityEngine.Rendering`
|
||||
|
||||
**描述**: 提供实现可编写脚本渲染管线的渲染逻辑的方式。继承自此类以重写 `Render` 方法来实现自定义 SRP。
|
||||
|
||||
**示例代码**:
|
||||
```csharp
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class CustomRenderPipeline : RenderPipeline
|
||||
{
|
||||
protected override void Render(ScriptableRenderContext context, List<Camera> cameras)
|
||||
{
|
||||
// 实现自定义 SRP 渲染逻辑
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**属性**:
|
||||
| 属性 | 描述 |
|
||||
|------|------|
|
||||
| `disposed` | 返回 true 表示 RenderPipeline 无效或已销毁 |
|
||||
|
||||
**受保护的方法**:
|
||||
| 方法 | 描述 |
|
||||
|------|------|
|
||||
| `IsPreviewSupported()` | 指定相机是否可以预览 |
|
||||
| `IsRenderRequestSupported()` | 实现此方法以指定特定的相机和渲染请求组合是否受支持 |
|
||||
| `ProcessRenderRequests()` | 执行使用 RenderPipeline.SubmitRenderRequest 提交的渲染请求 |
|
||||
| `Render()` | 定义此 RenderPipeline 自定义渲染的入口点方法 |
|
||||
|
||||
**静态方法**:
|
||||
| 方法 | 描述 |
|
||||
|------|------|
|
||||
| `BeginCameraRendering(ScriptableRenderContext, Camera)` | 调用 RenderPipelineManager.beginCameraRendering 委托 |
|
||||
| `BeginContextRendering(ScriptableRenderContext, List<Camera>)` | 调用 RenderPipelineManager.beginContextRendering 和 beginFrameRendering 委托 |
|
||||
| `BeginFrameRendering(ScriptableRenderContext, List<Camera>)` | 调用 RenderPipelineManager.beginFrameRendering 委托 |
|
||||
| `EndCameraRendering(ScriptableRenderContext, Camera)` | 调用 RenderPipelineManager.endCameraRendering 委托 |
|
||||
| `EndContextRendering(ScriptableRenderContext, List<Camera>)` | 调用 RenderPipelineManager.endContextRendering 和 endFrameRendering 委托 |
|
||||
| `EndFrameRendering(ScriptableRenderContext, List<Camera>)` | 调用 RenderPipelineManager.endFrameRendering 委托 |
|
||||
| `SubmitRenderRequest(Camera, RenderRequest)` | 向相机提交渲染请求(在 Unity 渲染循环之外) |
|
||||
| `SupportsRenderRequest(Camera, RequestData)` | 检查渲染管线是否支持使用相机的 RequestData 类型 |
|
||||
| `ProcessRenderRequests(List<RenderRequest>)` | 执行使用 Camera.SubmitRenderRequest 提交的渲染请求 |
|
||||
|
||||
---
|
||||
|
||||
### 2.2 RenderPipelineAsset 类
|
||||
|
||||
**命名空间**: `UnityEngine.Rendering`
|
||||
|
||||
**继承**: `ScriptableObject`
|
||||
|
||||
**描述**: 生成特定 IRenderPipeline 的资源。IRenderPipelineAsset 的默认实现。管理继承类型的生命周期,并确保创建的 IRenderPipeline 在资源更改时失效。
|
||||
|
||||
**属性**:
|
||||
| 属性 | 描述 |
|
||||
|------|------|
|
||||
| `autodeskInteractiveMaskedShader` | 获取此管线的默认 Autodesk Interactive 遮罩 Shader |
|
||||
| `autodeskInteractiveShader` | 获取此管线的默认 Autodesk Interactive Shader |
|
||||
| `autodeskInteractiveTransparentShader` | 获取此管线的默认 Autodesk Interactive 透明 Shader |
|
||||
| `default2DMaskMaterial` | 获取 Sprite Masks 使用的默认 2D 遮罩材质 |
|
||||
| `default2DMaterial` | 返回此管线的默认 2D 材质 |
|
||||
| `defaultLineMaterial` | 返回此管线的默认线条材质 |
|
||||
| `defaultMaterial` | 返回此管线的默认材质 |
|
||||
| `defaultParticleMaterial` | 返回此管线的默认粒子材质 |
|
||||
| `defaultShader` | 返回此管线的默认 Shader |
|
||||
| `defaultSpeedTree7Shader` | 返回 SpeedTree v7 Shader |
|
||||
| `defaultSpeedTree8Shader` | 返回 SpeedTree v8 Shader |
|
||||
| `defaultSpeedTree9Shader` | 返回 SpeedTree v9 Shader |
|
||||
| `defaultTerrainMaterial` | 返回此管线的默认地形材质 |
|
||||
| `defaultUIETC1SupportedMaterial` | 返回默认 UI ETC1 材质 |
|
||||
| `defaultUIMaterial` | 返回默认 UI 材质 |
|
||||
| `defaultUIOverdrawMaterial` | 返回默认 UI overdraw 材质 |
|
||||
| `pipelineType` | 返回与此 RenderPipelineAsset 实例关联的 RenderPipeline 类型 |
|
||||
| `renderPipelineShaderTag` | 返回此资源描述的渲染管线的 Shader Tag 值 |
|
||||
| `terrainBrushPassIndex` | 编辑器中地形笔刷的渲染索引 |
|
||||
| `terrainDetailGrassBillboardShader` | 返回此管线的细节草 Billboard Shader |
|
||||
| `terrainDetailGrassShader` | 返回此管线的细节草 Shader |
|
||||
| `terrainDetailLitShader` | 返回此管线的细节光照 Shader |
|
||||
|
||||
**受保护的方法**:
|
||||
| 方法 | 描述 |
|
||||
|------|------|
|
||||
| `CreatePipeline()` | 创建此资源特有的 IRenderPipeline |
|
||||
| `EnsureGlobalSettings()` | 确保全局设置已准备好并注册到 GraphicsSettings |
|
||||
| `OnDisable()` | RenderPipelineAsset 的 OnDisable 默认实现 |
|
||||
| `OnValidate()` | RenderPipelineAsset 的 OnValidate 默认实现 |
|
||||
|
||||
---
|
||||
|
||||
### 2.3 ScriptableRenderContext 类
|
||||
|
||||
**命名空间**: `UnityEngine.Rendering`
|
||||
|
||||
**类型**: struct (结构体)
|
||||
|
||||
**描述**: 定义自定义渲染管线使用的状态和绘制命令。当定义自定义 RenderPipeline 时,使用 ScriptableRenderContext 来调度和提交状态更新以及绘制命令到 GPU。
|
||||
|
||||
**公共方法**:
|
||||
| 方法 | 描述 |
|
||||
|------|------|
|
||||
| `BeginRenderPass(RenderTargetIdentifier, RenderPassAttachment, ClearFlag, Color)` | 调度新渲染 pass 的开始 |
|
||||
| `BeginScopedRenderPass(...)` | 调度渲染 pass 开始,使用 using 语句会自动调用 EndRenderPass |
|
||||
| `BeginScopedSubPass(...)` | 调度子 pass 开始,使用 using 语句会自动调用 EndSubPass |
|
||||
| `BeginSubPass(...)` | 调度子 pass 的开始 |
|
||||
| `CreateGizmoRendererList(...)` | 创建新的 Gizmo RendererList |
|
||||
| `CreateRendererList(...)` | 创建新的渲染器 RendererList |
|
||||
| `CreateShadowRendererList(...)` | 创建新的阴影 RendererList |
|
||||
| `CreateSkyboxRendererList(...)` | 创建新的天空盒 RendererList |
|
||||
| `CreateUIOverlayRendererList(...)` | 创建新的 UIOverlay RendererList |
|
||||
| `CreateWireOverlayRendererList(...)` | 创建新的线框覆盖层 RendererList |
|
||||
| `Cull(ScriptableCullingParameters)` | 执行基于 ScriptableCullingParameters 的剔除 |
|
||||
| `CullShadowCasters(...)` | 对所有可见光源执行阴影投射体剔除 |
|
||||
| `DrawGizmos(Camera, GizmoSubset)` | 调度绘制 Gizmos 子集 |
|
||||
| `DrawUIOverlay(Camera)` | 绘制 UI 覆盖层 |
|
||||
| `DrawWireOverlay(Camera)` | 调度线框覆盖层绘制 |
|
||||
| `EndRenderPass()` | 调度当前活动渲染 pass 的结束 |
|
||||
| `EndSubPass()` | 调度当前活动子 pass 的结束 |
|
||||
| `ExecuteCommandBuffer(CommandBuffer)` | 调度自定义图形 CommandBuffer 的执行 |
|
||||
| `ExecuteCommandBufferAsync(CommandBuffer, ComputeQueueType)` | 在异步计算队列上执行 CommandBuffer |
|
||||
| `HasInvokeOnRenderObjectCallbacks()` | 检查场景中是否有注册 OnRenderObject 回调的对象 |
|
||||
| `InvokeOnRenderObjectCallback(Camera)` | 调度 MonoBehaviour 脚本的 OnRenderObject 回调执行 |
|
||||
| `PrepareRendererListsAsync(List<RendererList>)` | 启动在后台处理提供的 RendererLists |
|
||||
| `QueryRendererListStatus(RendererList)` | 查询 RendererList 的状态 |
|
||||
| `SetupCameraProperties(Camera)` | 调度相机特定全局 Shader 变量的设置 |
|
||||
| `StartMultiEye(Camera)` | 调度在 ScriptableRenderContext 上开始细粒度立体渲染 |
|
||||
| `StopMultiEye(Camera)` | 调度停止立体渲染 |
|
||||
| `StereoEndRender(Camera)` | 调度单帧立体渲染完成通知 |
|
||||
| `Submit()` | 提交所有调度的命令到渲染循环执行 |
|
||||
| `SubmitForRenderPassValidation()` | 验证渲染 pass 是否可以执行调度的命令 |
|
||||
|
||||
**静态方法**:
|
||||
| 方法 | 描述 |
|
||||
|------|------|
|
||||
| `EmitGeometryForCamera(Camera)` | 为指定相机发射 UI 几何体进行渲染 |
|
||||
| `EmitWorldGeometryForSceneView(SceneView)` | 为场景视图发射 UI 几何体 |
|
||||
| `PopDisableApiRenderers()` | 启用渲染器场景节点的即时添加和移除 |
|
||||
| `PushDisableApiRenderers()` | 阻止渲染器场景节点的即时添加或移除 |
|
||||
|
||||
---
|
||||
|
||||
### 2.4 ScriptableRenderPass 类
|
||||
|
||||
**命名空间**: `UnityEngine.Rendering`
|
||||
|
||||
**描述**: 可编写脚本的渲染 Pass 基类。用于实现自定义渲染 passes。
|
||||
|
||||
**主要成员**:
|
||||
| 成员 | 描述 |
|
||||
|------|------|
|
||||
| `renderPassEvent` | 指定 Pass 在渲染管线中的执行时机 |
|
||||
| `ConfigureInput()` | 配置渲染器输入 |
|
||||
| `ConfigureTarget()` | 配置渲染目标 |
|
||||
| `Execute()` | 执行 Pass 的渲染逻辑 |
|
||||
| `FrameCleanup()` | 帧清理回调 |
|
||||
| `OnCameraSetup()` | 相机设置回调 |
|
||||
| `OnCameraCleanup()` | 相机清理回调 |
|
||||
|
||||
---
|
||||
|
||||
### 2.5 ScriptableRenderer 类
|
||||
|
||||
**命名空间**: `UnityEngine.Rendering`
|
||||
|
||||
**描述**: 可编写脚本的渲染器实现基类。
|
||||
|
||||
**主要方法**:
|
||||
| 方法 | 描述 |
|
||||
|------|------|
|
||||
| `EnqueuePass(ScriptableRenderPass)` | 将渲染 Pass 加入队列 |
|
||||
| `Execute(ScriptableRenderContext, ref RenderingData)` | 执行渲染 |
|
||||
| `Initialize()` | 初始化渲染器 |
|
||||
| `Submit()` | 提交渲染 |
|
||||
| `ConfigureCameraTarget(RenderTargetIdentifier, RenderTargetIdentifier)` | 配置相机渲染目标 |
|
||||
| `ConfigureColorStoreAction(RenderTargetStoreAction)` | 配置颜色存储操作 |
|
||||
| `ConfigureDepthStoreAction(RenderTargetStoreAction)` | 配置深度存储操作 |
|
||||
|
||||
**属性**:
|
||||
| 属性 | 描述 |
|
||||
|------|------|
|
||||
| `supportedRenderingFeatures` | 支持的渲染特性 |
|
||||
| `rendererFeatures` | 渲染器特性列表 |
|
||||
| `krenderGraphResourceSet` | 渲染图资源集 |
|
||||
|
||||
---
|
||||
|
||||
### 2.6 RenderPassEvent 枚举
|
||||
|
||||
**命名空间**: `UnityEngine.Rendering`
|
||||
|
||||
**描述**: 指定渲染 Pass 在渲染管线中的执行时机。
|
||||
|
||||
**枚举值**:
|
||||
| 值 | 描述 |
|
||||
|------|------|
|
||||
| `BeforeRendering` | 渲染开始前 |
|
||||
| `BeforeRenderingShadows` | 阴影渲染前 |
|
||||
| `BeforeRenderingPrePasses` | 预 Pass (如深度预通道) 前 |
|
||||
| `BeforeRenderingOpaques` | 不透明物体渲染前 |
|
||||
| `BeforeRenderingGbuffer` | G-Buffer (延迟渲染) 前 |
|
||||
| `BeforeRenderingLit` | 光照物体前 |
|
||||
| `BeforeRenderingTransparents` | 透明物体渲染前 |
|
||||
| `BeforeRenderingOverlays` | 覆盖层 (如 UI) 前 |
|
||||
| `BeforeAlphaMask` | Alpha 遮罩前 |
|
||||
| `AfterRendering` | 渲染结束后 |
|
||||
| `AfterRenderingShadows` | 阴影渲染后 |
|
||||
| `AfterRenderingPrePasses` | 预 Pass 后 |
|
||||
| `AfterRenderingOpaques` | 不透明物体渲染后 |
|
||||
| `AfterRenderingGbuffer` | G-Buffer 后 |
|
||||
| `AfterRenderingLit` | 光照物体后 |
|
||||
| `AfterRenderingTransparents` | 透明物体渲染后 |
|
||||
| `AfterRenderingOverlays` | 覆盖层后 |
|
||||
| `AfterAlphaMask` | Alpha 遮罩后 |
|
||||
|
||||
---
|
||||
|
||||
### 2.7 CullingResults 类
|
||||
|
||||
**命名空间**: `UnityEngine.Rendering`
|
||||
|
||||
**描述**: 包含剔除操作的结果,用于渲染对象和光源。
|
||||
|
||||
**主要方法**:
|
||||
| 方法 | 描述 |
|
||||
|------|------|
|
||||
| `FillLightAndReflectionProbeIndices(...)` | 填充光照和反射探针索引 |
|
||||
| `GetLightIndexMap()` | 获取光照索引映射 |
|
||||
| `GetReflectionProbeIndexMap()` | 获取反射探针索引映射 |
|
||||
| `SetLightIndexMap(int[], int[])` | 设置光照索引映射 |
|
||||
|
||||
**属性**:
|
||||
| 属性 | 描述 |
|
||||
|------|------|
|
||||
| `visibleLights` | 可见光源列表 |
|
||||
| `visibleReflectionProbes` | 可见反射探针列表 |
|
||||
| `lightAndReflectionProbeIndex` | 光照和反射探针索引数据 |
|
||||
|
||||
---
|
||||
|
||||
### 2.8 ScriptableCullingParameters 结构体
|
||||
|
||||
**命名空间**: `UnityEngine.Rendering`
|
||||
|
||||
**描述**: 包含用于剔除操作的参数。
|
||||
|
||||
**主要成员**:
|
||||
| 成员 | 描述 |
|
||||
|------|------|
|
||||
| `camera` | 剔除相机 |
|
||||
| `cullingPlaneSet` | 剔除平面集 |
|
||||
| `cullingMask` | 剔除遮罩 |
|
||||
| `lightCullingMode` | 光照剔除模式 |
|
||||
| `reflectionProbeCullingMode` | 反射探针剔除模式 |
|
||||
| `shadowDistance` | 阴影距离 |
|
||||
| `shadowNearPlane` | 阴影近平面 |
|
||||
| `maximumPortalCullingJobs` | 最大门户剔除作业数 |
|
||||
|
||||
**静态方法**:
|
||||
| 方法 | 描述 |
|
||||
|------|------|
|
||||
| `GetCullingParameters(Camera, ScriptableCullingParameters)` | 从相机获取剔除参数 |
|
||||
| `GetCullingParametersForEditor(Camera, ScriptableCullingParameters)` | 为编辑器获取剔除参数 |
|
||||
|
||||
---
|
||||
|
||||
## 3. CommandBuffer 相关 API
|
||||
|
||||
### 3.1 CommandBuffer 类
|
||||
|
||||
**命名空间**: `UnityEngine.Rendering`
|
||||
|
||||
**描述**: 用于存储渲染命令的缓冲区。
|
||||
|
||||
**常用方法**:
|
||||
| 方法 | 描述 |
|
||||
|------|------|
|
||||
| `Blit()` | 执行纹理拷贝 (blit) 操作 |
|
||||
| `DrawRenderer()` | 绘制渲染器 |
|
||||
| `DrawMesh()` | 绘制网格 |
|
||||
| `DrawMeshInstanced()` | 绘制实例化网格 |
|
||||
| `SetRenderTarget()` | 设置渲染目标 |
|
||||
| `SetGlobalTexture()` | 设置全局纹理 |
|
||||
| `SetGlobalFloat()` | 设置全局浮点数 |
|
||||
| `SetGlobalVector()` | 设置全局向量 |
|
||||
| `SetGlobalMatrix()` | 设置全局矩阵 |
|
||||
| `SetViewProjectionMatrices()` | 设置视图投影矩阵 |
|
||||
| `ClearRenderTarget()` | 清除渲染目标 |
|
||||
| `CopyTexture()` | 复制纹理 |
|
||||
| `ComputeDispatch()` | 计算着色器调度 |
|
||||
|
||||
### 3.2 CommandBufferPool 类
|
||||
|
||||
**命名空间**: `UnityEngine.Rendering`
|
||||
|
||||
**描述**: CommandBuffer 池化管理器,用于优化内存分配。
|
||||
|
||||
**静态方法**:
|
||||
| 方法 | 描述 |
|
||||
|------|------|
|
||||
| `Get(string)` | 从池中获取 CommandBuffer |
|
||||
| `Release(CommandBuffer)` | 释放 CommandBuffer 回池 |
|
||||
| `Create(string)` | 创建新的 CommandBuffer |
|
||||
| `ReleaseAll()` | 释放所有池化的 CommandBuffer |
|
||||
|
||||
### 3.3 RenderingData 结构体
|
||||
|
||||
**命名空间**: `UnityEngine.Rendering`
|
||||
|
||||
**描述**: 包含传递给 ScriptableRenderPass.Execute 的渲染数据。
|
||||
|
||||
**属性**:
|
||||
| 属性 | 描述 |
|
||||
|------|------|
|
||||
| `cameraData` | 相机数据 |
|
||||
| `cullingResults` | 剔除结果 |
|
||||
| `lightData` | 光照数据 |
|
||||
| `shadowData` | 阴影数据 |
|
||||
|
||||
### 3.4 CameraData 结构体
|
||||
|
||||
**命名空间**: `UnityEngine.Rendering`
|
||||
|
||||
**描述**: 包含相机相关的渲染数据。
|
||||
|
||||
**属性**:
|
||||
| 属性 | 描述 |
|
||||
|------|------|
|
||||
| `camera` | Unity Camera 对象 |
|
||||
| `projectionMatrix` | 投影矩阵 |
|
||||
| `viewMatrix` | 视图矩阵 |
|
||||
| `renderer` | 渲染器 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 渲染相关类
|
||||
|
||||
### 4.1 ShaderTagId
|
||||
|
||||
**命名空间**: `UnityEngine.Rendering`
|
||||
|
||||
**描述**: Shader 标签标识符,用于标识 Shader 的渲染通道。
|
||||
|
||||
### 4.2 LightProbe
|
||||
|
||||
**命名空间**: `UnityEngine.Rendering`
|
||||
|
||||
**描述**: 光照探针管理类,用于处理光照探针数据。
|
||||
|
||||
### 4.3 DrawRendererSettings
|
||||
|
||||
**命名空间**: `UnityEngine.Rendering`
|
||||
|
||||
**描述**: 渲染器绘制设置结构体,用于配置渲染器绘制参数。
|
||||
|
||||
**主要成员**:
|
||||
| 成员 | 描述 |
|
||||
|------|------|
|
||||
| `sorting` | 排序设置 |
|
||||
| `flags` | 渲染标志 |
|
||||
| `rendererConfiguration` | 渲染器配置 |
|
||||
| `passIndex` | Pass 索引 |
|
||||
|
||||
---
|
||||
|
||||
## 5. URP (Universal Render Pipeline) 核心 API
|
||||
|
||||
**包**: `com.unity.render-pipelines.universal`
|
||||
|
||||
**命名空间**: `UnityEngine.Rendering.Universal`
|
||||
|
||||
URP 是建立在 SRP Core 之上的渲染管线,提供了更简化的 API。
|
||||
|
||||
### 5.1 UniversalRenderPipeline 类
|
||||
|
||||
**命名空间**: `UnityEngine.Rendering.Universal`
|
||||
|
||||
**描述**: URP 的主渲染管线类。
|
||||
|
||||
**属性**:
|
||||
| 属性 | 描述 |
|
||||
|------|------|
|
||||
| `asset` | 当前 URP 资源 |
|
||||
| `current` | 当前活动的渲染管线 |
|
||||
|
||||
### 5.2 UniversalRenderPipelineAsset 类
|
||||
|
||||
**命名空间**: `UnityEngine.Rendering.Universal`
|
||||
|
||||
**描述**: URP 的渲染管线资源资产。
|
||||
|
||||
### 5.3 ForwardRenderer 类
|
||||
|
||||
**命名空间**: `UnityEngine.Rendering.Universal`
|
||||
|
||||
**描述**: URP 的前向渲染器实现。
|
||||
|
||||
### 5.4 RenderingData (URP扩展)
|
||||
|
||||
URP 扩展了基础的 RenderingData,添加了 URP 特有的渲染数据。
|
||||
|
||||
### 5.5 URP 核心 Pass 类
|
||||
|
||||
| 类名 | 描述 |
|
||||
|------|------|
|
||||
| `ScriptableRenderPass` | URP 中继承自基类的渲染 Pass |
|
||||
| `ScriptableBlitPass` | Blit 渲染 Pass |
|
||||
| `ScriptableFullscreenPass` | 全屏渲染 Pass |
|
||||
| `ColorGradingLutPass` | 颜色分级 LUT Pass |
|
||||
| `BloomPass` | 泛光 Pass |
|
||||
| `DepthOfFieldPass` | 景深 Pass |
|
||||
| `MotionVectorPass` | 运动矢量 Pass |
|
||||
|
||||
### 5.6 RenderPassEvent (URP扩展)
|
||||
|
||||
URP 扩展了标准的 RenderPassEvent,添加了 URP 特有的渲染事件。
|
||||
|
||||
---
|
||||
|
||||
## 6. HDRP (High Definition Render Pipeline) 核心 API
|
||||
|
||||
**包**: `com.unity.render-pipelines.high-definition`
|
||||
|
||||
**命名空间**: `UnityEngine.Rendering.HighDefinition`
|
||||
|
||||
HDRP 是建立在 SRP Core 之上的高端渲染管线,提供了高质量的渲染效果。
|
||||
|
||||
### 6.1 HDRenderPipeline 类
|
||||
|
||||
**命名空间**: `UnityEngine.Rendering.HighDefinition`
|
||||
|
||||
**描述**: HDRP 的主渲染管线类。
|
||||
|
||||
### 6.2 HDRenderPipelineAsset 类
|
||||
|
||||
**命名空间**: `UnityEngine.Rendering.HighDefinition`
|
||||
|
||||
**描述**: HDRP 的渲染管线资源资产。
|
||||
|
||||
### 6.3 HDRenderer 类
|
||||
|
||||
**命名空间**: `UnityEngine.Rendering.HighDefinition`
|
||||
|
||||
**描述**: HDRP 的渲染器实现。
|
||||
|
||||
### 6.4 HDRP 核心组件
|
||||
|
||||
| 类名 | 描述 |
|
||||
|------|------|
|
||||
| `HDRenderPipelineAsset` | HDRP 资源资产 |
|
||||
| `HDRenderer` | HDRP 渲染器 |
|
||||
| `HDBaker` | 光照烘焙器 |
|
||||
| `RayTracingShader` | 光线追踪着色器 |
|
||||
|
||||
### 6.5 HDRP 专用 Pass
|
||||
|
||||
| Pass 类 | 描述 |
|
||||
|---------|------|
|
||||
| `DeferredPass` | 延迟渲染 Pass |
|
||||
| `ForwardEmissivePass` | 前向发光 Pass |
|
||||
| `TransparentDepthPrePass` | 透明物体深度预 Pass |
|
||||
| `MotionVectorPass` | 运动矢量 Pass |
|
||||
|
||||
---
|
||||
|
||||
## 7. SRP Core 核心类 (com.unity.render-pipelines.core)
|
||||
|
||||
### 7.1 核心工具类
|
||||
|
||||
| 类名 | 描述 |
|
||||
|------|------|
|
||||
| `CoreUtils` | SRP 核心工具函数集合 |
|
||||
| `CoreMatrixUtils` | 矩阵操作工具函数 |
|
||||
| `Blitter` | Blit (纹理拷贝) 工具 |
|
||||
| `RTHandle` | 可自动缩放的渲染纹理 |
|
||||
| `RTHandleSystem` | RTHandle 纹理管理系统 |
|
||||
| `Volume` | 通用 Volume 组件 |
|
||||
| `VolumeManager` | Volume 全局管理器 |
|
||||
| `VolumeProfile` | Volume 设置资源 |
|
||||
| `VolumeComponent` | Volume 组件基类 |
|
||||
|
||||
### 7.2 调试相关类
|
||||
|
||||
| 类名 | 描述 |
|
||||
|------|------|
|
||||
| `DebugManager` | 调试窗口管理器 |
|
||||
| `DebugUI` | 调试 UI 类 |
|
||||
| `DebugUI.Widget` | 调试 UI 组件基类 |
|
||||
| `ProfilingSampler` | CPU/GPU 性能分析采样器 |
|
||||
| `ProfilingScope` | 性能分析作用域 |
|
||||
| `Recorder` | 性能记录器 |
|
||||
| `Profiler` | 性能分析器 |
|
||||
|
||||
### 7.3 资源管理类
|
||||
|
||||
| 类名 | 描述 |
|
||||
|------|------|
|
||||
| `RenderPipelineGlobalSettings` | 渲染管线全局设置 |
|
||||
| `RenderPipelineResources` | 渲染管线资源资产基类 |
|
||||
| `ConstantBuffer` | 常量缓冲区管理 |
|
||||
| `ShaderVariation` | Shader 变体管理 |
|
||||
| `MaterialDescription` | 材质描述 |
|
||||
|
||||
### 7.4 渲染 Pass 基类
|
||||
|
||||
| 类名 | 描述 |
|
||||
|------|------|
|
||||
| `ScriptableRenderPass` | 可编写脚本的渲染 Pass 基类 |
|
||||
| `ScriptableBlitPass` | Blit 操作 Pass 基类 |
|
||||
| `ScriptableCopyPass` | 拷贝 Pass 基类 |
|
||||
|
||||
### 7.5 渲染器特性
|
||||
|
||||
| 类名 | 描述 |
|
||||
|------|------|
|
||||
| `RenderingFeatures` | 渲染特性集合 |
|
||||
| `RendererFeatures` | 渲染器特性集合 |
|
||||
| `RenderPipelineFeature` | 渲染管线特性基类 |
|
||||
|
||||
---
|
||||
|
||||
## 8. 使用示例
|
||||
|
||||
### 8.1 创建自定义渲染管线
|
||||
|
||||
```csharp
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class CustomRenderPipeline : RenderPipeline
|
||||
{
|
||||
protected override void Render(ScriptableRenderContext context, List<Camera> cameras)
|
||||
{
|
||||
foreach (var camera in cameras)
|
||||
{
|
||||
// 渲染每个相机
|
||||
Render(context, camera);
|
||||
}
|
||||
|
||||
// 提交渲染命令
|
||||
context.Submit();
|
||||
}
|
||||
|
||||
private void Render(ScriptableRenderContext context, Camera camera)
|
||||
{
|
||||
// 设置相机属性
|
||||
context.SetupCameraProperties(camera);
|
||||
|
||||
// 创建命令缓冲区
|
||||
CommandBuffer cmd = CommandBufferPool.Get("Clear");
|
||||
cmd.ClearRenderTarget(true, true, Color.black);
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
CommandBufferPool.Release(cmd);
|
||||
|
||||
// 提交
|
||||
context.Submit();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 8.2 创建自定义渲染 Pass
|
||||
|
||||
```csharp
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
public class CustomRenderPass : ScriptableRenderPass
|
||||
{
|
||||
public CustomRenderPass()
|
||||
{
|
||||
// 设置 Pass 执行时机
|
||||
renderPassEvent = RenderPassEvent.BeforeRenderingOpaques;
|
||||
}
|
||||
|
||||
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
|
||||
{
|
||||
// 相机设置
|
||||
}
|
||||
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
// 执行渲染逻辑
|
||||
}
|
||||
|
||||
public override void FrameCleanup(CommandBuffer cmd)
|
||||
{
|
||||
// 帧清理
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. 官方文档资源
|
||||
|
||||
- [SRP 官方文档](https://docs.unity3d.com/Manual/ScriptableRenderPipeline.html)
|
||||
- [URP Scripting API](https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@latest/api/)
|
||||
- [HDRP Scripting API](https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@latest/api/)
|
||||
- [SRP Core Scripting API](https://docs.unity3d.com/Packages/com.unity.render-pipelines.core@latest/api/)
|
||||
|
||||
---
|
||||
|
||||
*文档版本: 1.1*
|
||||
*更新日期: 2026-03-16*
|
||||
*Unity 版本: 6.3 LTS (6000.3)*
|
||||
*基于官方 Unity API 文档调研整理*
|
||||
4564
docs/plan/XCEngine渲染引擎架构设计.md
Normal file
4564
docs/plan/XCEngine渲染引擎架构设计.md
Normal file
File diff suppressed because it is too large
Load Diff
6025
docs/plan/XCGameEngine架构设计.md
Normal file
6025
docs/plan/XCGameEngine架构设计.md
Normal file
File diff suppressed because it is too large
Load Diff
1325
docs/plan/仿Unity RHI架构设计.md
Normal file
1325
docs/plan/仿Unity RHI架构设计.md
Normal file
File diff suppressed because it is too large
Load Diff
297
docs/plan/开题报告和任务书/DXR_Volumetric_Rendering_Research_Report.md
Normal file
297
docs/plan/开题报告和任务书/DXR_Volumetric_Rendering_Research_Report.md
Normal file
@@ -0,0 +1,297 @@
|
||||
# DirectX Raytracing (DXR) 体积渲染技术调研报告
|
||||
|
||||
## 一、DXR基本能力与工作原理
|
||||
|
||||
### 1.1 什么是DirectX Raytracing (DXR)
|
||||
|
||||
DirectX Raytracing(DXR)是Microsoft在DirectX 12中引入的光线追踪API,于2018年随Windows 10 1809版本正式发布。DXR代表了实时图形渲染的重大技术飞跃,它使得在游戏和应用程序中实现电影级真实感渲染成为可能此前这一直是离线渲染领域的专利。
|
||||
|
||||
DXR的核心设计目标是提供硬件加速的光线追踪能力,让开发者能够在可交互的帧率下实现全局光照、反射、阴影等高级渲染效果。作为DirectX 12 Ultimate的一部分,DXR现已得到业界广泛支持,包括NVIDIA、AMD、Intel在内的主流GPU厂商都提供了兼容的驱动程序。
|
||||
|
||||
### 1.2 DXR核心组件架构
|
||||
|
||||
DXR的技术架构由几个关键组件构成,每个组件都在光线追踪流程中扮演着不可或缺的角色:
|
||||
|
||||
**Acceleration Structure(加速结构)** 是DXR中最核心的数据结构。加速结构是一种层次化的边界体积层次(BVH),用于在GPU上高效地组织场景几何体数据。它将场景中的三角形组织成树形结构,使得光线与场景的求交测试可以从O(n)降低到O(log n)的复杂度。DXR支持两种类型的加速结构:Top-Level AS(TLAS)用于组织多个Bottom-Level AS,可以高效处理动态场景中的对象更新;Bottom-Level AS(BLAS)用于组织单个几何体的三角形数据。这种双层设计允许开发者仅更新发生变化的对象对应的BLAS,而无需重建整个场景的加速结构,这对于实时应用至关重要。
|
||||
|
||||
**Shader Table(着色器表)** 是DXR中用于将光线追踪管道中的各种着色器与场景对象关联起来的数据结构。Shader Table本质上是一个包含着色器标识符和着色器参数的GPU缓冲区,开发者可以通过它为不同的几何体指定不同的材质属性、反射特性或自定义着色器逻辑。这种设计使得DXR具有高度的灵活性,能够支持复杂多样的材质和渲染效果。
|
||||
|
||||
**Ray Dispatch(光线调度)** 是发起光线追踪计算的操作。通过DispatchRays,开发者可以指定光线生成着色器(Ray Generation Shader)的入口点,以及光线追踪管道的各项参数。GPU会根据这些配置启动大量的光线追踪计算单元,每个计算单元会执行相应的着色器代码来完成光线与场景的求交测试。
|
||||
|
||||
**Pipeline State Object(管道状态对象)** 定义了光线追踪管道的完整配置,包括各种着色器(光线生成着色器、命中着色器、未命中着色器、相交着色器)的编译状态,以及管道配置参数如最大递归深度等。
|
||||
|
||||
### 1.3 DXR着色器类型与光线追踪管道
|
||||
|
||||
DXR定义了一套专用的着色器类型来支持完整的光线追踪流程,每种着色器都有其特定的职责:
|
||||
|
||||
**Ray Generation Shader(光线生成着色器)** 是光线追踪管道的起点,通常每个像素或每个采样点发射一条光线。开发者可以在此着色器中实现相机光线生成、抖动采样、反锯齿等逻辑。
|
||||
|
||||
**Intersection Shader(相交着色器)** 用于处理非三角形几何体的求交测试。通过自定义相交着色器,开发者可以实现程序化几何体(如球体、圆锥体)、体素数据或其他自定义图元的光线求交逻辑。这一功能对于体积渲染尤为重要,因为它允许直接在加速结构中表示体数据。
|
||||
|
||||
**AnyHit Shader(任意命中着色器)** 在光线与几何体求交时被调用,可用于执行透明材质测试、Alpha遮罩剔除等操作。DXR 1.1版本引入了更高效的Opacity Micromaps技术,可以硬件加速Alpha测试几何体的处理。
|
||||
|
||||
**ClosestHit Shader(最近命中着色器)** 当光线命中几何体时执行,通常用于计算表面的着色属性如漫反射、镜面反射、材质纹理查询等。
|
||||
|
||||
**Miss Shader(未命中着色器)** 当光线未命中任何几何体时执行,常用于实现环境映射、天空盒渲染或雾效等效果。
|
||||
|
||||
### 1.4 DXR版本演进与最新特性
|
||||
|
||||
自首次发布以来,DXR经历了多个版本的演进,持续引入新功能以提升光线追踪的效率和能力:
|
||||
|
||||
DXR 1.0版本奠定了基础架构,提供了核心的光线追踪能力。从DXR 1.1开始,Microsoft引入了内联光线追踪(Inline Raytracing)功能,允许在普通计算着色器中直接调用TraceRay函数,而无需完整的射线追踪管道。这为混合渲染方案打开了大门,开发者可以在传统光栅化渲染中局部使用光线追踪来增强特定效果。
|
||||
|
||||
DXR 1.2版本(2025年GDC大会上发布)带来了多项重要更新:**Shader Execution Reordering(SER)** 允许应用层向GPU提供光线执行顺序的提示,使硬件能够更好地并行化光线执行,对于处理非相干光线(如间接照明)特别有效,NVIDIA在《Alan Wake 2》中的演示显示该技术可减少约三分之一的光线追踪开销。**Opacity Micromaps(OMMs)** 为Alpha测试几何体提供了硬件加速支持,使得树木、栅栏等复杂透明几何体的光线追踪更加高效。此外还有**打孔板(Per-primitive)着色器标识符**和**可加载管道**等改进。
|
||||
|
||||
## 二、DXR与体积渲染的兼容性分析
|
||||
|
||||
### 2.1 体积渲染概述
|
||||
|
||||
体积渲染是一种用于渲染具有体积属性的介质(如云、雾、烟、火、人体组织等)的技术。与传统基于表面的渲染不同,体积渲染需要考虑光线在穿过介质时的吸收、发射和散射现象。典型的体积渲染算法包括Ray Marching(光线步进)、体光线投射(Volume Ray Casting)和基于物理的体积散射等。
|
||||
|
||||
体积渲染的核心挑战在于处理可能占据整个空间的无边界介质,以及需要在光线穿过的每个位置进行采样和累积计算的特性。这些特性使得体积渲染在计算上极为密集,特别适合GPU并行处理。
|
||||
|
||||
### 2.2 DXR对体积渲染的原生支持程度
|
||||
|
||||
DXR本身并未为体积渲染提供专门的API或内置支持,但通过其灵活的扩展机制,开发者完全可以在DXR框架内实现体积渲染功能。关键在于如何有效地将体积数据表示为DXR可以处理的形式。
|
||||
|
||||
从架构角度看,DXR的Intersection Shader机制是实现体积渲染的核心。开发者可以编写自定义的相交着色器来处理体数据的求交测试,或者更常见地,使用程序化几何体(Procedural Geometry)来表示体积边界,然后结合Ray Marching在ClosestHit或Miss着色器中执行体积采样。
|
||||
|
||||
另一种常见方案是将体积渲染与传统的表面光线追踪相结合:使用DXR处理场景中的实体几何体(提供反射、阴影、全局光照等效果),而使用Compute Shader处理体积效果。这种混合方法在游戏开发中尤为常见,可以在视觉质量和性能之间取得良好平衡。
|
||||
|
||||
值得注意的是,NVIDIA在其RTX技术栈中提供了**Volumetric Fog**(体积雾)解决方案,这可以被视为DXR生态中体积渲染的一个参考实现。该方案利用硬件加速的VDB体素数据处理能力,实现了高效的体积雾效果。
|
||||
|
||||
### 2.3 在DXR中实现体积渲染的技术路径
|
||||
|
||||
在DXR框架内实现体积渲染主要有以下几种技术路径:
|
||||
|
||||
**基于Intersection Shader的体数据求交**:通过编写自定义的相交着色器,可以直接在加速结构中表示体数据的边界。相交着色器负责计算光线与体数据边界盒的交点,并返回光线进入和离开体积的位置。随后可以在ClosestHit着色器中执行Ray Marching来累积体积属性。
|
||||
|
||||
**基于Procedural Geometry的程序化体积**:将程序化几何体添加到加速结构中,可以用于表示体积的边界表面。在ClosestHit着色器中,开发者可以实现更复杂的体积渲染逻辑,包括多层Ray Marching、体积光照计算等。
|
||||
|
||||
**混合渲染架构**:这是目前业界最常用的方法。使用DXR处理场景中的所有表面几何体,实现高质量的反射、阴影和全局光照;同时使用Compute Shader或Pixel Shader实现体积效果的渲染。这种方法可以充分利用DXR的硬件加速能力处理传统光线追踪效果,同时保持体积渲染的灵活性。
|
||||
|
||||
**内联光线追踪(Inline Raytracing)**:DXR 1.1引入的内联光线追踪允许在普通着色器中直接调用TraceRay函数,这为在Compute Shader中结合传统Ray Marching与DXR加速结构提供了便利。开发者可以使用内联光线追踪来查询场景中几何体的遮挡关系,用于体积渲染中的阴影计算等。
|
||||
|
||||
## 三、Acceleration Structure与NanoVDB的结合可能性
|
||||
|
||||
### 3.1 NanoVDB技术解析
|
||||
|
||||
NanoVDB是由NVIDIA开发的一种针对GPU优化的稀疏体素数据结构,最初作为OpenVDB的轻量级分支引入。NanoVDB的设计目标是提供高效的体数据存储和访问模式,特别适合GPU计算场景。
|
||||
|
||||
NanoVDB的核心特性包括:紧凑的内存布局采用分层结构,包括Root节点、Internal节点和Leaf节点,支持极高的空间稀疏性;GPU原生支持数据可以直接传输到GPU显存中而无需预处理或转换;多用途API支持访问密度值、法线、颜色等属性,适用于渲染和物理模拟等多种应用;快速的插入和删除操作支持动态体积数据的实时更新。
|
||||
|
||||
在渲染领域,NanoVDB被广泛用于体积云、烟雾、火焰等效果的实现。NVIDIA的Omniverse平台和多个游戏引擎都已集成了NanoVDB支持。
|
||||
|
||||
### 3.2 Acceleration Structure在体积渲染中的角色
|
||||
|
||||
DXR的Acceleration Structure本质上是针对三角形几何体优化的边界体积层次(BVH)结构。它通过层次化的包围盒组织来实现高效的光线-几何体求交。对于体积渲染数据,Acceleration Structure可以扮演以下角色:
|
||||
|
||||
**体积边界表示**:可以将体积数据的边界盒作为加速结构中的几何体添加进去。这样DXR可以快速判断光线是否穿过体积区域,避免对空白空间的无效采样。
|
||||
|
||||
**多层加速结构组合**:对于同时包含表面几何体和体积数据的复杂场景,可以分别构建表面几何体的加速结构和体积边界的加速结构,通过Top-Level AS将它们组合在一起。这种设计允许DXR同时处理表面光线追踪(反射、阴影)和体积效果。
|
||||
|
||||
**空间查询加速**:Acceleration Structure的空间查询能力可以被体积渲染利用。例如,可以使用加速结构来查询体积中的光照遮挡,或者用于体积阴影的计算。
|
||||
|
||||
### 3.3 NanoVDB与Acceleration Structure结合的技术方案
|
||||
|
||||
将NanoVDB与DXR的Acceleration Structure结合使用存在若干技术路径:
|
||||
|
||||
**方案一:NanoVDB作为纹理数据源,Acceleration Structure作为空间索引**
|
||||
|
||||
这是最直接的结合方式。在这种架构中,NanoVDB存储实际的体数据(密度、颜色、法线等),而DXR的Acceleration Structure用于快速空间查询。具体的实现流程如下:
|
||||
|
||||
首先,为场景中的表面几何体构建标准的Bottom-Level AS。其次,将体积边界(可以是简单的盒形或更复杂的凸包)作为程序化几何体添加到加速结构中。然后,在相应的着色器中,通过查询NanoVDB数据结构来获取体积属性:对于表面几何体,使用传统的着色器逻辑;对于体积边界,使用Ray Marching遍历NanoVDB数据结构进行采样累积。
|
||||
|
||||
这种方案的优点是充分利用了DXR的硬件光线追踪能力来处理场景几何体,同时NanoVDB提供了高效的体数据访问。缺点是体积边界需要预先定义,可能不够精确。
|
||||
|
||||
**方案二:完全基于Acceleration Structure的混合方法**
|
||||
|
||||
这种方法将所有渲染元素都纳入加速结构管理。对于表面几何体使用标准的三角形加速;对于体积数据,可以使用程序化几何体表示体积边界,或者使用Instance Buffer来引用体积区域。
|
||||
|
||||
体积渲染的计算完全在Compute Shader中执行,使用NanoVDB作为数据源。DXR的加速结构仅用于快速的光线-场景求交查询,例如计算体积中的太阳光遮挡或实现体积阴影。
|
||||
|
||||
这种方案的优点是架构清晰,体积渲染的灵活性不受限制。缺点是需要额外的工作来同步DXR加速结构和NanoVDB数据。
|
||||
|
||||
**方案三:基于内联光线追踪的深度集成**
|
||||
|
||||
DXR 1.1引入的内联光线追踪提供了更灵活的集成方案。开发者可以在Compute Shader中执行自定义的Ray Marching逻辑,同时使用TraceRay函数查询DXR加速结构来实现与场景几何体的交互(如体积阴影、间接光照等)。
|
||||
|
||||
具体实现时,在Compute Shader中为每个像素执行Ray Marching遍历NanoVDB数据;在Ray Marching的每个采样点,使用内联光线追踪查询场景几何体的遮挡情况,用于计算光照衰减;最终累积体积颜色和不透明度到输出缓冲区。
|
||||
|
||||
这种方案的优点是实现了DXR加速结构与NanoVDB的深度结合,可以产生更真实的体积渲染效果(包括体积阴影、多次散射等)。缺点是实现复杂度较高,需要处理两种渲染管道的同步和数据传递。
|
||||
|
||||
### 3.4 结合方案的性能考量
|
||||
|
||||
在设计NanoVDB与Acceleration Structure的结合方案时,以下性能因素需要重点考虑:
|
||||
|
||||
**加速结构构建成本**:DXR的Acceleration Structure构建(尤其是Bottom-Level AS)是一个相对昂贵的操作。对于动态场景,可能需要采用增量更新策略或使用Instance层级的变换更新来避免全量重建。
|
||||
|
||||
**内存占用**:NanoVDB和Acceleration Structure都会占用GPU显存。对于大规模场景,需要评估内存预算并可能采用流式加载策略。
|
||||
|
||||
**数据同步开销**:当体积数据或场景几何体发生变化时,需要确保NanoVDB数据和DXR加速结构保持一致。这可能需要额外的CPU端协调逻辑。
|
||||
|
||||
**GPU带宽**:体积渲染通常需要高频的体数据访问。NanoVDB的数据布局已经针对GPU访问进行了优化,但在设计结合方案时仍需注意减少不必要的数据传输。
|
||||
|
||||
## 四、DXR体积渲染vs传统Compute Shader Ray Marching对比分析
|
||||
|
||||
### 4.1 两种技术路径的概述
|
||||
|
||||
**DXR体积渲染方案**是指利用DXR API和硬件加速光线追踪能力来实现体积渲染效果。这种方案的核心思想是:使用Acceleration Structure组织场景几何体,使用DXR着色器(Ray Generation、ClosestHit、Miss等)执行光线追踪逻辑,在着色器中结合Ray Marching实现体积效果。
|
||||
|
||||
**传统Compute Shader Ray Marching方案**是指使用Compute Shader直接执行Ray Marching算法来渲染体积效果。这种方案完全在Compute Shader中实现光线与体积数据的求交和累积,不依赖DXR的光线追踪硬件。
|
||||
|
||||
### 4.2 性能对比分析
|
||||
|
||||
**光线生成与调度效率**:DXR方案具有显著优势。DXR的硬件光线调度器经过专门优化,可以高效地生成和分发大量光线。传统Compute Shader需要手动管理线程组织和光线调度,效率相对较低。特别是在处理大规模并行光线时,DXR的硬件加速优势更为明显。
|
||||
|
||||
**空间查询效率**:DXR的Acceleration Structure对于场景几何体的空间查询具有极高的效率。当体积渲染需要与场景几何体交互(如计算体积阴影、遮挡)时,DXR可以快速完成这些查询。传统Compute Shader通常需要使用额外的加速结构(如BVH库或网格结构)来实现类似功能,增加了开发复杂度。
|
||||
|
||||
**灵活性与控制**:Compute Shader方案具有更高的灵活性。开发者可以完全控制Ray Marching的每个步骤,包括步长策略、早停条件、采样模式等。DXR方案受到管道结构的限制,虽然提供了足够的灵活性,但在某些极端定制场景下可能不如Compute Shader自由。
|
||||
|
||||
**混合渲染支持**:DXR方案在混合渲染场景中具有天然优势。可以轻松地将体积渲染与反射、全局光照、软阴影等DXR原生效果结合。Compute Shader方案需要额外的工作来集成这些效果。
|
||||
|
||||
**内存效率**:Compute Shader方案通常具有更小的内存占用,因为它不需要维护Acceleration Structure等额外数据结构。DXR的加速结构虽然经过了优化,但仍然会占用可观的显存,特别是在大规模复杂场景中。
|
||||
|
||||
### 4.3 画质对比分析
|
||||
|
||||
**阴影质量**:DXR方案可以提供物理准确的体积阴影。通过硬件加速的光线追踪,可以实现高质量的软阴影和多次散射效果。Compute Shader方案需要手动实现阴影光线计算,虽然可以达成类似效果,但计算成本较高。
|
||||
|
||||
**全局光照集成**:DXR可以更容易地实现体积与全局光照的集成。例如,体积可以接收来自场景几何体的间接光照,这是DXR原生支持的能力。Compute Shader方案需要额外的计算来模拟间接光照。
|
||||
|
||||
**抗锯齿与降噪**:两种方案都需要处理采样不足导致的噪声问题。DXR可以使用硬件降噪器或NVIDIA的Optix降噪库。Compute Shader方案通常需要使用基于屏幕空间的降噪方法。
|
||||
|
||||
### 4.4 开发复杂度对比
|
||||
|
||||
**API复杂度**:DXR API相对复杂,需要理解Acceleration Structure构建、Shader Table配置、管道状态对象等概念。Compute Shader Ray Marching的实现更接近传统的图形编程模式,对有图形编程经验的开发者更加友好。
|
||||
|
||||
**调试工具支持**:DXR有专门的调试工具支持,包括PIX for Windows和DirectX Graphics Developer Debugger。Compute Shader的调试工具更为成熟。
|
||||
|
||||
**跨平台兼容性**:DXR仅在Windows平台可用(通过DirectX 12)。Compute Shader是DirectX 12和Vulkan都支持的功能,具有更好的跨平台潜力。
|
||||
|
||||
### 4.5 适用场景建议
|
||||
|
||||
**推荐使用DXR体积渲染的场景**:需要与场景几何体进行复杂交互的体积效果;需要同时实现反射、全局光照等DXR原生效果;目标平台仅为Windows且硬件支持DXR;对性能要求较高,需要利用硬件光线追踪加速。
|
||||
|
||||
**推荐使用Compute Shader Ray Marching的场景**:体积效果独立于场景几何体;需要高度定制化的Ray Marching策略;需要跨平台支持(Windows/Linux/macOS);项目已有成熟的Compute Shader渲染管线。
|
||||
|
||||
**混合方案建议**:对于大多数实际应用,推荐采用混合方案。使用DXR处理场景中的表面几何体和传统光线追踪效果,使用Compute Shader处理体积渲染。这种方案可以兼得两种技术的优势。
|
||||
|
||||
## 五、现有DXR体积渲染示例与项目调研
|
||||
|
||||
### 5.1 Microsoft官方DXR示例
|
||||
|
||||
Microsoft的DirectX-Graphics-Samples GitHub仓库提供了丰富的DXR学习资源。虽然官方示例主要聚焦于基础光线追踪功能,但其中包含的若干示例对于理解DXR体积渲染具有重要参考价值:
|
||||
|
||||
**D3D12RaytracingHelloWorld**:作为入门级示例,展示了DXR的基本设置流程,包括加速结构构建、Shader Table配置和光线调度。理解这个示例是开发更复杂渲染效果的基础。
|
||||
|
||||
**D3D12RaytracingProceduralGeometry**:展示了如何使用Intersection Shader实现程序化几何体。这一技术对于在DXR中实现体积渲染具有直接参考价值,因为程序化几何体可以用于表示体积边界。
|
||||
|
||||
**D3D12RaytracingRealTimeDenoisedAmbientOcclusion**:虽然聚焦于环境光遮罩,但展示了如何实现实时光线追踪降噪,这对于体积渲染中的噪声控制具有参考意义。
|
||||
|
||||
**D3D12RaytracingMiniEngineSample**:集成了DXR的MiniEngine示例,展示了更完整的渲染管线集成方案。
|
||||
|
||||
### 5.2 NVIDIA相关技术与示例
|
||||
|
||||
作为DXR硬件支持的主要推动者,NVIDIA提供了多个与体积渲染相关的技术和示例:
|
||||
|
||||
**NVIDIA RTX技术演示**:NVIDIA的官方RTX演示包含多个体积渲染相关的展示,如带有体积雾和云的效果场景。这些演示虽然不一定是开源的,但展示了RTX硬件在体积渲染方面的能力。
|
||||
|
||||
**GVF(Grand Vehicle Framework)**:NVIDIA开源的车辆渲染框架中包含了一些体积渲染的实现细节,可以作为参考。
|
||||
|
||||
**Omniverse平台**:NVIDIA的Omniverse平台支持基于NanoVDB的体积渲染。虽然这不是直接的DXR示例,但提供了NanoVDB与GPU渲染结合的最佳实践。
|
||||
|
||||
### 5.3 社区开源项目
|
||||
|
||||
GitHub上存在一些开发者社区实现的DXR相关项目,虽然专门针对体积渲染的完整开源项目较少,但以下项目具有参考价值:
|
||||
|
||||
**DXR-Projects**:一个收集DXR各种应用示例的仓库,包含反射、阴影、全局光照等效果的实现。
|
||||
|
||||
**WolvenKit**:一个开源的 Witcher 3 modding工具,其中包含对体积云效果的实现参考。
|
||||
|
||||
### 5.4 学术研究与论文
|
||||
|
||||
相关的学术研究也为DXR体积渲染提供了理论支持:
|
||||
|
||||
光线步进与光线追踪的混合渲染技术已有大量研究论文,这些论文提供了体积渲染与表面光线追踪结合的算法基础。
|
||||
|
||||
基于物理的体积散射模型研究为体积渲染的着色计算提供了理论基础。
|
||||
|
||||
### 5.5 商业引擎支持情况
|
||||
|
||||
主流游戏引擎对DXR体积渲染的支持状况如下:
|
||||
|
||||
**Unreal Engine 5**:UE5已全面支持DXR,包括体积雾、体积云等效果。Epic Games展示了使用DXR实现的高质量体积渲染效果。
|
||||
|
||||
**Unity HDRP**:Unity的High Definition Render Pipeline支持DXR和体积渲染。Unity的体积渲染实现可以作为理解体积渲染工程实践的参考。
|
||||
|
||||
这些商业引擎的实现虽然不开源,但其背后的技术原理和实现思路对开发自有DXR体积渲染系统具有重要参考价值。
|
||||
|
||||
## 六、可行性评估与建议
|
||||
|
||||
### 6.1 技术可行性评估
|
||||
|
||||
**DXR体积渲染的技术可行性:高**
|
||||
|
||||
基于前述分析,使用DXR实现体积渲染是完全可行的。核心原因包括:DXR提供了足够的API灵活性来支持体积渲染所需的自定义着色器逻辑;硬件加速的光线追踪可以显著提升体积渲染中与场景几何体交互的性能;NVIDIA等厂商的硬件和软件栈已经验证了DXR体积渲染的可行性。
|
||||
|
||||
**Acceleration Structure与NanoVDB结合的技术可行性:高**
|
||||
|
||||
两者结合的技术路径已经明确,多种实现方案都经过了理论验证。NVIDIA的Omniverse平台已经展示了类似的结合方案。这种结合可以产生高质量的体积渲染效果,同时保持与DXR生态的兼容性。
|
||||
|
||||
### 6.2 性能可行性评估
|
||||
|
||||
DXR体积渲染的性能表现取决于多种因素,包括硬件支持(RTX系列GPU具有专门的光线追踪硬件单元)、场景复杂度(加速结构构建和查询的开销)以及体积数据规模(NanoVDB的访问效率)。
|
||||
|
||||
在现代RTX GPU上,DXR体积渲染可以实现实时或接近实时的帧率。对于较旧的硬件或更复杂的场景,可能需要采用降采样、降噪或LOD策略来维持可交互的帧率。
|
||||
|
||||
### 6.3 开发成本评估
|
||||
|
||||
开发DXR体积渲染系统需要投入相当的开发资源:
|
||||
|
||||
**学习曲线**:需要理解DXR API、Acceleration Structure原理、HLSL光线追踪着色器编写等专业知识。
|
||||
|
||||
**开发时间**:根据项目复杂度,从头构建一个功能完整的DXR体积渲染系统可能需要数月的工作量。
|
||||
|
||||
**维护成本**:需要跟进DXR API的演进和硬件驱动程序的更新。
|
||||
|
||||
### 6.4 建议的技术路线
|
||||
|
||||
基于本次调研,对于VolumeRender项目的DXR体积渲染实现,提出以下建议:
|
||||
|
||||
**短期目标**:实现基础功能
|
||||
|
||||
- 首先在DXR框架下实现基本的体积渲染效果,使用简单的体积边界
|
||||
- 集成NanoVDB作为体数据源
|
||||
- 实现基本的体积光照和阴影计算
|
||||
|
||||
**中期目标**:优化与增强
|
||||
|
||||
- 实现基于Acceleration Structure的空间查询优化
|
||||
- 集成降噪算法提升画质
|
||||
- 优化加速结构更新策略支持动态场景
|
||||
|
||||
**长期目标**:完善与集成
|
||||
|
||||
- 实现完整的体积渲染效果链(云、雾、烟等)
|
||||
- 与场景的DXR光线追踪效果(反射、全局光照)深度集成
|
||||
- 针对不同硬件平台进行性能调优
|
||||
|
||||
### 6.5 风险与挑战
|
||||
|
||||
需要注意的风险和挑战包括:
|
||||
|
||||
**硬件兼容性**:DXR需要支持光线追踪的硬件(RTX系列或同等性能的AMD/Intel显卡)。对于较老的硬件或非RTX显卡,性能可能不理想。
|
||||
|
||||
**驱动稳定性**:DXR作为一个相对较新的API,驱动程序可能存在稳定性问题或兼容性问题。
|
||||
|
||||
**调试复杂性**:光线追踪着色器的调试比传统着色器更加复杂,需要借助专门的调试工具。
|
||||
|
||||
**生态系统变化**:DXR API和生态系统仍在快速发展中,需要持续跟进最新的技术发展。
|
||||
|
||||
## 七、结论
|
||||
|
||||
综合以上分析,DXR完全具备支持体积渲染的能力,并且与NanoVDB的结合在技术上是可行且有价值的。DXR体积渲染相对于传统Compute Shader Ray Marching在处理与场景几何体的交互时具有明显优势,但在完全自定义的体积效果实现上灵活性略低。
|
||||
|
||||
对于VolumeRender项目,建议采用混合渲染架构:利用DXR处理场景几何体的光线追踪效果,同时使用Compute Shader处理NanoVDB体积数据的渲染,两通过内联光线追踪或混合管道进行深度集成。这种方案可以在视觉效果和性能之间取得最佳平衡。
|
||||
|
||||
现有资源和示例虽不完全针对体积渲染,但提供了足够的技术基础来开发自定义的DXR体积渲染系统。建议在开发过程中参考Microsoft官方示例、NVIDIA技术文档以及商业引擎(如UE5)的实现思路。
|
||||
BIN
docs/plan/开题报告和任务书/任务书-王子文.docx
Normal file
BIN
docs/plan/开题报告和任务书/任务书-王子文.docx
Normal file
Binary file not shown.
131
docs/plan/开题报告和任务书/完整开题报告.md
Normal file
131
docs/plan/开题报告和任务书/完整开题报告.md
Normal file
@@ -0,0 +1,131 @@
|
||||
题 目 基于DirectX 12的NanoVDB体积特效实时渲染引擎
|
||||
英文题目 Real-time Rendering Engine for NanoVDB Volume Effects Based on DirectX 12
|
||||
|
||||
学生姓名 王子文 学号 2022302111081
|
||||
所在学院 计算机学院 专业 计算机科学与技术
|
||||
指导教师 肖春霞 职称 教授
|
||||
|
||||
课题简介
|
||||
|
||||
本课题研究基于DirectX 12图形API的NanoVDB稀疏体积数据实时渲染技术,旨在实现一个完整的体积特效渲染引擎。课题主要内容包括:搭建DirectX 12基础渲染框架;实现VDB文件的解析与GPU数据传输;设计基于Compute Shader的Ray Marching体积渲染算法,利用NanoVDB的空域跳过优化提升性能;集成DXR光线追踪技术实现体积阴影效果。研究方法采用文献调研、实验对比与迭代开发相结合的方式。预期成果为一个可交互的体积渲染引擎,能够实时加载并渲染VDB格式的体积数据,支持自由漫游相机和动态光照调节功能。该研究将NanoVDB数据格式与DirectX 12技术相结合,探索体积特效在游戏、VR/AR等实时应用场景中的技术实现方案。
|
||||
|
||||
一、选题目的和意义
|
||||
|
||||
1.1 选题背景
|
||||
随着游戏画质要求的不断提升以及虚拟现实、增强现实技术的快速发展,体积特效已经成为构建逼真虚拟世界不可或缺的核心元素。无论是电影中震撼的爆炸场景、游戏里弥漫的硝烟废墟,还是实时渲染中飘动的云层和雾气,这些效果的实现都离不开体积渲染技术的支撑。与传统的基于表面的渲染不同,体积渲染需要处理光线在介质内部的吸收、散射和自发光等复杂物理过程,其技术难度和计算开销都要高出数个量级。
|
||||
在工业界,OpenVDB已经成为存储和处理稀疏体积数据的标准格式而被广泛采用。然而,传统的高质量体积渲染严重依赖蒙特卡洛路径追踪等离线渲染技术,计算一帧往往需要数分钟甚至数小时,完全无法满足实时交互的需求。近年来,NVIDIA推出的NanoVDB通过线性化树结构大幅优化了GPU访问性能,使得稀疏体积数据在实时环境中的应用成为可能。但目前NanoVDB的官方支持主要面向CUDA生态,在Windows平台主流的DirectX 12环境下,缺乏成熟的开源实现方案,这正是本课题的研究切入点。
|
||||
|
||||
1.2 核心问题
|
||||
|
||||
本课题旨在实现NanoVDB稀疏体积数据在DirectX 12环境下的实时渲染,主要面临以下三个核心问题:
|
||||
|
||||
(1)NanoVDB数据结构的DirectX 12适配。NanoVDB采用线性化树结构优化GPU访问,但其设计主要面向CUDA生态。在DirectX 12环境下,需要重新设计资源管理方案,实现VDB文件的解析加载和GPU数据传输,同时保持NanoVDB原本的内存访问效率。
|
||||
|
||||
(2)体积渲染的性能与质量平衡。体积渲染需要在光线路径上进行密集采样计算,传统的Ray Marching算法计算量极大。如何利用NanoVDB的稀疏特性实现空域跳过,仅对含有效数据的区域进行采样,是实现实时渲染的关键技术难点。另外,体积介质中的光线传输涉及吸收、散射和自发光三种基本光学现象,其中散射的各向异性特性需要通过相位函数正确模拟。如何在保证实时性的前提下实现物理准确的着色模型,是渲染质量的核心保障。
|
||||
|
||||
(3)渲染引擎架构设计。一个完整的体积渲染引擎涉及窗口管理、图形初始化、资源调度、渲染管线、交互系统等多个模块。如何设计合理的分层架构,使各模块职责清晰、接口明确,便于后续的功能扩展和维护,是工程实现的重要问题。
|
||||
|
||||
1.3 解决思路
|
||||
|
||||
首先,在数据层面,深入分析NanoVDB的内存布局结构,设计适配DirectX 12的资源管理方案。通过研究VDB文件的存储格式,实现CPU端解析到GPU端数据结构的高效转换,构建可直接用于渲染的NanoVDB访问接口。
|
||||
|
||||
其次,在算法层面,以体积渲染方程为理论基础,在Compute Shader中实现Ray Marching体积光线投射算法。利用NanoVDB的内部索引结构实现空域跳过优化,在保证渲染质量的前提下大幅减少无效采样。着色模型方面,正确实现吸收、散射和自发光三种光学现象,其中散射采用Henyey-Greenstein相位函数处理各向异性散射效果。
|
||||
|
||||
最后,在扩展层面,集成DXR光线追踪技术实现体积阴影和场景遮挡计算。通过构建加速结构,利用硬件加速的光线追踪计算体积中的光照衰减,提升渲染效果的物理真实性和视觉表现力。
|
||||
|
||||
1.4 选题意义
|
||||
|
||||
本选题的意义在于:将NanoVDB稀疏体积数据与DirectX 12图形API相结合,探索实时体积渲染的技术实现方案,为体积特效在游戏、VR/AR等交互式场景中的应用提供技术参考;同时,通过完整的工程实践,加深对体积渲染核心算法的理解,提升图形编程能力。
|
||||
|
||||
二、国内外研究现状和发展趋势
|
||||
|
||||
2.1 体积渲染技术发展现状
|
||||
|
||||
体积渲染技术在计算机图形学领域有着悠久的历史,早在上世纪八十年代,Kajiya提出的渲染方程就为体积光照传输奠定了理论基础。进入二十一世纪后,随着GPU计算能力的飞速提升,实时体积渲染逐渐从理论走向实践。目前主流的实时体积渲染方案主要包括Ray Marching和体光线投射两类技术路线,前者通过在光线上进行固定步长采样来累积体积属性,后者则通过求交体积边界盒来优化采样区域。两种方案各有优劣,Ray Marching实现简单但计算量大,体光线投射效率高但需要额外的数据结构支持。
|
||||
在体积数据格式方面,OpenVDB自2012年由DreamWorks Animation开源以来,已经成为电影工业的事实标准。OpenVDB采用分级稀疏数据结构,可以高效地存储烟雾、火焰、云层等体积效果,但其在GPU上的访问效率较低。NVIDIA在2021年推出了NanoVDB,通过线性化树结构消除了指针依赖,大幅提升了GPU访问性能,成为实时渲染场景的理想选择。然而,NanoVDB官方主要提供CUDA接口,在DirectX 12和Vulkan等通用GPU API上的支持相对薄弱。
|
||||
|
||||
2.2 DirectX 12与光线追踪技术
|
||||
|
||||
DirectX 12是微软推出的新一代图形API,相比前代DirectX 11,它提供了更底层的GPU控制能力,允许开发者直接管理GPU资源分配和命令调度,从而最大化利用现代显卡的计算潜力。DirectX 12 Ultimate进一步引入了DXR(DirectX Raytracing)技术,使得实时光线追踪成为可能。DXR通过硬件加速的加速结构(Acceleration Structure)实现了高效的空间查询,已经在游戏和渲染领域得到广泛应用。
|
||||
在体积渲染领域,DXR的价值主要体现在两个方面。其一是加速体积与场景几何体的交互计算,如体积阴影、遮挡剔除等传统上需要额外处理的效果可以通过光线追踪自然地实现。其二是内联光线追踪(Inline Raytracing)功能的引入,使得在Compute Shader中调用TraceRay成为可能,为混合渲染架构提供了技术基础。UE5和Unity HDRP已经展示了DXR与体积渲染结合的潜力,但相关的开源实现仍然匮乏。
|
||||
|
||||
2.3 发展趋势
|
||||
|
||||
展望未来,体积渲染技术的发展趋势主要指向以下几个方向。首先是混合渲染架构的成熟,即结合光栅化、计算着色器和光线追踪各自的优势,在不同渲染阶段使用最适合的技术方案。其次是神经渲染技术与传统体积渲染的融合,NVIDIA提出的神经材质概念已经被拓展到体积领域,通过神经网络近似复杂的体积光照传输过程。第三是标准化和开放化的推进,随着更多开源项目的涌现,体积渲染技术的门槛将持续降低。
|
||||
|
||||
三、研究内容、研究方法、技术路线及可行性分析
|
||||
|
||||
3.1 研究内容
|
||||
|
||||
本课题的研究内容可以划分为五个主要模块。第一模块是DirectX 12基础框架的搭建,包括Win32窗口系统的实现、DirectX 12设备的初始化、命令队列和描述符堆的管理,以及基础渲染管线的建立。这一模块是整个系统的基础,需要确保GPU资源能够正确分配和调度。
|
||||
第二模块是NanoVDB数据管线的设计与实现。具体包括VDB文件的解析与加载、CPU到GPU的高效数据传输机制,以及在Compute Shader中访问NanoVDB数据的采样器实现。由于NanoVDB的数据结构较为复杂,需要深入理解其内存布局才能实现高效的GPU访问。
|
||||
第三模块是体积渲染核心算法的实现。核心是以体积渲染方程为背景,基于Compute Shader的Ray Marching算法,包括光线与体积包围盒的求交、基于NanoVDB的空域跳过优化、步进采样策略,以及物理着色模型的实现。物理着色模型需要正确处理吸收、散射和自发光三种光学现象,其中散射部分还要考虑相位函数的影响。
|
||||
第四模块是DXR光线追踪技术的集成。这一模块作为可选扩展,主要实现体积阴影的计算和场景遮挡查询。通过构建加速结构,可以利用硬件加速的光线追踪来计算体积中的光照衰减,使渲染效果更加真实。
|
||||
第五模块是交互系统的设计与实现,包括自由漫游相机的控制(支持WASD移动和鼠标视角调节)、动态光源的管理(支持位置、颜色、强度调节),以及基本的画面参数调整功能。这一模块决定了用户能否直观地体验渲染效果,是系统实用性的重要保障。
|
||||
|
||||
3.2 研究方法
|
||||
|
||||
本课题采用的研究方法主要包括文献研究法、实验对比法和迭代开发法三种。文献研究法贯穿整个研究过程,需要系统性地研读NanoVDB官方文档、DirectX 12编程指南、DXR技术规范,以及计算机图形学领域的经典论文,特别是体积渲染和光线追踪相关的资料。通过文献研究,可以充分了解现有技术的优缺点,为系统设计提供理论支撑。
|
||||
实验对比法主要用于评估不同实现方案的性能和画质差异。例如,在Ray Marching中,步长的大小直接影响渲染质量和运行速度,需要通过实验找到合理的平衡点。又如,空域跳过策略的设计也需要通过对照实验来验证其有效性。实验对比的方法可以避免主观臆断,使设计决策更加科学。
|
||||
迭代开发法是本课题的主要开发模式。由于渲染引擎涉及多个相互依赖的模块,不可能一次性完成所有设计,因此采用快速原型、迭代完善的方式进行开发。首先实现一个最小可用的版本,验证核心技术路线可行后再逐步添加新功能。这种开发方式可以及早发现问题并调整方向,降低开发风险。
|
||||
|
||||
3.3 技术路线
|
||||
|
||||
整个课题的技术路线可以分为六个阶段推进。第一阶段是准备阶段,时间安排在第一周到第二周,主要完成文献调研、需求分析和系统架构设计,输出物是一份详细的设计文档,明确各模块的接口和数据流。
|
||||
第二阶段是基础框架开发,时间安排在第三周到第四周。这一阶段的目标是搭建起DirectX 12的运行环境和最基本的渲染管线。具体的交付物是一个可以正常显示窗口并完成清屏渲染的最小系统。这一阶段的难点在于理解DirectX 12的资源模型和命令提交机制。
|
||||
第三阶段是数据管线开发,时间安排在第五周到第六周。这一阶段要实现VDB文件的加载器和GPU数据传输机制。由于NanoVDB的数据结构较为复杂,需要仔细研究其存储格式,设计合理的数据转换和传输流程。交付物是能够成功加载标准VDB文件并在GPU端访问的测试程序。
|
||||
第四阶段是渲染核心开发,时间安排在第七周到第十周。这是整个课题最核心的部分,需要实现完整的Ray Marching渲染管线。包括光线与体积的求交算法、基于NanoVDB的空域跳过优化、不同类型光源的照度计算,以及最终的体积累积逻辑。这一阶段的交付物是一个能够渲染基本体积效果的完整渲染管线。
|
||||
第五阶段是交互系统开发,时间安排在第十一周到第十二周。在渲染管线的基础上添加相机控制、光照调节和参数UI等交互功能。这一阶段的重点是用户体验的优化,要确保操作流畅、反馈及时。
|
||||
第六阶段是优化收尾,时间安排在第十三周到第十六周。主要进行性能优化、功能完善和测试验收,最后撰写毕业设计说明书。性能优化可能包括分辨率缩放、降采样、混合精度等技术手段,需要根据实际情况灵活选择。
|
||||
|
||||
3.4 可行性分析
|
||||
|
||||
本课题在技术上可行。从硬件条件来看,实验室配备的RTX系列显卡完全支持DirectX 12和DXR的全部功能,可以满足开发需求。从软件基础来看,NanoVDB已经开源并提供了详细的文档,DirectX 12的编程接口也有丰富的教程和参考代码可供学习。从理论基础来看,体积渲染的核心算法已经有成熟的理论支撑,Ray Marching的实现也有大量开源项目可供参考。
|
||||
|
||||
四、项目特色与创新点
|
||||
|
||||
4.1 跨平台技术迁移
|
||||
|
||||
本课题的首要特色在于将NanoVDB在DirectX 12环境中实现实时渲染。NanoVDB虽然在NVIDIA的推动下逐渐成为行业标准,但其官方实现主要面向CUDA编程模型,在DirectX 12环境下的适配工作需要开发者自行完成。本课题将深入研究NanoVDB的内存布局,设计适配DirectX 12的资源管理方案,实现GPU端的高效数据访问。这一工作本身具有一定的技术创新性,可以为后续研究者提供参考。
|
||||
|
||||
4.2 分层架构设计
|
||||
|
||||
在系统架构层面,本课题采用分层设计思想,将整个引擎划分为应用层、引擎层、渲染层和数据层四个层次。应用层负责用户交互和业务逻辑,引擎层提供窗口管理、资源调度等通用功能,渲染层专注于图形管线的实现,数据层处理文件解析和数据传输。这种分层架构的好处是各层职责明确,便于独立开发和测试,同时也为后续的功能扩展留出了空间。渲染层还实现了后端抽象,可以支持Compute Shader和DXR两种不同的渲染方案。
|
||||
|
||||
4.3 混合渲染思路
|
||||
|
||||
在渲染技术上,本课题尝试结合Compute Shader和DXR的混合渲染思路。Compute Shader负责体积数据的采样和累积,这是其擅长的计算密集型任务;DXR则用于体积阴影和场景遮挡的计算,利用硬件加速提升查询效率。这种混合方案可以在保证渲染质量的同时提升整体性能,是未来渲染引擎发展的主流方向。
|
||||
|
||||
4.4 完整的工程实现
|
||||
|
||||
本课题的目标是一个完整可用的工程系统,而非单纯的算法验证。这意味着不仅需要关注渲染效果的优劣,还要考虑代码的组织结构、模块的接口设计、错误处理机制、参数的可配置性和用户交互体验等工程实践问题。交付的代码将遵循良好的编码规范,关键模块配有详细注释,可以作为学习渲染引擎开发的参考资料。
|
||||
|
||||
五、进度安排
|
||||
|
||||
第1-2周: 国内外文献调研,明确需求,完成系统架构设计,撰写开题报告。
|
||||
第3-4周: 搭建DirectX 12开发环境,实现Win32窗口系统和基础渲染管线。
|
||||
第5-6周: 研究NanoVDB数据结构,实现VDB文件加载器和GPU数据传输模块。
|
||||
第7-8周: 实现Compute Shader Ray Marching核心算法,完成基础体积渲染功能。
|
||||
第9-10周: 优化渲染管线,实现空域跳过和物理着色模型,完善渲染质量。
|
||||
第11-12周: 开发交互系统,实现自由相机漫游和动态光照控制功能。
|
||||
第13-14周: 性能调优和测试,完善功能,撰写毕业设计说明书初稿。
|
||||
第15-16周: 论文修改定稿,准备答辩演示,进行项目验收。
|
||||
|
||||
六、主要参考文献
|
||||
|
||||
\[1] Museth K. NanoVDB: A GPU-Friendly and Portable VDB Data Structure for Real-Time Rendering and Simulation\[J]. ACM Transactions on Graphics, 2021, 40(4): 1-16.
|
||||
|
||||
\[2] NVIDIA. Accelerating OpenVDB on GPUs with NanoVDB\[EB/OL]. NVIDIA Developer Blog, 2021.
|
||||
|
||||
\[3] Microsoft. DirectX 12 Graphics Programming Guide\[EB/OL]. Microsoft Docs, 2024.
|
||||
|
||||
\[4] Microsoft. DirectX Raytracing (DXR) Technical Specification\[EB/OL]. Microsoft Docs, 2024.
|
||||
|
||||
\[5] Kajiya J F. The Rendering Equation\[J]. Computer Graphics, 1986, 20(4): 143-150.
|
||||
|
||||
\[6] Max N. Efficient Light Propagation for Multiple Anisotropic Scattering in Semi-Transparent Media\[J]. Journal of Graphics Tools, 1995, 2(3): 21-32.
|
||||
|
||||
\[7] Wihlidal C. Optimizing the Graphics Pipeline with Compute\[C]//Game Developers Conference 2019, 2019.
|
||||
|
||||
\[8] Clarberg P, Hasselgren T, Toth R, et al. Real-time Neural Appearance Models\[C]//SIGGRAPH 2023, 2023.
|
||||
|
||||
3
docs/plan/开题报告和任务书/开题报告-王子文.doc
Normal file
3
docs/plan/开题报告和任务书/开题报告-王子文.doc
Normal file
File diff suppressed because one or more lines are too long
3
docs/plan/旧版题目/开题报告-王子文.doc
Normal file
3
docs/plan/旧版题目/开题报告-王子文.doc
Normal file
File diff suppressed because one or more lines are too long
180
docs/plan/旧版题目/开题报告-王子文.md
Normal file
180
docs/plan/旧版题目/开题报告-王子文.md
Normal file
@@ -0,0 +1,180 @@
|
||||
\# 武汉大学本科毕业设计(论文)开题报告
|
||||
|
||||
| 项目 | 信息 |
|
||||
|
||||
| ---- | ---- |
|
||||
|
||||
| 题 目 | 神经着色驱动的VDB特效实时渲染 |
|
||||
|
||||
| 学生姓名 | 王子文 |
|
||||
|
||||
| 学号 | 2022302111081 |
|
||||
|
||||
| 所在学院 | 计算机学院 |
|
||||
|
||||
| 专业 | 计算机科学与技术 |
|
||||
|
||||
| 指导教师 | 肖春霞 |
|
||||
|
||||
| 职称 | 教授 |
|
||||
|
||||
|
||||
|
||||
\## 一、选题目的和意义
|
||||
|
||||
\### 1.1 选题背景
|
||||
|
||||
3D渲染技术正经历着从传统的“基于物理的建模(Physically Based Rendering, PBR)”向“神经网络渲染(Neural Rendering)”的范式转变。神经网络渲染融合了机器学习与计算机图形学,利用深度神经网络高效拟合复杂的光线传输过程,能够在不依赖繁重物理积分的情况下逼近真实世界的视觉效果。
|
||||
|
||||
|
||||
|
||||
在这一背景下,体积特效(Volumetric Effects)如烟雾、火焰、云层和爆炸等,作为构建逼真虚拟世界的关键元素,其渲染技术的革新尤为迫切。目前,工业界主要采用 OpenVDB 格式来存储和处理这些复杂的稀疏体积数据。然而,传统的高质量体积渲染严重依赖于蒙特卡洛路径追踪(Monte Carlo Path Tracing),其计算复杂度极高,往往需要数分钟甚至数小时才能渲染一帧,这限制了其在实时交互应用(如游戏、VR/AR)中的使用。
|
||||
|
||||
|
||||
|
||||
\### 1.2 核心问题
|
||||
|
||||
随着硬件性能的提升,原本用于离线影视级渲染的 VDB 数据,正逐渐向游戏引擎等实时渲染环境迁移。然而,这一迁移过程面临巨大挑战。现有的实时体积渲染方案(如 Ray Marching)通常为了性能而牺牲画质,难以复现离线渲染中复杂的光照效果(如多次散射、各向异性散射)。同时,高精度的 VDB 数据占用的显存空间巨大,难以在消费级显卡上流畅运行。如何兼顾“电影级画质”与“实时帧率”,同时降低存储开销,是实现这一行业迁移的关键难题。
|
||||
|
||||
|
||||
|
||||
\### 1.3 解决思路与意义
|
||||
|
||||
本课题旨在借鉴 NVIDIA “神经材质(Neural Materials)” 的核心思想,并将其创新性地应用于体积(Volume)渲染领域。通过构建一个轻量级的神经网络(神经体积着色器),将复杂的体积光传输计算(Radiative Transfer)“烘焙”到网络权重中。
|
||||
|
||||
|
||||
|
||||
本选题的意义在于:
|
||||
|
||||
突破性能瓶颈:利用神经网络(MLP)强大的拟合能力替代复杂的物理积分计算,结合 Tensor Core 硬件加速,实现体积特效的实时推理渲染。
|
||||
|
||||
提升实时画质:使实时引擎能够呈现原本仅存于离线渲染中的复杂光照细节,推动游戏画质向电影级迈进。
|
||||
|
||||
|
||||
|
||||
\## 二、国内外研究现状和发展趋势
|
||||
|
||||
\### 2.1 稀疏体积数据结构(OpenVDB \& NanoVDB)
|
||||
|
||||
OpenVDB(Museth, 2013)是电影工业的标准体积格式,但在 GPU 上运行效率较低。NVIDIA 推出的 NanoVDB(Museth, 2021)通过线性化树结构优化了 GPU 访问性能,成为实时渲染的理想载体。然而,NanoVDB 仅解决了“数据存储与访问”的问题,并未解决“光照计算复杂”的问题。
|
||||
|
||||
|
||||
|
||||
\### 2.2 神经渲染与神经着色(Neural Rendering \& Shading)
|
||||
|
||||
近年来,神经辐射场(NeRF, Mildenhall et al., 2020)展示了神经网络在视图合成上的强大能力。然而,当前大多数神经渲染方法仍依赖图像输入,缺乏对原始几何和物理材质信息的显式支持,这种“黑盒”特性限制了其在标准图形管线中的集成与编辑。
|
||||
|
||||
|
||||
|
||||
针对这一问题,NVIDIA 的 Neural Materials(Rainier et al., 2022; Clarberg et al., 2023)提出了一种新范式:将复杂的表面材质模型压缩为小型 MLP,在着色器中实时运行。这种方法在保留影视级材质细节的同时,实现了 10 倍以上的性能提升和纹理压缩。
|
||||
|
||||
|
||||
|
||||
\### 2.3 发展趋势
|
||||
|
||||
目前的趋势是将“神经材质”的成功经验从“表面(Surface)”向“体积(Volume)”拓展。即利用 NanoVDB 的稀疏结构来跳过空白区域(Space Skipping),利用神经网络来近似非线性的体积属性映射(Neural Shading)。这种结合了“显式结构加速”与“隐式计算加速”的混合管线,是未来实时渲染的重要方向。
|
||||
|
||||
|
||||
|
||||
\## 三、研究内容、研究方法、技术路线及可行性分析
|
||||
|
||||
\### 3.1 研究内容
|
||||
|
||||
NanoVDB 数据管线构建:研究 OpenVDB 到 NanoVDB 的转换流程,实现稀疏体积数据在 GPU 上的高效加载与采样。
|
||||
|
||||
神经体积着色器(Neural Volume Shader)设计:设计一个轻量级的 MLP 网络,用于替代传统的体积着色方程。
|
||||
|
||||
输入:归一化空间坐标 (x,y,z)、视线方向、光照方向 、以及 NanoVDB 采样的基础属性(密度、温度等)。
|
||||
|
||||
输出:物理光学参数,包括吸收系数、散射系数、自发光辐射率和相位函数参数。
|
||||
|
||||
混合监督训练策略:构建基于物理的损失函数,结合 L1/L2 图像损失与物理约束(如能量守恒),确保网络输出不仅视觉逼真,且符合物理规律。
|
||||
|
||||
Unity 实时渲染集成:在 Unity 引擎中编写 Compute Shader 或利用 TensorRT,将训练好的网络集成到渲染管线中,实现实时交互。
|
||||
|
||||
|
||||
|
||||
\### 3.2 研究方法
|
||||
|
||||
文献研究法:深入研读 NanoVDB 源码及 Neural Materials 相关论文。
|
||||
|
||||
实验对比法:以 Houdini + Arnold 渲染结果为 Ground Truth(真值),对比本方法与传统 Ray Marching 的画质差异(PSNR/SSIM)及帧率表现。
|
||||
|
||||
控制变量法:探究网络层数、通道数对渲染质量与推理速度的影响。
|
||||
|
||||
|
||||
|
||||
\### 3.3 技术路线
|
||||
|
||||
数据准备:使用 Houdini 制作烟雾/火焰特效,导出 .vdb 文件;使用 Arnold 渲染多角度、多光照条件下的高质图像作为训练集。
|
||||
|
||||
预处理:将 .vdb 转换为 .nvdb 格式,提取稀疏体素特征。
|
||||
|
||||
模型训练 (PyTorch):
|
||||
|
||||
构建 MLP 网络(如 4层 x 64宽)。
|
||||
|
||||
利用 CUDA 加速的 NanoVDB 采样器进行射线步进采样。
|
||||
|
||||
计算预测值与 GT 的损失,反向传播更新权重。
|
||||
|
||||
引擎部署 (Unity):
|
||||
|
||||
将训练好的权重导出为二进制或 ONNX。
|
||||
|
||||
在 Unity Shader 中实现 MLP 推理逻辑(前向传播)。
|
||||
|
||||
结合 NanoVDB 的光线求交(Ray Casting)进行实时渲染。
|
||||
|
||||
|
||||
|
||||
\### 3.4 可行性分析
|
||||
|
||||
硬件支持:实验室配备 RTX 系列显卡,支持 Tensor Core 加速和 CUDA 编程。
|
||||
|
||||
软件基础:NanoVDB 已开源且支持 C++/CUDA;PyTorch 框架成熟;Unity 支持 Compute Shader 自定义渲染。
|
||||
|
||||
理论支撑:辐射传输方程(RTE)理论成熟,Neural Materials 已验证了 MLP 拟合着色方程的可行性。
|
||||
|
||||
|
||||
|
||||
\## 四、项目特色与创新点
|
||||
|
||||
跨域技术迁移(创新性):将 NVIDIA Neural Materials 在“表面材质”上的成功范式,迁移创新至“体积渲染”领域,提出“神经体积着色器”概念。
|
||||
|
||||
稀疏-神经混合架构与几何解耦:结合 NanoVDB 的“空间稀疏性”与神经网络的“计算紧凑性”,不仅实现了存储与计算的双重优化,更实现了几何结构(NanoVDB)与外观材质(Neural Shader)的解耦。这解决了传统神经渲染方法难以编辑几何形状的痛点,支持在保持几何不变的情况下调整材质,或在保持材质风格的情况下修改几何。
|
||||
|
||||
物理可解释性:网络输出的是中间光学参数(如散射系数)而非最终像素颜色,这使得渲染结果可以与动态光照环境交互(Relighting),保留了物理着色的灵活性。
|
||||
|
||||
|
||||
|
||||
\## 五、进度安排
|
||||
|
||||
第1-2周:查阅文献,熟悉 NanoVDB 数据结构与 PyTorch 框架,完成开题报告。
|
||||
|
||||
第3-4周:搭建 Houdini 数据生成管线,制作数据集,完成 VDB 到 NanoVDB 的转换测试。
|
||||
|
||||
第5-8周:设计并实现神经体积着色器网络,在 PyTorch 中完成训练与验证,优化损失函数。
|
||||
|
||||
第9-12周:将训练好的模型集成至 Unity 引擎,编写实时渲染 Shader,进行性能调优。
|
||||
|
||||
第13-14周:撰写毕业论文,整理实验数据与对比结果。
|
||||
|
||||
第15-16周:论文修改定稿,准备答辩演示。
|
||||
|
||||
|
||||
|
||||
\## 六、主要参考文献
|
||||
|
||||
1\. Museth, K. (2021). NanoVDB: A GPU-Friendly and Portable VDB Data Structure For Real-Time Rendering And Simulation. ACM Transactions on Graphics (TOG), 40(4).
|
||||
|
||||
2\. Lombardi, S., et al. (2019). Neural Volumes: Learning Dynamic Renderable Volumes from Images. ACM Transactions on Graphics (TOG), 38(4).
|
||||
|
||||
3\. Rainier, G., et al. (2022). Neural Materials: Unified Spectral Rendering of Layered Materials. Computer Graphics Forum.
|
||||
|
||||
4\. Clarberg, P., et al. (2023). Real-time Neural Appearance Models. SIGGRAPH 2023.
|
||||
|
||||
5\. Mildenhall, B., et al. (2020). NeRF: Representing Scenes as Neural Radiance Fields for View Synthesis. ECCV.
|
||||
|
||||
6\. NVIDIA. RTX Neural Shaders \& Neural Materials SDK Documentation.
|
||||
|
||||
1309
docs/plan/深入方向规划.md
Normal file
1309
docs/plan/深入方向规划.md
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user