void FIndirectLightingCache::EncodeBlock( FViewInfo* DebugDrawingView, const FIndirectLightingCacheBlock& Block, const TArray<float>& AccumulatedWeight, const TArray<FSHVectorRGB2>& AccumulatedIncidentRadiance, const TArray<FVector>& AccumulatedSkyBentNormal, TArray<FFloat16Color>& Texture0Data, TArray<FFloat16Color>& Texture1Data, TArray<FFloat16Color>& Texture2Data, FSHVectorRGB2& SingleSample, FVector& SkyBentNormal) { FViewElementPDI DebugPDI(DebugDrawingView, NULL); for (int32 Z = 0; Z < Block.TexelSize; Z++) { for (int32 Y = 0; Y < Block.TexelSize; Y++) { for (int32 X = 0; X < Block.TexelSize; X++) { const int32 LinearIndex = Z * Block.TexelSize * Block.TexelSize + Y * Block.TexelSize + X; FSHVectorRGB2 IncidentRadiance = AccumulatedIncidentRadiance[LinearIndex]; float Weight = AccumulatedWeight[LinearIndex]; if (Weight > 0) { IncidentRadiance = IncidentRadiance / Weight; if (GCacheReduceSHRinging != 0) { ReduceSHRinging(IncidentRadiance); } } // Populate single sample from center if (X == Block.TexelSize / 2 && Y == Block.TexelSize / 2 && Z == Block.TexelSize / 2) { SingleSample = IncidentRadiance; SkyBentNormal = AccumulatedSkyBentNormal[LinearIndex] / (Weight > 0 ? Weight : 1); } if (GCacheDrawInterpolationPoints != 0 && DebugDrawingView) { const FVector WorldPosition = Block.Min + (FVector(X, Y, Z) + .5f) / Block.TexelSize * Block.Size; DebugPDI.DrawPoint(WorldPosition, FLinearColor(0, 0, 1), 10, SDPG_World); } Texture0Data[LinearIndex] = FLinearColor(IncidentRadiance.R.V[0], IncidentRadiance.G.V[0], IncidentRadiance.B.V[0], IncidentRadiance.R.V[3]); Texture1Data[LinearIndex] = FLinearColor(IncidentRadiance.R.V[1], IncidentRadiance.G.V[1], IncidentRadiance.B.V[1], IncidentRadiance.G.V[3]); Texture2Data[LinearIndex] = FLinearColor(IncidentRadiance.R.V[2], IncidentRadiance.G.V[2], IncidentRadiance.B.V[2], IncidentRadiance.B.V[3]); } } } }
void FIndirectLightingCache::InterpolatePoint( FScene* Scene, const FIndirectLightingCacheBlock& Block, float& OutDirectionalShadowing, FSHVectorRGB3& OutIncidentRadiance, FVector& OutSkyBentNormal) { FSHVectorRGB3 AccumulatedIncidentRadiance; FVector AccumulatedSkyBentNormal(0, 0, 0); float AccumulatedDirectionalShadowing = 0; float AccumulatedWeight = 0; for (int32 VolumeIndex = 0; VolumeIndex < Scene->PrecomputedLightVolumes.Num(); VolumeIndex++) { const FPrecomputedLightVolume* PrecomputedLightVolume = Scene->PrecomputedLightVolumes[VolumeIndex]; if (PrecomputedLightVolume) { PrecomputedLightVolume->InterpolateIncidentRadiancePoint( Block.Min + Block.Size / 2, AccumulatedWeight, AccumulatedDirectionalShadowing, AccumulatedIncidentRadiance, AccumulatedSkyBentNormal); } } if (AccumulatedWeight > 0) { OutDirectionalShadowing = AccumulatedDirectionalShadowing / AccumulatedWeight; OutIncidentRadiance = AccumulatedIncidentRadiance / AccumulatedWeight; OutSkyBentNormal = AccumulatedSkyBentNormal / AccumulatedWeight; if (GCacheReduceSHRinging != 0) { ReduceSHRinging(OutIncidentRadiance); } } else { OutIncidentRadiance = AccumulatedIncidentRadiance; OutDirectionalShadowing = 1; // Use an unoccluded vector if no valid samples were found for interpolation OutSkyBentNormal = FVector(0, 0, 1); } }
void FIndirectLightingCache::InterpolatePoint( FScene* Scene, const FIndirectLightingCacheBlock& Block, float& OutDirectionalShadowing, FSHVectorRGB2& OutIncidentRadiance) { FSHVectorRGB2 AccumulatedIncidentRadiance; float AccumulatedDirectionalShadowing = 0; float AccumulatedWeight = 0; for (int32 VolumeIndex = 0; VolumeIndex < Scene->PrecomputedLightVolumes.Num(); VolumeIndex++) { const FPrecomputedLightVolume* PrecomputedLightVolume = Scene->PrecomputedLightVolumes[VolumeIndex]; PrecomputedLightVolume->InterpolateIncidentRadiancePoint( Block.Min + Block.Size / 2, AccumulatedWeight, AccumulatedDirectionalShadowing, AccumulatedIncidentRadiance); } if (AccumulatedWeight > 0) { OutDirectionalShadowing = AccumulatedDirectionalShadowing / AccumulatedWeight; OutIncidentRadiance = AccumulatedIncidentRadiance / AccumulatedWeight; if (GCacheReduceSHRinging != 0) { ReduceSHRinging(OutIncidentRadiance); } } else { OutIncidentRadiance = AccumulatedIncidentRadiance; OutDirectionalShadowing = AccumulatedDirectionalShadowing; } }