Refactor rendering frame execution contracts

This commit is contained in:
2026-04-13 22:16:04 +08:00
parent 48daaa1bd0
commit 712f99e723
30 changed files with 1398 additions and 247 deletions

View File

@@ -0,0 +1,179 @@
#pragma once
#include <XCEngine/Rendering/Planning/CameraRenderRequest.h>
namespace XCEngine {
namespace Rendering {
struct CameraFramePlan {
CameraRenderRequest request = {};
ShadowCasterRenderRequest shadowCaster = {};
DirectionalShadowRenderPlan directionalShadow = {};
PostProcessRenderRequest postProcess = {};
FinalOutputRenderRequest finalOutput = {};
ResolvedFinalColorPolicy finalColorPolicy = {};
RenderPassSequence* preScenePasses = nullptr;
RenderPassSequence* postScenePasses = nullptr;
RenderPassSequence* overlayPasses = nullptr;
static CameraFramePlan FromRequest(const CameraRenderRequest& request) {
CameraFramePlan plan = {};
plan.request = request;
plan.shadowCaster = request.shadowCaster;
plan.directionalShadow = request.directionalShadow;
plan.postProcess = request.postProcess;
plan.finalOutput = request.finalOutput;
plan.finalColorPolicy = request.finalColorPolicy;
plan.preScenePasses = request.preScenePasses;
plan.postScenePasses = request.postScenePasses;
plan.overlayPasses = request.overlayPasses;
return plan;
}
bool IsValid() const {
return request.IsValid();
}
bool HasFrameStage(CameraFrameStage stage) const {
switch (stage) {
case CameraFrameStage::PreScenePasses:
return preScenePasses != nullptr;
case CameraFrameStage::ShadowCaster:
return shadowCaster.IsRequested() || directionalShadow.IsValid();
case CameraFrameStage::DepthOnly:
return request.depthOnly.IsRequested();
case CameraFrameStage::MainScene:
return true;
case CameraFrameStage::PostProcess:
return postProcess.IsRequested();
case CameraFrameStage::FinalOutput:
return finalOutput.IsRequested();
case CameraFrameStage::ObjectId:
return request.objectId.IsRequested();
case CameraFrameStage::PostScenePasses:
return postScenePasses != nullptr;
case CameraFrameStage::OverlayPasses:
return overlayPasses != nullptr;
default:
return false;
}
}
RenderPassSequence* GetPassSequence(CameraFrameStage stage) const {
switch (stage) {
case CameraFrameStage::PreScenePasses:
return preScenePasses;
case CameraFrameStage::PostProcess:
return postProcess.passes;
case CameraFrameStage::FinalOutput:
return finalOutput.passes;
case CameraFrameStage::PostScenePasses:
return postScenePasses;
case CameraFrameStage::OverlayPasses:
return overlayPasses;
default:
return nullptr;
}
}
const RenderSurface& GetMainSceneSurface() const {
if (postProcess.IsRequested()) {
return postProcess.sourceSurface;
}
if (finalOutput.IsRequested()) {
return finalOutput.sourceSurface;
}
return request.surface;
}
const RenderSurface& GetFinalCompositedSurface() const {
if (finalOutput.IsRequested()) {
return finalOutput.destinationSurface;
}
if (postProcess.IsRequested()) {
return postProcess.destinationSurface;
}
return request.surface;
}
const RenderSurface* GetOutputSurface(CameraFrameStage stage) const {
switch (stage) {
case CameraFrameStage::PreScenePasses:
case CameraFrameStage::MainScene:
return &GetMainSceneSurface();
case CameraFrameStage::ShadowCaster:
return shadowCaster.IsRequested() ? &shadowCaster.surface : nullptr;
case CameraFrameStage::DepthOnly:
return request.depthOnly.IsRequested() ? &request.depthOnly.surface : nullptr;
case CameraFrameStage::PostProcess:
return postProcess.IsRequested() ? &postProcess.destinationSurface : nullptr;
case CameraFrameStage::FinalOutput:
return finalOutput.IsRequested() ? &finalOutput.destinationSurface : nullptr;
case CameraFrameStage::ObjectId:
return request.objectId.IsRequested() ? &request.objectId.surface : nullptr;
case CameraFrameStage::PostScenePasses:
case CameraFrameStage::OverlayPasses:
return &GetFinalCompositedSurface();
default:
return nullptr;
}
}
const RenderSurface* GetSourceSurface(CameraFrameStage stage) const {
switch (stage) {
case CameraFrameStage::PostProcess:
return postProcess.IsRequested() ? &postProcess.sourceSurface : nullptr;
case CameraFrameStage::FinalOutput:
return finalOutput.IsRequested() ? &finalOutput.sourceSurface : nullptr;
default:
return nullptr;
}
}
RHI::RHIResourceView* GetSourceColorView(CameraFrameStage stage) const {
switch (stage) {
case CameraFrameStage::PostProcess:
return postProcess.IsRequested() ? postProcess.sourceColorView : nullptr;
case CameraFrameStage::FinalOutput:
return finalOutput.IsRequested() ? finalOutput.sourceColorView : nullptr;
default:
return nullptr;
}
}
RHI::ResourceStates GetSourceColorState(CameraFrameStage stage) const {
switch (stage) {
case CameraFrameStage::PostProcess:
return postProcess.IsRequested() ? postProcess.sourceColorState : RHI::ResourceStates::Common;
case CameraFrameStage::FinalOutput:
return finalOutput.IsRequested() ? finalOutput.sourceColorState : RHI::ResourceStates::Common;
default:
return RHI::ResourceStates::Common;
}
}
bool RequiresIntermediateSceneColor() const {
return postProcess.IsRequested() || finalOutput.IsRequested();
}
};
inline CameraRenderRequest BuildLegacyCameraRenderRequest(
const CameraFramePlan& plan) {
CameraRenderRequest request = plan.request;
request.shadowCaster = plan.shadowCaster;
request.directionalShadow = plan.directionalShadow;
request.postProcess = plan.postProcess;
request.finalOutput = plan.finalOutput;
request.finalColorPolicy = plan.finalColorPolicy;
request.preScenePasses = plan.preScenePasses;
request.postScenePasses = plan.postScenePasses;
request.overlayPasses = plan.overlayPasses;
return request;
}
} // namespace Rendering
} // namespace XCEngine

