First shadow mapping commit

Former-commit-id: 7465a7c3297626f8db8c1ff48a20c0e0d9feb765
This commit is contained in:
Lynix 2015-06-16 14:21:20 +02:00
parent c879bd1656
commit 974df4288f
6 changed files with 190 additions and 28 deletions

View File

@ -8,6 +8,7 @@
#define NDK_SYSTEMS_RENDERSYSTEM_HPP #define NDK_SYSTEMS_RENDERSYSTEM_HPP
#include <Nazara/Graphics/ForwardRenderTechnique.hpp> #include <Nazara/Graphics/ForwardRenderTechnique.hpp>
#include <Nazara/Renderer/RenderTexture.hpp>
#include <NDK/EntityList.hpp> #include <NDK/EntityList.hpp>
#include <NDK/System.hpp> #include <NDK/System.hpp>
#include <unordered_map> #include <unordered_map>
@ -31,11 +32,14 @@ namespace Ndk
private: private:
void OnEntityRemoved(Entity* entity) override; void OnEntityRemoved(Entity* entity) override;
void OnEntityValidation(Entity* entity, bool justAdded) override; void OnEntityValidation(Entity* entity, bool justAdded) override;
void UpdateShadowMaps();
EntityList m_cameras; EntityList m_cameras;
EntityList m_drawables; EntityList m_drawables;
EntityList m_lights; EntityList m_lights;
NzForwardRenderTechnique m_renderTechnique; NzForwardRenderTechnique m_renderTechnique;
NzForwardRenderTechnique m_shadowTechnique;
NzRenderTexture m_shadowRT;
}; };
} }

View File

