重构D3D12集成测试目录结构,每个测试独立子文件夹隔离资源

This commit is contained in:
2026-03-20 16:33:35 +08:00
parent 33e9958751
commit dba3dc23f2
16 changed files with 254 additions and 297 deletions

View File

@@ -1,224 +0,0 @@
# D3D12 测试改进计划
## 一、当前状态
### 1.1 已完成
| 阶段 | 内容 | 状态 |
|------|------|------|
| Phase 0 | 单元测试框架搭建 (54 tests) | ✅ 完成 |
| Phase 1 | 集成测试注册到 CTest | ✅ 完成 |
### 1.2 测试统计
```
单元测试: 54 tests (全部通过)
集成测试: 2 tests (D3D12_Minimal_Integration ✅, D3D12_RenderModel_Integration 待修复)
```
### 1.3 目录结构
```
tests/RHI/D3D12/
├── unit/
│ ├── CMakeLists.txt
│ ├── fixtures/D3D12TestFixture.h
│ └── test_*.cpp # 54 tests
└── integration/
├── CMakeLists.txt # 已注册 CTest
├── main_minimal.cpp # D3D12_Minimal_Integration
├── main_render.cpp # D3D12_RenderModel_Integration (有API问题)
├── run_integration_test.py
├── compare_ppm.py
├── GT.ppm # RenderModel 用
└── GT_minimal.ppm # Minimal 用
```
---
## 二、Phase 2: 测试命名规范化
### 2.1 目标
将测试命名统一为 `Component_Category_SubBehavior` 格式。
### 2.2 当前命名问题
| 当前名称 | 问题 |
|---------|------|
| `D3D12TestFixture.Buffer_Placeholder` | "Placeholder" 无意义 |
| `D3D12TestFixture.Buffer_CreateDefaultHeap` | 格式不统一 |
| `D3D12TestFixture.CommandQueue_ExecuteCommandList` | 未用下划线分隔 |
### 2.3 目标格式
```
Component_Category_SubBehavior
```
| 部分 | 说明 | 示例 |
|------|------|------|
| Component | 被测组件 | Device, Buffer, Texture, CommandQueue |
| Category | 操作类别 | Create, Get, Set, Map, Reset |
| SubBehavior | 具体行为 | DefaultHeap, UploadHeap, GPUAddress |
### 2.4 重命名规则
#### 规则 1: 组件名称标准化
| 当前 | 规范 |
|------|------|
| D3D12TestFixture | Device, Buffer, Texture... (直接用组件名) |
#### 规则 2: 操作类别标准化
| Category | 说明 | 示例 |
|----------|------|------|
| Create | 创建资源 | Buffer_Create, Texture_Create |
| Get | 获取属性 | Device_GetAdapterInfo |
| Set | 设置属性 | Buffer_SetName |
| Map | 内存映射 | Buffer_MapUnmap |
| Reset | 重置状态 | CommandAllocator_Reset |
#### 规则 3: Placeholder 测试
所有 `*_Placeholder` 测试应:
- 删除(如果只验证对象存在)
- 或改为有意义的验证测试
### 2.5 具体重命名方案
#### Buffer tests (6 → 5, 删除 Placeholder)
| 当前名称 | 建议名称 |
|---------|---------|
| Buffer_Placeholder | (删除) |
| Buffer_CreateDefaultHeap | Buffer_Create_DefaultHeap |
| Buffer_CreateUploadHeap | Buffer_Create_UploadHeap |
| Buffer_GetGPUAddress | Buffer_Get_GPUAddress |
| Buffer_MapUnmap | Buffer_Map_Unmap |
| Buffer_AlignmentRequirements | Buffer_Get_AlignmentRequirements |
#### Texture tests (5 → 5)
| 当前名称 | 建议名称 |
|---------|---------|
| Texture_Placeholder | (删除或改为 Texture_Create_2D) |
| Texture_Create2D | Texture_Create_2D |
| Texture_Create3D | Texture_Create_3D |
| Texture_CreateMultipleMips | Texture_Create_MultipleMips |
| Texture_CreateTextureArray | Texture_Create_Array |
#### CommandAllocator tests (4 → 3)
| 当前名称 | 建议名称 |
|---------|---------|
| CommandAllocator_Placeholder | (删除) |
| CommandAllocator_Reset | CommandAllocator_Reset_Basic |
| CommandAllocator_ResetMultiple | CommandAllocator_Reset_Multiple |
| CommandAllocator_DifferentTypes | CommandAllocator_Create_DifferentTypes |
#### 其他组件类似处理...
### 2.6 实施步骤
1. **批量重命名测试用例** (test_*.cpp)
2. **更新 fixtures/D3D12TestFixture.h** (如有必要)
3. **运行测试验证**
4. **更新文档**
### 2.7 CMake 配置
无需修改,测试名称不影响构建。
---
## 三、Phase 3: 错误路径测试
### 3.1 目标
添加负面测试,验证错误处理。
### 3.2 建议测试用例
```cpp
// Device 错误测试
Device_Create_NullAdapter // 无效适配器
Device_Create_InvalidFeatureLevel // 不支持的功能级别
// Buffer 错误测试
Buffer_Create_ZeroSize // 零大小
Buffer_Create_OverflowSize // 超出限制大小
// Texture 错误测试
Texture_Create_ZeroDimension // 零尺寸
Texture_Create_InvalidFormat // 无效格式
// CommandList 错误测试
CommandList_Close_WithoutRecord // 未录制就关闭
CommandList_Reset_WhileRecording // 录制中重置
```
---
## 四、Phase 4: Golden Image 扩展
### 4.1 目标
为更多集成测试场景添加 Golden Template。
### 4.2 建议添加
| 场景 | Golden Template | 阈值 |
|------|----------------|------|
| 2D 渲染测试 | GT_render_2d.ppm | 5% |
| 深度测试 | GT_depth_test.ppm | 5% |
| 混合模式测试 | GT_blend.ppm | 5% |
---
## 五、Phase 5: CI 集成
### 5.1 目标
创建跨平台测试运行脚本。
### 5.2 建议结构
```bash
scripts/
└── run_tests.py # 统一测试入口
```
### 5.3 功能需求
- 自动检测平台 (Windows/Linux)
- 运行单元测试
- 运行集成测试 (可选,需 GUI)
- 生成测试报告
- 支持 CI 环境
---
## 六、优先级和排期
| Phase | 优先级 | 估计工作量 | 说明 |
|-------|--------|----------|------|
| Phase 2 | P1 | 中 | 纯重命名,无代码逻辑变更 |
| Phase 3 | P1 | 高 | 需设计错误注入方案 |
| Phase 4 | P2 | 中 | 需手动生成 Golden Images |
| Phase 5 | P2 | 低 | 主要是脚本工作 |
---
## 七、待解决问题
1. **D3D12_RenderModel_Integration** - main_render.cpp API 不兼容,需修复
2. **GUI 集成测试** - CTest 无法直接运行 Win32 GUI 程序 (已用 Python wrapper 解决)
3. **Golden Image 更新流程** - 如何在硬件差异时更新 GT
---
**文档版本**: 1.0
**更新日期**: 2026-03-20
**当前阶段**: Phase 1 完成,等待 Phase 2 开始