View File

@@ -1,5 +1,6 @@
#pragma once
#include <XCEngine/Rendering/Execution/CameraFramePlan.h>
#include <XCEngine/Rendering/Extraction/RenderSceneExtractor.h>
#include <XCEngine/Rendering/Planning/CameraRenderRequest.h>
#include <XCEngine/Rendering/RenderPass.h>
@@ -49,19 +50,20 @@ public:
RenderPass* GetShadowCasterPass() const { return m_shadowCasterPass.get(); }
bool Render(const CameraRenderRequest& request);
bool Render(const CameraFramePlan& plan);
private:
void ResetPipeline(std::unique_ptr<RenderPipeline> pipeline);
bool ResolveShadowCasterRequest(
const CameraRenderRequest& request,
const CameraFramePlan& plan,
ShadowCasterRenderRequest& outResolvedShadowCaster,
RHI::RHIResourceView*& outShadowMapView);
bool BuildSceneDataForRequest(
const CameraRenderRequest& request,
bool BuildSceneDataForPlan(
const CameraFramePlan& plan,
RHI::RHIResourceView* shadowMapView,
RenderSceneData& outSceneData);
bool ExecuteRenderPlan(
const CameraRenderRequest& request,
const CameraFramePlan& plan,
const ShadowCasterRenderRequest& resolvedShadowCaster,
const RenderSceneData& sceneData);

View File

@@ -0,0 +1,15 @@
#pragma once
#include <XCEngine/Rendering/Execution/ScenePhase.h>
#include <XCEngine/Rendering/FrameData/CullingResults.h>
namespace XCEngine {
namespace Rendering {
struct DrawSettings {
ScenePhase scenePhase = ScenePhase::Opaque;
RendererListType rendererListType = RendererListType::AllVisible;
};
} // namespace Rendering
} // namespace XCEngine

View File

@@ -0,0 +1,56 @@
#pragma once
#include <XCEngine/Rendering/Execution/ScenePhase.h>
#include <XCEngine/Rendering/RenderContext.h>
namespace XCEngine {
namespace RHI {
class RHIResourceView;
} // namespace RHI
namespace Rendering {
struct RenderSceneData;
class RenderSurface;
struct FrameExecutionContext {
FrameExecutionContext(
const RenderContext& inRenderContext,
const RenderSurface& inSurface,
const RenderSceneData& inSceneData,
const RenderSurface* inSourceSurface = nullptr,
RHI::RHIResourceView* inSourceColorView = nullptr,
RHI::ResourceStates inSourceColorState = RHI::ResourceStates::Common)
: renderContext(inRenderContext)
, surface(inSurface)
, sceneData(inSceneData)
, sourceSurface(inSourceSurface)
, sourceColorView(inSourceColorView)
, sourceColorState(inSourceColorState) {
}
const RenderContext& renderContext;
const RenderSurface& surface;
const RenderSceneData& sceneData;
const RenderSurface* sourceSurface = nullptr;
RHI::RHIResourceView* sourceColorView = nullptr;
RHI::ResourceStates sourceColorState = RHI::ResourceStates::Common;
};
struct ScenePhaseExecutionContext {
ScenePhaseExecutionContext(
const FrameExecutionContext& inFrameContext,
ScenePhase inScenePhase,
bool inSampledDirectionalShadow = false)
: frameContext(inFrameContext)
, scenePhase(inScenePhase)
, sampledDirectionalShadow(inSampledDirectionalShadow) {
}
FrameExecutionContext frameContext;
ScenePhase scenePhase = ScenePhase::Opaque;
bool sampledDirectionalShadow = false;
};
} // namespace Rendering
} // namespace XCEngine

View File

@@ -0,0 +1,40 @@
#pragma once
#include <XCEngine/Core/Types.h>
namespace XCEngine {
namespace Rendering {
enum class ScenePhase : Core::uint32 {
Opaque = 0,
Skybox = 1,
Feature = 2,
Transparent = 3,
EditorExtension = 4,
PostProcess = 5,
FinalOutput = 6
};
inline const char* ToString(ScenePhase scenePhase) {
switch (scenePhase) {
case ScenePhase::Opaque:
return "Opaque";
case ScenePhase::Skybox:
return "Skybox";
case ScenePhase::Feature:
return "Feature";
case ScenePhase::Transparent:
return "Transparent";
case ScenePhase::EditorExtension:
return "EditorExtension";
case ScenePhase::PostProcess:
return "PostProcess";
case ScenePhase::FinalOutput:
return "FinalOutput";
}
return "Unknown";
}
} // namespace Rendering
} // namespace XCEngine

View File

@@ -1,5 +1,6 @@
#pragma once
#include <XCEngine/Rendering/Execution/CameraFramePlan.h>
#include <XCEngine/Rendering/Execution/CameraRenderer.h>
#include <XCEngine/Rendering/Planning/CameraRenderRequest.h>
#include <XCEngine/Rendering/Planning/SceneRenderRequestPlanner.h>
@@ -35,9 +36,16 @@ public:
Components::CameraComponent* overrideCamera,
const RenderContext& context,
const RenderSurface& surface);
std::vector<CameraFramePlan> BuildFramePlans(
const Components::Scene& scene,
Components::CameraComponent* overrideCamera,
const RenderContext& context,
const RenderSurface& surface);
bool Render(const CameraRenderRequest& request);
bool Render(const std::vector<CameraRenderRequest>& requests);
bool Render(const CameraFramePlan& plan);
bool Render(const std::vector<CameraFramePlan>& plans);
bool Render(
const Components::Scene& scene,
Components::CameraComponent* overrideCamera,
@@ -45,12 +53,14 @@ public:
const RenderSurface& surface);
private:
std::vector<CameraFramePlan> CreateFramePlansFromRequests(
const std::vector<CameraRenderRequest>& requests) const;
void PrepareOwnedFullscreenStageState(size_t requestCount);
void ResolveCameraFinalColorPolicies(
std::vector<CameraRenderRequest>& requests) const;
std::vector<CameraFramePlan>& plans) const;
void AttachFullscreenStageRequests(
const RenderContext& context,
std::vector<CameraRenderRequest>& requests);
std::vector<CameraFramePlan>& plans);
SceneRenderRequestPlanner m_requestPlanner;
CameraRenderer m_cameraRenderer;