@ -3,7 +3,9 @@
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp // For conditions of distribution and use, see copyright notice in Prerequesites.hpp
#include <NDK/Systems/RenderSystem.hpp> #include <NDK/Systems/RenderSystem.hpp>
#include <Nazara/Graphics/Camera.hpp>
#include <Nazara/Graphics/ColorBackground.hpp> #include <Nazara/Graphics/ColorBackground.hpp>
#include <Nazara/Renderer/Renderer.hpp>
#include <NDK/Components/CameraComponent.hpp> #include <NDK/Components/CameraComponent.hpp>
#include <NDK/Components/GraphicsComponent.hpp> #include <NDK/Components/GraphicsComponent.hpp>
#include <NDK/Components/LightComponent.hpp> #include <NDK/Components/LightComponent.hpp>
@ -17,6 +19,8 @@ namespace Ndk
void RenderSystem::Update(float elapsedTime) void RenderSystem::Update(float elapsedTime)
{ {
UpdateShadowMaps();
for (const Ndk::EntityHandle& camera : m_cameras) for (const Ndk::EntityHandle& camera : m_cameras)
{ {
CameraComponent& camComponent = camera->GetComponent<CameraComponent>(); CameraComponent& camComponent = camera->GetComponent<CameraComponent>();
@ -25,10 +29,10 @@ namespace Ndk
NzAbstractRenderQueue* renderQueue = m_renderTechnique.GetRenderQueue(); NzAbstractRenderQueue* renderQueue = m_renderTechnique.GetRenderQueue();
renderQueue->Clear(); renderQueue->Clear();
for (const Ndk::EntityHandle& light : m_drawables) for (const Ndk::EntityHandle& drawable : m_drawables)
{ {
GraphicsComponent& graphicsComponent = light->GetComponent<GraphicsComponent>(); GraphicsComponent& graphicsComponent = drawable->GetComponent<GraphicsComponent>();
NodeComponent& drawableNode = light->GetComponent<NodeComponent>(); NodeComponent& drawableNode = drawable->GetComponent<NodeComponent>();
graphicsComponent.AddToRenderQueue(renderQueue); graphicsComponent.AddToRenderQueue(renderQueue);
} }
@ -36,9 +40,9 @@ namespace Ndk
for (const Ndk::EntityHandle& light : m_lights) for (const Ndk::EntityHandle& light : m_lights)
{ {
LightComponent& lightComponent = light->GetComponent<LightComponent>(); LightComponent& lightComponent = light->GetComponent<LightComponent>();
NodeComponent& drawableNode = light->GetComponent<NodeComponent>(); NodeComponent& lightNode = light->GetComponent<NodeComponent>();
lightComponent.AddToRenderQueue(renderQueue, drawableNode.GetTransformMatrix()); lightComponent.AddToRenderQueue(renderQueue, lightNode.GetTransformMatrix());
} }
NzColorBackground background; NzColorBackground background;
@ -83,5 +87,55 @@ namespace Ndk
m_lights.Remove(entity); m_lights.Remove(entity);
} }
void RenderSystem::UpdateShadowMaps()
{
if (!m_shadowRT.IsValid())
m_shadowRT.Create();
for (const Ndk::EntityHandle& light : m_lights)
{
LightComponent& lightComponent = light->GetComponent<LightComponent>();
NodeComponent& lightNode = light->GetComponent<NodeComponent>();
if (!lightComponent.IsShadowCastingEnabled() || lightComponent.GetLightType() != nzLightType_Spot)
continue;
/// HACKY
NzCamera lightPOV;
lightPOV.SetPosition(lightNode.GetPosition());
lightPOV.SetFOV(lightComponent.GetOuterAngle());
lightPOV.SetRotation(lightNode.GetRotation());
lightPOV.SetZFar(1000.f);
lightPOV.SetTarget(&m_shadowRT);
NzVector2ui shadowMapSize(lightComponent.GetShadowMap()->GetSize());
m_shadowRT.AttachTexture(nzAttachmentPoint_Depth, 0, lightComponent.GetShadowMap());
NzRenderer::SetMatrix(nzMatrixType_Projection, lightPOV.GetProjectionMatrix());
NzRenderer::SetMatrix(nzMatrixType_View, lightPOV.GetViewMatrix());
NzRenderer::SetTarget(&m_shadowRT);
NzRenderer::SetViewport(NzRecti(0, 0, shadowMapSize.x, shadowMapSize.y));
NzAbstractRenderQueue* renderQueue = m_renderTechnique.GetRenderQueue();
renderQueue->Clear();
for (const Ndk::EntityHandle& drawable : m_drawables)
{
GraphicsComponent& graphicsComponent = drawable->GetComponent<GraphicsComponent>();
NodeComponent& drawableNode = drawable->GetComponent<NodeComponent>();
graphicsComponent.AddToRenderQueue(renderQueue);
}
NzSceneData sceneData;
sceneData.ambientColor = NzColor(0, 0, 0);
sceneData.background = nullptr;
sceneData.viewer = &lightPOV;
m_renderTechnique.Draw(sceneData);
}
}
SystemIndex RenderSystem::systemIndex; SystemIndex RenderSystem::systemIndex;
} }

View File