View File

@@ -86,7 +86,37 @@ protected:
## 3. 集成测试规范
### 3.1 Python Wrapper
### 3.1 目录结构
每个集成测试独占一个子文件夹,资源相互隔离:
```
integration/
├── CMakeLists.txt # 构建配置
├── run_integration_test.py # 公共测试运行脚本
├── compare_ppm.py # PPM 图像比对脚本
├── run.bat # Windows 启动脚本
├── minimal/ # 最小化测试
│ ├── main.cpp
│ ├── GT_minimal.ppm
│ └── Res/
│ └── Shader/
│ ├── ndctriangle.hlsl
│ └── gs.hlsl
├── render_model/ # 模型渲染测试
│ ├── main.cpp
│ ├── GT.ppm
│ └── Res/
│ ├── Image/
│ ├── Model/
│ └── Shader/
└── triangle/ # 三角形渲染测试 (待实现)
├── main.cpp
├── GT_triangle.ppm
└── Res/
```
### 3.2 Python Wrapper
**位置**: `tests/RHI/D3D12/integration/run_integration_test.py`
@@ -97,44 +127,42 @@ protected:
4. 调用 `compare_ppm.py` 比对 Golden Image
5. 返回 0(成功)/1(失败)
### 3.2 CTest 注册格式
### 3.3 CTest 注册格式
```cmake
find_package(Python3 REQUIRED)
enable_testing()
add_test(NAME D3D12_Minimal_Integration
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/run_integration_test.py
COMMAND ${Python3_EXECUTABLE} $<TARGET_FILE_DIR:D3D12_Minimal>/run_integration_test.py
$<TARGET_FILE:D3D12_Minimal>
minimal.ppm
${CMAKE_CURRENT_SOURCE_DIR}/GT_minimal.ppm
${CMAKE_CURRENT_SOURCE_DIR}/minimal/GT_minimal.ppm
5
WORKING_DIRECTORY $<TARGET_FILE_DIR:D3D12_Minimal>
)
```
### 3.3 Golden Image 规范
### 3.4 Golden Image 规范
| 属性 | 值 |
|------|-----|
| 格式 | PPM (P6) |
| 命名 | `GT_<test_name>.ppm` |
| 阈值 | 默认 5% |
| 存储位置 | `tests/RHI/D3D12/integration/` |
| 存储位置 | `tests/RHI/D3D12/integration/<test_name>/` |
### 3.4 Golden Image 生成流程
### 3.5 Golden Image 生成流程
1. 在干净硬件环境运行集成测试
2. 截图保存为 `GT_<name>.ppm`
3. 人工验证截图正确性
4. 提交到版本控制
### 3.5 当前集成测试
### 3.6 当前集成测试
| 测试名 | Golden Image | 状态 |
|--------|-------------|------|
| D3D12_Minimal_Integration | GT_minimal.ppm | ✅ 通过 |
| D3D12_RenderModel_Integration | GT.ppm | ❌ 待修复 |
| D3D12_Minimal_Integration | `minimal/GT_minimal.ppm` | ✅ 通过 |
| D3D12_RenderModel_Integration | `render_model/GT.ppm` | ❌ 待修复 |
| D3D12_Triangle_Integration | `triangle/GT_triangle.ppm` | 🔄 待实现 |
---
@@ -166,7 +194,7 @@ ctest -C Debug --output-on-failure
```bash
# 构建
cmake --build . --target d3d12_engine_tests D3D12_Minimal --config Debug
cmake --build . --target D3D12_Minimal D3D12_RenderModel --config Debug
# 运行测试
python scripts/run_tests.py --build
@@ -192,7 +220,7 @@ jobs:
run: cmake -B build -DCMAKE_BUILD_TYPE=Debug
- name: Build D3D12 Tests
run: cmake --build build --target d3d12_engine_tests D3D12_Minimal --config Debug
run: cmake --build build --target D3D12_Minimal D3D12_RenderModel --config Debug
- name: Run Unit Tests
run: cd build/tests/RHI/D3D12/unit && ctest -C Debug --output-on-failure
@@ -227,19 +255,34 @@ tests/RHI/D3D12/
│ └── ...
└── integration/
├── CMakeLists.txt
├── main_minimal.cpp
├── main_render.cpp # 有 API 问题,待修复
├── run_integration_test.py
├── compare_ppm.py
├── GT.ppm
── GT_minimal.ppm
├── run_integration_test.py # 公共脚本
├── compare_ppm.py # 公共脚本
├── run.bat # 公共脚本
├── minimal/ # 测试子文件夹
│ ├── main.cpp
│ ├── GT_minimal.ppm
│ └── Res/
├── render_model/ # 测试子文件夹
│ ├── main.cpp # 有 API 问题,待修复
│ ├── GT.ppm
│ └── Res/
└── triangle/ # 测试子文件夹 (待实现)
├── main.cpp
├── GT_triangle.ppm
└── Res/
engine/
└── third_party/
└── stb/ # stb 图像库
├── stb_image.h
└── stb_image.cpp
```
---
## 7. 已知问题
### 7.1 main_render.cpp API 不兼容
### 7.1 render_model API 不兼容
**问题**: `D3D12Buffer::Initialize``D3D12Screenshot::Capture` API 签名变更
@@ -255,9 +298,10 @@ tests/RHI/D3D12/
|------|------|------|
| 1.0 | 2026-03-20 | 初始版本 |
| 1.1 | 2026-03-20 | 添加 CI 集成章节,补充 Phase 5 内容 |
| 1.2 | 2026-03-20 | 重构集成测试目录结构每个测试独立子文件夹stb 库移至 engine/third_party/stb/ |
---
**规范版本**: 1.1
**规范版本**: 1.2
**最后更新**: 2026-03-20
**前置文档**: [tests/TEST_SPEC.md](../TEST_SPEC.md)
**前置文档**: [tests/TEST_SPEC.md](../TEST_SPEC.md)

View File

@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.15)
project(D3D12_Integration)
set(ENGINE_ROOT_DIR ${CMAKE_SOURCE_DIR}/../engine)
set(ENGINE_ROOT_DIR ${CMAKE_SOURCE_DIR}/engine)
find_package(Python3 REQUIRED)
@@ -11,12 +11,11 @@ enable_testing()
# Minimal test - just verifies initialization and render loop
add_executable(D3D12_Minimal
WIN32
main_minimal.cpp
minimal/main.cpp
)
target_include_directories(D3D12_Minimal PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/stbi
${CMAKE_CURRENT_SOURCE_DIR}/minimal
${ENGINE_ROOT_DIR}/include
)
@@ -25,12 +24,6 @@ target_compile_definitions(D3D12_Minimal PRIVATE
_UNICODE
)
target_include_directories(D3D12_Minimal PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${ENGINE_ROOT_DIR}/third_party
${ENGINE_ROOT_DIR}/include
)
target_link_libraries(D3D12_Minimal PRIVATE
d3d12
dxgi
@@ -42,14 +35,13 @@ target_link_libraries(D3D12_Minimal PRIVATE
# Render model test - complete rendering with model, shader, texture
add_executable(D3D12_RenderModel
WIN32
main_render.cpp
${CMAKE_CURRENT_SOURCE_DIR}/stbi/stb_image.cpp
render_model/main.cpp
)
target_include_directories(D3D12_RenderModel PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/stbi
${CMAKE_CURRENT_SOURCE_DIR}/render_model
${ENGINE_ROOT_DIR}/include
${ENGINE_ROOT_DIR}
)
target_compile_definitions(D3D12_RenderModel PRIVATE
@@ -57,12 +49,6 @@ target_compile_definitions(D3D12_RenderModel PRIVATE
_UNICODE
)
target_include_directories(D3D12_RenderModel PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${ENGINE_ROOT_DIR}/third_party
${ENGINE_ROOT_DIR}/include
)
target_link_libraries(D3D12_RenderModel PRIVATE
d3d12
dxgi
@@ -74,71 +60,58 @@ target_link_libraries(D3D12_RenderModel PRIVATE
# Copy Res folder to output directory for Minimal test
add_custom_command(TARGET D3D12_Minimal POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_CURRENT_SOURCE_DIR}/Res
$<TARGET_FILE_DIR:D3D12_Minimal>/Res
${CMAKE_CURRENT_SOURCE_DIR}/minimal/Res
$<TARGET_FILE_DIR:D3D12_Minimal>/Res
)
# Copy Res folder to output directory for RenderModel test
add_custom_command(TARGET D3D12_RenderModel POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_CURRENT_SOURCE_DIR}/Res
$<TARGET_FILE_DIR:D3D12_RenderModel>/Res
${CMAKE_CURRENT_SOURCE_DIR}/render_model/Res
$<TARGET_FILE_DIR:D3D12_RenderModel>/Res
)
# Copy test scripts to output directory for Minimal test
add_custom_command(TARGET D3D12_Minimal POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_SOURCE_DIR}/run.bat
$<TARGET_FILE_DIR:D3D12_Minimal>/run.bat
$<TARGET_FILE_DIR:D3D12_Minimal>/
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_SOURCE_DIR}/compare_ppm.py
$<TARGET_FILE_DIR:D3D12_Minimal>/compare_ppm.py
$<TARGET_FILE_DIR:D3D12_Minimal>/
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_SOURCE_DIR}/GT.ppm
$<TARGET_FILE_DIR:D3D12_Minimal>/GT.ppm
${CMAKE_CURRENT_SOURCE_DIR}/run_integration_test.py
$<TARGET_FILE_DIR:D3D12_Minimal>/
)
# Copy test scripts to output directory for RenderModel test
add_custom_command(TARGET D3D12_RenderModel POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_SOURCE_DIR}/run.bat
$<TARGET_FILE_DIR:D3D12_RenderModel>/run.bat
$<TARGET_FILE_DIR:D3D12_RenderModel>/
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_SOURCE_DIR}/compare_ppm.py
$<TARGET_FILE_DIR:D3D12_RenderModel>/compare_ppm.py
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_SOURCE_DIR}/GT.ppm
$<TARGET_FILE_DIR:D3D12_RenderModel>/GT.ppm
)
# Copy run_integration_test.py to output directories
add_custom_command(TARGET D3D12_Minimal POST_BUILD
$<TARGET_FILE_DIR:D3D12_RenderModel>/
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_SOURCE_DIR}/run_integration_test.py
$<TARGET_FILE_DIR:D3D12_Minimal>/run_integration_test.py
)
add_custom_command(TARGET D3D12_RenderModel POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_SOURCE_DIR}/run_integration_test.py
$<TARGET_FILE_DIR:D3D12_RenderModel>/run_integration_test.py
$<TARGET_FILE_DIR:D3D12_RenderModel>/
)
# Register integration tests with CTest
add_test(NAME D3D12_Minimal_Integration
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/run_integration_test.py
COMMAND ${Python3_EXECUTABLE} $<TARGET_FILE_DIR:D3D12_Minimal>/run_integration_test.py
$<TARGET_FILE:D3D12_Minimal>
minimal.ppm
${CMAKE_CURRENT_SOURCE_DIR}/GT_minimal.ppm
${CMAKE_CURRENT_SOURCE_DIR}/minimal/GT_minimal.ppm
5
WORKING_DIRECTORY $<TARGET_FILE_DIR:D3D12_Minimal>
)
add_test(NAME D3D12_RenderModel_Integration
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/run_integration_test.py
COMMAND ${Python3_EXECUTABLE} $<TARGET_FILE_DIR:D3D12_RenderModel>/run_integration_test.py
$<TARGET_FILE:D3D12_RenderModel>
screenshot.ppm
${CMAKE_CURRENT_SOURCE_DIR}/GT.ppm
${CMAKE_CURRENT_SOURCE_DIR}/render_model/GT.ppm
5
WORKING_DIRECTORY $<TARGET_FILE_DIR:D3D12_RenderModel>
)

View File

Before

Width:  |  Height:  |  Size: 189 KiB

After

Width:  |  Height:  |  Size: 189 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -0,0 +1,99 @@
struct VertexData{
float4 position:POSITION;
float4 texcoord:TEXCOORD0;
float4 normal:NORMAL;
float4 tangent:TANGENT;
};
struct VSOut{
float4 position:SV_POSITION;
float4 normal:NORMAL;
float4 texcoord:TEXCOORD0;
};
static const float PI=3.141592;
cbuffer globalConstants:register(b0){
float4 misc;
};
Texture2D T_DiffuseTexture:register(t0);
SamplerState samplerState:register(s0);
struct MaterialData{
float r;
};
StructuredBuffer<MaterialData> materialData:register(t0,space1);
cbuffer DefaultVertexCB:register(b1){
float4x4 ProjectionMatrix;
float4x4 ViewMatrix;
float4x4 ModelMatrix;
float4x4 IT_ModelMatrix;
float4x4 ReservedMemory[1020];
};
VSOut MainVS(VertexData inVertexData){
VSOut vo;
vo.normal=mul(IT_ModelMatrix,inVertexData.normal);
float4 positionWS=mul(ModelMatrix,inVertexData.position);
float4 positionVS=mul(ViewMatrix,positionWS);
vo.position=mul(ProjectionMatrix,positionVS);
//vo.position=float4(positionWS.xyz+vo.normal.xyz*sin(misc.x)*0.2f,1.0f);
vo.texcoord=inVertexData.texcoord;
return vo;
}
[maxvertexcount(4)]
void MainGS(triangle VSOut inPoint[3],uint inPrimitiveID:SV_PrimitiveID,
inout TriangleStream<VSOut> outTriangleStream){
outTriangleStream.Append(inPoint[0]);
outTriangleStream.Append(inPoint[1]);
outTriangleStream.Append(inPoint[2]);
/*VSOut vo;
float3 positionWS=inPoint[0].position.xyz;
float3 N=normalize(inPoint[0].normal.xyz);
vo.normal=float4(N,0.0f);
float3 helperVec=abs(N.y)>0.999?float3(0.0f,0.0f,1.0f):float3(0.0f,1.0f,0.0f);
float3 tangent=normalize(cross(N,helperVec));//u
float3 bitangent=normalize(cross(tangent,N));//v
float scale=materialData[inPrimitiveID].r;
float3 p0WS=positionWS-(bitangent*0.5f-tangent*0.5f)*scale;//left bottom
float4 p0VS=mul(ViewMatrix,float4(p0WS,1.0f));
vo.position=mul(ProjectionMatrix,p0VS);
vo.texcoord=float4(0.0f,1.0f,0.0f,0.0f);
outTriangleStream.Append(vo);
float3 p1WS=positionWS-(bitangent*0.5f+tangent*0.5f)*scale;//right bottom
float4 p1VS=mul(ViewMatrix,float4(p1WS,1.0f));
vo.position=mul(ProjectionMatrix,p1VS);
vo.texcoord=float4(1.0f,1.0f,0.0f,0.0f);
outTriangleStream.Append(vo);
float3 p2WS=positionWS+(bitangent*0.5f+tangent*0.5f)*scale;//left top
float4 p2VS=mul(ViewMatrix,float4(p2WS,1.0f));
vo.position=mul(ProjectionMatrix,p2VS);
vo.texcoord=float4(0.0f,0.0f,0.0f,0.0f);
outTriangleStream.Append(vo);
float3 p3WS=positionWS+(bitangent*0.5f-tangent*0.5f)*scale;//right top
float4 p3VS=mul(ViewMatrix,float4(p3WS,1.0f));
vo.position=mul(ProjectionMatrix,p3VS);
vo.texcoord=float4(1.0f,0.0f,0.0f,0.0f);
outTriangleStream.Append(vo);*/
}
float4 MainPS(VSOut inPSInput):SV_TARGET{
float3 N=normalize(inPSInput.normal.xyz);
float3 bottomColor=float3(0.1f,0.4f,0.6f);
float3 topColor=float3(0.7f,0.7f,0.7f);
float theta=asin(N.y);//-PI/2 ~ PI/2
theta/=PI;//-0.5~0.5
theta+=0.5f;//0.0~1.0
float ambientColorIntensity=1.0;
float3 ambientColor=lerp(bottomColor,topColor,theta)*ambientColorIntensity;
float4 diffuseColor=T_DiffuseTexture.Sample(samplerState,inPSInput.texcoord.xy);
float3 surfaceColor=diffuseColor.rgb;
return float4(surfaceColor,1.0f);
}

