uint32 FRendererModule::GetNumDynamicLightsAffectingPrimitive(const FPrimitiveSceneInfo* PrimitiveSceneInfo,const FLightCacheInterface* LCI) { uint32 NumDynamicLights = 0; FLightPrimitiveInteraction *LightList = PrimitiveSceneInfo->LightList; while ( LightList ) { const FLightSceneInfo* LightSceneInfo = LightList->GetLight(); // Determine the interaction type between the mesh and the light. FLightInteraction LightInteraction = FLightInteraction::Dynamic(); if(LCI) { LightInteraction = LCI->GetInteraction(LightSceneInfo->Proxy); } // Don't count light-mapped or irrelevant lights. if(LightInteraction.GetType() != LIT_CachedIrrelevant && LightInteraction.GetType() != LIT_CachedLightMap) { ++NumDynamicLights; } LightList = LightList->GetNextLight(); } return NumDynamicLights; }
const FProjectedShadowInfo* FDeferredShadingSceneRenderer::PrepareTranslucentShadowMap(FRHICommandList& RHICmdList, const FViewInfo& View, FPrimitiveSceneInfo* PrimitiveSceneInfo, bool bSeparateTranslucencyPass) { const FVisibleLightInfo* VisibleLightInfo = NULL; FProjectedShadowInfo* TranslucentSelfShadow = NULL; // Find this primitive's self shadow if there is one if (PrimitiveSceneInfo->Proxy && PrimitiveSceneInfo->Proxy->CastsVolumetricTranslucentShadow()) { for (FLightPrimitiveInteraction* Interaction = PrimitiveSceneInfo->LightList; Interaction && !TranslucentSelfShadow; Interaction = Interaction->GetNextLight() ) { const FLightSceneInfo* LightSceneInfo = Interaction->GetLight(); if (LightSceneInfo->Proxy->GetLightType() == LightType_Directional // Only reuse cached shadows from the light which last used TranslucentSelfShadowLayout // This has the side effect of only allowing per-pixel self shadowing from one light && LightSceneInfo->Id == CachedTranslucentSelfShadowLightId) { VisibleLightInfo = &VisibleLightInfos[LightSceneInfo->Id]; FProjectedShadowInfo* ObjectShadow = NULL; for (int32 ShadowIndex = 0; ShadowIndex < VisibleLightInfo->AllProjectedShadows.Num(); ShadowIndex++) { FProjectedShadowInfo* CurrentShadowInfo = VisibleLightInfo->AllProjectedShadows[ShadowIndex]; if (CurrentShadowInfo && CurrentShadowInfo->bTranslucentShadow && CurrentShadowInfo->ParentSceneInfo == PrimitiveSceneInfo) { TranslucentSelfShadow = CurrentShadowInfo; break; } } } } // Allocate and render the shadow's depth map if needed if (TranslucentSelfShadow && !TranslucentSelfShadow->bAllocatedInTranslucentLayout) { check(IsInRenderingThread()); bool bPossibleToAllocate = true; // Attempt to find space in the layout TranslucentSelfShadow->bAllocatedInTranslucentLayout = TranslucentSelfShadowLayout.AddElement( TranslucentSelfShadow->X, TranslucentSelfShadow->Y, TranslucentSelfShadow->ResolutionX + SHADOW_BORDER * 2, TranslucentSelfShadow->ResolutionY + SHADOW_BORDER * 2); // Free shadowmaps from this light until allocation succeeds while (!TranslucentSelfShadow->bAllocatedInTranslucentLayout && bPossibleToAllocate) { bPossibleToAllocate = false; for (int32 ShadowIndex = 0; ShadowIndex < VisibleLightInfo->AllProjectedShadows.Num(); ShadowIndex++) { FProjectedShadowInfo* CurrentShadowInfo = VisibleLightInfo->AllProjectedShadows[ShadowIndex]; if (CurrentShadowInfo->bTranslucentShadow && CurrentShadowInfo->bAllocatedInTranslucentLayout) { verify(TranslucentSelfShadowLayout.RemoveElement( CurrentShadowInfo->X, CurrentShadowInfo->Y, CurrentShadowInfo->ResolutionX + SHADOW_BORDER * 2, CurrentShadowInfo->ResolutionY + SHADOW_BORDER * 2)); CurrentShadowInfo->bAllocatedInTranslucentLayout = false; bPossibleToAllocate = true; break; } } TranslucentSelfShadow->bAllocatedInTranslucentLayout = TranslucentSelfShadowLayout.AddElement( TranslucentSelfShadow->X, TranslucentSelfShadow->Y, TranslucentSelfShadow->ResolutionX + SHADOW_BORDER * 2, TranslucentSelfShadow->ResolutionY + SHADOW_BORDER * 2); } if (!bPossibleToAllocate) { // Failed to allocate space for the shadow depth map, so don't use the self shadow TranslucentSelfShadow = NULL; } else { check(TranslucentSelfShadow->bAllocatedInTranslucentLayout); // Render the translucency shadow map TranslucentSelfShadow->RenderTranslucencyDepths(RHICmdList, this); // Restore state SetTranslucentRenderTargetAndState(RHICmdList, View, bSeparateTranslucencyPass); } } } return TranslucentSelfShadow; }