| 1455 | } |
| 1456 | |
| 1457 | void ShadowsPass::RenderShadowMaps(RenderContextBatch& renderContextBatch) |
| 1458 | { |
| 1459 | const RenderContext& renderContext = renderContextBatch.GetMainContext(); |
| 1460 | const ShadowsCustomBuffer* shadowsPtr = renderContext.Buffers->FindCustomBuffer<ShadowsCustomBuffer>(TEXT("Shadows"), false); |
| 1461 | if (shadowsPtr == nullptr || shadowsPtr->Lights.IsEmpty() || shadowsPtr->LastFrameUsed != Engine::FrameCount) |
| 1462 | return; |
| 1463 | PROFILE_GPU_CPU("Shadow Maps"); |
| 1464 | const ShadowsCustomBuffer& shadows = *shadowsPtr; |
| 1465 | GPUContext* context = GPUDevice::Instance->GetMainContext(); |
| 1466 | context->ResetSR(); |
| 1467 | GPUConstantBuffer* quadShaderCB = GPUDevice::Instance->QuadShader->GetCB(0); |
| 1468 | QuadShaderData quadShaderData; |
| 1469 | |
| 1470 | // Update static shadows |
| 1471 | if (shadows.StaticShadowMapAtlas) |
| 1472 | { |
| 1473 | PROFILE_GPU_CPU("Static"); |
| 1474 | if (shadows.ClearStaticShadowMapAtlas) |
| 1475 | context->ClearDepth(shadows.StaticShadowMapAtlas->View()); |
| 1476 | bool renderedAny = false; |
| 1477 | for (auto& e : shadows.Lights) |
| 1478 | { |
| 1479 | const ShadowAtlasLight& atlasLight = e.Value; |
| 1480 | if (!atlasLight.HasStaticShadowContext || atlasLight.ContextCount == 0) |
| 1481 | continue; |
| 1482 | int32 contextIndex = 0; |
| 1483 | |
| 1484 | if (atlasLight.StaticState == ShadowAtlasLight::WaitForGeometryCheck) |
| 1485 | { |
| 1486 | // Check for any static geometry to use in static shadow map |
| 1487 | for (int32 tileIndex = 0; tileIndex < atlasLight.TilesCount; tileIndex++) |
| 1488 | { |
| 1489 | const ShadowAtlasLightTile& tile = atlasLight.Tiles[tileIndex]; |
| 1490 | contextIndex++; // Skip dynamic context |
| 1491 | auto& shadowContextStatic = renderContextBatch.Contexts[atlasLight.ContextIndex + contextIndex++]; |
| 1492 | if (!shadowContextStatic.List->DrawCallsLists[(int32)DrawCallsListType::Depth].IsEmpty() || !shadowContextStatic.List->ShadowDepthDrawCallsList.IsEmpty()) |
| 1493 | { |
| 1494 | tile.HasStaticGeometry = true; |
| 1495 | } |
| 1496 | } |
| 1497 | } |
| 1498 | |
| 1499 | if (atlasLight.StaticState != ShadowAtlasLight::UpdateStaticShadow) |
| 1500 | continue; |
| 1501 | |
| 1502 | contextIndex = 0; |
| 1503 | for (int32 tileIndex = 0; tileIndex < atlasLight.TilesCount; tileIndex++) |
| 1504 | { |
| 1505 | const ShadowAtlasLightTile& tile = atlasLight.Tiles[tileIndex]; |
| 1506 | if (!tile.RectTile) |
| 1507 | break; |
| 1508 | if (!tile.StaticRectTile) |
| 1509 | continue; |
| 1510 | if (!renderedAny) |
| 1511 | { |
| 1512 | renderedAny = true; |
| 1513 | context->SetRenderTarget(shadows.StaticShadowMapAtlas->View(), (GPUTextureView*)nullptr); |
| 1514 | } |
no test coverage detected