Graphics: Rework shadowing (add cascaded shadow mapping)
- Add support for per-viewer shadows - Add cascaded shadow mapping for directional lights (wip) - Rework the way lights are sent to the shaders (they are now selected once per viewer) - Fixes PointLight shadow mapping (using a dedicated pass) - Lights out of frustum for every viewers are no longer processed (wip)
This commit is contained in:
committed by
Jérôme Leclercq
parent
a08850946a
commit
9aebb4f745
@@ -61,7 +61,6 @@ namespace Nz
|
||||
std::size_t m_lastVisibilityHash;
|
||||
std::string m_passName;
|
||||
std::vector<std::unique_ptr<ElementRendererData>> m_elementRendererData;
|
||||
std::vector<ElementRenderer::RenderStates> m_renderStates;
|
||||
std::vector<RenderElementOwner> m_renderElements;
|
||||
std::unordered_map<const MaterialInstance*, MaterialPassEntry> m_materialInstances;
|
||||
RenderQueue<const RenderElement*> m_renderQueue;
|
||||
|
||||
@@ -24,9 +24,9 @@ namespace Nz
|
||||
DirectionalLight(DirectionalLight&&) noexcept = default;
|
||||
~DirectionalLight() = default;
|
||||
|
||||
float ComputeContributionScore(const BoundingVolumef& boundingVolume) const override;
|
||||
float ComputeContributionScore(const Frustumf& viewerFrustum) const override;
|
||||
|
||||
void FillLightData(void* data) const override;
|
||||
bool FrustumCull(const Frustumf& viewerFrustum) const override;
|
||||
|
||||
std::unique_ptr<LightShadowData> InstanciateShadowData(FramePipeline& pipeline, ElementRendererRegistry& elementRegistry) const override;
|
||||
|
||||
|
||||
94
include/Nazara/Graphics/DirectionalLightShadowData.hpp
Normal file
94
include/Nazara/Graphics/DirectionalLightShadowData.hpp
Normal file
@@ -0,0 +1,94 @@
|
||||
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_GRAPHICS_DIRECTIONALLIGHTSHADOWDATA_HPP
|
||||
#define NAZARA_GRAPHICS_DIRECTIONALLIGHTSHADOWDATA_HPP
|
||||
|
||||
#include <NazaraUtils/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/DepthPipelinePass.hpp>
|
||||
#include <Nazara/Graphics/Light.hpp>
|
||||
#include <Nazara/Graphics/LightShadowData.hpp>
|
||||
#include <Nazara/Graphics/ShadowViewer.hpp>
|
||||
#include <NazaraUtils/FixedVector.hpp>
|
||||
#include <NazaraUtils/SparsePtr.hpp>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class FramePipeline;
|
||||
class DirectionalLight;
|
||||
|
||||
class NAZARA_GRAPHICS_API DirectionalLightShadowData : public LightShadowData
|
||||
{
|
||||
public:
|
||||
DirectionalLightShadowData(FramePipeline& pipeline, ElementRendererRegistry& elementRegistry, const DirectionalLight& light, std::size_t cascadeCount);
|
||||
DirectionalLightShadowData(const DirectionalLightShadowData&) = delete;
|
||||
DirectionalLightShadowData(DirectionalLightShadowData&&) = delete;
|
||||
~DirectionalLightShadowData() = default;
|
||||
|
||||
inline void EnableShadowStabilization(bool enable);
|
||||
|
||||
inline std::size_t GetCascadeCount() const;
|
||||
inline void GetCascadeData(const AbstractViewer* viewer, SparsePtr<float> distance, SparsePtr<Matrix4f> viewProjMatrix) const;
|
||||
|
||||
inline bool IsShadowStabilization() const;
|
||||
|
||||
void PrepareRendering(RenderFrame& renderFrame, const AbstractViewer* viewer) override;
|
||||
|
||||
void RegisterMaterialInstance(const MaterialInstance& matInstance) override;
|
||||
void RegisterPassInputs(FramePass& pass, const AbstractViewer* viewer) override;
|
||||
void RegisterToFrameGraph(FrameGraph& frameGraph, const AbstractViewer* viewer) override;
|
||||
void RegisterViewer(const AbstractViewer* viewer) override;
|
||||
|
||||
const Texture* RetrieveLightShadowmap(const BakedFrameGraph& bakedGraph, const AbstractViewer* viewer) const override;
|
||||
|
||||
void UnregisterMaterialInstance(const MaterialInstance& matInstance) override;
|
||||
void UnregisterViewer(const AbstractViewer* viewer) override;
|
||||
|
||||
DirectionalLightShadowData& operator=(const DirectionalLightShadowData&) = delete;
|
||||
DirectionalLightShadowData& operator=(DirectionalLightShadowData&&) = delete;
|
||||
|
||||
private:
|
||||
struct CascadeData;
|
||||
|
||||
template<typename F> void ForEachCascade(F&& callback);
|
||||
|
||||
void ComputeLightView(CascadeData& cascade, const Frustumf& cascadeFrustum, float cascadeDist);
|
||||
void StabilizeShadows(CascadeData& cascade);
|
||||
|
||||
NazaraSlot(Light, OnLightShadowMapSettingChange, m_onLightShadowMapSettingChange);
|
||||
NazaraSlot(Light, OnLightTransformInvalided, m_onLightTransformInvalidated);
|
||||
|
||||
struct CascadeData
|
||||
{
|
||||
std::optional<DepthPipelinePass> depthPass;
|
||||
std::size_t attachmentIndex;
|
||||
Matrix4f viewProjMatrix;
|
||||
ShadowViewer viewer;
|
||||
float distance;
|
||||
};
|
||||
|
||||
struct PerViewerData
|
||||
{
|
||||
FixedVector<CascadeData, 8> cascades;
|
||||
std::size_t textureArrayAttachmentIndex;
|
||||
};
|
||||
|
||||
std::size_t m_cascadeCount;
|
||||
std::unordered_map<const AbstractViewer*, std::unique_ptr<PerViewerData>> m_viewerData;
|
||||
ElementRendererRegistry& m_elementRegistry;
|
||||
FramePipeline& m_pipeline;
|
||||
const DirectionalLight& m_light;
|
||||
bool m_isShadowStabilizationEnabled;
|
||||
float m_invTexelScale;
|
||||
float m_texelScale;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DirectionalLightShadowData.inl>
|
||||
|
||||
#endif // NAZARA_GRAPHICS_DIRECTIONALLIGHTSHADOWDATA_HPP
|
||||
42
include/Nazara/Graphics/DirectionalLightShadowData.inl
Normal file
42
include/Nazara/Graphics/DirectionalLightShadowData.inl
Normal file
@@ -0,0 +1,42 @@
|
||||
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <cassert>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline void DirectionalLightShadowData::EnableShadowStabilization(bool enable)
|
||||
{
|
||||
m_isShadowStabilizationEnabled = enable;
|
||||
}
|
||||
|
||||
inline std::size_t DirectionalLightShadowData::GetCascadeCount() const
|
||||
{
|
||||
return m_cascadeCount;
|
||||
}
|
||||
|
||||
inline void DirectionalLightShadowData::GetCascadeData(const AbstractViewer* viewer, SparsePtr<float> distance, SparsePtr<Matrix4f> viewProjMatrix) const
|
||||
{
|
||||
assert(viewer);
|
||||
PerViewerData& viewerData = *Retrieve(m_viewerData, viewer);
|
||||
|
||||
for (const auto& cascadeData : viewerData.cascades)
|
||||
{
|
||||
if (distance)
|
||||
*distance++ = cascadeData.distance;
|
||||
|
||||
if (viewProjMatrix)
|
||||
*viewProjMatrix++ = cascadeData.viewProjMatrix;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool DirectionalLightShadowData::IsShadowStabilization() const
|
||||
{
|
||||
return m_isShadowStabilizationEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <Nazara/Graphics/PredefinedShaderStructs.hpp>
|
||||
#include <Nazara/Graphics/RenderElementPool.hpp>
|
||||
#include <Nazara/Renderer/RenderBufferView.hpp>
|
||||
#include <NazaraUtils/SparsePtr.hpp>
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
@@ -24,6 +25,7 @@ namespace Nz
|
||||
class CommandBufferBuilder;
|
||||
class RenderElement;
|
||||
class RenderFrame;
|
||||
class Texture;
|
||||
class ViewerInstance;
|
||||
struct ElementRendererData;
|
||||
|
||||
@@ -38,7 +40,7 @@ namespace Nz
|
||||
virtual RenderElementPoolBase& GetPool() = 0;
|
||||
|
||||
virtual std::unique_ptr<ElementRendererData> InstanciateData() = 0;
|
||||
virtual void Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& currentFrame, std::size_t elementCount, const Pointer<const RenderElement>* elements, const RenderStates* renderStates);
|
||||
virtual void Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& currentFrame, std::size_t elementCount, const Pointer<const RenderElement>* elements, SparsePtr<const RenderStates> renderStates);
|
||||
virtual void PrepareEnd(RenderFrame& currentFrame, ElementRendererData& rendererData);
|
||||
virtual void Render(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, CommandBufferBuilder& commandBuffer, std::size_t elementCount, const Pointer<const RenderElement>* elements) = 0;
|
||||
virtual void Reset(ElementRendererData& rendererData, RenderFrame& currentFrame);
|
||||
@@ -47,12 +49,14 @@ namespace Nz
|
||||
{
|
||||
RenderStates()
|
||||
{
|
||||
shadowMaps2D.fill(nullptr);
|
||||
shadowMapsCube.fill(nullptr);
|
||||
shadowMapsDirectional.fill(nullptr);
|
||||
shadowMapsPoint.fill(nullptr);
|
||||
shadowMapsSpot.fill(nullptr);
|
||||
}
|
||||
|
||||
std::array<const Texture*, PredefinedLightData::MaxLightCount> shadowMaps2D;
|
||||
std::array<const Texture*, PredefinedLightData::MaxLightCount> shadowMapsCube;
|
||||
std::array<const Texture*, PredefinedLightData::MaxLightCount> shadowMapsDirectional;
|
||||
std::array<const Texture*, PredefinedLightData::MaxLightCount> shadowMapsPoint;
|
||||
std::array<const Texture*, PredefinedLightData::MaxLightCount> shadowMapsSpot;
|
||||
RenderBufferView lightData;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -125,8 +125,9 @@ namespace Nz
|
||||
InstanceDataUbo,
|
||||
LightDataUbo,
|
||||
OverlayTexture,
|
||||
Shadowmap2D,
|
||||
ShadowmapCube,
|
||||
ShadowmapDirectional,
|
||||
ShadowmapPoint,
|
||||
ShadowmapSpot,
|
||||
SkeletalDataUbo,
|
||||
ViewerDataUbo,
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/DebugDrawPipelinePass.hpp>
|
||||
#include <Nazara/Graphics/DepthPipelinePass.hpp>
|
||||
#include <Nazara/Graphics/ElementRenderer.hpp>
|
||||
#include <Nazara/Graphics/ForwardPipelinePass.hpp>
|
||||
#include <Nazara/Graphics/FramePipeline.hpp>
|
||||
#include <Nazara/Graphics/InstancedRenderable.hpp>
|
||||
@@ -35,6 +34,7 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class LightShadowData;
|
||||
class RenderFrame;
|
||||
class RenderTarget;
|
||||
|
||||
@@ -59,7 +59,8 @@ namespace Nz
|
||||
std::size_t RegisterWorldInstance(WorldInstancePtr worldInstance) override;
|
||||
|
||||
const Light* RetrieveLight(std::size_t lightIndex) const override;
|
||||
const Texture* RetrieveLightShadowmap(std::size_t lightIndex) const override;
|
||||
const LightShadowData* RetrieveLightShadowData(std::size_t lightIndex) const override;
|
||||
const Texture* RetrieveLightShadowmap(std::size_t lightIndex, const AbstractViewer* viewer) const override;
|
||||
|
||||
void Render(RenderFrame& renderFrame) override;
|
||||
|
||||
@@ -132,6 +133,12 @@ namespace Nz
|
||||
|
||||
struct ViewerData
|
||||
{
|
||||
struct FrameData
|
||||
{
|
||||
Bitset<UInt64> visibleLights;
|
||||
Frustumf frustum;
|
||||
};
|
||||
|
||||
std::size_t finalColorAttachment;
|
||||
std::size_t forwardColorAttachment;
|
||||
std::size_t debugColorAttachment;
|
||||
@@ -145,6 +152,8 @@ namespace Nz
|
||||
RenderQueueRegistry forwardRegistry;
|
||||
RenderQueue<RenderElement*> forwardRenderQueue;
|
||||
ShaderBindingPtr blitShaderBinding;
|
||||
FrameData frame;
|
||||
bool pendingDestruction = false;
|
||||
|
||||
NazaraSlot(TransferInterface, OnTransferRequired, onTransferRequired);
|
||||
};
|
||||
@@ -158,17 +167,17 @@ namespace Nz
|
||||
|
||||
std::unordered_map<const RenderTarget*, RenderTargetData> m_renderTargets;
|
||||
std::unordered_map<MaterialInstance*, MaterialInstanceData> m_materialInstances;
|
||||
std::vector<ElementRenderer::RenderStates> m_renderStates;
|
||||
mutable std::vector<FramePipelinePass::VisibleRenderable> m_visibleRenderables;
|
||||
std::vector<std::size_t> m_visibleLights;
|
||||
robin_hood::unordered_set<TransferInterface*> m_transferSet;
|
||||
BakedFrameGraph m_bakedFrameGraph;
|
||||
Bitset<UInt64> m_shadowCastingLights;
|
||||
Bitset<UInt64> m_activeLights;
|
||||
Bitset<UInt64> m_removedSkeletonInstances;
|
||||
Bitset<UInt64> m_removedViewerInstances;
|
||||
Bitset<UInt64> m_removedWorldInstances;
|
||||
Bitset<UInt64> m_shadowCastingLights;
|
||||
Bitset<UInt64> m_visibleShadowCastingLights;
|
||||
ElementRendererRegistry& m_elementRegistry;
|
||||
mutable MemoryPool<RenderableData> m_renderablePool; //< FIXME: has to be mutable because MemoryPool has no const_iterator
|
||||
MemoryPool<RenderableData> m_renderablePool;
|
||||
MemoryPool<LightData> m_lightPool;
|
||||
MemoryPool<SkeletonInstanceData> m_skeletonInstances;
|
||||
MemoryPool<ViewerData> m_viewerPool;
|
||||
|
||||
@@ -11,9 +11,7 @@
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/ElementRenderer.hpp>
|
||||
#include <Nazara/Graphics/FramePipelinePass.hpp>
|
||||
#include <Nazara/Graphics/Light.hpp>
|
||||
#include <Nazara/Graphics/MaterialInstance.hpp>
|
||||
#include <Nazara/Graphics/MaterialPass.hpp>
|
||||
#include <Nazara/Graphics/RenderElement.hpp>
|
||||
#include <Nazara/Graphics/RenderElementOwner.hpp>
|
||||
#include <Nazara/Graphics/RenderQueue.hpp>
|
||||
@@ -24,13 +22,16 @@
|
||||
namespace Nz
|
||||
{
|
||||
class AbstractViewer;
|
||||
class DirectionalLight;
|
||||
class ElementRendererRegistry;
|
||||
class FrameGraph;
|
||||
class FramePass;
|
||||
class FramePipeline;
|
||||
class Light;
|
||||
|
||||
class NAZARA_GRAPHICS_API ForwardPipelinePass : public FramePipelinePass
|
||||
class PointLight;
|
||||
class SpotLight;
|
||||
|
||||
class NAZARA_GRAPHICS_API ForwardPipelinePass : public FramePipelinePass, TransferInterface
|
||||
{
|
||||
public:
|
||||
ForwardPipelinePass(FramePipeline& owner, ElementRendererRegistry& elementRegistry, AbstractViewer* viewer);
|
||||
@@ -41,7 +42,7 @@ namespace Nz
|
||||
inline void InvalidateCommandBuffers();
|
||||
inline void InvalidateElements();
|
||||
|
||||
void Prepare(RenderFrame& renderFrame, const Frustumf& frustum, const std::vector<FramePipelinePass::VisibleRenderable>& visibleRenderables, const std::vector<std::size_t>& visibleLights, std::size_t visibilityHash);
|
||||
void Prepare(RenderFrame& renderFrame, const Frustumf& frustum, const std::vector<FramePipelinePass::VisibleRenderable>& visibleRenderables, const Bitset<UInt64>& visibleLights, std::size_t visibilityHash);
|
||||
|
||||
void RegisterMaterialInstance(const MaterialInstance& material);
|
||||
FramePass& RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t colorBufferIndex, std::size_t depthBufferIndex, bool hasDepthPrepass);
|
||||
@@ -51,9 +52,14 @@ namespace Nz
|
||||
ForwardPipelinePass& operator=(const ForwardPipelinePass&) = delete;
|
||||
ForwardPipelinePass& operator=(ForwardPipelinePass&&) = delete;
|
||||
|
||||
static constexpr std::size_t MaxLightCountPerDraw = 3;
|
||||
|
||||
private:
|
||||
void OnTransfer(RenderFrame& renderFrame, CommandBufferBuilder& builder) override;
|
||||
|
||||
void PrepareDirectionalLights(void* lightMemory);
|
||||
void PreparePointLights(void* lightMemory);
|
||||
void PrepareSpotLights(void* lightMemory);
|
||||
void PrepareLights(RenderFrame& renderFrame, const Frustumf& frustum, const Bitset<UInt64>& visibleLights);
|
||||
|
||||
struct MaterialPassEntry
|
||||
{
|
||||
std::size_t usedCount = 1;
|
||||
@@ -62,55 +68,30 @@ namespace Nz
|
||||
NazaraSlot(MaterialInstance, OnMaterialInstanceShaderBindingInvalidated, onMaterialInstanceShaderBindingInvalidated);
|
||||
};
|
||||
|
||||
using LightKey = std::array<const Light*, MaxLightCountPerDraw>;
|
||||
|
||||
struct LightKeyHasher
|
||||
{
|
||||
inline std::size_t operator()(const LightKey& lightKey) const;
|
||||
};
|
||||
|
||||
struct LightDataUbo
|
||||
{
|
||||
std::shared_ptr<RenderBuffer> renderBuffer;
|
||||
std::size_t offset = 0;
|
||||
UploadPool::Allocation* allocation = nullptr;
|
||||
};
|
||||
|
||||
struct LightPerElementData
|
||||
{
|
||||
RenderBufferView lightUniformBuffer;
|
||||
std::array<const Texture*, MaxLightCountPerDraw> shadowMaps;
|
||||
std::size_t lightCount;
|
||||
};
|
||||
|
||||
struct LightUboPool
|
||||
{
|
||||
std::vector<std::shared_ptr<RenderBuffer>> lightUboBuffers;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct RenderableLight
|
||||
{
|
||||
const Light* light;
|
||||
const T* light;
|
||||
std::size_t lightIndex;
|
||||
float contributionScore;
|
||||
};
|
||||
|
||||
std::size_t m_forwardPassIndex;
|
||||
std::size_t m_lastVisibilityHash;
|
||||
std::shared_ptr<LightUboPool> m_lightUboPool;
|
||||
std::shared_ptr<RenderBuffer> m_lightDataBuffer;
|
||||
std::vector<std::unique_ptr<ElementRendererData>> m_elementRendererData;
|
||||
std::vector<ElementRenderer::RenderStates> m_renderStates;
|
||||
std::vector<RenderElementOwner> m_renderElements;
|
||||
std::unordered_map<const MaterialInstance*, MaterialPassEntry> m_materialInstances;
|
||||
std::unordered_map<const RenderElement*, LightPerElementData> m_lightPerRenderElement;
|
||||
std::unordered_map<LightKey, RenderBufferView, LightKeyHasher> m_lightBufferPerLights;
|
||||
std::vector<LightDataUbo> m_lightDataBuffers;
|
||||
std::vector<RenderableLight> m_renderableLights;
|
||||
std::vector<RenderableLight<DirectionalLight>> m_directionalLights;
|
||||
std::vector<RenderableLight<PointLight>> m_pointLights;
|
||||
std::vector<RenderableLight<SpotLight>> m_spotLights;
|
||||
ElementRenderer::RenderStates m_renderState;
|
||||
RenderQueue<const RenderElement*> m_renderQueue;
|
||||
RenderQueueRegistry m_renderQueueRegistry;
|
||||
AbstractViewer* m_viewer;
|
||||
ElementRendererRegistry& m_elementRegistry;
|
||||
FramePipeline& m_pipeline;
|
||||
UploadPool::Allocation* m_pendingLightUploadAllocation;
|
||||
bool m_rebuildCommandBuffer;
|
||||
bool m_rebuildElements;
|
||||
};
|
||||
|
||||
@@ -15,21 +15,6 @@ namespace Nz
|
||||
{
|
||||
m_rebuildElements = true;
|
||||
}
|
||||
|
||||
inline std::size_t ForwardPipelinePass::LightKeyHasher::operator()(const LightKey& lightKey) const
|
||||
{
|
||||
std::size_t lightHash = 5;
|
||||
auto CombineHash = [](std::size_t currentHash, std::size_t newHash)
|
||||
{
|
||||
return currentHash * 23 + newHash;
|
||||
};
|
||||
|
||||
std::hash<const Light*> lightPtrHasher;
|
||||
for (std::size_t i = 0; i < lightKey.size(); ++i)
|
||||
lightHash = CombineHash(lightHash, lightPtrHasher(lightKey[i]));
|
||||
|
||||
return lightHash;
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/LightShadowData.hpp>
|
||||
#include <Nazara/Math/BoundingVolume.hpp>
|
||||
#include <Nazara/Math/Frustum.hpp>
|
||||
#include <Nazara/Math/Quaternion.hpp>
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
#include <Nazara/Utility/PixelFormat.hpp>
|
||||
@@ -19,12 +20,8 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class CommandBufferBuilder;
|
||||
class ElementRendererRegistry;
|
||||
class FramePipeline;
|
||||
class RenderBuffer;
|
||||
class RenderFrame;
|
||||
class Texture;
|
||||
|
||||
class NAZARA_GRAPHICS_API Light
|
||||
{
|
||||
@@ -34,11 +31,11 @@ namespace Nz
|
||||
Light(Light&&) noexcept = default;
|
||||
virtual ~Light();
|
||||
|
||||
virtual float ComputeContributionScore(const BoundingVolumef& boundingVolume) const = 0;
|
||||
virtual float ComputeContributionScore(const Frustumf& viewerFrustum) const = 0;
|
||||
|
||||
inline void EnableShadowCasting(bool castShadows);
|
||||
|
||||
virtual void FillLightData(void* data) const = 0;
|
||||
virtual bool FrustumCull(const Frustumf& viewerFrustum) const = 0;
|
||||
|
||||
inline const BoundingVolumef& GetBoundingVolume() const;
|
||||
inline UInt8 GetLightType() const;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class AbstractViewer;
|
||||
class BakedFrameGraph;
|
||||
class FrameGraph;
|
||||
class FramePass;
|
||||
@@ -22,25 +23,33 @@ namespace Nz
|
||||
class NAZARA_GRAPHICS_API LightShadowData
|
||||
{
|
||||
public:
|
||||
LightShadowData() = default;
|
||||
inline LightShadowData();
|
||||
LightShadowData(const LightShadowData&) = delete;
|
||||
LightShadowData(LightShadowData&&) = delete;
|
||||
virtual ~LightShadowData();
|
||||
|
||||
virtual void PrepareRendering(RenderFrame& renderFrame) = 0;
|
||||
inline bool IsPerViewer() const;
|
||||
|
||||
virtual void PrepareRendering(RenderFrame& renderFrame, const AbstractViewer* viewer) = 0;
|
||||
|
||||
virtual void RegisterMaterialInstance(const MaterialInstance& matInstance) = 0;
|
||||
virtual void RegisterPassInputs(FramePass& pass) = 0;
|
||||
virtual void RegisterToFrameGraph(FrameGraph& frameGraph) = 0;
|
||||
virtual void RegisterPassInputs(FramePass& pass, const AbstractViewer* viewer) = 0;
|
||||
virtual void RegisterToFrameGraph(FrameGraph& frameGraph, const AbstractViewer* viewer) = 0;
|
||||
virtual void RegisterViewer(const AbstractViewer* viewer);
|
||||
|
||||
virtual const Texture* RetrieveLightShadowmap(const BakedFrameGraph& bakedGraph) const = 0;
|
||||
virtual const Texture* RetrieveLightShadowmap(const BakedFrameGraph& bakedGraph, const AbstractViewer* viewer) const = 0;
|
||||
|
||||
virtual void UnregisterMaterialInstance(const MaterialInstance& matInstance) = 0;
|
||||
virtual void UnregisterViewer(const AbstractViewer* viewer);
|
||||
|
||||
LightShadowData& operator=(const LightShadowData&) = delete;
|
||||
LightShadowData& operator=(LightShadowData&&) = delete;
|
||||
|
||||
protected:
|
||||
inline void UpdatePerViewerStatus(bool isPerViewer);
|
||||
|
||||
private:
|
||||
bool m_isPerViewer;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,20 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline LightShadowData::LightShadowData() :
|
||||
m_isPerViewer(false)
|
||||
{
|
||||
}
|
||||
|
||||
inline void LightShadowData::UpdatePerViewerStatus(bool isPerViewer)
|
||||
{
|
||||
m_isPerViewer = isPerViewer;
|
||||
}
|
||||
|
||||
inline bool LightShadowData::IsPerViewer() const
|
||||
{
|
||||
return m_isPerViewer;
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
|
||||
@@ -23,9 +23,9 @@ namespace Nz
|
||||
PointLight(PointLight&&) noexcept = default;
|
||||
~PointLight() = default;
|
||||
|
||||
float ComputeContributionScore(const BoundingVolumef& boundingVolume) const override;
|
||||
float ComputeContributionScore(const Frustumf& viewerFrustum) const override;
|
||||
|
||||
void FillLightData(void* data) const override;
|
||||
bool FrustumCull(const Frustumf& viewerFrustum) const override;
|
||||
|
||||
std::unique_ptr<LightShadowData> InstanciateShadowData(FramePipeline& pipeline, ElementRendererRegistry& elementRegistry) const override;
|
||||
|
||||
@@ -33,6 +33,7 @@ namespace Nz
|
||||
inline float GetDiffuseFactor() const;
|
||||
inline Color GetColor() const;
|
||||
inline const Vector3f& GetPosition() const;
|
||||
inline float GetInvRadius() const;
|
||||
inline float GetRadius() const;
|
||||
|
||||
inline void UpdateAmbientFactor(float factor);
|
||||
|
||||
@@ -28,14 +28,19 @@ namespace Nz
|
||||
return m_color;
|
||||
}
|
||||
|
||||
inline float PointLight::GetDiffuseFactor() const
|
||||
{
|
||||
return m_diffuseFactor;
|
||||
}
|
||||
|
||||
inline const Vector3f& PointLight::GetPosition() const
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
|
||||
inline float PointLight::GetDiffuseFactor() const
|
||||
inline float PointLight::GetInvRadius() const
|
||||
{
|
||||
return m_diffuseFactor;
|
||||
return m_invRadius;
|
||||
}
|
||||
|
||||
inline float PointLight::GetRadius() const
|
||||
|
||||
@@ -28,13 +28,13 @@ namespace Nz
|
||||
PointLightShadowData(PointLightShadowData&&) = delete;
|
||||
~PointLightShadowData() = default;
|
||||
|
||||
void PrepareRendering(RenderFrame& renderFrame) override;
|
||||
void PrepareRendering(RenderFrame& renderFrame, const AbstractViewer* viewer) override;
|
||||
|
||||
void RegisterMaterialInstance(const MaterialInstance& matInstance) override;
|
||||
void RegisterPassInputs(FramePass& pass) override;
|
||||
void RegisterToFrameGraph(FrameGraph& frameGraph) override;
|
||||
void RegisterPassInputs(FramePass& pass, const AbstractViewer* viewer) override;
|
||||
void RegisterToFrameGraph(FrameGraph& frameGraph, const AbstractViewer* viewer) override;
|
||||
|
||||
const Texture* RetrieveLightShadowmap(const BakedFrameGraph& bakedGraph) const override;
|
||||
const Texture* RetrieveLightShadowmap(const BakedFrameGraph& bakedGraph, const AbstractViewer* viewer) const override;
|
||||
|
||||
void UnregisterMaterialInstance(const MaterialInstance& matInstance) override;
|
||||
|
||||
|
||||
@@ -24,19 +24,24 @@ namespace Nz
|
||||
SpotLight(SpotLight&&) noexcept = default;
|
||||
~SpotLight() = default;
|
||||
|
||||
float ComputeContributionScore(const BoundingVolumef& boundingVolume) const override;
|
||||
float ComputeContributionScore(const Frustumf& viewerFrustum) const override;
|
||||
|
||||
void FillLightData(void* data) const override;
|
||||
bool FrustumCull(const Frustumf& viewerFrustum) const override;
|
||||
|
||||
inline float GetAmbientFactor() const;
|
||||
inline float GetDiffuseFactor() const;
|
||||
inline Color GetColor() const;
|
||||
inline const Vector3f& GetDirection() const;
|
||||
inline RadianAnglef GetInnerAngle() const;
|
||||
inline float GetInnerAngleCos() const;
|
||||
inline float GetInvRadius() const;
|
||||
inline RadianAnglef GetOuterAngle() const;
|
||||
inline float GetOuterAngleCos() const;
|
||||
inline float GetOuterAngleTan() const;
|
||||
inline const Vector3f& GetPosition() const;
|
||||
inline const Quaternionf& GetRotation() const;
|
||||
inline float GetRadius() const;
|
||||
inline const Matrix4f& GetViewProjMatrix() const;
|
||||
|
||||
std::unique_ptr<LightShadowData> InstanciateShadowData(FramePipeline& pipeline, ElementRendererRegistry& elementRegistry) const override;
|
||||
|
||||
|
||||
@@ -31,6 +31,11 @@ namespace Nz
|
||||
return m_color;
|
||||
}
|
||||
|
||||
inline float SpotLight::GetDiffuseFactor() const
|
||||
{
|
||||
return m_diffuseFactor;
|
||||
}
|
||||
|
||||
inline const Vector3f& SpotLight::GetDirection() const
|
||||
{
|
||||
return m_direction;
|
||||
@@ -41,11 +46,31 @@ namespace Nz
|
||||
return m_innerAngle;
|
||||
}
|
||||
|
||||
inline float SpotLight::GetInnerAngleCos() const
|
||||
{
|
||||
return m_innerAngleCos;
|
||||
}
|
||||
|
||||
inline float SpotLight::GetInvRadius() const
|
||||
{
|
||||
return m_invRadius;
|
||||
}
|
||||
|
||||
inline RadianAnglef SpotLight::GetOuterAngle() const
|
||||
{
|
||||
return m_outerAngle;
|
||||
}
|
||||
|
||||
inline float SpotLight::GetOuterAngleCos() const
|
||||
{
|
||||
return m_outerAngleCos;
|
||||
}
|
||||
|
||||
inline float SpotLight::GetOuterAngleTan() const
|
||||
{
|
||||
return m_outerAngleTan;
|
||||
}
|
||||
|
||||
inline const Vector3f& SpotLight::GetPosition() const
|
||||
{
|
||||
return m_position;
|
||||
@@ -56,16 +81,16 @@ namespace Nz
|
||||
return m_rotation;
|
||||
}
|
||||
|
||||
inline float SpotLight::GetDiffuseFactor() const
|
||||
{
|
||||
return m_diffuseFactor;
|
||||
}
|
||||
|
||||
inline float SpotLight::GetRadius() const
|
||||
{
|
||||
return m_radius;
|
||||
}
|
||||
|
||||
inline const Matrix4f& SpotLight::GetViewProjMatrix() const
|
||||
{
|
||||
return m_viewProjMatrix;
|
||||
}
|
||||
|
||||
inline void SpotLight::UpdateAmbientFactor(float factor)
|
||||
{
|
||||
m_ambientFactor = factor;
|
||||
@@ -164,10 +189,10 @@ namespace Nz
|
||||
|
||||
inline void SpotLight::UpdateViewProjMatrix()
|
||||
{
|
||||
Matrix4f biasMatrix(0.5f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.5f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.5f, 0.5f, 0.0f, 1.0f);
|
||||
constexpr Matrix4f biasMatrix(0.5f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.5f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.5f, 0.5f, 0.0f, 1.0f);
|
||||
|
||||
Matrix4f projection = Matrix4f::Perspective(m_outerAngle * 2.f, 1.f, 0.01f, m_radius);
|
||||
Matrix4f view = Matrix4f::TransformInverse(m_position, m_rotation);
|
||||
|
||||
@@ -26,13 +26,15 @@ namespace Nz
|
||||
SpotLightShadowData(SpotLightShadowData&&) = delete;
|
||||
~SpotLightShadowData() = default;
|
||||
|
||||
void PrepareRendering(RenderFrame& renderFrame) override;
|
||||
inline const ViewerInstance& GetViewerInstance() const;
|
||||
|
||||
void PrepareRendering(RenderFrame& renderFrame, const AbstractViewer* viewer) override;
|
||||
|
||||
void RegisterMaterialInstance(const MaterialInstance& matInstance) override;
|
||||
void RegisterPassInputs(FramePass& pass) override;
|
||||
void RegisterToFrameGraph(FrameGraph& frameGraph) override;
|
||||
void RegisterPassInputs(FramePass& pass, const AbstractViewer* viewer) override;
|
||||
void RegisterToFrameGraph(FrameGraph& frameGraph, const AbstractViewer* viewer) override;
|
||||
|
||||
const Texture* RetrieveLightShadowmap(const BakedFrameGraph& bakedGraph) const override;
|
||||
const Texture* RetrieveLightShadowmap(const BakedFrameGraph& bakedGraph, const AbstractViewer* viewer) const override;
|
||||
|
||||
void UnregisterMaterialInstance(const MaterialInstance& matInstance) override;
|
||||
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline const ViewerInstance& SpotLightShadowData::GetViewerInstance() const
|
||||
{
|
||||
return m_viewer.GetViewerInstance();
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace Nz
|
||||
RenderElementPool<RenderSpriteChain>& GetPool() override;
|
||||
|
||||
std::unique_ptr<ElementRendererData> InstanciateData() override;
|
||||
void Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& currentFrame, std::size_t elementCount, const Pointer<const RenderElement>* elements, const RenderStates* renderStates) override;
|
||||
void Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& currentFrame, std::size_t elementCount, const Pointer<const RenderElement>* elements, SparsePtr<const RenderStates> renderStates) override;
|
||||
void PrepareEnd(RenderFrame& currentFrame, ElementRendererData& rendererData) override;
|
||||
void Render(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, CommandBufferBuilder& commandBuffer, std::size_t elementCount, const Pointer<const RenderElement>* elements) override;
|
||||
void Reset(ElementRendererData& rendererData, RenderFrame& currentFrame) override;
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Nz
|
||||
RenderElementPool<RenderSubmesh>& GetPool() override;
|
||||
|
||||
std::unique_ptr<ElementRendererData> InstanciateData() override;
|
||||
void Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& currentFrame, std::size_t elementCount, const Pointer<const RenderElement>* elements, const RenderStates* renderStates) override;
|
||||
void Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& currentFrame, std::size_t elementCount, const Pointer<const RenderElement>* elements, SparsePtr<const RenderStates> renderStates) override;
|
||||
void Render(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, CommandBufferBuilder& commandBuffer, std::size_t elementCount, const Pointer<const RenderElement>* elements) override;
|
||||
void Reset(ElementRendererData& rendererData, RenderFrame& currentFrame) override;
|
||||
|
||||
|
||||
@@ -56,6 +56,11 @@ namespace Nz
|
||||
constexpr IntersectionSide Intersect(const Sphere<T>& sphere) const;
|
||||
constexpr IntersectionSide Intersect(const Vector3<T>* points, std::size_t pointCount) const;
|
||||
|
||||
constexpr Frustum<T> Reduce(T nearFactor, T farFactor) const;
|
||||
|
||||
template<typename F> constexpr void Split(std::initializer_list<T> splitFactors, F&& callback) const;
|
||||
template<typename F> constexpr void Split(const T* splitFactors, std::size_t factorCount, F&& callback) const;
|
||||
|
||||
std::string ToString() const;
|
||||
|
||||
constexpr Frustum& operator=(const Frustum&) = default;
|
||||
|
||||
@@ -427,6 +427,38 @@ namespace Nz
|
||||
return side;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr Frustum<T> Frustum<T>::Reduce(T nearFactor, T farFactor) const
|
||||
{
|
||||
EnumArray<FrustumPlane, Plane<T>> planes = m_planes;
|
||||
planes[FrustumPlane::Near].distance = Lerp(m_planes[FrustumPlane::Near].distance, -m_planes[FrustumPlane::Far].distance, nearFactor);
|
||||
planes[FrustumPlane::Far].distance = Lerp(-m_planes[FrustumPlane::Near].distance, m_planes[FrustumPlane::Far].distance, farFactor);
|
||||
|
||||
return Frustum<T>(planes);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename F>
|
||||
constexpr void Frustum<T>::Split(std::initializer_list<T> splitFactors, F&& callback) const
|
||||
{
|
||||
return Split(splitFactors.begin(), splitFactors.size(), std::forward<F>(callback));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename F>
|
||||
constexpr void Frustum<T>::Split(const T* splitFactors, std::size_t factorCount, F&& callback) const
|
||||
{
|
||||
T previousFar = T(0.0);
|
||||
for (std::size_t i = 0; i < factorCount; ++i)
|
||||
{
|
||||
T farFactor = splitFactors[i];
|
||||
callback(previousFar, farFactor);
|
||||
previousFar = farFactor;
|
||||
}
|
||||
|
||||
callback(previousFar, T(1.0));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gives a string representation
|
||||
* \return A string representation of the object: "Frustum(Plane ...)"
|
||||
|
||||
Reference in New Issue
Block a user