View File

@@ -0,0 +1,85 @@
#pragma once
#include <XCEngine/Core/Types.h>
#include <cstddef>
#include <limits>
#include <vector>
namespace XCEngine {
namespace Rendering {
enum class RendererListType : Core::uint32 {
AllVisible = 0,
Opaque = 1,
Transparent = 2,
ShadowCaster = 3,
ObjectId = 4
};
enum class RendererSortMode : Core::uint32 {
None = 0,
FrontToBack = 1,
BackToFront = 2
};
struct FilteringSettings {
Core::int32 renderQueueMin = std::numeric_limits<Core::int32>::lowest();
Core::int32 renderQueueMax = std::numeric_limits<Core::int32>::max();
bool requireShadowCasting = false;
bool requireRenderObjectId = false;
};
struct SortingSettings {
RendererSortMode sortMode = RendererSortMode::None;
};
struct RendererListDesc {
RendererListType type = RendererListType::AllVisible;
FilteringSettings filtering = {};
SortingSettings sorting = {};
};
struct RendererList {
RendererListDesc desc = {};
std::vector<Core::uint32> visibleRenderItemIndices;
bool Empty() const {
return visibleRenderItemIndices.empty();
}
size_t Size() const {
return visibleRenderItemIndices.size();
}
};
struct CullingResults {
std::vector<RendererList> rendererLists;
void Clear() {
rendererLists.clear();
}
RendererList* FindRendererList(RendererListType type) {
for (RendererList& rendererList : rendererLists) {
if (rendererList.desc.type == type) {
return &rendererList;
}
}
return nullptr;
}
const RendererList* FindRendererList(RendererListType type) const {
for (const RendererList& rendererList : rendererLists) {
if (rendererList.desc.type == type) {
return &rendererList;
}
}
return nullptr;
}
};
} // namespace Rendering
} // namespace XCEngine

View File

@@ -3,6 +3,7 @@
#include <XCEngine/Core/Math/Vector2.h>
#include <XCEngine/Core/Math/Vector3.h>
#include <XCEngine/Core/Math/Vector4.h>
#include <XCEngine/Rendering/FrameData/CullingResults.h>
#include <XCEngine/Rendering/FrameData/RenderCameraData.h>
#include <XCEngine/Rendering/FrameData/RenderEnvironmentData.h>
#include <XCEngine/Rendering/Shadow/DirectionalShadowSettings.h>
@@ -115,6 +116,7 @@ struct RenderSceneData {
RenderEnvironmentData environment;
RenderLightingData lighting;
Resources::ShaderKeywordSet globalShaderKeywords;
CullingResults cullingResults;
std::vector<VisibleRenderItem> visibleItems;
std::vector<VisibleGaussianSplatItem> visibleGaussianSplats;
std::vector<VisibleVolumeItem> visibleVolumes;
@@ -122,6 +124,22 @@ struct RenderSceneData {
bool HasCamera() const {
return camera != nullptr;
}
RendererList* FindRendererList(RendererListType type) {
return cullingResults.FindRendererList(type);
}
const RendererList* FindRendererList(RendererListType type) const {
return cullingResults.FindRendererList(type);
}
const VisibleRenderItem* TryGetVisibleRenderItem(Core::uint32 index) const {
if (index >= visibleItems.size()) {
return nullptr;
}
return &visibleItems[index];
}
};
} // namespace Rendering

View File

