void RenderSystem::UpdateDirectionalShadowMaps(const Nz::AbstractViewer& /*viewer*/) { if (!m_shadowRT.IsValid()) m_shadowRT.Create(); Nz::SceneData dummySceneData; dummySceneData.ambientColor = Nz::Color(0, 0, 0); dummySceneData.background = nullptr; dummySceneData.viewer = nullptr; //< Depth technique doesn't require any viewer for (const Ndk::EntityHandle& light : m_directionalLights) { LightComponent& lightComponent = light->GetComponent<LightComponent>(); NodeComponent& lightNode = light->GetComponent<NodeComponent>(); if (!lightComponent.IsShadowCastingEnabled()) continue; Nz::Vector2ui shadowMapSize(lightComponent.GetShadowMap()->GetSize()); m_shadowRT.AttachTexture(Nz::AttachmentPoint_Depth, 0, lightComponent.GetShadowMap()); Nz::Renderer::SetTarget(&m_shadowRT); Nz::Renderer::SetViewport(Nz::Recti(0, 0, shadowMapSize.x, shadowMapSize.y)); Nz::AbstractRenderQueue* renderQueue = m_shadowTechnique.GetRenderQueue(); renderQueue->Clear(); ///TODO: Culling for (const Ndk::EntityHandle& drawable : m_drawables) { GraphicsComponent& graphicsComponent = drawable->GetComponent<GraphicsComponent>(); graphicsComponent.AddToRenderQueue(renderQueue); } ///TODO: Cache the matrices in the light? Nz::Renderer::SetMatrix(Nz::MatrixType_Projection, Nz::Matrix4f::Ortho(0.f, 100.f, 100.f, 0.f, 1.f, 100.f)); Nz::Renderer::SetMatrix(Nz::MatrixType_View, Nz::Matrix4f::ViewMatrix(lightNode.GetRotation() * Nz::Vector3f::Forward() * 100.f, lightNode.GetRotation())); m_shadowTechnique.Clear(dummySceneData); m_shadowTechnique.Draw(dummySceneData); } }
void RenderSystem::UpdatePointSpotShadowMaps() { if (!m_shadowRT.IsValid()) m_shadowRT.Create(); Nz::SceneData dummySceneData; dummySceneData.ambientColor = Nz::Color(0, 0, 0); dummySceneData.background = nullptr; dummySceneData.viewer = nullptr; //< Depth technique doesn't require any viewer for (const Ndk::EntityHandle& light : m_pointSpotLights) { LightComponent& lightComponent = light->GetComponent<LightComponent>(); NodeComponent& lightNode = light->GetComponent<NodeComponent>(); if (!lightComponent.IsShadowCastingEnabled()) continue; Nz::Vector2ui shadowMapSize(lightComponent.GetShadowMap()->GetSize()); switch (lightComponent.GetLightType()) { case Nz::LightType_Directional: NazaraInternalError("Directional lights included in point/spot light list"); break; case Nz::LightType_Point: { static Nz::Quaternionf rotations[6] = { Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), Nz::Vector3f::UnitX()), // CubemapFace_PositiveX Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), -Nz::Vector3f::UnitX()), // CubemapFace_NegativeX Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), -Nz::Vector3f::UnitY()), // CubemapFace_PositiveY Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), Nz::Vector3f::UnitY()), // CubemapFace_NegativeY Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), -Nz::Vector3f::UnitZ()), // CubemapFace_PositiveZ Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), Nz::Vector3f::UnitZ()) // CubemapFace_NegativeZ }; for (unsigned int face = 0; face < 6; ++face) { m_shadowRT.AttachTexture(Nz::AttachmentPoint_Depth, 0, lightComponent.GetShadowMap(), face); Nz::Renderer::SetTarget(&m_shadowRT); Nz::Renderer::SetViewport(Nz::Recti(0, 0, shadowMapSize.x, shadowMapSize.y)); ///TODO: Cache the matrices in the light? Nz::Renderer::SetMatrix(Nz::MatrixType_Projection, Nz::Matrix4f::Perspective(Nz::FromDegrees(90.f), 1.f, 0.1f, lightComponent.GetRadius())); Nz::Renderer::SetMatrix(Nz::MatrixType_View, Nz::Matrix4f::ViewMatrix(lightNode.GetPosition(), rotations[face])); Nz::AbstractRenderQueue* renderQueue = m_shadowTechnique.GetRenderQueue(); renderQueue->Clear(); ///TODO: Culling for (const Ndk::EntityHandle& drawable : m_drawables) { GraphicsComponent& graphicsComponent = drawable->GetComponent<GraphicsComponent>(); graphicsComponent.AddToRenderQueue(renderQueue); } m_shadowTechnique.Clear(dummySceneData); m_shadowTechnique.Draw(dummySceneData); } break; } case Nz::LightType_Spot: { m_shadowRT.AttachTexture(Nz::AttachmentPoint_Depth, 0, lightComponent.GetShadowMap()); Nz::Renderer::SetTarget(&m_shadowRT); Nz::Renderer::SetViewport(Nz::Recti(0, 0, shadowMapSize.x, shadowMapSize.y)); ///TODO: Cache the matrices in the light? Nz::Renderer::SetMatrix(Nz::MatrixType_Projection, Nz::Matrix4f::Perspective(lightComponent.GetOuterAngle()*2.f, 1.f, 0.1f, lightComponent.GetRadius())); Nz::Renderer::SetMatrix(Nz::MatrixType_View, Nz::Matrix4f::ViewMatrix(lightNode.GetPosition(), lightNode.GetRotation())); Nz::AbstractRenderQueue* renderQueue = m_shadowTechnique.GetRenderQueue(); renderQueue->Clear(); ///TODO: Culling for (const Ndk::EntityHandle& drawable : m_drawables) { GraphicsComponent& graphicsComponent = drawable->GetComponent<GraphicsComponent>(); graphicsComponent.AddToRenderQueue(renderQueue); } m_shadowTechnique.Clear(dummySceneData); m_shadowTechnique.Draw(dummySceneData); break; } } } }
void DeferredSpotLightsPass::renderLight(SpotLight* light, IEffect* lightEffect, IViewer* viewer, unsigned int normalMap) { GraphicsInterface::beginPerformanceEvent("Lighting"); light->update(); GraphicsInterface::setFrameBuffer(spotLightFrameBuffer_); GraphicsInterface::clearActiveColorBuffers(Color4::CORNFLOWERBLUE); lightEffect->beginDraw(); GraphicsInterface::setRenderState(CULL_MODE_BACK); Matrix4x4 viewProjection = viewer->projection() * viewer->viewTransform(); lightEffect->setUniform(viewer->viewTransform(), "View"); lightEffect->setUniform(viewProjection, "ViewProj"); lightEffect->setUniform(viewProjection.inverse(), "ViewProjInv"); lightEffect->setUniform(viewer->projection().inverse(), "ProjInv"); lightEffect->setUniform(viewer->position(), "ViewerPosition"); Matrix4x4 worldViewProj = viewer->projection() * viewer->viewTransform() * light->transform(); lightEffect->setUniform(worldViewProj, "WorldViewProj"); Matrix4x4 worldView = viewer->viewTransform() * light->transform(); lightEffect->setUniform(worldView, "WorldView"); Matrix3x3 normalMatrix = viewer->viewTransform().inverse().transpose().mat3x3(); // strips out the translation; lightEffect->setUniform(normalMatrix, "NormalMatrix"); Matrix4x4 lightViewProj = light->projection() * light->viewTransform(); lightEffect->setUniform(lightViewProj, "LightViewProj"); lightEffect->setUniform(lightViewProj.inverse(), "LightViewProjRaw"); float lightDistance = light->direction().length(); float lightDistanceSquared = lightDistance * lightDistance; lightEffect->setUniform(1.0f / lightDistanceSquared, "LightDistance"); lightEffect->setUniform(light->direction().inverse().normalize(), "DirectionToLight"); lightEffect->setUniform(light->position(), "LightPosition"); lightEffect->setUniform(light->direction().normalize(), "LightDirection"); lightEffect->setUniform(light->color(), "LightColor"); lightEffect->setUniform(light->outerAngle(), "LightOuterAngle"); lightEffect->setUniform(light->innerAngle(), "LightInnerAngle"); lightEffect->setUniform(GraphicsInterface::halfBackBufferPixel(), "HalfPixel"); unsigned int depthBufferId = GraphicsInterface::depthBufferTexture(); lightEffect->setTexture(depthBufferId, "DepthMap"); lightEffect->setTexture(normalMap, "NormalMap"); if (light->castsShadows()) { CSize shadowMapResolution = light->shadowMapResolution(); Vector2 shadowMapSize(1.0f/shadowMapResolution.width, 1.0f/shadowMapResolution.height); lightEffect->setUniform(shadowMapSize, "ShadowMapSize"); lightEffect->setTexture(light->shadowMapTexture(), "ShadowMap"); lightEffect->setUniform(light->lightBias(), "LightBias"); lightEffect->setUniform(light->lightBleed(), "LightBleed"); lightEffect->setUniform(light->shadowBias(), "ShadowBias"); } //GraphicsInterface::setBlendState(IGraphicsInterface::ALPHA); lightEffect->commitBuffers(); GraphicsInterface::drawVertexBuffer(quadVbo_, Geometry::SCREEN_PLANE_VERTEX_COUNT, Geometry::SCREEN_PLANE_VERTEX_FORMAT); lightEffect->endDraw(); GraphicsInterface::endPerformanceEvent(); }