View File

@@ -0,0 +1,65 @@
struct VertexData{
float4 position:POSITION;
float4 texcoord:TEXCOORD0;
float4 normal:NORMAL;
float4 tangent:TANGENT;
};
struct VSOut{
float4 position:SV_POSITION;
float4 normal:NORMAL;
float4 texcoord:TEXCOORD0;
float4 positionWS:TEXCOORD1;
};
static const float PI=3.141592;
cbuffer globalConstants:register(b0){
float4 misc;
};
cbuffer DefaultVertexCB:register(b1){
float4x4 ProjectionMatrix;
float4x4 ViewMatrix;
float4x4 ModelMatrix;
float4x4 IT_ModelMatrix;
float4x4 ReservedMemory[1020];
};
VSOut MainVS(VertexData inVertexData){
VSOut vo;
vo.normal=mul(IT_ModelMatrix,inVertexData.normal);
float3 positionMS=inVertexData.position.xyz+vo.normal*sin(misc.x);
float4 positionWS=mul(ModelMatrix,float4(positionMS,1.0));
float4 positionVS=mul(ViewMatrix,positionWS);
vo.position=mul(ProjectionMatrix,positionVS);
vo.positionWS=positionWS;
vo.texcoord=inVertexData.texcoord;
return vo;
}
float4 MainPS(VSOut inPSInput):SV_TARGET{
float3 N=normalize(inPSInput.normal.xyz);
float3 bottomColor=float3(0.1f,0.4f,0.6f);
float3 topColor=float3(0.7f,0.7f,0.7f);
float theta=asin(N.y);//-PI/2 ~ PI/2
theta/=PI;//-0.5~0.5
theta+=0.5f;//0.0~1.0
float ambientColorIntensity=0.2;
float3 ambientColor=lerp(bottomColor,topColor,theta)*ambientColorIntensity;
float3 L=normalize(float3(1.0f,1.0f,-1.0f));
float diffuseIntensity=max(0.0f,dot(N,L));
float3 diffuseLightColor=float3(0.1f,0.4f,0.6f);
float3 diffuseColor=diffuseLightColor*diffuseIntensity;
float3 specularColor=float3(0.0f,0.0f,0.0f);
if(diffuseIntensity>0.0f){
float3 cameraPositionWS=float3(0.0f,0.0f,0.0f);
float3 V=normalize(cameraPositionWS.xyz-inPSInput.positionWS.xyz);
float3 R=normalize(reflect(-L,N));
float specularIntensity=pow(max(0.0f,dot(V,R)),128.0f);
specularColor=float3(1.0f,1.0f,1.0f)*specularIntensity;
}
float3 surfaceColor=ambientColor+diffuseColor+specularColor;
return float4(surfaceColor,1.0f);
}

View File

@@ -31,7 +31,7 @@
#include "XCEngine/Debug/ConsoleLogSink.h"
#include "XCEngine/Debug/FileLogSink.h"
#include "XCEngine/Containers/String.h"
#include "stbi/stb_image.h"
#include "third_party/stb/stb_image.h"
using namespace XCEngine::RHI;
using namespace XCEngine::Debug;