@ -11,6 +11,8 @@
#include <Nazara/Core/Color.hpp> #include <Nazara/Core/Color.hpp>
#include <Nazara/Graphics/Enums.hpp> #include <Nazara/Graphics/Enums.hpp>
#include <Nazara/Graphics/Renderable.hpp> #include <Nazara/Graphics/Renderable.hpp>
#include <Nazara/Renderer/RenderTexture.hpp>
#include <Nazara/Renderer/Texture.hpp>
class NzLight; class NzLight;
struct NzLightUniforms; struct NzLightUniforms;
@ -19,7 +21,7 @@ class NAZARA_GRAPHICS_API NzLight : public NzRenderable
{ {
public: public:
NzLight(nzLightType type = nzLightType_Point); NzLight(nzLightType type = nzLightType_Point);
NzLight(const NzLight& light) = default; inline NzLight(const NzLight& light);
~NzLight() = default; ~NzLight() = default;
void AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const NzMatrix4f& transformMatrix) const override; void AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const NzMatrix4f& transformMatrix) const override;
@ -29,37 +31,48 @@ class NAZARA_GRAPHICS_API NzLight : public NzRenderable
bool Cull(const NzFrustumf& frustum, const NzMatrix4f& transformMatrix) const override; bool Cull(const NzFrustumf& frustum, const NzMatrix4f& transformMatrix) const override;
float GetAmbientFactor() const; inline void EnableShadowCasting(bool castShadows);
float GetAttenuation() const;
NzColor GetColor() const;
float GetDiffuseFactor() const;
float GetInnerAngle() const;
float GetInnerAngleCosine() const;
float GetInvRadius() const;
nzLightType GetLightType() const;
float GetOuterAngle() const;
float GetOuterAngleCosine() const;
float GetOuterAngleTangent() const;
float GetRadius() const;
void SetAmbientFactor(float factor); inline void EnsureShadowMapUpdate() const;
void SetAttenuation(float attenuation);
void SetColor(const NzColor& color); inline float GetAmbientFactor() const;
void SetDiffuseFactor(float factor); inline float GetAttenuation() const;
void SetInnerAngle(float innerAngle); inline NzColor GetColor() const;
void SetLightType(nzLightType type); inline float GetDiffuseFactor() const;
void SetOuterAngle(float outerAngle); inline float GetInnerAngle() const;
void SetRadius(float radius); inline float GetInnerAngleCosine() const;
inline float GetInvRadius() const;
inline nzLightType GetLightType() const;
inline float GetOuterAngle() const;
inline float GetOuterAngleCosine() const;
inline float GetOuterAngleTangent() const;
inline float GetRadius() const;
inline NzTextureRef GetShadowMap() const;
inline bool IsShadowCastingEnabled() const;
inline void SetAmbientFactor(float factor);
inline void SetAttenuation(float attenuation);
inline void SetColor(const NzColor& color);
inline void SetDiffuseFactor(float factor);
inline void SetInnerAngle(float innerAngle);
inline void SetLightType(nzLightType type);
inline void SetOuterAngle(float outerAngle);
inline void SetRadius(float radius);
void UpdateBoundingVolume(const NzMatrix4f& transformMatrix) override; void UpdateBoundingVolume(const NzMatrix4f& transformMatrix) override;
NzLight& operator=(const NzLight& light) = default; NzLight& operator=(const NzLight& light);
private: private:
void MakeBoundingVolume() const override; void MakeBoundingVolume() const override;
void UpdateShadowMap() const;
nzLightType m_type; nzLightType m_type;
NzColor m_color; NzColor m_color;
mutable NzTextureRef m_shadowMap;
bool m_shadowCastingEnabled;
mutable bool m_shadowMapUpdated;
float m_ambientFactor; float m_ambientFactor;
float m_attenuation; float m_attenuation;
float m_diffuseFactor; float m_diffuseFactor;

View File

