Add directional shadow request planning
This commit is contained in:
@@ -165,6 +165,7 @@ TEST(RenderSceneExtractor_Test, ExtractsBrightestDirectionalLightAsMainLight) {
|
||||
mainLight->SetLightType(LightType::Directional);
|
||||
mainLight->SetColor(Color(1.0f, 0.8f, 0.6f, 1.0f));
|
||||
mainLight->SetIntensity(2.5f);
|
||||
mainLight->SetCastsShadows(true);
|
||||
mainLightObject->GetTransform()->SetLocalRotation(
|
||||
Quaternion::LookRotation(Vector3(-0.3f, -1.0f, -0.2f).Normalized()));
|
||||
|
||||
@@ -177,6 +178,7 @@ TEST(RenderSceneExtractor_Test, ExtractsBrightestDirectionalLightAsMainLight) {
|
||||
EXPECT_EQ(sceneData.lighting.mainDirectionalLight.color.r, 1.0f);
|
||||
EXPECT_EQ(sceneData.lighting.mainDirectionalLight.color.g, 0.8f);
|
||||
EXPECT_EQ(sceneData.lighting.mainDirectionalLight.color.b, 0.6f);
|
||||
EXPECT_TRUE(sceneData.lighting.mainDirectionalLight.castsShadows);
|
||||
EXPECT_EQ(
|
||||
sceneData.lighting.mainDirectionalLight.direction,
|
||||
mainLightObject->GetTransform()->GetForward().Normalized() * -1.0f);
|
||||
@@ -357,7 +359,6 @@ TEST(RenderSceneExtractor_Test, FallsBackToEmbeddedMeshMaterialsWhenRendererHasN
|
||||
EXPECT_EQ(ResolveMaterial(sceneData.visibleItems[0]), embeddedMaterial);
|
||||
|
||||
meshFilter->ClearMesh();
|
||||
delete embeddedMaterial;
|
||||
delete mesh;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <XCEngine/Components/CameraComponent.h>
|
||||
#include <XCEngine/Components/LightComponent.h>
|
||||
#include <XCEngine/Rendering/SceneRenderRequestPlanner.h>
|
||||
#include <XCEngine/Scene/Scene.h>
|
||||
|
||||
@@ -126,3 +127,76 @@ TEST(SceneRenderRequestPlanner_Test, BuildsRequestsAndDropsZeroSizedViewportsWit
|
||||
EXPECT_EQ(requests[1].camera, overlay);
|
||||
EXPECT_EQ(requests[1].clearFlags, RenderClearFlags::Depth);
|
||||
}
|
||||
|
||||
TEST(SceneRenderRequestPlanner_Test, BuildsDirectionalShadowPlanForBaseCameraWhenMainDirectionalLightCastsShadows) {
|
||||
Scene scene("SceneRenderRequestPlannerDirectionalShadow");
|
||||
|
||||
GameObject* cameraObject = scene.CreateGameObject("Camera");
|
||||
auto* camera = cameraObject->AddComponent<CameraComponent>();
|
||||
camera->SetStackType(CameraStackType::Base);
|
||||
camera->SetDepth(1.0f);
|
||||
|
||||
GameObject* shadowLightObject = scene.CreateGameObject("ShadowLight");
|
||||
auto* shadowLight = shadowLightObject->AddComponent<LightComponent>();
|
||||
shadowLight->SetLightType(LightType::Directional);
|
||||
shadowLight->SetIntensity(2.5f);
|
||||
shadowLight->SetCastsShadows(true);
|
||||
|
||||
SceneRenderRequestPlanner planner;
|
||||
const std::vector<CameraRenderRequest> requests = planner.BuildRequests(
|
||||
scene,
|
||||
nullptr,
|
||||
CreateValidContext(),
|
||||
RenderSurface(640, 360));
|
||||
|
||||
ASSERT_EQ(requests.size(), 1u);
|
||||
const CameraRenderRequest& request = requests[0];
|
||||
EXPECT_EQ(request.camera, camera);
|
||||
ASSERT_TRUE(request.directionalShadow.IsValid());
|
||||
EXPECT_TRUE(request.directionalShadow.enabled);
|
||||
EXPECT_EQ(request.directionalShadow.mapWidth, 1024u);
|
||||
EXPECT_EQ(request.directionalShadow.mapHeight, 1024u);
|
||||
EXPECT_EQ(request.directionalShadow.lightDirection, XCEngine::Math::Vector3::Back());
|
||||
EXPECT_GT(request.directionalShadow.focusPoint.z, 0.0f);
|
||||
EXPECT_TRUE(request.shadowCaster.hasCameraDataOverride);
|
||||
EXPECT_EQ(request.shadowCaster.clearFlags, RenderClearFlags::Depth);
|
||||
EXPECT_EQ(request.shadowCaster.cameraDataOverride.viewportWidth, 1024u);
|
||||
EXPECT_EQ(request.shadowCaster.cameraDataOverride.viewportHeight, 1024u);
|
||||
EXPECT_EQ(request.shadowCaster.cameraDataOverride.clearFlags, RenderClearFlags::Depth);
|
||||
}
|
||||
|
||||
TEST(SceneRenderRequestPlanner_Test, SkipsDirectionalShadowPlanForOverlayCameraWhenBaseCameraExists) {
|
||||
Scene scene("SceneRenderRequestPlannerOverlayShadow");
|
||||
|
||||
GameObject* baseCameraObject = scene.CreateGameObject("BaseCamera");
|
||||
auto* baseCamera = baseCameraObject->AddComponent<CameraComponent>();
|
||||
baseCamera->SetStackType(CameraStackType::Base);
|
||||
baseCamera->SetDepth(1.0f);
|
||||
|
||||
GameObject* overlayCameraObject = scene.CreateGameObject("OverlayCamera");
|
||||
auto* overlayCamera = overlayCameraObject->AddComponent<CameraComponent>();
|
||||
overlayCamera->SetStackType(CameraStackType::Overlay);
|
||||
overlayCamera->SetDepth(2.0f);
|
||||
|
||||
GameObject* shadowLightObject = scene.CreateGameObject("ShadowLight");
|
||||
auto* shadowLight = shadowLightObject->AddComponent<LightComponent>();
|
||||
shadowLight->SetLightType(LightType::Directional);
|
||||
shadowLight->SetIntensity(3.0f);
|
||||
shadowLight->SetCastsShadows(true);
|
||||
|
||||
SceneRenderRequestPlanner planner;
|
||||
const std::vector<CameraRenderRequest> requests = planner.BuildRequests(
|
||||
scene,
|
||||
nullptr,
|
||||
CreateValidContext(),
|
||||
RenderSurface(640, 360));
|
||||
|
||||
ASSERT_EQ(requests.size(), 2u);
|
||||
EXPECT_EQ(requests[0].camera, baseCamera);
|
||||
EXPECT_TRUE(requests[0].directionalShadow.enabled);
|
||||
EXPECT_TRUE(requests[0].shadowCaster.hasCameraDataOverride);
|
||||
|
||||
EXPECT_EQ(requests[1].camera, overlayCamera);
|
||||
EXPECT_FALSE(requests[1].directionalShadow.enabled);
|
||||
EXPECT_FALSE(requests[1].shadowCaster.hasCameraDataOverride);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user