@@ -0,0 +1,145 @@
#pragma once
#include <XCEngine/Components/MeshRendererComponent.h>
#include <XCEngine/Rendering/FrameData/RenderSceneData.h>
#include <XCEngine/Resources/Material/Material.h>
#include <utility>
namespace XCEngine {
namespace Rendering {
inline FilteringSettings BuildDefaultFilteringSettings(RendererListType type) {
FilteringSettings filtering = {};
switch (type) {
case RendererListType::AllVisible:
break;
case RendererListType::Opaque:
filtering.renderQueueMax =
static_cast<Core::int32>(Resources::MaterialRenderQueue::Transparent) - 1;
break;
case RendererListType::Transparent:
filtering.renderQueueMin =
static_cast<Core::int32>(Resources::MaterialRenderQueue::Transparent);
break;
case RendererListType::ShadowCaster:
filtering.requireShadowCasting = true;
break;
case RendererListType::ObjectId:
filtering.requireRenderObjectId = true;
break;
}
return filtering;
}
inline SortingSettings BuildDefaultSortingSettings(RendererListType type) {
SortingSettings sorting = {};
switch (type) {
case RendererListType::Opaque:
case RendererListType::ShadowCaster:
case RendererListType::ObjectId:
sorting.sortMode = RendererSortMode::FrontToBack;
break;
case RendererListType::Transparent:
sorting.sortMode = RendererSortMode::BackToFront;
break;
case RendererListType::AllVisible:
sorting.sortMode = RendererSortMode::None;
break;
}
return sorting;
}
inline RendererListDesc BuildDefaultRendererListDesc(RendererListType type) {
RendererListDesc desc = {};
desc.type = type;
desc.filtering = BuildDefaultFilteringSettings(type);
desc.sorting = BuildDefaultSortingSettings(type);
return desc;
}
inline bool MatchesFilteringSettings(
const VisibleRenderItem& visibleItem,
const FilteringSettings& filtering) {
if (visibleItem.renderQueue < filtering.renderQueueMin ||
visibleItem.renderQueue > filtering.renderQueueMax) {
return false;
}
if (filtering.requireShadowCasting &&
visibleItem.meshRenderer != nullptr &&
!visibleItem.meshRenderer->GetCastShadows()) {
return false;
}
if (filtering.requireRenderObjectId &&
!IsValidRenderObjectId(visibleItem.renderObjectId)) {
return false;
}
return true;
}
inline bool MatchesRendererListDesc(
const VisibleRenderItem& visibleItem,
const RendererListDesc& desc) {
return MatchesFilteringSettings(visibleItem, desc.filtering);
}
inline RendererList BuildRendererList(
RendererListType type,
const std::vector<VisibleRenderItem>& visibleItems) {
RendererList rendererList = {};
rendererList.desc = BuildDefaultRendererListDesc(type);
rendererList.visibleRenderItemIndices.reserve(visibleItems.size());
for (Core::uint32 visibleItemIndex = 0;
visibleItemIndex < static_cast<Core::uint32>(visibleItems.size());
++visibleItemIndex) {
if (!MatchesRendererListDesc(
visibleItems[visibleItemIndex],
rendererList.desc)) {
continue;
}
rendererList.visibleRenderItemIndices.push_back(visibleItemIndex);
}
return rendererList;
}
template <typename Visitor>
inline void VisitRendererListVisibleItems(
const RenderSceneData& sceneData,
RendererListType rendererListType,
Visitor&& visitor) {
const RendererList* rendererList = sceneData.FindRendererList(rendererListType);
if (rendererList != nullptr) {
for (Core::uint32 visibleItemIndex : rendererList->visibleRenderItemIndices) {
const VisibleRenderItem* visibleItem =
sceneData.TryGetVisibleRenderItem(visibleItemIndex);
if (visibleItem == nullptr) {
continue;
}
visitor(*visibleItem);
}
return;
}
const RendererListDesc fallbackDesc = BuildDefaultRendererListDesc(rendererListType);
for (const VisibleRenderItem& visibleItem : sceneData.visibleItems) {
if (!MatchesRendererListDesc(visibleItem, fallbackDesc)) {
continue;
}
visitor(visibleItem);
}
}
} // namespace Rendering
} // namespace XCEngine

View File

@@ -3,6 +3,7 @@
#include <XCEngine/Core/Asset/ResourceHandle.h>
#include <XCEngine/Core/Math/Matrix4.h>
#include <XCEngine/Rendering/Builtin/BuiltinPassTypes.h>
#include <XCEngine/Rendering/FrameData/CullingResults.h>
#include <XCEngine/Rendering/Materials/RenderMaterialResolve.h>
#include <XCEngine/Rendering/RenderPass.h>
#include <XCEngine/Rendering/Materials/RenderMaterialStateUtils.h>
@@ -46,6 +47,7 @@ protected:
BuiltinMaterialPass passType,
Containers::String builtinShaderPath);
virtual RendererListType GetRendererListType() const;
virtual bool ShouldRenderVisibleItem(const VisibleRenderItem& visibleItem) const;
private:

View File

@@ -6,7 +6,7 @@
#include <XCEngine/Rendering/Caches/RenderResourceCache.h>
#include <XCEngine/Rendering/Materials/RenderMaterialResolve.h>
#include <XCEngine/Rendering/Materials/RenderMaterialStateUtils.h>
#include <XCEngine/Rendering/RenderPass.h>
#include <XCEngine/Rendering/SceneRenderFeaturePass.h>
#include <XCEngine/RHI/RHIDescriptorPool.h>
#include <XCEngine/RHI/RHIDescriptorSet.h>
#include <XCEngine/RHI/RHIPipelineLayout.h>
@@ -40,12 +40,16 @@ class BuiltinGaussianSplatPassResources;
namespace Passes {
class BuiltinGaussianSplatPass final : public RenderPass {
class BuiltinGaussianSplatPass final : public SceneRenderFeaturePass {
public:
~BuiltinGaussianSplatPass() override;
const char* GetName() const override;
bool Initialize(const RenderContext& context) override;
bool IsActive(const RenderSceneData& sceneData) const override;
bool Prepare(
const RenderContext& context,
const RenderSceneData& sceneData) override;
bool PrepareGaussianSplatResources(
const RenderContext& context,
const RenderSceneData& sceneData);

View File

@@ -16,6 +16,7 @@ public:
const char* GetName() const override;
protected:
RendererListType GetRendererListType() const override;
bool ShouldRenderVisibleItem(const VisibleRenderItem& visibleItem) const override;
};

View File

@@ -6,7 +6,7 @@
#include <XCEngine/Rendering/Caches/RenderResourceCache.h>
#include <XCEngine/Rendering/Materials/RenderMaterialResolve.h>
#include <XCEngine/Rendering/Materials/RenderMaterialStateUtils.h>
#include <XCEngine/Rendering/RenderPass.h>
#include <XCEngine/Rendering/SceneRenderFeaturePass.h>
#include <XCEngine/RHI/RHIDescriptorPool.h>
#include <XCEngine/RHI/RHIDescriptorSet.h>
#include <XCEngine/RHI/RHIPipelineLayout.h>
@@ -33,7 +33,7 @@ struct RenderLightingData;
namespace Passes {
class BuiltinVolumetricPass final : public RenderPass {
class BuiltinVolumetricPass final : public SceneRenderFeaturePass {
public:
~BuiltinVolumetricPass() override;
@@ -41,6 +41,10 @@ public:
const char* GetName() const override;
bool Initialize(const RenderContext& context) override;
bool IsActive(const RenderSceneData& sceneData) const override;
bool Prepare(
const RenderContext& context,
const RenderSceneData& sceneData) override;
bool PrepareVolumeResources(
const RenderContext& context,
const RenderSceneData& sceneData);

View File

@@ -1,11 +1,14 @@
#pragma once
#include <XCEngine/Rendering/Execution/DrawSettings.h>
#include <XCEngine/Rendering/Execution/FrameExecutionContext.h>
#include <XCEngine/Rendering/Builtin/BuiltinPassTypes.h>
#include <XCEngine/Rendering/Materials/RenderMaterialResolve.h>
#include <XCEngine/Rendering/Materials/RenderMaterialStateUtils.h>
#include <XCEngine/Rendering/RenderPass.h>
#include <XCEngine/Rendering/RenderPipeline.h>
#include <XCEngine/Rendering/RenderPipelineAsset.h>
#include <XCEngine/Rendering/SceneRenderFeaturePass.h>
#include <XCEngine/Rendering/Caches/RenderResourceCache.h>
#include <XCEngine/RHI/RHIDescriptorPool.h>
@@ -50,16 +53,21 @@ public:
BuiltinForwardPipeline();
~BuiltinForwardPipeline() override;
using RenderPipeline::Render;
static RHI::InputLayoutDesc BuildInputLayout();
bool Initialize(const RenderContext& context) override;
void Shutdown() override;
bool Render(const FrameExecutionContext& executionContext) override;
bool Render(
const RenderContext& context,
const RenderSurface& surface,
const RenderSceneData& sceneData) override;
private:
using ForwardSceneFeaturePassArray = std::array<SceneRenderFeaturePass*, 2>;
struct OwnedDescriptorSet {
RHI::RHIDescriptorPool* pool = nullptr;
RHI::RHIDescriptorSet* set = nullptr;
@@ -263,6 +271,19 @@ private:
};
bool EnsureInitialized(const RenderContext& context);
ForwardSceneFeaturePassArray CollectForwardSceneFeaturePasses() const;
bool InitializeForwardSceneFeaturePasses(const RenderContext& context);
void ShutdownForwardSceneFeaturePasses();
bool PrepareForwardSceneFeaturePasses(
const FrameExecutionContext& executionContext) const;
bool ExecuteForwardSceneFeaturePasses(
const ScenePhaseExecutionContext& executionContext) const;
ScenePhaseExecutionContext BuildScenePhaseExecutionContext(
const FrameExecutionContext& executionContext,
ScenePhase scenePhase) const;
DrawSettings BuildDrawSettings(ScenePhase scenePhase) const;
bool ExecuteForwardScene(const FrameExecutionContext& executionContext);
bool ExecuteScenePhase(const ScenePhaseExecutionContext& executionContext);
bool CreatePipelineResources(const RenderContext& context);
void DestroyPipelineResources();
static bool TryResolveSurfacePassType(
@@ -315,18 +336,14 @@ private:
bool HasProceduralSkybox(const RenderSceneData& sceneData) const;
bool BeginForwardScenePass(const RenderPassContext& context);
void EndForwardScenePass(const RenderPassContext& context);
bool ExecuteForwardOpaquePass(const RenderPassContext& context);
bool ExecuteForwardOpaquePass(const ScenePhaseExecutionContext& context);
bool ExecuteForwardSkyboxPass(const RenderPassContext& context);
bool ExecuteForwardTransparentPass(const RenderPassContext& context);
bool ExecuteForwardTransparentPass(const ScenePhaseExecutionContext& context);
bool DrawVisibleItems(
const RenderContext& context,
const RenderSurface& surface,
const RenderSceneData& sceneData,
bool drawTransparentItems);
const FrameExecutionContext& executionContext,
const DrawSettings& drawSettings);
bool DrawVisibleItem(
const RenderContext& context,
const RenderSurface& surface,
const RenderSceneData& sceneData,
const FrameExecutionContext& executionContext,
const VisibleRenderItem& visibleItem);
bool EnsureSkyboxResources(const RenderContext& context);
bool CreateSkyboxResources(const RenderContext& context);

View File

@@ -24,7 +24,7 @@ struct DirectionalShadowPlanningSettings {
float perspectiveFocusFactor = 1.0f;
float orthographicFocusFactor = 2.0f;
float minDepthRange = 20.0f;
float boundsPadding = 1.0f;
float boundsPadding = 0.5f;
float minDepthPadding = 2.0f;
DirectionalShadowSamplingSettings sampling = {};
DirectionalShadowCasterBiasSettings casterBias = {};

View File

@@ -1,5 +1,6 @@
#pragma once
#include <XCEngine/Rendering/Execution/FrameExecutionContext.h>
#include <XCEngine/Rendering/RenderContext.h>
#include <cstddef>
@@ -25,6 +26,23 @@ struct RenderPassContext {
RHI::ResourceStates sourceColorState = RHI::ResourceStates::Common;
};
inline RenderPassContext BuildRenderPassContext(
const FrameExecutionContext& executionContext) {
return {
executionContext.renderContext,
executionContext.surface,
executionContext.sceneData,
executionContext.sourceSurface,
executionContext.sourceColorView,
executionContext.sourceColorState
};
}
inline RenderPassContext BuildRenderPassContext(
const ScenePhaseExecutionContext& executionContext) {
return BuildRenderPassContext(executionContext.frameContext);
}
class RenderPass {
public:
virtual ~RenderPass() = default;

View File

@@ -1,5 +1,6 @@
#pragma once
#include <XCEngine/Rendering/Execution/FrameExecutionContext.h>
#include <XCEngine/Rendering/FrameData/RenderSceneData.h>
#include <XCEngine/Rendering/RenderContext.h>
@@ -14,6 +15,12 @@ public:
virtual bool Initialize(const RenderContext& context) = 0;
virtual void Shutdown() = 0;
virtual bool Render(const FrameExecutionContext& executionContext) {
return Render(
executionContext.renderContext,
executionContext.surface,
executionContext.sceneData);
}
virtual bool Render(
const RenderContext& context,
const RenderSurface& surface,

View File

@@ -0,0 +1,24 @@
#pragma once
#include <XCEngine/Rendering/RenderPass.h>
namespace XCEngine {
namespace Rendering {
class SceneRenderFeaturePass : public RenderPass {
public:
~SceneRenderFeaturePass() override = default;
virtual bool IsActive(const RenderSceneData& sceneData) const = 0;
virtual bool Prepare(
const RenderContext& renderContext,
const RenderSceneData& sceneData) {
(void)renderContext;
(void)sceneData;
return true;
}
};
} // namespace Rendering
} // namespace XCEngine