@ -5,6 +5,40 @@
#include <memory> #include <memory>
#include <Nazara/Renderer/Debug.hpp> #include <Nazara/Renderer/Debug.hpp>
inline NzLight::NzLight(const NzLight& light) :
NzRenderable(light),
m_type(light.m_type),
m_color(light.m_color),
m_shadowCastingEnabled(light.m_shadowCastingEnabled),
m_shadowMapUpdated(false),
m_ambientFactor(light.m_ambientFactor),
m_attenuation(light.m_attenuation),
m_diffuseFactor(light.m_diffuseFactor),
m_innerAngle(light.m_innerAngle),
m_innerAngleCosine(light.m_innerAngleCosine),
m_invRadius(light.m_invRadius),
m_outerAngle(light.m_outerAngle),
m_outerAngleCosine(light.m_outerAngleCosine),
m_outerAngleTangent(light.m_outerAngleTangent),
m_radius(light.m_radius)
{
}
inline void NzLight::EnableShadowCasting(bool castShadows)
{
if (m_shadowCastingEnabled != castShadows)
{
m_shadowCastingEnabled = castShadows;
m_shadowMapUpdated = false;
}
}
inline void NzLight::EnsureShadowMapUpdate() const
{
if (!m_shadowMapUpdated)
UpdateShadowMap();
}
inline float NzLight::GetAmbientFactor() const inline float NzLight::GetAmbientFactor() const
{ {
return m_ambientFactor; return m_ambientFactor;
@ -45,6 +79,18 @@ inline float NzLight::GetRadius() const
return m_radius; return m_radius;
} }
inline NzTextureRef NzLight::GetShadowMap() const
{
EnsureShadowMapUpdate();
return m_shadowMap;
}
inline bool NzLight::IsShadowCastingEnabled() const
{
return m_shadowCastingEnabled;
}
inline void NzLight::SetAmbientFactor(float factor) inline void NzLight::SetAmbientFactor(float factor)
{ {
m_ambientFactor = factor; m_ambientFactor = factor;
@ -94,4 +140,26 @@ inline void NzLight::SetRadius(float radius)
InvalidateBoundingVolume(); InvalidateBoundingVolume();
} }
inline NzLight& NzLight::operator=(const NzLight& light)
{
NzRenderable::operator=(light);
m_ambientFactor = light.m_ambientFactor;
m_attenuation = light.m_attenuation;
m_color = light.m_color;
m_diffuseFactor = light.m_diffuseFactor;
m_innerAngle = light.m_innerAngle;
m_innerAngleCosine = light.m_innerAngleCosine;
m_invRadius = light.m_invRadius;
m_outerAngle = light.m_outerAngle;
m_outerAngleCosine = light.m_outerAngleCosine;
m_outerAngleTangent = light.m_outerAngleTangent;
m_radius = light.m_radius;
m_shadowCastingEnabled = light.m_shadowCastingEnabled;
m_shadowMapUpdated = false;
m_type = light.m_type;
return *this;
}
#include <Nazara/Renderer/DebugOff.hpp> #include <Nazara/Renderer/DebugOff.hpp>

View File

@ -17,7 +17,9 @@
///TODO: Scale ? ///TODO: Scale ?
NzLight::NzLight(nzLightType type) : NzLight::NzLight(nzLightType type) :
m_type(type) m_type(type),
m_shadowCastingEnabled(false),
m_shadowMapUpdated(false)
{ {
SetAmbientFactor((type == nzLightType_Directional) ? 0.2f : 0.f); SetAmbientFactor((type == nzLightType_Directional) ? 0.2f : 0.f);
SetAttenuation(0.9f); SetAttenuation(0.9f);
@ -177,3 +179,18 @@ void NzLight::MakeBoundingVolume() const
break; break;
} }
} }
void NzLight::UpdateShadowMap() const
{
if (m_shadowCastingEnabled)
{
if (!m_shadowMap)
m_shadowMap = NzTexture::New();
m_shadowMap->Create(nzImageType_2D, nzPixelFormat_Depth16, 256, 256);
}
else
m_shadowMap.Reset();
m_shadowMapUpdated = true;
}

View File

@ -148,6 +148,9 @@ bool NzRenderTexture::AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 in
Unlock(); Unlock();
unsigned int attachIndex = attachmentIndex[attachmentPoint] + index; unsigned int attachIndex = attachmentIndex[attachmentPoint] + index;
if (attachIndex >= m_impl->attachments.size())
m_impl->attachments.resize(attachIndex+1);
Attachment& attachment = m_impl->attachments[attachIndex]; Attachment& attachment = m_impl->attachments[attachIndex];
attachment.attachmentPoint = attachmentPoint; attachment.attachmentPoint = attachmentPoint;
attachment.buffer = buffer; attachment.buffer = buffer;
@ -286,6 +289,9 @@ bool NzRenderTexture::AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 i
Unlock(); Unlock();
unsigned int attachIndex = attachmentIndex[attachmentPoint] + index; unsigned int attachIndex = attachmentIndex[attachmentPoint] + index;
if (attachIndex >= m_impl->attachments.size())
m_impl->attachments.resize(attachIndex+1);
Attachment& attachment = m_impl->attachments[attachIndex]; Attachment& attachment = m_impl->attachments[attachIndex];
attachment.attachmentPoint = attachmentPoint; attachment.attachmentPoint = attachmentPoint;
attachment.isBuffer = false; attachment.isBuffer = false;