Add volume renderer extraction stage 5

This commit is contained in:
2026-04-08 20:12:14 +08:00
parent c6815fa809
commit b839fd98af
14 changed files with 906 additions and 7 deletions

View File

@@ -5,8 +5,10 @@
#include <XCEngine/Components/LightComponent.h>
#include <XCEngine/Components/MeshFilterComponent.h>
#include <XCEngine/Components/MeshRendererComponent.h>
#include <XCEngine/Components/VolumeRendererComponent.h>
#include <XCEngine/Core/Asset/IResource.h>
#include <XCEngine/Core/Math/Color.h>
#include <XCEngine/Core/Math/Bounds.h>
#include <XCEngine/Core/Math/Quaternion.h>
#include <XCEngine/Core/Math/Vector3.h>
#include <XCEngine/Rendering/Builtin/BuiltinPassContract.h>
@@ -18,6 +20,7 @@
#include <XCEngine/Resources/Mesh/Mesh.h>
#include <XCEngine/Resources/Shader/Shader.h>
#include <XCEngine/Resources/Texture/Texture.h>
#include <XCEngine/Resources/Volume/VolumeField.h>
#include <XCEngine/Scene/Scene.h>
#include <string>
@@ -96,6 +99,24 @@ Material* CreateTestMaterial(const char* path, int32_t renderQueue) {
return material;
}
VolumeField* CreateTestVolumeField(const char* path) {
auto* volumeField = new VolumeField();
IResource::ConstructParams params = {};
params.name = "TestVolume";
params.path = path;
params.guid = ResourceGUID::Generate(path);
volumeField->Initialize(params);
const unsigned char payload[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
EXPECT_TRUE(volumeField->Create(
VolumeStorageKind::NanoVDB,
payload,
sizeof(payload),
Bounds(Vector3::Zero(), Vector3(2.0f, 2.0f, 2.0f)),
Vector3(0.25f, 0.25f, 0.25f)));
return volumeField;
}
Texture* CreateTestTexture(const char* path, TextureType type) {
auto* texture = new Texture();
IResource::ConstructParams params = {};
@@ -372,6 +393,81 @@ TEST(RenderSceneExtractor_Test, FiltersVisibleItemsByCameraCullingMask) {
delete hiddenMesh;
}
TEST(RenderSceneExtractor_Test, ExtractsVisibleVolumesAndSortsByRenderQueue) {
Scene scene("VolumeScene");
GameObject* cameraObject = scene.CreateGameObject("Camera");
auto* camera = cameraObject->AddComponent<CameraComponent>();
camera->SetPrimary(true);
camera->SetCullingMask(1u << 0);
GameObject* opaqueVolumeObject = scene.CreateGameObject("OpaqueVolume");
opaqueVolumeObject->SetLayer(0);
opaqueVolumeObject->GetTransform()->SetLocalPosition(Vector3(0.0f, 0.0f, 2.0f));
auto* opaqueVolumeRenderer = opaqueVolumeObject->AddComponent<VolumeRendererComponent>();
VolumeField* opaqueVolume = CreateTestVolumeField("Volumes/opaque.nvdb");
Material* opaqueMaterial = CreateTestMaterial(
"Materials/opaque_volume.mat",
static_cast<int32_t>(MaterialRenderQueue::Geometry));
opaqueVolumeRenderer->SetVolumeField(opaqueVolume);
opaqueVolumeRenderer->SetMaterial(opaqueMaterial);
GameObject* transparentVolumeObject = scene.CreateGameObject("TransparentVolume");
transparentVolumeObject->SetLayer(0);
transparentVolumeObject->GetTransform()->SetLocalPosition(Vector3(0.0f, 0.0f, 8.0f));
auto* transparentVolumeRenderer = transparentVolumeObject->AddComponent<VolumeRendererComponent>();
VolumeField* transparentVolume = CreateTestVolumeField("Volumes/transparent.nvdb");
Material* transparentMaterial = CreateTestMaterial(
"Materials/transparent_volume.mat",
static_cast<int32_t>(MaterialRenderQueue::Transparent));
transparentVolumeRenderer->SetVolumeField(transparentVolume);
transparentVolumeRenderer->SetMaterial(transparentMaterial);
GameObject* hiddenVolumeObject = scene.CreateGameObject("HiddenVolume");
hiddenVolumeObject->SetLayer(2);
auto* hiddenVolumeRenderer = hiddenVolumeObject->AddComponent<VolumeRendererComponent>();
VolumeField* hiddenVolume = CreateTestVolumeField("Volumes/hidden.nvdb");
Material* hiddenMaterial = CreateTestMaterial(
"Materials/hidden_volume.mat",
static_cast<int32_t>(MaterialRenderQueue::Geometry));
hiddenVolumeRenderer->SetVolumeField(hiddenVolume);
hiddenVolumeRenderer->SetMaterial(hiddenMaterial);
RenderSceneExtractor extractor;
const RenderSceneData sceneData = extractor.Extract(scene, nullptr, 800, 600);
ASSERT_TRUE(sceneData.HasCamera());
EXPECT_TRUE(sceneData.visibleItems.empty());
ASSERT_EQ(sceneData.visibleVolumes.size(), 2u);
EXPECT_EQ(sceneData.visibleVolumes[0].gameObject, opaqueVolumeObject);
EXPECT_EQ(sceneData.visibleVolumes[0].volumeRenderer, opaqueVolumeRenderer);
EXPECT_EQ(sceneData.visibleVolumes[0].volumeField, opaqueVolume);
EXPECT_EQ(sceneData.visibleVolumes[0].material, opaqueMaterial);
EXPECT_EQ(sceneData.visibleVolumes[0].renderQueue, static_cast<int32_t>(MaterialRenderQueue::Geometry));
EXPECT_EQ(sceneData.visibleVolumes[0].localToWorld.GetTranslation(), Vector3(0.0f, 0.0f, 2.0f));
EXPECT_EQ(sceneData.visibleVolumes[1].gameObject, transparentVolumeObject);
EXPECT_EQ(sceneData.visibleVolumes[1].volumeRenderer, transparentVolumeRenderer);
EXPECT_EQ(sceneData.visibleVolumes[1].volumeField, transparentVolume);
EXPECT_EQ(sceneData.visibleVolumes[1].material, transparentMaterial);
EXPECT_EQ(sceneData.visibleVolumes[1].renderQueue, static_cast<int32_t>(MaterialRenderQueue::Transparent));
EXPECT_EQ(sceneData.visibleVolumes[1].localToWorld.GetTranslation(), Vector3(0.0f, 0.0f, 8.0f));
opaqueVolumeRenderer->ClearVolumeField();
opaqueVolumeRenderer->ClearMaterial();
transparentVolumeRenderer->ClearVolumeField();
transparentVolumeRenderer->ClearMaterial();
hiddenVolumeRenderer->ClearVolumeField();
hiddenVolumeRenderer->ClearMaterial();
delete opaqueVolume;
delete opaqueMaterial;
delete transparentVolume;
delete transparentMaterial;
delete hiddenVolume;
delete hiddenMaterial;
}
TEST(RenderSceneExtractor_Test, ExtractsSectionLevelVisibleItemsAndSortsByRenderQueue) {
Scene scene("SectionScene");