Extract bounded additional scene lights

This commit is contained in:
2026-04-05 15:55:48 +08:00
parent 2c96f0d164
commit 18f53bd920
6 changed files with 555 additions and 93 deletions

View File

@@ -182,6 +182,101 @@ TEST(RenderSceneExtractor_Test, ExtractsBrightestDirectionalLightAsMainLight) {
EXPECT_EQ(
sceneData.lighting.mainDirectionalLight.direction,
mainLightObject->GetTransform()->GetForward().Normalized() * -1.0f);
ASSERT_EQ(sceneData.lighting.additionalLightCount, 2u);
EXPECT_EQ(sceneData.lighting.additionalLights[0].type, RenderLightType::Directional);
EXPECT_FLOAT_EQ(sceneData.lighting.additionalLights[0].intensity, 0.5f);
EXPECT_EQ(sceneData.lighting.additionalLights[1].type, RenderLightType::Point);
EXPECT_FLOAT_EQ(sceneData.lighting.additionalLights[1].intensity, 10.0f);
}
TEST(RenderSceneExtractor_Test, ExtractsAdditionalLightsWithoutMainDirectionalAndFiltersByLightCullingMask) {
Scene scene("AdditionalLightsScene");
GameObject* cameraObject = scene.CreateGameObject("Camera");
auto* camera = cameraObject->AddComponent<CameraComponent>();
camera->SetPrimary(true);
camera->SetCullingMask(1u << 3);
GameObject* hiddenSpotObject = scene.CreateGameObject("HiddenSpot");
hiddenSpotObject->SetLayer(0);
auto* hiddenSpot = hiddenSpotObject->AddComponent<LightComponent>();
hiddenSpot->SetLightType(LightType::Spot);
hiddenSpot->SetIntensity(100.0f);
hiddenSpot->SetRange(50.0f);
hiddenSpot->SetSpotAngle(60.0f);
hiddenSpotObject->GetTransform()->SetLocalPosition(Vector3(0.0f, 0.0f, 1.0f));
GameObject* visiblePointObject = scene.CreateGameObject("VisiblePoint");
visiblePointObject->SetLayer(3);
auto* visiblePoint = visiblePointObject->AddComponent<LightComponent>();
visiblePoint->SetLightType(LightType::Point);
visiblePoint->SetColor(Color(0.9f, 0.2f, 0.1f, 1.0f));
visiblePoint->SetIntensity(4.0f);
visiblePoint->SetRange(12.0f);
visiblePointObject->GetTransform()->SetLocalPosition(Vector3(0.0f, 0.0f, 4.0f));
GameObject* visibleSpotObject = scene.CreateGameObject("VisibleSpot");
visibleSpotObject->SetLayer(3);
auto* visibleSpot = visibleSpotObject->AddComponent<LightComponent>();
visibleSpot->SetLightType(LightType::Spot);
visibleSpot->SetColor(Color(0.1f, 0.8f, 0.4f, 1.0f));
visibleSpot->SetIntensity(3.0f);
visibleSpot->SetRange(8.0f);
visibleSpot->SetSpotAngle(48.0f);
visibleSpotObject->GetTransform()->SetLocalPosition(Vector3(0.0f, 0.0f, 2.0f));
visibleSpotObject->GetTransform()->SetLocalRotation(
Quaternion::LookRotation(Vector3(0.0f, 0.0f, -1.0f)));
RenderSceneExtractor extractor;
const RenderSceneData sceneData = extractor.Extract(scene, nullptr, 800, 600);
EXPECT_FALSE(sceneData.lighting.HasMainDirectionalLight());
ASSERT_TRUE(sceneData.lighting.HasAdditionalLights());
ASSERT_EQ(sceneData.lighting.additionalLightCount, 2u);
const RenderAdditionalLightData& spotLight = sceneData.lighting.additionalLights[0];
EXPECT_EQ(spotLight.type, RenderLightType::Spot);
EXPECT_EQ(spotLight.color.g, 0.8f);
EXPECT_EQ(spotLight.position, Vector3(0.0f, 0.0f, 2.0f));
EXPECT_EQ(spotLight.direction, Vector3(0.0f, 0.0f, 1.0f));
EXPECT_FLOAT_EQ(spotLight.range, 8.0f);
EXPECT_FLOAT_EQ(spotLight.spotAngle, 48.0f);
const RenderAdditionalLightData& pointLightData = sceneData.lighting.additionalLights[1];
EXPECT_EQ(pointLightData.type, RenderLightType::Point);
EXPECT_EQ(pointLightData.color.r, 0.9f);
EXPECT_EQ(pointLightData.position, Vector3(0.0f, 0.0f, 4.0f));
EXPECT_FLOAT_EQ(pointLightData.range, 12.0f);
EXPECT_FLOAT_EQ(pointLightData.spotAngle, 0.0f);
}
TEST(RenderSceneExtractor_Test, LimitsAdditionalLightsToBoundedCountUsingStableTieBreakOrder) {
Scene scene("AdditionalLightCapScene");
GameObject* cameraObject = scene.CreateGameObject("Camera");
auto* camera = cameraObject->AddComponent<CameraComponent>();
camera->SetPrimary(true);
for (uint32_t index = 0; index < RenderLightingData::kMaxAdditionalLightCount + 2u; ++index) {
GameObject* lightObject = scene.CreateGameObject("PointLight" + std::to_string(index));
auto* light = lightObject->AddComponent<LightComponent>();
light->SetLightType(LightType::Point);
light->SetIntensity(1.0f);
light->SetRange(16.0f);
light->SetColor(Color(static_cast<float>(index), 0.0f, 0.0f, 1.0f));
lightObject->GetTransform()->SetLocalPosition(Vector3(0.0f, 0.0f, 4.0f));
}
RenderSceneExtractor extractor;
const RenderSceneData sceneData = extractor.Extract(scene, nullptr, 800, 600);
ASSERT_FALSE(sceneData.lighting.HasMainDirectionalLight());
ASSERT_EQ(sceneData.lighting.additionalLightCount, RenderLightingData::kMaxAdditionalLightCount);
for (uint32_t index = 0; index < RenderLightingData::kMaxAdditionalLightCount; ++index) {
EXPECT_EQ(sceneData.lighting.additionalLights[index].type, RenderLightType::Point);
EXPECT_FLOAT_EQ(sceneData.lighting.additionalLights[index].color.r, static_cast<float>(index));
}
}
TEST(RenderSceneExtractor_Test, FiltersVisibleItemsByCameraCullingMask) {