Add shadow mapping (wip)
This commit is contained in:
parent
be9fba3190
commit
4a10c1f8fe
|
|
@ -18,6 +18,7 @@
|
||||||
#include <NZSL/Math/FieldOffsets.hpp>
|
#include <NZSL/Math/FieldOffsets.hpp>
|
||||||
#include <entt/entt.hpp>
|
#include <entt/entt.hpp>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <bitset>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
|
|
@ -111,18 +112,27 @@ int main()
|
||||||
const Nz::Boxf& bobAABB = bobMesh->GetAABB();
|
const Nz::Boxf& bobAABB = bobMesh->GetAABB();
|
||||||
std::shared_ptr<Nz::GraphicalMesh> bobGfxMesh = Nz::GraphicalMesh::BuildFromMesh(*bobMesh);
|
std::shared_ptr<Nz::GraphicalMesh> bobGfxMesh = Nz::GraphicalMesh::BuildFromMesh(*bobMesh);
|
||||||
|
|
||||||
std::shared_ptr<Nz::Material> material = Nz::Graphics::Instance()->GetDefaultMaterials().basicMaterial;
|
//std::shared_ptr<Nz::Material> material = Nz::Graphics::Instance()->GetDefaultMaterials().basicTransparent;
|
||||||
|
|
||||||
std::shared_ptr<Nz::Model> bobModel = std::make_shared<Nz::Model>(std::move(bobGfxMesh), bobAABB);
|
std::shared_ptr<Nz::Model> bobModel = std::make_shared<Nz::Model>(std::move(bobGfxMesh), bobAABB);
|
||||||
std::vector<std::shared_ptr<Nz::MaterialInstance>> materials(bobMesh->GetMaterialCount());
|
std::vector<std::shared_ptr<Nz::MaterialInstance>> materials(bobMesh->GetMaterialCount());
|
||||||
|
|
||||||
|
std::bitset<5> alphaMaterials("01010");
|
||||||
for (std::size_t i = 0; i < bobMesh->GetMaterialCount(); ++i)
|
for (std::size_t i = 0; i < bobMesh->GetMaterialCount(); ++i)
|
||||||
{
|
{
|
||||||
materials[i] = std::make_shared<Nz::MaterialInstance>(material);
|
const Nz::ParameterList& materialData = bobMesh->GetMaterialData(i);
|
||||||
|
std::string matPath = materialData.GetStringParameter(Nz::MaterialData::BaseColorTexturePath).GetValueOr("");
|
||||||
std::string matPath = bobMesh->GetMaterialData(i).GetStringParameter(Nz::MaterialData::BaseColorTexturePath).GetValueOr("");
|
|
||||||
if (!matPath.empty())
|
if (!matPath.empty())
|
||||||
materials[i]->SetTextureProperty("BaseColorMap", Nz::Texture::LoadFromFile(matPath, texParams));
|
{
|
||||||
|
Nz::MaterialInstanceParams params;
|
||||||
|
params.lightingType = Nz::MaterialLightingType::Phong;
|
||||||
|
if (alphaMaterials.test(i))
|
||||||
|
params.custom.SetParameter("EnableAlphaBlending", true);
|
||||||
|
|
||||||
|
materials[i] = Nz::MaterialInstance::LoadFromFile(matPath, params);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
materials[i] = Nz::Graphics::Instance()->GetDefaultMaterials().basicDefault;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::size_t i = 0; i < bobMesh->GetSubMeshCount(); ++i)
|
for (std::size_t i = 0; i < bobMesh->GetSubMeshCount(); ++i)
|
||||||
|
|
@ -149,7 +159,21 @@ int main()
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
entt::handle bobEntity = entt::handle(registry, registry.create());
|
entt::handle bobEntity = entt::handle(registry, registry.create());
|
||||||
|
entt::entity bobLight = registry.create();
|
||||||
{
|
{
|
||||||
|
auto& lightNode = registry.emplace<Nz::NodeComponent>(bobLight);
|
||||||
|
lightNode.SetPosition(Nz::Vector3f::Up() * 3.f);
|
||||||
|
lightNode.SetRotation(Nz::EulerAnglesf(-90.f, 0.f, 0.f));
|
||||||
|
|
||||||
|
auto spotLight = std::make_shared<Nz::SpotLight>();
|
||||||
|
spotLight->UpdateAmbientFactor(1.f);
|
||||||
|
spotLight->UpdateInnerAngle(Nz::DegreeAnglef(15.f));
|
||||||
|
spotLight->UpdateOuterAngle(Nz::DegreeAnglef(20.f));
|
||||||
|
spotLight->EnableShadowCasting(true);
|
||||||
|
|
||||||
|
auto& cameraLight = registry.emplace<Nz::LightComponent>(bobLight);
|
||||||
|
cameraLight.AttachLight(spotLight, 0xFFFFFFFF);
|
||||||
|
|
||||||
auto& bobNode = bobEntity.emplace<Nz::NodeComponent>();
|
auto& bobNode = bobEntity.emplace<Nz::NodeComponent>();
|
||||||
//bobNode.SetRotation(Nz::EulerAnglesf(-90.f, -90.f, 0.f));
|
//bobNode.SetRotation(Nz::EulerAnglesf(-90.f, -90.f, 0.f));
|
||||||
//bobNode.SetScale(1.f / 40.f * 0.5f);
|
//bobNode.SetScale(1.f / 40.f * 0.5f);
|
||||||
|
|
@ -172,9 +196,6 @@ int main()
|
||||||
std::shared_ptr<Nz::GraphicalMesh> gfxMesh = Nz::GraphicalMesh::BuildFromMesh(*sphereMesh);
|
std::shared_ptr<Nz::GraphicalMesh> gfxMesh = Nz::GraphicalMesh::BuildFromMesh(*sphereMesh);
|
||||||
|
|
||||||
// Textures
|
// Textures
|
||||||
Nz::TextureParams texParams;
|
|
||||||
texParams.renderDevice = device;
|
|
||||||
|
|
||||||
Nz::TextureParams srgbTexParams = texParams;
|
Nz::TextureParams srgbTexParams = texParams;
|
||||||
srgbTexParams.loadFormat = Nz::PixelFormat::RGBA8_SRGB;
|
srgbTexParams.loadFormat = Nz::PixelFormat::RGBA8_SRGB;
|
||||||
|
|
||||||
|
|
@ -209,6 +230,7 @@ int main()
|
||||||
|
|
||||||
|
|
||||||
entt::entity planeEntity = registry.create();
|
entt::entity planeEntity = registry.create();
|
||||||
|
Nz::Boxf floorBox;
|
||||||
{
|
{
|
||||||
Nz::MeshParams meshPrimitiveParams;
|
Nz::MeshParams meshPrimitiveParams;
|
||||||
meshPrimitiveParams.vertexDeclaration = Nz::VertexDeclaration::Get(Nz::VertexLayout::XYZ_Normal_UV);
|
meshPrimitiveParams.vertexDeclaration = Nz::VertexDeclaration::Get(Nz::VertexLayout::XYZ_Normal_UV);
|
||||||
|
|
@ -230,13 +252,15 @@ int main()
|
||||||
std::shared_ptr<Nz::MaterialInstance> planeMat = Nz::Graphics::Instance()->GetDefaultMaterials().phongMaterial->Instantiate();
|
std::shared_ptr<Nz::MaterialInstance> planeMat = Nz::Graphics::Instance()->GetDefaultMaterials().phongMaterial->Instantiate();
|
||||||
planeMat->SetTextureProperty("BaseColorMap", Nz::Texture::LoadFromFile(resourceDir / "dev_grey.png", texParams), planeSampler);
|
planeMat->SetTextureProperty("BaseColorMap", Nz::Texture::LoadFromFile(resourceDir / "dev_grey.png", texParams), planeSampler);
|
||||||
|
|
||||||
|
floorBox = planeMesh.GetAABB();
|
||||||
|
|
||||||
std::shared_ptr<Nz::Model> planeModel = std::make_shared<Nz::Model>(std::move(planeMeshGfx), planeMesh.GetAABB());
|
std::shared_ptr<Nz::Model> planeModel = std::make_shared<Nz::Model>(std::move(planeMeshGfx), planeMesh.GetAABB());
|
||||||
planeModel->SetMaterial(0, planeMat);
|
planeModel->SetMaterial(0, planeMat);
|
||||||
|
|
||||||
auto& planeGfx = registry.emplace<Nz::GraphicsComponent>(planeEntity);
|
auto& planeGfx = registry.emplace<Nz::GraphicsComponent>(planeEntity);
|
||||||
planeGfx.AttachRenderable(planeModel, 0xFFFFFFFF);
|
planeGfx.AttachRenderable(planeModel, 0xFFFFFFFF);
|
||||||
|
|
||||||
auto& planeNode = registry.emplace<Nz::NodeComponent>(planeEntity);
|
registry.emplace<Nz::NodeComponent>(planeEntity);
|
||||||
|
|
||||||
auto& planeBody = registry.emplace<Nz::RigidBody3DComponent>(planeEntity, &physSytem.GetPhysWorld());
|
auto& planeBody = registry.emplace<Nz::RigidBody3DComponent>(planeEntity, &physSytem.GetPhysWorld());
|
||||||
planeBody.SetGeom(std::make_shared<Nz::BoxCollider3D>(Nz::Vector3f(planeSize.x, 0.5f, planeSize.y), Nz::Vector3f(0.f, -0.25f, 0.f)));
|
planeBody.SetGeom(std::make_shared<Nz::BoxCollider3D>(Nz::Vector3f(planeSize.x, 0.5f, planeSize.y), Nz::Vector3f(0.f, -0.25f, 0.f)));
|
||||||
|
|
@ -255,10 +279,6 @@ int main()
|
||||||
|
|
||||||
while (window.IsOpen())
|
while (window.IsOpen())
|
||||||
{
|
{
|
||||||
Nz::UInt64 now = Nz::GetElapsedMicroseconds();
|
|
||||||
Nz::UInt64 elapsedTime = (now - lastTime) / 1'000'000.f;
|
|
||||||
lastTime = now;
|
|
||||||
|
|
||||||
Nz::WindowEvent event;
|
Nz::WindowEvent event;
|
||||||
while (window.PollEvent(&event))
|
while (window.PollEvent(&event))
|
||||||
{
|
{
|
||||||
|
|
@ -389,8 +409,14 @@ int main()
|
||||||
playerShipBody.AddForce(Nz::Vector3f::Down() * 3.f * mass, Nz::CoordSys::Local);*/
|
playerShipBody.AddForce(Nz::Vector3f::Down() * 3.f * mass, Nz::CoordSys::Local);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
Nz::DebugDrawer& debugDrawer = renderSystem.GetFramePipeline().GetDebugDrawer();
|
|
||||||
//debugDrawer.DrawSkeleton(*skeleton, Nz::Color::Red);
|
/*Nz::DebugDrawer& debugDrawer = renderSystem.GetFramePipeline().GetDebugDrawer();
|
||||||
|
Nz::Boxf test = spotLight->GetBoundingVolume().aabb;
|
||||||
|
debugDrawer.DrawBox(test, Nz::Color::Blue);
|
||||||
|
debugDrawer.DrawBox(floorBox, Nz::Color::Red);
|
||||||
|
Nz::Boxf intersection;
|
||||||
|
if (floorBox.Intersect(test, &intersection))
|
||||||
|
debugDrawer.DrawBox(intersection, Nz::Color::Green);*/
|
||||||
|
|
||||||
systemGraph.Update();
|
systemGraph.Update();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,7 @@ namespace Nz
|
||||||
TextureUsageFlags usage;
|
TextureUsageFlags usage;
|
||||||
unsigned int width;
|
unsigned int width;
|
||||||
unsigned int height;
|
unsigned int height;
|
||||||
|
bool hasFixedSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<CommandPool> m_commandPool;
|
std::shared_ptr<CommandPool> m_commandPool;
|
||||||
|
|
|
||||||
|
|
@ -178,12 +178,21 @@ namespace Nz
|
||||||
|
|
||||||
inline void Camera::UpdateViewport(const Recti& viewport)
|
inline void Camera::UpdateViewport(const Recti& viewport)
|
||||||
{
|
{
|
||||||
NazaraAssert(m_renderTarget, "no render target");
|
if (m_renderTarget)
|
||||||
|
{
|
||||||
|
// We compute the region necessary to make this view port with the actual size of the target
|
||||||
|
Vector2f invSize = 1.f / Vector2f(m_renderTarget->GetSize());
|
||||||
|
|
||||||
// We compute the region necessary to make this view port with the actual size of the target
|
UpdateTargetRegion(Rectf(invSize.x * viewport.x, invSize.y * viewport.y, invSize.x * viewport.width, invSize.y * viewport.height));
|
||||||
Vector2f invSize = 1.f / Vector2f(m_renderTarget->GetSize());
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_aspectRatio = float(viewport.width) / float(viewport.height);
|
||||||
|
m_viewport = viewport;
|
||||||
|
m_viewerInstance.UpdateTargetSize(Vector2f(viewport.GetLengths()));
|
||||||
|
|
||||||
UpdateTargetRegion(Rectf(invSize.x * viewport.x, invSize.y * viewport.y, invSize.x * viewport.width, invSize.y * viewport.height));
|
UpdateProjectionMatrix();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Camera::UpdateSize(const Vector2f& size)
|
inline void Camera::UpdateSize(const Vector2f& size)
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
class AbstractViewer;
|
class AbstractViewer;
|
||||||
class FrameGraph;
|
class FrameGraph;
|
||||||
|
class FramePass;
|
||||||
class FramePipeline;
|
class FramePipeline;
|
||||||
class Material;
|
class Material;
|
||||||
|
|
||||||
|
|
@ -34,7 +35,7 @@ namespace Nz
|
||||||
|
|
||||||
void Prepare(RenderFrame& renderFrame);
|
void Prepare(RenderFrame& renderFrame);
|
||||||
|
|
||||||
void RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t inputColorBufferIndex, std::size_t outputColorBufferIndex);
|
FramePass& RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t inputColorBufferIndex, std::size_t outputColorBufferIndex);
|
||||||
|
|
||||||
DebugDrawPipelinePass& operator=(const DebugDrawPipelinePass&) = delete;
|
DebugDrawPipelinePass& operator=(const DebugDrawPipelinePass&) = delete;
|
||||||
DebugDrawPipelinePass& operator=(DebugDrawPipelinePass&&) = delete;
|
DebugDrawPipelinePass& operator=(DebugDrawPipelinePass&&) = delete;
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ namespace Nz
|
||||||
class AbstractViewer;
|
class AbstractViewer;
|
||||||
class ElementRendererRegistry;
|
class ElementRendererRegistry;
|
||||||
class FrameGraph;
|
class FrameGraph;
|
||||||
|
class FramePass;
|
||||||
class FramePipeline;
|
class FramePipeline;
|
||||||
|
|
||||||
class NAZARA_GRAPHICS_API DepthPipelinePass : public FramePipelinePass
|
class NAZARA_GRAPHICS_API DepthPipelinePass : public FramePipelinePass
|
||||||
|
|
@ -40,7 +41,7 @@ namespace Nz
|
||||||
void Prepare(RenderFrame& renderFrame, const Frustumf& frustum, const std::vector<FramePipelinePass::VisibleRenderable>& visibleRenderables, std::size_t visibilityHash);
|
void Prepare(RenderFrame& renderFrame, const Frustumf& frustum, const std::vector<FramePipelinePass::VisibleRenderable>& visibleRenderables, std::size_t visibilityHash);
|
||||||
|
|
||||||
void RegisterMaterialInstance(const MaterialInstance& materialInstance);
|
void RegisterMaterialInstance(const MaterialInstance& materialInstance);
|
||||||
void RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t depthBufferIndex);
|
FramePass& RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t depthBufferIndex);
|
||||||
|
|
||||||
void UnregisterMaterialInstance(const MaterialInstance& materialInstance);
|
void UnregisterMaterialInstance(const MaterialInstance& materialInstance);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include <Nazara/Prerequisites.hpp>
|
#include <Nazara/Prerequisites.hpp>
|
||||||
#include <Nazara/Graphics/BakedFrameGraph.hpp>
|
#include <Nazara/Graphics/BakedFrameGraph.hpp>
|
||||||
|
#include <Nazara/Graphics/Camera.hpp>
|
||||||
#include <Nazara/Graphics/Config.hpp>
|
#include <Nazara/Graphics/Config.hpp>
|
||||||
#include <Nazara/Graphics/DebugDrawPipelinePass.hpp>
|
#include <Nazara/Graphics/DebugDrawPipelinePass.hpp>
|
||||||
#include <Nazara/Graphics/DepthPipelinePass.hpp>
|
#include <Nazara/Graphics/DepthPipelinePass.hpp>
|
||||||
|
|
@ -76,9 +77,13 @@ namespace Nz
|
||||||
struct LightData
|
struct LightData
|
||||||
{
|
{
|
||||||
std::shared_ptr<Light> light;
|
std::shared_ptr<Light> light;
|
||||||
|
std::size_t shadowMapAttachmentIndex;
|
||||||
|
std::unique_ptr<Camera> camera;
|
||||||
|
std::unique_ptr<DepthPipelinePass> pass;
|
||||||
UInt32 renderMask;
|
UInt32 renderMask;
|
||||||
|
|
||||||
NazaraSlot(Light, OnLightDataInvalided, onLightInvalidated);
|
NazaraSlot(Light, OnLightDataInvalided, onLightInvalidated);
|
||||||
|
NazaraSlot(Light, OnLightShadowCastingChanged, onLightShadowCastingChanged);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MaterialInstanceData
|
struct MaterialInstanceData
|
||||||
|
|
@ -145,6 +150,7 @@ namespace Nz
|
||||||
std::vector<const Light*> m_visibleLights;
|
std::vector<const Light*> m_visibleLights;
|
||||||
robin_hood::unordered_set<TransferInterface*> m_transferSet;
|
robin_hood::unordered_set<TransferInterface*> m_transferSet;
|
||||||
BakedFrameGraph m_bakedFrameGraph;
|
BakedFrameGraph m_bakedFrameGraph;
|
||||||
|
Bitset<UInt64> m_shadowCastingLights;
|
||||||
Bitset<UInt64> m_removedSkeletonInstances;
|
Bitset<UInt64> m_removedSkeletonInstances;
|
||||||
Bitset<UInt64> m_removedViewerInstances;
|
Bitset<UInt64> m_removedViewerInstances;
|
||||||
Bitset<UInt64> m_removedWorldInstances;
|
Bitset<UInt64> m_removedWorldInstances;
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ namespace Nz
|
||||||
class AbstractViewer;
|
class AbstractViewer;
|
||||||
class ElementRendererRegistry;
|
class ElementRendererRegistry;
|
||||||
class FrameGraph;
|
class FrameGraph;
|
||||||
|
class FramePass;
|
||||||
class FramePipeline;
|
class FramePipeline;
|
||||||
class Light;
|
class Light;
|
||||||
|
|
||||||
|
|
@ -43,7 +44,7 @@ namespace Nz
|
||||||
void Prepare(RenderFrame& renderFrame, const Frustumf& frustum, const std::vector<FramePipelinePass::VisibleRenderable>& visibleRenderables, const std::vector<const Light*>& visibleLights, std::size_t visibilityHash);
|
void Prepare(RenderFrame& renderFrame, const Frustumf& frustum, const std::vector<FramePipelinePass::VisibleRenderable>& visibleRenderables, const std::vector<const Light*>& visibleLights, std::size_t visibilityHash);
|
||||||
|
|
||||||
void RegisterMaterialInstance(const MaterialInstance& material);
|
void RegisterMaterialInstance(const MaterialInstance& material);
|
||||||
void RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t colorBufferIndex, std::size_t depthBufferIndex, bool hasDepthPrepass);
|
FramePass& RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t colorBufferIndex, std::size_t depthBufferIndex, bool hasDepthPrepass);
|
||||||
|
|
||||||
void UnregisterMaterialInstance(const MaterialInstance& material);
|
void UnregisterMaterialInstance(const MaterialInstance& material);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,7 @@ namespace Nz
|
||||||
TextureUsageFlags usage;
|
TextureUsageFlags usage;
|
||||||
unsigned int width;
|
unsigned int width;
|
||||||
unsigned int height;
|
unsigned int height;
|
||||||
|
bool hasFixedSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WorkData
|
struct WorkData
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ namespace Nz
|
||||||
PixelFormat format;
|
PixelFormat format;
|
||||||
unsigned int width = 100'000;
|
unsigned int width = 100'000;
|
||||||
unsigned int height = 100'000;
|
unsigned int height = 100'000;
|
||||||
|
bool hasFixedSize = false;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
#include <Nazara/Math/BoundingVolume.hpp>
|
#include <Nazara/Math/BoundingVolume.hpp>
|
||||||
#include <Nazara/Math/Quaternion.hpp>
|
#include <Nazara/Math/Quaternion.hpp>
|
||||||
#include <Nazara/Math/Vector3.hpp>
|
#include <Nazara/Math/Vector3.hpp>
|
||||||
|
#include <Nazara/Utility/PixelFormat.hpp>
|
||||||
#include <Nazara/Utils/Signal.hpp>
|
#include <Nazara/Utils/Signal.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
|
@ -20,21 +21,32 @@ namespace Nz
|
||||||
class CommandBufferBuilder;
|
class CommandBufferBuilder;
|
||||||
class RenderBuffer;
|
class RenderBuffer;
|
||||||
class RenderFrame;
|
class RenderFrame;
|
||||||
|
class Texture;
|
||||||
|
|
||||||
class NAZARA_GRAPHICS_API Light
|
class NAZARA_GRAPHICS_API Light
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline Light(UInt8 lightType);
|
Light(UInt8 lightType);
|
||||||
Light(const Light&) = delete;
|
Light(const Light&) = delete;
|
||||||
Light(Light&&) noexcept = default;
|
Light(Light&&) noexcept = default;
|
||||||
virtual ~Light();
|
virtual ~Light();
|
||||||
|
|
||||||
virtual float ComputeContributionScore(const BoundingVolumef& boundingVolume) const = 0;
|
virtual float ComputeContributionScore(const BoundingVolumef& boundingVolume) const = 0;
|
||||||
|
|
||||||
|
inline void EnableShadowCasting(bool castShadows);
|
||||||
|
|
||||||
virtual void FillLightData(void* data) const = 0;
|
virtual void FillLightData(void* data) const = 0;
|
||||||
|
|
||||||
inline const BoundingVolumef& GetBoundingVolume() const;
|
inline const BoundingVolumef& GetBoundingVolume() const;
|
||||||
inline UInt8 GetLightType() const;
|
inline UInt8 GetLightType() const;
|
||||||
|
inline PixelFormat GetShadowMapFormat() const;
|
||||||
|
inline UInt32 GetShadowMapSize() const;
|
||||||
|
|
||||||
|
inline bool IsShadowCaster() const;
|
||||||
|
|
||||||
|
inline void UpdateShadowMapFormat(PixelFormat format);
|
||||||
|
inline void UpdateShadowMapSettings(UInt32 size, PixelFormat format);
|
||||||
|
inline void UpdateShadowMapSize(UInt32 size);
|
||||||
|
|
||||||
virtual void UpdateTransform(const Vector3f& position, const Quaternionf& rotation, const Vector3f& scale) = 0;
|
virtual void UpdateTransform(const Vector3f& position, const Quaternionf& rotation, const Vector3f& scale) = 0;
|
||||||
|
|
||||||
|
|
@ -42,13 +54,18 @@ namespace Nz
|
||||||
Light& operator=(Light&&) noexcept = default;
|
Light& operator=(Light&&) noexcept = default;
|
||||||
|
|
||||||
NazaraSignal(OnLightDataInvalided, Light* /*emitter*/);
|
NazaraSignal(OnLightDataInvalided, Light* /*emitter*/);
|
||||||
|
NazaraSignal(OnLightShadowCastingChanged, Light* /*light*/, bool /*isShadowCasting*/);
|
||||||
|
NazaraSignal(OnLightShadowMapSettingChange, Light* /*light*/, PixelFormat /*newPixelFormat*/, UInt32 /*newSize*/);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
inline void UpdateBoundingVolume(const BoundingVolumef& boundingVolume);
|
inline void UpdateBoundingVolume(const BoundingVolumef& boundingVolume);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BoundingVolumef m_boundingVolume;
|
BoundingVolumef m_boundingVolume;
|
||||||
|
PixelFormat m_shadowMapFormat;
|
||||||
UInt8 m_lightType;
|
UInt8 m_lightType;
|
||||||
|
UInt32 m_shadowMapSize;
|
||||||
|
bool m_isShadowCaster;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,13 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
inline Light::Light(UInt8 lightType) :
|
inline void Light::EnableShadowCasting(bool castShadows)
|
||||||
m_boundingVolume(BoundingVolumef::Null()),
|
|
||||||
m_lightType(lightType)
|
|
||||||
{
|
{
|
||||||
|
if (m_isShadowCaster != castShadows)
|
||||||
|
{
|
||||||
|
m_isShadowCaster = castShadows;
|
||||||
|
OnLightShadowCastingChanged(this, castShadows);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const BoundingVolumef& Light::GetBoundingVolume() const
|
inline const BoundingVolumef& Light::GetBoundingVolume() const
|
||||||
|
|
@ -24,6 +27,58 @@ namespace Nz
|
||||||
return m_lightType;
|
return m_lightType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline PixelFormat Light::GetShadowMapFormat() const
|
||||||
|
{
|
||||||
|
return m_shadowMapFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline UInt32 Light::GetShadowMapSize() const
|
||||||
|
{
|
||||||
|
return m_shadowMapSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Light::IsShadowCaster() const
|
||||||
|
{
|
||||||
|
return m_isShadowCaster;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Light::UpdateShadowMapFormat(PixelFormat format)
|
||||||
|
{
|
||||||
|
if (m_shadowMapFormat != format)
|
||||||
|
{
|
||||||
|
PixelFormatContent content = PixelFormatInfo::GetContent(format);
|
||||||
|
NazaraAssert(content != PixelFormatContent::Depth && content != PixelFormatContent::DepthStencil, "invalid shadow map format (has no depth)");
|
||||||
|
|
||||||
|
OnLightShadowMapSettingChange(this, format, m_shadowMapSize);
|
||||||
|
m_shadowMapFormat = format;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Light::UpdateShadowMapSettings(UInt32 size, PixelFormat format)
|
||||||
|
{
|
||||||
|
if (m_shadowMapFormat != format || m_shadowMapSize != size)
|
||||||
|
{
|
||||||
|
NazaraAssert(size > 0, "invalid shadow map size");
|
||||||
|
PixelFormatContent content = PixelFormatInfo::GetContent(format);
|
||||||
|
NazaraAssert(content != PixelFormatContent::Depth && content != PixelFormatContent::DepthStencil, "invalid shadow map format (has no depth)");
|
||||||
|
|
||||||
|
OnLightShadowMapSettingChange(this, format, size);
|
||||||
|
m_shadowMapFormat = format;
|
||||||
|
m_shadowMapSize = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Light::UpdateShadowMapSize(UInt32 size)
|
||||||
|
{
|
||||||
|
if (m_shadowMapSize != size)
|
||||||
|
{
|
||||||
|
NazaraAssert(size > 0, "invalid shadow map size");
|
||||||
|
|
||||||
|
OnLightShadowMapSettingChange(this, m_shadowMapFormat, size);
|
||||||
|
m_shadowMapSize = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline void Light::UpdateBoundingVolume(const BoundingVolumef& boundingVolume)
|
inline void Light::UpdateBoundingVolume(const BoundingVolumef& boundingVolume)
|
||||||
{
|
{
|
||||||
m_boundingVolume = boundingVolume;
|
m_boundingVolume = boundingVolume;
|
||||||
|
|
|
||||||
|
|
@ -131,8 +131,8 @@ namespace Nz
|
||||||
|
|
||||||
bool BakedFrameGraph::Resize(RenderFrame& renderFrame)
|
bool BakedFrameGraph::Resize(RenderFrame& renderFrame)
|
||||||
{
|
{
|
||||||
auto [width, height] = renderFrame.GetSize();
|
auto [frameWidth, frameHeight] = renderFrame.GetSize();
|
||||||
if (m_width == width && m_height == height)
|
if (m_width == frameWidth && m_height == frameHeight)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const std::shared_ptr<RenderDevice>& renderDevice = Graphics::Instance()->GetRenderDevice();
|
const std::shared_ptr<RenderDevice>& renderDevice = Graphics::Instance()->GetRenderDevice();
|
||||||
|
|
@ -151,10 +151,18 @@ namespace Nz
|
||||||
{
|
{
|
||||||
TextureInfo textureCreationParams;
|
TextureInfo textureCreationParams;
|
||||||
textureCreationParams.type = ImageType::E2D;
|
textureCreationParams.type = ImageType::E2D;
|
||||||
textureCreationParams.width = textureData.width * width / 100'000;
|
|
||||||
textureCreationParams.height = textureData.height * height / 100'000;
|
|
||||||
textureCreationParams.usageFlags = textureData.usage;
|
textureCreationParams.usageFlags = textureData.usage;
|
||||||
textureCreationParams.pixelFormat = textureData.format;
|
textureCreationParams.pixelFormat = textureData.format;
|
||||||
|
if (textureData.hasFixedSize)
|
||||||
|
{
|
||||||
|
textureCreationParams.width = textureData.width;
|
||||||
|
textureCreationParams.height = textureData.height;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
textureCreationParams.width = textureData.width * frameWidth / 100'000;
|
||||||
|
textureCreationParams.height = textureData.height * frameHeight / 100'000;
|
||||||
|
}
|
||||||
|
|
||||||
textureData.texture = renderDevice->InstantiateTexture(textureCreationParams);
|
textureData.texture = renderDevice->InstantiateTexture(textureCreationParams);
|
||||||
if (!textureData.name.empty())
|
if (!textureData.name.empty())
|
||||||
|
|
@ -173,12 +181,22 @@ namespace Nz
|
||||||
auto& textureData = m_textures[textureId];
|
auto& textureData = m_textures[textureId];
|
||||||
textures.push_back(textureData.texture);
|
textures.push_back(textureData.texture);
|
||||||
|
|
||||||
framebufferWidth = std::min(framebufferWidth, textureData.width);
|
unsigned int width;
|
||||||
framebufferHeight = std::min(framebufferHeight, textureData.height);
|
unsigned int height;
|
||||||
}
|
if (textureData.hasFixedSize)
|
||||||
|
{
|
||||||
|
width = textureData.width;
|
||||||
|
height = textureData.height;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
width = frameWidth * textureData.width / 100'000;
|
||||||
|
height = frameHeight * textureData.height / 100'000;
|
||||||
|
}
|
||||||
|
|
||||||
framebufferWidth = framebufferWidth * width / 100'000;
|
framebufferWidth = std::min(framebufferWidth, width);
|
||||||
framebufferHeight = framebufferHeight * height / 100'000;
|
framebufferHeight = std::min(framebufferHeight, height);
|
||||||
|
}
|
||||||
|
|
||||||
passData.renderRect.Set(0, 0, int(framebufferWidth), int(framebufferHeight));
|
passData.renderRect.Set(0, 0, int(framebufferWidth), int(framebufferHeight));
|
||||||
|
|
||||||
|
|
@ -189,8 +207,8 @@ namespace Nz
|
||||||
passData.forceCommandBufferRegeneration = true;
|
passData.forceCommandBufferRegeneration = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_width = width;
|
m_width = frameWidth;
|
||||||
m_height = height;
|
m_height = frameHeight;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ namespace Nz
|
||||||
debugDrawer.Prepare(renderFrame);
|
debugDrawer.Prepare(renderFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugDrawPipelinePass::RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t inputColorBufferIndex, std::size_t outputColorBufferIndex)
|
FramePass& DebugDrawPipelinePass::RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t inputColorBufferIndex, std::size_t outputColorBufferIndex)
|
||||||
{
|
{
|
||||||
FramePass& debugDrawPass = frameGraph.AddPass("Debug draw pass");
|
FramePass& debugDrawPass = frameGraph.AddPass("Debug draw pass");
|
||||||
debugDrawPass.AddInput(inputColorBufferIndex);
|
debugDrawPass.AddInput(inputColorBufferIndex);
|
||||||
|
|
@ -47,5 +47,7 @@ namespace Nz
|
||||||
DebugDrawer& debugDrawer = m_pipeline.GetDebugDrawer();
|
DebugDrawer& debugDrawer = m_pipeline.GetDebugDrawer();
|
||||||
debugDrawer.Draw(builder);
|
debugDrawer.Draw(builder);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return debugDrawPass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,7 @@ namespace Nz
|
||||||
it->second.usedCount++;
|
it->second.usedCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DepthPipelinePass::RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t depthBufferIndex)
|
FramePass& DepthPipelinePass::RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t depthBufferIndex)
|
||||||
{
|
{
|
||||||
FramePass& depthPrepass = frameGraph.AddPass("Depth pre-pass");
|
FramePass& depthPrepass = frameGraph.AddPass("Depth pre-pass");
|
||||||
depthPrepass.SetDepthStencilOutput(depthBufferIndex);
|
depthPrepass.SetDepthStencilOutput(depthBufferIndex);
|
||||||
|
|
@ -157,6 +157,8 @@ namespace Nz
|
||||||
|
|
||||||
m_rebuildCommandBuffer = false;
|
m_rebuildCommandBuffer = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return depthPrepass;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DepthPipelinePass::UnregisterMaterialInstance(const MaterialInstance& materialInstance)
|
void DepthPipelinePass::UnregisterMaterialInstance(const MaterialInstance& materialInstance)
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <Nazara/Graphics/DirectionalLight.hpp>
|
#include <Nazara/Graphics/DirectionalLight.hpp>
|
||||||
#include <Nazara/Graphics/Enums.hpp>
|
#include <Nazara/Graphics/Enums.hpp>
|
||||||
|
#include <Nazara/Graphics/Graphics.hpp>
|
||||||
#include <Nazara/Graphics/PredefinedShaderStructs.hpp>
|
#include <Nazara/Graphics/PredefinedShaderStructs.hpp>
|
||||||
#include <Nazara/Math/Vector2.hpp>
|
#include <Nazara/Math/Vector2.hpp>
|
||||||
#include <Nazara/Math/Vector3.hpp>
|
#include <Nazara/Math/Vector3.hpp>
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include <Nazara/Graphics/PointLight.hpp>
|
#include <Nazara/Graphics/PointLight.hpp>
|
||||||
#include <Nazara/Graphics/PredefinedShaderStructs.hpp>
|
#include <Nazara/Graphics/PredefinedShaderStructs.hpp>
|
||||||
#include <Nazara/Graphics/RenderElement.hpp>
|
#include <Nazara/Graphics/RenderElement.hpp>
|
||||||
|
#include <Nazara/Graphics/SpotLight.hpp>
|
||||||
#include <Nazara/Graphics/ViewerInstance.hpp>
|
#include <Nazara/Graphics/ViewerInstance.hpp>
|
||||||
#include <Nazara/Graphics/WorldInstance.hpp>
|
#include <Nazara/Graphics/WorldInstance.hpp>
|
||||||
#include <Nazara/Math/Angle.hpp>
|
#include <Nazara/Math/Angle.hpp>
|
||||||
|
|
@ -61,6 +62,25 @@ namespace Nz
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
lightData->onLightShadowCastingChanged.Connect(lightData->light->OnLightShadowCastingChanged, [=](Light* light, bool isCastingShadows)
|
||||||
|
{
|
||||||
|
if (isCastingShadows)
|
||||||
|
m_shadowCastingLights.UnboundedSet(lightIndex);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_shadowCastingLights.Reset(lightIndex);
|
||||||
|
lightData->pass.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_rebuildFrameGraph = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (lightData->light->IsShadowCaster())
|
||||||
|
{
|
||||||
|
m_shadowCastingLights.UnboundedSet(lightIndex);
|
||||||
|
m_rebuildFrameGraph = true;
|
||||||
|
}
|
||||||
|
|
||||||
return lightIndex;
|
return lightIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -248,6 +268,48 @@ namespace Nz
|
||||||
return currentHash * 23 + newHash;
|
return currentHash * 23 + newHash;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Shadow map handling
|
||||||
|
for (std::size_t i = m_shadowCastingLights.FindFirst(); i != m_shadowCastingLights.npos; i = m_shadowCastingLights.FindNext(i))
|
||||||
|
{
|
||||||
|
LightData* lightData = m_lightPool.RetrieveFromIndex(i);
|
||||||
|
|
||||||
|
const Matrix4f& viewProjMatrix = lightData->camera->GetViewerInstance().GetViewProjMatrix();
|
||||||
|
|
||||||
|
Frustumf frustum = Frustumf::Extract(viewProjMatrix);
|
||||||
|
|
||||||
|
std::size_t visibilityHash = 5U;
|
||||||
|
|
||||||
|
m_visibleRenderables.clear();
|
||||||
|
for (const RenderableData& renderableData : m_renderablePool)
|
||||||
|
{
|
||||||
|
if ((lightData->renderMask & renderableData.renderMask) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
WorldInstancePtr& worldInstance = m_worldInstances.RetrieveFromIndex(renderableData.worldInstanceIndex)->worldInstance;
|
||||||
|
|
||||||
|
// Get global AABB
|
||||||
|
BoundingVolumef boundingVolume(renderableData.renderable->GetAABB());
|
||||||
|
boundingVolume.Update(worldInstance->GetWorldMatrix());
|
||||||
|
|
||||||
|
if (!frustum.Contains(boundingVolume))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto& visibleRenderable = m_visibleRenderables.emplace_back();
|
||||||
|
visibleRenderable.instancedRenderable = renderableData.renderable;
|
||||||
|
visibleRenderable.scissorBox = renderableData.scissorBox;
|
||||||
|
visibleRenderable.worldInstance = worldInstance.get();
|
||||||
|
|
||||||
|
if (renderableData.skeletonInstanceIndex != NoSkeletonInstance)
|
||||||
|
visibleRenderable.skeletonInstance = m_skeletonInstances.RetrieveFromIndex(renderableData.skeletonInstanceIndex)->skeleton.get();
|
||||||
|
else
|
||||||
|
visibleRenderable.skeletonInstance = nullptr;
|
||||||
|
|
||||||
|
visibilityHash = CombineHash(visibilityHash, std::hash<const void*>()(&renderableData));
|
||||||
|
}
|
||||||
|
|
||||||
|
lightData->pass->Prepare(renderFrame, frustum, m_visibleRenderables, visibilityHash);
|
||||||
|
}
|
||||||
|
|
||||||
// Render queues handling
|
// Render queues handling
|
||||||
for (auto& viewerData : m_viewerPool)
|
for (auto& viewerData : m_viewerPool)
|
||||||
{
|
{
|
||||||
|
|
@ -398,6 +460,7 @@ namespace Nz
|
||||||
void ForwardFramePipeline::UnregisterLight(std::size_t lightIndex)
|
void ForwardFramePipeline::UnregisterLight(std::size_t lightIndex)
|
||||||
{
|
{
|
||||||
m_lightPool.Free(lightIndex);
|
m_lightPool.Free(lightIndex);
|
||||||
|
m_shadowCastingLights.UnboundedReset(lightIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ForwardFramePipeline::UnregisterRenderable(std::size_t renderableIndex)
|
void ForwardFramePipeline::UnregisterRenderable(std::size_t renderableIndex)
|
||||||
|
|
@ -486,6 +549,56 @@ namespace Nz
|
||||||
{
|
{
|
||||||
FrameGraph frameGraph;
|
FrameGraph frameGraph;
|
||||||
|
|
||||||
|
for (std::size_t i = m_shadowCastingLights.FindFirst(); i != m_shadowCastingLights.npos; i = m_shadowCastingLights.FindNext(i))
|
||||||
|
{
|
||||||
|
LightData* lightData = m_lightPool.RetrieveFromIndex(i);
|
||||||
|
|
||||||
|
assert(lightData->light->GetLightType() == UnderlyingCast(BasicLightType::Spot));
|
||||||
|
SpotLight& spotLight = SafeCast<SpotLight&>(*lightData->light);
|
||||||
|
|
||||||
|
PixelFormat shadowMapFormat = lightData->light->GetShadowMapFormat();
|
||||||
|
UInt32 shadowMapSize = lightData->light->GetShadowMapSize();
|
||||||
|
|
||||||
|
lightData->shadowMapAttachmentIndex = frameGraph.AddAttachment({
|
||||||
|
"Shadowmap",
|
||||||
|
shadowMapFormat,
|
||||||
|
shadowMapSize, shadowMapSize,
|
||||||
|
true // fixed size
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!lightData->camera)
|
||||||
|
{
|
||||||
|
lightData->camera = std::make_unique<Camera>(nullptr);
|
||||||
|
ViewerInstance& viewerInstance = lightData->camera->GetViewerInstance();
|
||||||
|
viewerInstance.OnTransferRequired.Connect([this](TransferInterface* transferInterface)
|
||||||
|
{
|
||||||
|
m_transferSet.insert(transferInterface);
|
||||||
|
});
|
||||||
|
|
||||||
|
lightData->camera->UpdateFOV(spotLight.GetOuterAngle());
|
||||||
|
lightData->camera->UpdateZFar(spotLight.GetRadius());
|
||||||
|
lightData->camera->UpdateViewport(Recti(0, 0, SafeCast<int>(shadowMapSize), SafeCast<int>(shadowMapSize)));
|
||||||
|
|
||||||
|
viewerInstance.UpdateViewMatrix(Nz::Matrix4f::TransformInverse(spotLight.GetPosition(), spotLight.GetRotation()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lightData->pass)
|
||||||
|
{
|
||||||
|
lightData->pass = std::make_unique<DepthPipelinePass>(*this, m_elementRegistry, lightData->camera.get());
|
||||||
|
for (RenderableData& renderable : m_renderablePool)
|
||||||
|
{
|
||||||
|
std::size_t matCount = renderable.renderable->GetMaterialCount();
|
||||||
|
for (std::size_t i = 0; i < matCount; ++i)
|
||||||
|
{
|
||||||
|
if (MaterialInstance* mat = renderable.renderable->GetMaterial(i).get())
|
||||||
|
lightData->pass->RegisterMaterialInstance(*mat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lightData->pass->RegisterToFrameGraph(frameGraph, lightData->shadowMapAttachmentIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& viewerData : m_viewerPool)
|
for (auto& viewerData : m_viewerPool)
|
||||||
{
|
{
|
||||||
viewerData.forwardColorAttachment = frameGraph.AddAttachment({
|
viewerData.forwardColorAttachment = frameGraph.AddAttachment({
|
||||||
|
|
@ -503,7 +616,12 @@ namespace Nz
|
||||||
if (viewerData.depthPrepass)
|
if (viewerData.depthPrepass)
|
||||||
viewerData.depthPrepass->RegisterToFrameGraph(frameGraph, viewerData.depthStencilAttachment);
|
viewerData.depthPrepass->RegisterToFrameGraph(frameGraph, viewerData.depthStencilAttachment);
|
||||||
|
|
||||||
viewerData.forwardPass->RegisterToFrameGraph(frameGraph, viewerData.forwardColorAttachment, viewerData.depthStencilAttachment, viewerData.depthPrepass != nullptr);
|
FramePass& forwardPass = viewerData.forwardPass->RegisterToFrameGraph(frameGraph, viewerData.forwardColorAttachment, viewerData.depthStencilAttachment, viewerData.depthPrepass != nullptr);
|
||||||
|
for (std::size_t i = m_shadowCastingLights.FindFirst(); i != m_shadowCastingLights.npos; i = m_shadowCastingLights.FindNext(i))
|
||||||
|
{
|
||||||
|
LightData* lightData = m_lightPool.RetrieveFromIndex(i);
|
||||||
|
forwardPass.AddInput(lightData->shadowMapAttachmentIndex);
|
||||||
|
}
|
||||||
|
|
||||||
viewerData.debugDrawPass->RegisterToFrameGraph(frameGraph, viewerData.forwardColorAttachment, viewerData.debugColorAttachment);
|
viewerData.debugDrawPass->RegisterToFrameGraph(frameGraph, viewerData.forwardColorAttachment, viewerData.debugColorAttachment);
|
||||||
}
|
}
|
||||||
|
|
@ -548,7 +666,7 @@ namespace Nz
|
||||||
mergePass.AddOutput(renderTargetData.finalAttachment);
|
mergePass.AddOutput(renderTargetData.finalAttachment);
|
||||||
mergePass.SetClearColor(0, Color::Black);
|
mergePass.SetClearColor(0, Color::Black);
|
||||||
|
|
||||||
mergePass.SetCommandCallback([&targetViewers](CommandBufferBuilder& builder, const Nz::FramePassEnvironment& env)
|
mergePass.SetCommandCallback([&targetViewers](CommandBufferBuilder& builder, const FramePassEnvironment& env)
|
||||||
{
|
{
|
||||||
builder.SetScissor(env.renderRect);
|
builder.SetScissor(env.renderRect);
|
||||||
builder.SetViewport(env.renderRect);
|
builder.SetViewport(env.renderRect);
|
||||||
|
|
|
||||||
|
|
@ -265,7 +265,7 @@ namespace Nz
|
||||||
it->second.usedCount++;
|
it->second.usedCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ForwardPipelinePass::RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t colorBufferIndex, std::size_t depthBufferIndex, bool hasDepthPrepass)
|
FramePass& ForwardPipelinePass::RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t colorBufferIndex, std::size_t depthBufferIndex, bool hasDepthPrepass)
|
||||||
{
|
{
|
||||||
FramePass& forwardPass = frameGraph.AddPass("Forward pass");
|
FramePass& forwardPass = frameGraph.AddPass("Forward pass");
|
||||||
forwardPass.AddOutput(colorBufferIndex);
|
forwardPass.AddOutput(colorBufferIndex);
|
||||||
|
|
@ -299,6 +299,8 @@ namespace Nz
|
||||||
|
|
||||||
m_rebuildCommandBuffer = false;
|
m_rebuildCommandBuffer = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return forwardPass;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ForwardPipelinePass::UnregisterMaterialInstance(const MaterialInstance& materialInstance)
|
void ForwardPipelinePass::UnregisterMaterialInstance(const MaterialInstance& materialInstance)
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,7 @@ namespace Nz
|
||||||
auto& bakedTexture = bakedTextures.emplace_back();
|
auto& bakedTexture = bakedTextures.emplace_back();
|
||||||
bakedTexture.name = std::move(texture.name);
|
bakedTexture.name = std::move(texture.name);
|
||||||
bakedTexture.format = texture.format;
|
bakedTexture.format = texture.format;
|
||||||
|
bakedTexture.hasFixedSize = texture.hasFixedSize;
|
||||||
bakedTexture.height = texture.height;
|
bakedTexture.height = texture.height;
|
||||||
bakedTexture.usage = texture.usage;
|
bakedTexture.usage = texture.usage;
|
||||||
bakedTexture.width = texture.width;
|
bakedTexture.width = texture.width;
|
||||||
|
|
@ -952,7 +953,8 @@ namespace Nz
|
||||||
TextureData& data = m_pending.textures[textureId];
|
TextureData& data = m_pending.textures[textureId];
|
||||||
if (data.format != attachmentData.format ||
|
if (data.format != attachmentData.format ||
|
||||||
data.width != attachmentData.width ||
|
data.width != attachmentData.width ||
|
||||||
data.height != attachmentData.height)
|
data.height != attachmentData.height ||
|
||||||
|
data.hasFixedSize != attachmentData.hasFixedSize)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
m_pending.texturePool.erase(it);
|
m_pending.texturePool.erase(it);
|
||||||
|
|
@ -972,6 +974,7 @@ namespace Nz
|
||||||
data.format = attachmentData.format;
|
data.format = attachmentData.format;
|
||||||
data.width = attachmentData.width;
|
data.width = attachmentData.width;
|
||||||
data.height = attachmentData.height;
|
data.height = attachmentData.height;
|
||||||
|
data.hasFixedSize = attachmentData.hasFixedSize;
|
||||||
|
|
||||||
return textureId;
|
return textureId;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,7 @@ namespace Nz
|
||||||
*/
|
*/
|
||||||
Graphics::Graphics(Config config) :
|
Graphics::Graphics(Config config) :
|
||||||
ModuleBase("Graphics", this),
|
ModuleBase("Graphics", this),
|
||||||
|
m_preferredDepthFormat(PixelFormat::Undefined),
|
||||||
m_preferredDepthStencilFormat(PixelFormat::Undefined)
|
m_preferredDepthStencilFormat(PixelFormat::Undefined)
|
||||||
{
|
{
|
||||||
Renderer* renderer = Renderer::Instance();
|
Renderer* renderer = Renderer::Instance();
|
||||||
|
|
@ -213,6 +214,7 @@ namespace Nz
|
||||||
void Graphics::BuildDefaultMaterials()
|
void Graphics::BuildDefaultMaterials()
|
||||||
{
|
{
|
||||||
std::size_t depthPassIndex = m_materialPassRegistry.GetPassIndex("DepthPass");
|
std::size_t depthPassIndex = m_materialPassRegistry.GetPassIndex("DepthPass");
|
||||||
|
std::size_t shadowPassIndex = m_materialPassRegistry.GetPassIndex("ShadowPass");
|
||||||
std::size_t forwardPassIndex = m_materialPassRegistry.GetPassIndex("ForwardPass");
|
std::size_t forwardPassIndex = m_materialPassRegistry.GetPassIndex("ForwardPass");
|
||||||
|
|
||||||
// BasicMaterial
|
// BasicMaterial
|
||||||
|
|
@ -228,6 +230,7 @@ namespace Nz
|
||||||
MaterialPass depthPass = forwardPass;
|
MaterialPass depthPass = forwardPass;
|
||||||
depthPass.options[CRC32("DepthPass")] = true;
|
depthPass.options[CRC32("DepthPass")] = true;
|
||||||
settings.AddPass(depthPassIndex, depthPass);
|
settings.AddPass(depthPassIndex, depthPass);
|
||||||
|
settings.AddPass(shadowPassIndex, depthPass);
|
||||||
|
|
||||||
m_defaultMaterials.basicMaterial = std::make_shared<Material>(std::move(settings), "BasicMaterial");
|
m_defaultMaterials.basicMaterial = std::make_shared<Material>(std::move(settings), "BasicMaterial");
|
||||||
}
|
}
|
||||||
|
|
@ -246,6 +249,7 @@ namespace Nz
|
||||||
MaterialPass depthPass = forwardPass;
|
MaterialPass depthPass = forwardPass;
|
||||||
depthPass.options[CRC32("DepthPass")] = true;
|
depthPass.options[CRC32("DepthPass")] = true;
|
||||||
settings.AddPass(depthPassIndex, depthPass);
|
settings.AddPass(depthPassIndex, depthPass);
|
||||||
|
settings.AddPass(shadowPassIndex, depthPass);
|
||||||
|
|
||||||
m_defaultMaterials.pbrMaterial = std::make_shared<Material>(std::move(settings), "PhysicallyBasedMaterial");
|
m_defaultMaterials.pbrMaterial = std::make_shared<Material>(std::move(settings), "PhysicallyBasedMaterial");
|
||||||
}
|
}
|
||||||
|
|
@ -264,6 +268,7 @@ namespace Nz
|
||||||
MaterialPass depthPass = forwardPass;
|
MaterialPass depthPass = forwardPass;
|
||||||
depthPass.options[CRC32("DepthPass")] = true;
|
depthPass.options[CRC32("DepthPass")] = true;
|
||||||
settings.AddPass(depthPassIndex, depthPass);
|
settings.AddPass(depthPassIndex, depthPass);
|
||||||
|
settings.AddPass(shadowPassIndex, depthPass);
|
||||||
|
|
||||||
m_defaultMaterials.phongMaterial = std::make_shared<Material>(std::move(settings), "PhongMaterial");
|
m_defaultMaterials.phongMaterial = std::make_shared<Material>(std::move(settings), "PhongMaterial");
|
||||||
}
|
}
|
||||||
|
|
@ -272,6 +277,7 @@ namespace Nz
|
||||||
|
|
||||||
m_defaultMaterials.basicNoDepth = m_defaultMaterials.basicMaterial->Instantiate();
|
m_defaultMaterials.basicNoDepth = m_defaultMaterials.basicMaterial->Instantiate();
|
||||||
m_defaultMaterials.basicNoDepth->DisablePass(depthPassIndex);
|
m_defaultMaterials.basicNoDepth->DisablePass(depthPassIndex);
|
||||||
|
m_defaultMaterials.basicNoDepth->DisablePass(shadowPassIndex);
|
||||||
m_defaultMaterials.basicNoDepth->UpdatePassStates(forwardPassIndex, [](RenderStates& states)
|
m_defaultMaterials.basicNoDepth->UpdatePassStates(forwardPassIndex, [](RenderStates& states)
|
||||||
{
|
{
|
||||||
states.depthBuffer = false;
|
states.depthBuffer = false;
|
||||||
|
|
@ -279,6 +285,7 @@ namespace Nz
|
||||||
|
|
||||||
m_defaultMaterials.basicTransparent = m_defaultMaterials.basicMaterial->Instantiate();
|
m_defaultMaterials.basicTransparent = m_defaultMaterials.basicMaterial->Instantiate();
|
||||||
m_defaultMaterials.basicTransparent->DisablePass(depthPassIndex);
|
m_defaultMaterials.basicTransparent->DisablePass(depthPassIndex);
|
||||||
|
m_defaultMaterials.basicTransparent->DisablePass(shadowPassIndex);
|
||||||
m_defaultMaterials.basicTransparent->UpdatePassStates(forwardPassIndex, [](RenderStates& renderStates)
|
m_defaultMaterials.basicTransparent->UpdatePassStates(forwardPassIndex, [](RenderStates& renderStates)
|
||||||
{
|
{
|
||||||
renderStates.depthWrite = false;
|
renderStates.depthWrite = false;
|
||||||
|
|
@ -316,6 +323,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
m_materialPassRegistry.RegisterPass("ForwardPass");
|
m_materialPassRegistry.RegisterPass("ForwardPass");
|
||||||
m_materialPassRegistry.RegisterPass("DepthPass");
|
m_materialPassRegistry.RegisterPass("DepthPass");
|
||||||
|
m_materialPassRegistry.RegisterPass("ShadowPass");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::RegisterShaderModules()
|
void Graphics::RegisterShaderModules()
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,19 @@
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Graphics/Light.hpp>
|
#include <Nazara/Graphics/Light.hpp>
|
||||||
|
#include <Nazara/Graphics/Graphics.hpp>
|
||||||
#include <Nazara/Graphics/Debug.hpp>
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
Light::Light(UInt8 lightType) :
|
||||||
|
m_boundingVolume(BoundingVolumef::Null()),
|
||||||
|
m_shadowMapFormat(Graphics::Instance()->GetPreferredDepthFormat()),
|
||||||
|
m_shadowMapSize(512),
|
||||||
|
m_lightType(lightType),
|
||||||
|
m_isShadowCaster(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Light::~Light() = default;
|
Light::~Light() = default;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <Nazara/Graphics/PointLight.hpp>
|
#include <Nazara/Graphics/PointLight.hpp>
|
||||||
#include <Nazara/Graphics/Enums.hpp>
|
#include <Nazara/Graphics/Enums.hpp>
|
||||||
|
#include <Nazara/Graphics/Graphics.hpp>
|
||||||
#include <Nazara/Graphics/PredefinedShaderStructs.hpp>
|
#include <Nazara/Graphics/PredefinedShaderStructs.hpp>
|
||||||
#include <Nazara/Math/Vector2.hpp>
|
#include <Nazara/Math/Vector2.hpp>
|
||||||
#include <Nazara/Math/Vector3.hpp>
|
#include <Nazara/Math/Vector3.hpp>
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,8 @@ option VertexUvLoc: i32 = -1;
|
||||||
option VertexJointIndicesLoc: i32 = -1;
|
option VertexJointIndicesLoc: i32 = -1;
|
||||||
option VertexJointWeightsLoc: i32 = -1;
|
option VertexJointWeightsLoc: i32 = -1;
|
||||||
|
|
||||||
|
option MaxLightCount: u32 = u32(3); //< FIXME: Fix integral value types
|
||||||
|
|
||||||
const HasNormal = (VertexNormalLoc >= 0);
|
const HasNormal = (VertexNormalLoc >= 0);
|
||||||
const HasVertexColor = (VertexColorLoc >= 0);
|
const HasVertexColor = (VertexColorLoc >= 0);
|
||||||
const HasColor = (HasVertexColor || Billboard);
|
const HasColor = (HasVertexColor || Billboard);
|
||||||
|
|
@ -93,7 +95,9 @@ external
|
||||||
[tag("InstanceData")] instanceData: uniform[InstanceData],
|
[tag("InstanceData")] instanceData: uniform[InstanceData],
|
||||||
[tag("ViewerData")] viewerData: uniform[ViewerData],
|
[tag("ViewerData")] viewerData: uniform[ViewerData],
|
||||||
[tag("SkeletalData")] skeletalData: uniform[SkeletalData],
|
[tag("SkeletalData")] skeletalData: uniform[SkeletalData],
|
||||||
[tag("LightData")] lightData: uniform[LightData]
|
[tag("LightData")] lightData: uniform[LightData],
|
||||||
|
[tag("ShadowMaps2D")] shadowMaps2D: array[sampler2D[f32], MaxLightCount],
|
||||||
|
[tag("ShadowMapsCube")] shadowMapsCube: array[samplerCube[f32], MaxLightCount]
|
||||||
}
|
}
|
||||||
|
|
||||||
struct VertToFrag
|
struct VertToFrag
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <Nazara/Graphics/SpotLight.hpp>
|
#include <Nazara/Graphics/SpotLight.hpp>
|
||||||
#include <Nazara/Graphics/Enums.hpp>
|
#include <Nazara/Graphics/Enums.hpp>
|
||||||
|
#include <Nazara/Graphics/Graphics.hpp>
|
||||||
#include <Nazara/Graphics/PredefinedShaderStructs.hpp>
|
#include <Nazara/Graphics/PredefinedShaderStructs.hpp>
|
||||||
#include <Nazara/Math/Vector2.hpp>
|
#include <Nazara/Math/Vector2.hpp>
|
||||||
#include <Nazara/Math/Vector3.hpp>
|
#include <Nazara/Math/Vector3.hpp>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue