| 318 | */ |
| 319 | |
| 320 | void RenderSystem::UpdatePointSpotShadowMaps() |
| 321 | { |
| 322 | if (!m_shadowRT.IsValid()) |
| 323 | m_shadowRT.Create(); |
| 324 | |
| 325 | Nz::SceneData dummySceneData; |
| 326 | dummySceneData.ambientColor = Nz::Color(0, 0, 0); |
| 327 | dummySceneData.background = nullptr; |
| 328 | dummySceneData.viewer = nullptr; //< Depth technique doesn't require any viewer |
| 329 | |
| 330 | for (const Ndk::EntityHandle& light : m_pointSpotLights) |
| 331 | { |
| 332 | LightComponent& lightComponent = light->GetComponent<LightComponent>(); |
| 333 | NodeComponent& lightNode = light->GetComponent<NodeComponent>(); |
| 334 | |
| 335 | if (!lightComponent.IsShadowCastingEnabled()) |
| 336 | continue; |
| 337 | |
| 338 | Nz::Vector2ui shadowMapSize(lightComponent.GetShadowMap()->GetSize()); |
| 339 | |
| 340 | switch (lightComponent.GetLightType()) |
| 341 | { |
| 342 | case Nz::LightType_Directional: |
| 343 | NazaraInternalError("Directional lights included in point/spot light list"); |
| 344 | break; |
| 345 | |
| 346 | case Nz::LightType_Point: |
| 347 | { |
| 348 | static Nz::Quaternionf rotations[6] = |
| 349 | { |
| 350 | Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), Nz::Vector3f::UnitX()), // CubemapFace_PositiveX |
| 351 | Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), -Nz::Vector3f::UnitX()), // CubemapFace_NegativeX |
| 352 | Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), -Nz::Vector3f::UnitY()), // CubemapFace_PositiveY |
| 353 | Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), Nz::Vector3f::UnitY()), // CubemapFace_NegativeY |
| 354 | Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), -Nz::Vector3f::UnitZ()), // CubemapFace_PositiveZ |
| 355 | Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), Nz::Vector3f::UnitZ()) // CubemapFace_NegativeZ |
| 356 | }; |
| 357 | |
| 358 | for (unsigned int face = 0; face < 6; ++face) |
| 359 | { |
| 360 | m_shadowRT.AttachTexture(Nz::AttachmentPoint_Depth, 0, lightComponent.GetShadowMap(), face); |
| 361 | Nz::Renderer::SetTarget(&m_shadowRT); |
| 362 | Nz::Renderer::SetViewport(Nz::Recti(0, 0, shadowMapSize.x, shadowMapSize.y)); |
| 363 | |
| 364 | ///TODO: Cache the matrices in the light? |
| 365 | Nz::Renderer::SetMatrix(Nz::MatrixType_Projection, Nz::Matrix4f::Perspective(Nz::FromDegrees(90.f), 1.f, 0.1f, lightComponent.GetRadius())); |
| 366 | Nz::Renderer::SetMatrix(Nz::MatrixType_View, Nz::Matrix4f::ViewMatrix(lightNode.GetPosition(), rotations[face])); |
| 367 | |
| 368 | Nz::AbstractRenderQueue* renderQueue = m_shadowTechnique.GetRenderQueue(); |
| 369 | renderQueue->Clear(); |
| 370 | |
| 371 | ///TODO: Culling |
| 372 | for (const Ndk::EntityHandle& drawable : m_drawables) |
| 373 | { |
| 374 | GraphicsComponent& graphicsComponent = drawable->GetComponent<GraphicsComponent>(); |
| 375 | |
| 376 | graphicsComponent.AddToRenderQueue(renderQueue); |
| 377 | } |
nothing calls this directly
no test coverage detected