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:
SirLynix
2023-09-06 13:20:52 +02:00
committed by Jérôme Leclercq
parent a08850946a
commit 9aebb4f745
41 changed files with 1320 additions and 576 deletions

View File

@@ -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;

View File

@@ -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;

View 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

View 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>

View File

@@ -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;
};
};

View File

@@ -125,8 +125,9 @@ namespace Nz
InstanceDataUbo,
LightDataUbo,
OverlayTexture,
Shadowmap2D,
ShadowmapCube,
ShadowmapDirectional,
ShadowmapPoint,
ShadowmapSpot,
SkeletalDataUbo,
ViewerDataUbo,

View File

@@ -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;

View File

@@ -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;
};

View File

@@ -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>

View File

@@ -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;

View File

@@ -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;
};
}

View File

@@ -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>

View File

@@ -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);

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -6,6 +6,10 @@
namespace Nz
{
inline const ViewerInstance& SpotLightShadowData::GetViewerInstance() const
{
return m_viewer.GetViewerInstance();
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@@ -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;

View File

@@ -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;