Formalize directional shadow runtime contracts
This commit is contained in:
@@ -478,11 +478,17 @@ add_library(XCEngine STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Builtin/BuiltinPassTypes.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Builtin/BuiltinPassMetadataUtils.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Builtin/BuiltinPassLayoutUtils.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Builtin/BuiltinPassContract.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Execution/CameraFramePlan.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Execution/CameraRenderer.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Execution/DirectionalShadowExecutionState.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Execution/DrawSettings.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Execution/FrameExecutionContext.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Execution/ScenePhase.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Execution/SceneRenderer.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/FrameData/CullingResults.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/FrameData/RenderCameraData.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/FrameData/RenderSceneData.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/FrameData/RendererListUtils.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/FrameData/VisibleGaussianSplatItem.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/FrameData/VisibleRenderItem.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/FrameData/VisibleVolumeItem.h
|
||||
@@ -500,8 +506,11 @@ add_library(XCEngine STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/RenderPipeline.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/RenderPipelineAsset.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/RenderSurface.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/SceneRenderFeaturePass.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Caches/RenderResourceCache.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Caches/DirectionalShadowSurfaceCache.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Shadow/DirectionalShadowData.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Shadow/DirectionalShadowRuntime.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Passes/BuiltinDepthStylePassBase.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Passes/BuiltinDepthOnlyPass.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Passes/BuiltinShadowCasterPass.h
|
||||
@@ -540,6 +549,8 @@ add_library(XCEngine STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Planning/SceneRenderRequestPlanner.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Planning/Internal/DirectionalShadowPlanning.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Planning/Internal/DirectionalShadowPlanning.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Shadow/DirectionalShadowData.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Shadow/DirectionalShadowRuntime.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Execution/SceneRenderer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Pipelines/BuiltinForwardPipeline.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Pipelines/Internal/BuiltinForwardPipelineSkybox.cpp
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Rendering/Builtin/BuiltinPassLayoutUtils.h>
|
||||
@@ -14,6 +14,16 @@ namespace Rendering {
|
||||
struct DirectionalShadowRenderPlan;
|
||||
struct RenderContext;
|
||||
|
||||
struct DirectionalShadowSurfaceAllocation {
|
||||
RenderSurface surface = {};
|
||||
RHI::RHIResourceView* depthShaderView = nullptr;
|
||||
|
||||
bool IsValid() const {
|
||||
return surface.GetDepthAttachment() != nullptr &&
|
||||
depthShaderView != nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
class DirectionalShadowSurfaceCache {
|
||||
public:
|
||||
DirectionalShadowSurfaceCache() = default;
|
||||
@@ -21,10 +31,9 @@ public:
|
||||
DirectionalShadowSurfaceCache& operator=(const DirectionalShadowSurfaceCache&) = delete;
|
||||
~DirectionalShadowSurfaceCache();
|
||||
|
||||
bool EnsureSurface(const RenderContext& context, const DirectionalShadowRenderPlan& plan);
|
||||
|
||||
const RenderSurface& GetSurface() const { return m_surface; }
|
||||
RHI::RHIResourceView* GetDepthShaderView() const { return m_depthShaderView; }
|
||||
const DirectionalShadowSurfaceAllocation* Resolve(
|
||||
const RenderContext& context,
|
||||
const DirectionalShadowRenderPlan& plan);
|
||||
|
||||
private:
|
||||
bool Matches(const RenderContext& context, const DirectionalShadowRenderPlan& plan) const;
|
||||
@@ -35,8 +44,7 @@ private:
|
||||
uint32_t m_height = 0;
|
||||
RHI::RHITexture* m_depthTexture = nullptr;
|
||||
RHI::RHIResourceView* m_depthView = nullptr;
|
||||
RHI::RHIResourceView* m_depthShaderView = nullptr;
|
||||
RenderSurface m_surface = {};
|
||||
DirectionalShadowSurfaceAllocation m_allocation = {};
|
||||
};
|
||||
|
||||
} // namespace Rendering
|
||||
|
||||
@@ -20,7 +20,8 @@ class RHIResourceView;
|
||||
|
||||
namespace Rendering {
|
||||
|
||||
class DirectionalShadowSurfaceCache;
|
||||
struct DirectionalShadowExecutionState;
|
||||
class DirectionalShadowRuntime;
|
||||
class FullscreenPassSurfaceCache;
|
||||
class RenderSurface;
|
||||
class RenderPipelineAsset;
|
||||
@@ -54,17 +55,13 @@ public:
|
||||
|
||||
private:
|
||||
void ResetPipeline(std::unique_ptr<RenderPipeline> pipeline);
|
||||
bool ResolveShadowCasterRequest(
|
||||
const CameraFramePlan& plan,
|
||||
ShadowCasterRenderRequest& outResolvedShadowCaster,
|
||||
RHI::RHIResourceView*& outShadowMapView);
|
||||
bool BuildSceneDataForPlan(
|
||||
const CameraFramePlan& plan,
|
||||
RHI::RHIResourceView* shadowMapView,
|
||||
const DirectionalShadowExecutionState& shadowState,
|
||||
RenderSceneData& outSceneData);
|
||||
bool ExecuteRenderPlan(
|
||||
const CameraFramePlan& plan,
|
||||
const ShadowCasterRenderRequest& resolvedShadowCaster,
|
||||
const DirectionalShadowExecutionState& shadowState,
|
||||
const RenderSceneData& sceneData);
|
||||
|
||||
RenderSceneExtractor m_sceneExtractor;
|
||||
@@ -73,7 +70,7 @@ private:
|
||||
std::unique_ptr<RenderPass> m_objectIdPass;
|
||||
std::unique_ptr<RenderPass> m_depthOnlyPass;
|
||||
std::unique_ptr<RenderPass> m_shadowCasterPass;
|
||||
std::unique_ptr<DirectionalShadowSurfaceCache> m_directionalShadowSurface;
|
||||
std::unique_ptr<DirectionalShadowRuntime> m_directionalShadowRuntime;
|
||||
std::unique_ptr<FullscreenPassSurfaceCache> m_postProcessSurfaceCache;
|
||||
std::unique_ptr<FullscreenPassSurfaceCache> m_finalOutputSurfaceCache;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Rendering/Planning/CameraRenderRequest.h>
|
||||
#include <XCEngine/Rendering/Shadow/DirectionalShadowData.h>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Rendering {
|
||||
|
||||
struct DirectionalShadowExecutionState {
|
||||
ShadowCasterRenderRequest shadowCasterRequest = {};
|
||||
RenderDirectionalShadowData shadowData = {};
|
||||
|
||||
bool HasShadowPass() const {
|
||||
return shadowCasterRequest.IsRequested();
|
||||
}
|
||||
|
||||
bool HasShadowSampling() const {
|
||||
return shadowData.IsValid();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Rendering
|
||||
} // namespace XCEngine
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <XCEngine/Rendering/FrameData/CullingResults.h>
|
||||
#include <XCEngine/Rendering/FrameData/RenderCameraData.h>
|
||||
#include <XCEngine/Rendering/FrameData/RenderEnvironmentData.h>
|
||||
#include <XCEngine/Rendering/Shadow/DirectionalShadowSettings.h>
|
||||
#include <XCEngine/Rendering/Shadow/DirectionalShadowData.h>
|
||||
#include <XCEngine/Rendering/FrameData/VisibleGaussianSplatItem.h>
|
||||
#include <XCEngine/Rendering/FrameData/VisibleRenderItem.h>
|
||||
#include <XCEngine/Rendering/FrameData/VisibleVolumeItem.h>
|
||||
@@ -21,10 +21,6 @@ namespace Components {
|
||||
class CameraComponent;
|
||||
} // namespace Components
|
||||
|
||||
namespace RHI {
|
||||
class RHIResourceView;
|
||||
} // namespace RHI
|
||||
|
||||
namespace Rendering {
|
||||
|
||||
struct RenderDirectionalLightData {
|
||||
@@ -53,42 +49,6 @@ struct RenderAdditionalLightData {
|
||||
float spotAngle = 0.0f;
|
||||
};
|
||||
|
||||
struct RenderDirectionalShadowMapMetrics {
|
||||
Math::Vector2 inverseMapSize = Math::Vector2::Zero();
|
||||
float worldTexelSize = 0.0f;
|
||||
float padding = 0.0f;
|
||||
};
|
||||
|
||||
static_assert(
|
||||
sizeof(RenderDirectionalShadowMapMetrics) == sizeof(float) * 4u,
|
||||
"RenderDirectionalShadowMapMetrics must stay float4-sized for GPU constant layout");
|
||||
|
||||
struct RenderDirectionalShadowSamplingData {
|
||||
float enabled = 0.0f;
|
||||
DirectionalShadowSamplingSettings settings = {};
|
||||
};
|
||||
|
||||
static_assert(
|
||||
sizeof(RenderDirectionalShadowSamplingData) == sizeof(float) * 4u,
|
||||
"RenderDirectionalShadowSamplingData must stay float4-sized for GPU constant layout");
|
||||
|
||||
struct RenderDirectionalShadowCasterBiasData {
|
||||
DirectionalShadowCasterBiasSettings settings = {};
|
||||
};
|
||||
|
||||
struct RenderDirectionalShadowData {
|
||||
bool enabled = false;
|
||||
Math::Matrix4x4 viewProjection = Math::Matrix4x4::Identity();
|
||||
RenderDirectionalShadowMapMetrics mapMetrics = {};
|
||||
RenderDirectionalShadowSamplingData sampling = {};
|
||||
RenderDirectionalShadowCasterBiasData casterBias = {};
|
||||
RHI::RHIResourceView* shadowMap = nullptr;
|
||||
|
||||
bool IsValid() const {
|
||||
return enabled && shadowMap != nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
struct RenderLightingData {
|
||||
static constexpr uint32_t kMaxAdditionalLightCount = 8u;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <XCEngine/Rendering/RenderContext.h>
|
||||
#include <XCEngine/Rendering/RenderPass.h>
|
||||
#include <XCEngine/Rendering/RenderSurface.h>
|
||||
#include <XCEngine/Rendering/Shadow/DirectionalShadowSettings.h>
|
||||
#include <XCEngine/Rendering/Shadow/DirectionalShadowData.h>
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
@@ -124,29 +124,6 @@ inline bool HasValidSingleSampleColorSource(const RenderSurface& surface) {
|
||||
surface.GetSampleQuality() == 0u;
|
||||
}
|
||||
|
||||
struct DirectionalShadowRenderPlan {
|
||||
bool enabled = false;
|
||||
Math::Vector3 lightDirection = Math::Vector3::Back();
|
||||
Math::Vector3 focusPoint = Math::Vector3::Zero();
|
||||
float orthographicHalfExtent = 0.0f;
|
||||
float texelWorldSize = 0.0f;
|
||||
float nearClipPlane = 0.1f;
|
||||
float farClipPlane = 0.0f;
|
||||
DirectionalShadowSamplingSettings sampling = {};
|
||||
DirectionalShadowCasterBiasSettings casterBias = {};
|
||||
uint32_t mapWidth = 0;
|
||||
uint32_t mapHeight = 0;
|
||||
RenderCameraData cameraData = {};
|
||||
|
||||
bool IsValid() const {
|
||||
return enabled &&
|
||||
mapWidth > 0 &&
|
||||
mapHeight > 0 &&
|
||||
cameraData.viewportWidth == mapWidth &&
|
||||
cameraData.viewportHeight == mapHeight;
|
||||
}
|
||||
};
|
||||
|
||||
struct ObjectIdRenderRequest {
|
||||
RenderSurface surface;
|
||||
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Core/Math/Matrix4.h>
|
||||
#include <XCEngine/Core/Math/Vector2.h>
|
||||
#include <XCEngine/Core/Math/Vector3.h>
|
||||
#include <XCEngine/Rendering/FrameData/RenderCameraData.h>
|
||||
#include <XCEngine/Rendering/Shadow/DirectionalShadowSettings.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
class RHIResourceView;
|
||||
} // namespace RHI
|
||||
|
||||
namespace Rendering {
|
||||
|
||||
struct DirectionalShadowRenderPlan {
|
||||
bool enabled = false;
|
||||
Math::Vector3 lightDirection = Math::Vector3::Back();
|
||||
Math::Vector3 focusPoint = Math::Vector3::Zero();
|
||||
float orthographicHalfExtent = 0.0f;
|
||||
float texelWorldSize = 0.0f;
|
||||
float nearClipPlane = 0.1f;
|
||||
float farClipPlane = 0.0f;
|
||||
DirectionalShadowSamplingSettings sampling = {};
|
||||
DirectionalShadowCasterBiasSettings casterBias = {};
|
||||
uint32_t mapWidth = 0;
|
||||
uint32_t mapHeight = 0;
|
||||
RenderCameraData cameraData = {};
|
||||
|
||||
bool IsValid() const {
|
||||
return enabled &&
|
||||
mapWidth > 0 &&
|
||||
mapHeight > 0 &&
|
||||
cameraData.viewportWidth == mapWidth &&
|
||||
cameraData.viewportHeight == mapHeight;
|
||||
}
|
||||
};
|
||||
|
||||
struct RenderDirectionalShadowMapMetrics {
|
||||
Math::Vector2 inverseMapSize = Math::Vector2::Zero();
|
||||
float worldTexelSize = 0.0f;
|
||||
float padding = 0.0f;
|
||||
};
|
||||
|
||||
static_assert(
|
||||
sizeof(RenderDirectionalShadowMapMetrics) == sizeof(float) * 4u,
|
||||
"RenderDirectionalShadowMapMetrics must stay float4-sized for GPU constant layout");
|
||||
|
||||
struct RenderDirectionalShadowSamplingData {
|
||||
float enabled = 0.0f;
|
||||
DirectionalShadowSamplingSettings settings = {};
|
||||
};
|
||||
|
||||
static_assert(
|
||||
sizeof(RenderDirectionalShadowSamplingData) == sizeof(float) * 4u,
|
||||
"RenderDirectionalShadowSamplingData must stay float4-sized for GPU constant layout");
|
||||
|
||||
struct RenderDirectionalShadowCasterBiasData {
|
||||
DirectionalShadowCasterBiasSettings settings = {};
|
||||
};
|
||||
|
||||
struct RenderDirectionalShadowData {
|
||||
bool enabled = false;
|
||||
Math::Matrix4x4 viewProjection = Math::Matrix4x4::Identity();
|
||||
RenderDirectionalShadowMapMetrics mapMetrics = {};
|
||||
RenderDirectionalShadowSamplingData sampling = {};
|
||||
RenderDirectionalShadowCasterBiasData casterBias = {};
|
||||
RHI::RHIResourceView* shadowMap = nullptr;
|
||||
|
||||
bool IsValid() const {
|
||||
return enabled && shadowMap != nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
RenderDirectionalShadowData BuildRenderDirectionalShadowData(
|
||||
const DirectionalShadowRenderPlan& plan,
|
||||
RHI::RHIResourceView* shadowMapView);
|
||||
|
||||
} // namespace Rendering
|
||||
} // namespace XCEngine
|
||||
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Rendering/Caches/DirectionalShadowSurfaceCache.h>
|
||||
#include <XCEngine/Rendering/Execution/DirectionalShadowExecutionState.h>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Rendering {
|
||||
|
||||
struct CameraFramePlan;
|
||||
|
||||
class DirectionalShadowRuntime {
|
||||
public:
|
||||
DirectionalShadowRuntime() = default;
|
||||
DirectionalShadowRuntime(const DirectionalShadowRuntime&) = delete;
|
||||
DirectionalShadowRuntime& operator=(const DirectionalShadowRuntime&) = delete;
|
||||
~DirectionalShadowRuntime() = default;
|
||||
|
||||
bool ResolveExecutionState(
|
||||
const CameraFramePlan& plan,
|
||||
DirectionalShadowExecutionState& outShadowState);
|
||||
|
||||
private:
|
||||
DirectionalShadowSurfaceCache m_surfaceCache;
|
||||
};
|
||||
|
||||
} // namespace Rendering
|
||||
} // namespace XCEngine
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "Rendering/Caches/DirectionalShadowSurfaceCache.h"
|
||||
|
||||
#include "Rendering/Planning/CameraRenderRequest.h"
|
||||
#include "Rendering/RenderContext.h"
|
||||
#include "Rendering/Shadow/DirectionalShadowData.h"
|
||||
#include "RHI/RHIDevice.h"
|
||||
#include "RHI/RHIResourceView.h"
|
||||
#include "RHI/RHITexture.h"
|
||||
@@ -18,15 +19,15 @@ DirectionalShadowSurfaceCache::~DirectionalShadowSurfaceCache() {
|
||||
Reset();
|
||||
}
|
||||
|
||||
bool DirectionalShadowSurfaceCache::EnsureSurface(
|
||||
const DirectionalShadowSurfaceAllocation* DirectionalShadowSurfaceCache::Resolve(
|
||||
const RenderContext& context,
|
||||
const DirectionalShadowRenderPlan& plan) {
|
||||
if (!context.IsValid() || !plan.IsValid()) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (Matches(context, plan)) {
|
||||
return true;
|
||||
return &m_allocation;
|
||||
}
|
||||
|
||||
RHI::TextureDesc depthDesc = {};
|
||||
@@ -43,7 +44,7 @@ bool DirectionalShadowSurfaceCache::EnsureSurface(
|
||||
|
||||
RHI::RHITexture* depthTexture = context.device->CreateTexture(depthDesc);
|
||||
if (depthTexture == nullptr) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RHI::ResourceViewDesc depthViewDesc = {};
|
||||
@@ -55,7 +56,7 @@ bool DirectionalShadowSurfaceCache::EnsureSurface(
|
||||
if (depthView == nullptr) {
|
||||
depthTexture->Shutdown();
|
||||
delete depthTexture;
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RHI::ResourceViewDesc depthShaderViewDesc = {};
|
||||
@@ -68,7 +69,7 @@ bool DirectionalShadowSurfaceCache::EnsureSurface(
|
||||
delete depthView;
|
||||
depthTexture->Shutdown();
|
||||
delete depthTexture;
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Reset();
|
||||
@@ -77,11 +78,11 @@ bool DirectionalShadowSurfaceCache::EnsureSurface(
|
||||
m_height = plan.mapHeight;
|
||||
m_depthTexture = depthTexture;
|
||||
m_depthView = depthView;
|
||||
m_depthShaderView = depthShaderView;
|
||||
m_surface = RenderSurface(plan.mapWidth, plan.mapHeight);
|
||||
m_surface.SetDepthAttachment(depthView);
|
||||
m_surface.SetSampleDesc(1u, 0u);
|
||||
return true;
|
||||
m_allocation.depthShaderView = depthShaderView;
|
||||
m_allocation.surface = RenderSurface(plan.mapWidth, plan.mapHeight);
|
||||
m_allocation.surface.SetDepthAttachment(depthView);
|
||||
m_allocation.surface.SetSampleDesc(1u, 0u);
|
||||
return &m_allocation;
|
||||
}
|
||||
|
||||
bool DirectionalShadowSurfaceCache::Matches(
|
||||
@@ -92,7 +93,7 @@ bool DirectionalShadowSurfaceCache::Matches(
|
||||
m_height == plan.mapHeight &&
|
||||
m_depthTexture != nullptr &&
|
||||
m_depthView != nullptr &&
|
||||
m_depthShaderView != nullptr;
|
||||
m_allocation.IsValid();
|
||||
}
|
||||
|
||||
void DirectionalShadowSurfaceCache::Reset() {
|
||||
@@ -102,10 +103,10 @@ void DirectionalShadowSurfaceCache::Reset() {
|
||||
m_depthView = nullptr;
|
||||
}
|
||||
|
||||
if (m_depthShaderView != nullptr) {
|
||||
m_depthShaderView->Shutdown();
|
||||
delete m_depthShaderView;
|
||||
m_depthShaderView = nullptr;
|
||||
if (m_allocation.depthShaderView != nullptr) {
|
||||
m_allocation.depthShaderView->Shutdown();
|
||||
delete m_allocation.depthShaderView;
|
||||
m_allocation.depthShaderView = nullptr;
|
||||
}
|
||||
|
||||
if (m_depthTexture != nullptr) {
|
||||
@@ -117,7 +118,7 @@ void DirectionalShadowSurfaceCache::Reset() {
|
||||
m_device = nullptr;
|
||||
m_width = 0;
|
||||
m_height = 0;
|
||||
m_surface = RenderSurface();
|
||||
m_allocation = {};
|
||||
}
|
||||
|
||||
} // namespace Rendering
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
#include "Rendering/Execution/CameraRenderer.h"
|
||||
|
||||
#include "Components/CameraComponent.h"
|
||||
#include "Rendering/Caches/DirectionalShadowSurfaceCache.h"
|
||||
#include "Rendering/Caches/FullscreenPassSurfaceCache.h"
|
||||
#include "Rendering/Execution/DirectionalShadowExecutionState.h"
|
||||
#include "Rendering/Passes/BuiltinDepthOnlyPass.h"
|
||||
#include "Rendering/Passes/BuiltinObjectIdPass.h"
|
||||
#include "Rendering/Passes/BuiltinShadowCasterPass.h"
|
||||
#include "Rendering/Pipelines/BuiltinForwardPipeline.h"
|
||||
#include "Rendering/RenderPipelineAsset.h"
|
||||
#include "Rendering/RenderSurface.h"
|
||||
#include "Rendering/Shadow/DirectionalShadowRuntime.h"
|
||||
#include "RHI/RHIResourceView.h"
|
||||
#include "Scene/Scene.h"
|
||||
|
||||
@@ -305,7 +306,7 @@ RenderPassContext BuildFrameStagePassContext(
|
||||
bool ExecuteFrameStage(
|
||||
CameraFrameStage stage,
|
||||
const CameraFramePlan& plan,
|
||||
const ShadowCasterRenderRequest& resolvedShadowCaster,
|
||||
const DirectionalShadowExecutionState& shadowState,
|
||||
const RenderSceneData& sceneData,
|
||||
CameraFrameExecutionState& executionState) {
|
||||
const RenderPassContext passContext = BuildFrameStagePassContext(stage, plan, sceneData);
|
||||
@@ -320,7 +321,7 @@ bool ExecuteFrameStage(
|
||||
case CameraFrameStage::ShadowCaster:
|
||||
return ExecuteScenePassRequest(
|
||||
executionState.shadowCasterPass,
|
||||
resolvedShadowCaster,
|
||||
shadowState.shadowCasterRequest,
|
||||
plan.request.context,
|
||||
sceneData);
|
||||
case CameraFrameStage::DepthOnly:
|
||||
@@ -377,32 +378,6 @@ bool ExecuteFrameStage(
|
||||
}
|
||||
}
|
||||
|
||||
RenderDirectionalShadowData BuildDirectionalShadowData(
|
||||
const DirectionalShadowRenderPlan& plan,
|
||||
RHI::RHIResourceView* shadowMapView) {
|
||||
RenderDirectionalShadowData shadowData = {};
|
||||
if (!plan.IsValid() || shadowMapView == nullptr) {
|
||||
return shadowData;
|
||||
}
|
||||
|
||||
shadowData.enabled = true;
|
||||
shadowData.viewProjection = plan.cameraData.viewProjection;
|
||||
shadowData.shadowMap = shadowMapView;
|
||||
const float texelWorldSize = plan.texelWorldSize > Math::EPSILON
|
||||
? plan.texelWorldSize
|
||||
: (plan.orthographicHalfExtent > Math::EPSILON && plan.mapWidth > 0u
|
||||
? (plan.orthographicHalfExtent * 2.0f) / static_cast<float>(plan.mapWidth)
|
||||
: 0.0f);
|
||||
shadowData.mapMetrics.inverseMapSize = Math::Vector2(
|
||||
1.0f / static_cast<float>(plan.mapWidth),
|
||||
1.0f / static_cast<float>(plan.mapHeight));
|
||||
shadowData.mapMetrics.worldTexelSize = texelWorldSize;
|
||||
shadowData.sampling.enabled = 1.0f;
|
||||
shadowData.sampling.settings = plan.sampling;
|
||||
shadowData.casterBias.settings = plan.casterBias;
|
||||
return shadowData;
|
||||
}
|
||||
|
||||
RenderEnvironmentData BuildEnvironmentData(const CameraFramePlan& plan) {
|
||||
RenderEnvironmentData environment = {};
|
||||
const RenderSurface& mainSceneSurface = plan.GetMainSceneSurface();
|
||||
@@ -450,6 +425,7 @@ CameraRenderer::CameraRenderer(
|
||||
, m_objectIdPass(std::move(objectIdPass))
|
||||
, m_depthOnlyPass(std::move(depthOnlyPass))
|
||||
, m_shadowCasterPass(std::move(shadowCasterPass))
|
||||
, m_directionalShadowRuntime(std::make_unique<DirectionalShadowRuntime>())
|
||||
, m_postProcessSurfaceCache(std::make_unique<FullscreenPassSurfaceCache>())
|
||||
, m_finalOutputSurfaceCache(std::make_unique<FullscreenPassSurfaceCache>()) {
|
||||
if (m_objectIdPass == nullptr) {
|
||||
@@ -469,6 +445,7 @@ CameraRenderer::CameraRenderer(std::shared_ptr<const RenderPipelineAsset> pipeli
|
||||
, m_objectIdPass(std::make_unique<Passes::BuiltinObjectIdPass>())
|
||||
, m_depthOnlyPass(CreateDefaultDepthOnlyPass())
|
||||
, m_shadowCasterPass(CreateDefaultShadowCasterPass())
|
||||
, m_directionalShadowRuntime(std::make_unique<DirectionalShadowRuntime>())
|
||||
, m_postProcessSurfaceCache(std::make_unique<FullscreenPassSurfaceCache>())
|
||||
, m_finalOutputSurfaceCache(std::make_unique<FullscreenPassSurfaceCache>()) {
|
||||
SetPipelineAsset(m_pipelineAsset);
|
||||
@@ -544,43 +521,9 @@ void CameraRenderer::ResetPipeline(std::unique_ptr<RenderPipeline> pipeline) {
|
||||
}
|
||||
}
|
||||
|
||||
bool CameraRenderer::ResolveShadowCasterRequest(
|
||||
const CameraFramePlan& plan,
|
||||
ShadowCasterRenderRequest& outResolvedShadowCaster,
|
||||
RHI::RHIResourceView*& outShadowMapView) {
|
||||
outResolvedShadowCaster = plan.shadowCaster;
|
||||
outShadowMapView = nullptr;
|
||||
|
||||
if (outResolvedShadowCaster.IsRequested()) {
|
||||
return outResolvedShadowCaster.IsValid();
|
||||
}
|
||||
|
||||
if (!plan.directionalShadow.IsValid()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_directionalShadowSurface == nullptr) {
|
||||
m_directionalShadowSurface = std::make_unique<DirectionalShadowSurfaceCache>();
|
||||
}
|
||||
|
||||
if (!m_directionalShadowSurface->EnsureSurface(plan.request.context, plan.directionalShadow)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outResolvedShadowCaster.surface = m_directionalShadowSurface->GetSurface();
|
||||
outResolvedShadowCaster.clearFlags = RenderClearFlags::Depth;
|
||||
if (!outResolvedShadowCaster.hasCameraDataOverride) {
|
||||
outResolvedShadowCaster.hasCameraDataOverride = true;
|
||||
outResolvedShadowCaster.cameraDataOverride = plan.directionalShadow.cameraData;
|
||||
}
|
||||
|
||||
outShadowMapView = m_directionalShadowSurface->GetDepthShaderView();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CameraRenderer::BuildSceneDataForPlan(
|
||||
const CameraFramePlan& plan,
|
||||
RHI::RHIResourceView* shadowMapView,
|
||||
const DirectionalShadowExecutionState& shadowState,
|
||||
RenderSceneData& outSceneData) {
|
||||
const RenderSurface& mainSceneSurface = plan.GetMainSceneSurface();
|
||||
outSceneData = m_sceneExtractor.ExtractForCamera(
|
||||
@@ -592,10 +535,7 @@ bool CameraRenderer::BuildSceneDataForPlan(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (plan.directionalShadow.IsValid()) {
|
||||
outSceneData.lighting.mainDirectionalShadow =
|
||||
BuildDirectionalShadowData(plan.directionalShadow, shadowMapView);
|
||||
}
|
||||
outSceneData.lighting.mainDirectionalShadow = shadowState.shadowData;
|
||||
outSceneData.globalShaderKeywords = BuildSceneGlobalShaderKeywords(outSceneData);
|
||||
|
||||
outSceneData.cameraData.clearFlags = plan.request.clearFlags;
|
||||
@@ -609,7 +549,7 @@ bool CameraRenderer::BuildSceneDataForPlan(
|
||||
|
||||
bool CameraRenderer::ExecuteRenderPlan(
|
||||
const CameraFramePlan& plan,
|
||||
const ShadowCasterRenderRequest& resolvedShadowCaster,
|
||||
const DirectionalShadowExecutionState& shadowState,
|
||||
const RenderSceneData& sceneData) {
|
||||
CameraFrameExecutionState executionState = {};
|
||||
executionState.pipeline = m_pipeline.get();
|
||||
@@ -628,7 +568,7 @@ bool CameraRenderer::ExecuteRenderPlan(
|
||||
if (!ExecuteFrameStage(
|
||||
stageInfo.stage,
|
||||
plan,
|
||||
resolvedShadowCaster,
|
||||
shadowState,
|
||||
sceneData,
|
||||
executionState)) {
|
||||
return false;
|
||||
@@ -689,24 +629,24 @@ bool CameraRenderer::Render(
|
||||
return false;
|
||||
}
|
||||
|
||||
ShadowCasterRenderRequest resolvedShadowCaster = {};
|
||||
RHI::RHIResourceView* shadowMapView = nullptr;
|
||||
if (!ResolveShadowCasterRequest(plan, resolvedShadowCaster, shadowMapView)) {
|
||||
DirectionalShadowExecutionState shadowState = {};
|
||||
if (m_directionalShadowRuntime == nullptr ||
|
||||
!m_directionalShadowRuntime->ResolveExecutionState(plan, shadowState)) {
|
||||
Debug::Logger::Get().Error(
|
||||
Debug::LogCategory::Rendering,
|
||||
"CameraRenderer::Render failed: ResolveShadowCasterRequest returned false");
|
||||
"CameraRenderer::Render failed: DirectionalShadowRuntime::ResolveExecutionState returned false");
|
||||
return false;
|
||||
}
|
||||
|
||||
RenderSceneData sceneData = {};
|
||||
if (!BuildSceneDataForPlan(plan, shadowMapView, sceneData)) {
|
||||
if (!BuildSceneDataForPlan(plan, shadowState, sceneData)) {
|
||||
Debug::Logger::Get().Error(
|
||||
Debug::LogCategory::Rendering,
|
||||
"CameraRenderer::Render failed: BuildSceneDataForPlan returned false");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ExecuteRenderPlan(plan, resolvedShadowCaster, sceneData)) {
|
||||
if (!ExecuteRenderPlan(plan, shadowState, sceneData)) {
|
||||
Debug::Logger::Get().Error(
|
||||
Debug::LogCategory::Rendering,
|
||||
"CameraRenderer::Render failed: ExecuteRenderPlan returned false");
|
||||
|
||||
33
engine/src/Rendering/Shadow/DirectionalShadowData.cpp
Normal file
33
engine/src/Rendering/Shadow/DirectionalShadowData.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#include "Rendering/Shadow/DirectionalShadowData.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Rendering {
|
||||
|
||||
RenderDirectionalShadowData BuildRenderDirectionalShadowData(
|
||||
const DirectionalShadowRenderPlan& plan,
|
||||
RHI::RHIResourceView* shadowMapView) {
|
||||
RenderDirectionalShadowData shadowData = {};
|
||||
if (!plan.IsValid() || shadowMapView == nullptr) {
|
||||
return shadowData;
|
||||
}
|
||||
|
||||
shadowData.enabled = true;
|
||||
shadowData.viewProjection = plan.cameraData.viewProjection;
|
||||
shadowData.shadowMap = shadowMapView;
|
||||
const float texelWorldSize = plan.texelWorldSize > Math::EPSILON
|
||||
? plan.texelWorldSize
|
||||
: (plan.orthographicHalfExtent > Math::EPSILON && plan.mapWidth > 0u
|
||||
? (plan.orthographicHalfExtent * 2.0f) / static_cast<float>(plan.mapWidth)
|
||||
: 0.0f);
|
||||
shadowData.mapMetrics.inverseMapSize = Math::Vector2(
|
||||
1.0f / static_cast<float>(plan.mapWidth),
|
||||
1.0f / static_cast<float>(plan.mapHeight));
|
||||
shadowData.mapMetrics.worldTexelSize = texelWorldSize;
|
||||
shadowData.sampling.enabled = 1.0f;
|
||||
shadowData.sampling.settings = plan.sampling;
|
||||
shadowData.casterBias.settings = plan.casterBias;
|
||||
return shadowData;
|
||||
}
|
||||
|
||||
} // namespace Rendering
|
||||
} // namespace XCEngine
|
||||
44
engine/src/Rendering/Shadow/DirectionalShadowRuntime.cpp
Normal file
44
engine/src/Rendering/Shadow/DirectionalShadowRuntime.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include "Rendering/Shadow/DirectionalShadowRuntime.h"
|
||||
|
||||
#include "Rendering/Execution/CameraFramePlan.h"
|
||||
#include "Rendering/Shadow/DirectionalShadowData.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Rendering {
|
||||
|
||||
bool DirectionalShadowRuntime::ResolveExecutionState(
|
||||
const CameraFramePlan& plan,
|
||||
DirectionalShadowExecutionState& outShadowState) {
|
||||
outShadowState = {};
|
||||
outShadowState.shadowCasterRequest = plan.shadowCaster;
|
||||
|
||||
if (outShadowState.shadowCasterRequest.IsRequested()) {
|
||||
return outShadowState.shadowCasterRequest.IsValid();
|
||||
}
|
||||
|
||||
if (!plan.directionalShadow.IsValid()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const DirectionalShadowSurfaceAllocation* shadowAllocation =
|
||||
m_surfaceCache.Resolve(plan.request.context, plan.directionalShadow);
|
||||
if (shadowAllocation == nullptr || !shadowAllocation->IsValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outShadowState.shadowCasterRequest.surface = shadowAllocation->surface;
|
||||
outShadowState.shadowCasterRequest.clearFlags = RenderClearFlags::Depth;
|
||||
if (!outShadowState.shadowCasterRequest.hasCameraDataOverride) {
|
||||
outShadowState.shadowCasterRequest.hasCameraDataOverride = true;
|
||||
outShadowState.shadowCasterRequest.cameraDataOverride = plan.directionalShadow.cameraData;
|
||||
}
|
||||
|
||||
outShadowState.shadowData =
|
||||
BuildRenderDirectionalShadowData(
|
||||
plan.directionalShadow,
|
||||
shadowAllocation->depthShaderView);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Rendering
|
||||
} // namespace XCEngine
|
||||
Reference in New Issue
Block a user