vault backup: 2025-03-25 17:18:11

This commit is contained in:
BlueRose 2025-03-25 17:18:11 +08:00
parent 938eab3068
commit 39586e089b

View File

@ -548,6 +548,287 @@ float3 CompositeReflectionCapturesAndSkylightTWS(
8. 应用GI到渲染结果上。 8. 应用GI到渲染结果上。
9. ApplyAmbientCubemapComposite() 9. ApplyAmbientCubemapComposite()
DiffuseIndirectComposite FDiffuseIndirectCompositePS位于/Engine/Private/DiffuseIndirectComposite.usf的MainPS()
FDiffuseIndirectCompositePS, "/Engine/Private/DiffuseIndirectComposite.usf", "MainPS", SF_Pixel); ### FDiffuseIndirectCompositePS
```c++
void MainPS(
float4 SvPosition : SV_POSITION
#if DIM_APPLY_DIFFUSE_INDIRECT
#if ENABLE_DUAL_SRC_BLENDING
, out float4 OutAddColor DUAL_SOURCE_BLENDING_SLOT(0) : SV_Target0
, out float4 OutMultiplyColor DUAL_SOURCE_BLENDING_SLOT(1) : SV_Target1
#else
, out float4 OutColor : SV_Target0
#endif
#else
, out float4 OutMultiplyColor : SV_Target0
#endif
)
{
const uint2 PixelPos = SvPosition.xy;
const float2 SceneBufferUV = SvPositionToBufferUV(SvPosition);
const float2 ScreenPosition = SvPositionToScreenPosition(SvPosition).xy;
#if !ENABLE_DUAL_SRC_BLENDING && DIM_APPLY_DIFFUSE_INDIRECT
float4 OutAddColor = float4(0.0, 0.0, 0.0, 0.0);
float4 OutMultiplyColor;
const float4 SceneColor = SceneColorTexture.SampleLevel(SceneColorSampler, SceneBufferUV, 0);
#endif
// Sample scene textures.
const FLumenMaterialData Material = ReadMaterialData(PixelPos, SceneBufferUV);
// Sample the ambient occlusion that is dynamically generated every frame.
const float DynamicAmbientOcclusion = AmbientOcclusionTexture.SampleLevel(AmbientOcclusionSampler, SceneBufferUV, 0).r;
// Compute the final ambient occlusion to be applied. Lumen handles material AO internally.
float FinalAmbientOcclusion = 1.0f;
#if DIM_APPLY_DIFFUSE_INDIRECT != DIM_APPLY_DIFFUSE_INDIRECT_SCREEN_PROBE_GATHER
{
float AOMask = IsValid(Material);
FinalAmbientOcclusion = lerp(1.0f, Material.MaterialAO * DynamicAmbientOcclusion, AOMask * AmbientOcclusionStaticFraction);
}
#endif
const float3 TranslatedWorldPosition = mul(float4(GetScreenPositionForProjectionType(ScreenPosition, Material.SceneDepth), Material.SceneDepth, 1), View.ScreenToTranslatedWorld).xyz;
const float3 N = Material.WorldNormal;
const float3 V = normalize(View.TranslatedWorldCameraOrigin - TranslatedWorldPosition);
const float NoV = saturate(dot(N, V));
// Apply diffuse indirect.
//这里的DIM可能是Diffuse Indirect Map的缩写
#if DIM_APPLY_DIFFUSE_INDIRECT
OutAddColor = 0;
{
FDirectLighting IndirectLighting = (FDirectLighting)0;
if (IsValid(Material))
{
float3 DiffuseIndirectLighting = 0;
float3 RoughSpecularIndirectLighting = 0;
float4 SpecularIndirectLighting = 0;
//直接从屏幕空间探针中获取数据Lumen
#if DIM_APPLY_DIFFUSE_INDIRECT == DIM_APPLY_DIFFUSE_INDIRECT_SCREEN_PROBE_GATHER
DiffuseIndirectLighting = DiffuseIndirect_Textures_0.SampleLevel(GlobalPointClampedSampler, SceneBufferUV, 0).rgb;
RoughSpecularIndirectLighting = DiffuseIndirect_Textures_2.SampleLevel(GlobalPointClampedSampler, SceneBufferUV, 0).rgb;
SpecularIndirectLighting = DiffuseIndirect_Textures_3.SampleLevel(GlobalPointClampedSampler, SceneBufferUV, 0).rgba;
#else
{
//设置降噪器参数
// Sample the output of the denoiser.
FSSDKernelConfig KernelConfig = CreateKernelConfig();
#if DEBUG_OUTPUT
{
KernelConfig.DebugPixelPosition = uint2(SvPosition.xy);
KernelConfig.DebugEventCounter = 0;
}
#endif
// Compile time.
KernelConfig.bSampleKernelCenter = true;
KernelConfig.BufferLayout = CONFIG_SIGNAL_INPUT_LAYOUT;
KernelConfig.bUnroll = true;
#if DIM_UPSCALE_DIFFUSE_INDIRECT
{
KernelConfig.SampleSet = SAMPLE_SET_2X2_BILINEAR;
KernelConfig.BilateralDistanceComputation = SIGNAL_WORLD_FREQUENCY_REF_METADATA_ONLY;
KernelConfig.WorldBluringDistanceMultiplier = 16.0;
KernelConfig.BilateralSettings[0] = BILATERAL_POSITION_BASED(3);
// SGPRs
KernelConfig.BufferSizeAndInvSize = View.BufferSizeAndInvSize * float4(0.5, 0.5, 2.0, 2.0);
KernelConfig.BufferBilinearUVMinMax = View.BufferBilinearUVMinMax;
}
#else
{
KernelConfig.SampleSet = SAMPLE_SET_1X1;
KernelConfig.bNormalizeSample = true;
// SGPRs
KernelConfig.BufferSizeAndInvSize = View.BufferSizeAndInvSize;
KernelConfig.BufferBilinearUVMinMax = View.BufferBilinearUVMinMax;
}
#endif
// VGPRs
KernelConfig.BufferUV = SceneBufferUV;
{
// STRATA_TODO: We use the top layer data, but we should resolve lighting for each BSDFs.
KernelConfig.CompressedRefSceneMetadata = MaterialToCompressedSceneMetadata(Material.SceneDepth, Material.WorldNormal, Material.Roughness, Material.ShadingID);
KernelConfig.RefBufferUV = SceneBufferUV;
KernelConfig.RefSceneMetadataLayout = METADATA_BUFFER_LAYOUT_DISABLED;
}
KernelConfig.HammersleySeed = Rand3DPCG16(int3(SvPosition.xy, View.StateFrameIndexMod8)).xy;
FSSDSignalAccumulatorArray UncompressedAccumulators = CreateSignalAccumulatorArray();
FSSDCompressedSignalAccumulatorArray CompressedAccumulators = CompressAccumulatorArray(
UncompressedAccumulators, CONFIG_ACCUMULATOR_VGPR_COMPRESSION);
AccumulateKernel(
KernelConfig,
DiffuseIndirect_Textures_0,
DiffuseIndirect_Textures_1,
DiffuseIndirect_Textures_2,
DiffuseIndirect_Textures_3,
/* inout */ UncompressedAccumulators,
/* inout */ CompressedAccumulators);
//PassDebugOutput[uint2(SvPosition.xy)] = float4(UncompressedAccumulators.Array[0].Moment1.SampleCount, 0, 0, 0);
FSSDSignalSample Sample;
#if DIM_UPSCALE_DIFFUSE_INDIRECT
Sample = NormalizeToOneSample(UncompressedAccumulators.Array[0].Moment1);
#else
Sample = UncompressedAccumulators.Array[0].Moment1;
#endif
//SSGI、RTGI直接将降噪上采样结果赋予DiffuseIndirectLighting
#if DIM_APPLY_DIFFUSE_INDIRECT == DIM_APPLY_DIFFUSE_INDIRECT_SSGI || DIM_APPLY_DIFFUSE_INDIRECT == DIM_APPLY_DIFFUSE_INDIRECT_RTGI
{
DiffuseIndirectLighting = Sample.SceneColor.rgb;
}
#else
#error Unimplemented
#endif
}
#endif
#if STRATA_ENABLED
{
FStrataAddressing StrataAddressing = GetStrataPixelDataByteOffset(PixelPos, uint2(View.BufferSizeAndInvSize.xy), Strata.MaxBytesPerPixel);
FStrataPixelHeader StrataPixelHeader = UnpackStrataHeaderIn(Strata.MaterialTextureArray, StrataAddressing, Strata.TopLayerTexture);
if (StrataPixelHeader.GetMaterialMode() > HEADER_MATERIALMODE_NONE)
{
const FStrataDeferredLighting IndirectLighting_Strata = StrataIndirectLighting(
PixelPos,
Strata.MaterialTextureArray,
StrataAddressing,
StrataPixelHeader,
V,
DynamicAmbientOcclusion,
DiffuseIndirectLighting,
SpecularIndirectLighting);
OutAddColor = IndirectLighting_Strata.SceneColor;
#if STRATA_OPAQUE_ROUGH_REFRACTION_ENABLED
const uint2 OutCoord = PixelPos;
OutOpaqueRoughRefractionSceneColor[OutCoord] = IndirectLighting_Strata.OpaqueRoughRefractionSceneColor;
OutSubSurfaceSceneColor[OutCoord] = IndirectLighting_Strata.SubSurfaceSceneColor;
#endif
}
}
#else // STRATA_ENABLED
{
FGBufferData GBuffer = Material.GBufferData;
float3 DiffuseColor = bVisualizeDiffuseIndirect ? float3(.18f, .18f, .18f) : GBuffer.DiffuseColor;
float3 SpecularColor = GBuffer.SpecularColor;
#if DIM_APPLY_DIFFUSE_INDIRECT == DIM_APPLY_DIFFUSE_INDIRECT_SCREEN_PROBE_GATHER
RemapClearCoatDiffuseAndSpecularColor(GBuffer, NoV, DiffuseColor, SpecularColor);
#endif
//取得AO
FShadingOcclusion Occlusion = GetShadingOcclusion(PixelPos, V, N, GBuffer.Roughness, GBuffer.BaseColor, DynamicAmbientOcclusion);
//对双面植被与次表面进行DiffuseOcclusion适配
if (GBuffer.ShadingModelID == SHADINGMODELID_TWOSIDED_FOLIAGE || GBuffer.ShadingModelID == SHADINGMODELID_SUBSURFACE)
{
Occlusion.DiffuseOcclusion = lerp(1, Occlusion.DiffuseOcclusion, LumenFoliageOcclusionStrength);
}
//Hair需要单独处理
if (GBuffer.ShadingModelID == SHADINGMODELID_HAIR)
{
float3 L = 0;
const float3 IndirectDiffuseColor = EvaluateEnvHair(GBuffer, V, N, L /*out*/);
IndirectLighting.Diffuse = DiffuseIndirectLighting * Occlusion.DiffuseOcclusion * IndirectDiffuseColor;
IndirectLighting.Specular = 0;
}
else
{
float3 BackfaceDiffuseIndirectLighting = 0;
//双面植被计算BackfaceDiffuseIndirectLighting。如果不支持BackfaceDiffuse则将预积分结果加到DiffuseColor中。
if (GBuffer.ShadingModelID == SHADINGMODELID_TWOSIDED_FOLIAGE)
{
float3 SubsurfaceColor = ExtractSubsurfaceColor(GBuffer);
if (bLumenSupportBackfaceDiffuse > 0)
{
BackfaceDiffuseIndirectLighting += SubsurfaceColor * DiffuseIndirect_Textures_1.SampleLevel(GlobalPointClampedSampler, SceneBufferUV, 0).rgb;
}
else
{
// Adding Subsurface energy to the diffuse lobe is a poor approximation when DiffuseColor is small and SubsurfaceColor is large
// Reduce the error by attenuating SubsurfaceColor, even though diffuse already has the 1/PI for Lambert.
const float PreintegratedTwoSidedBxDF = 1.0f / PI;
DiffuseColor += SubsurfaceColor * PreintegratedTwoSidedBxDF;
}
}
//次表面、预积分皮肤直接将次表面颜色加到Diffsue上。
if (GBuffer.ShadingModelID == SHADINGMODELID_SUBSURFACE || GBuffer.ShadingModelID == SHADINGMODELID_PREINTEGRATED_SKIN)
{
float3 SubsurfaceColor = ExtractSubsurfaceColor(GBuffer);
// Add subsurface energy to diffuse
DiffuseColor += SubsurfaceColor;
}
//布料计算
if (GBuffer.ShadingModelID == SHADINGMODELID_CLOTH)
{
float3 ClothFuzz = ExtractSubsurfaceColor(GBuffer);
DiffuseColor += ClothFuzz * GBuffer.CustomData.a;
}
//最终GI结果计算
IndirectLighting.Diffuse = (DiffuseIndirectLighting * DiffuseColor + BackfaceDiffuseIndirectLighting) * Occlusion.DiffuseOcclusion;
IndirectLighting.Transmission = 0;
#if DIM_APPLY_DIFFUSE_INDIRECT == DIM_APPLY_DIFFUSE_INDIRECT_SCREEN_PROBE_GATHER
//Lumen计算的反射
RoughSpecularIndirectLighting *= Occlusion.SpecularOcclusion;
IndirectLighting.Specular = CombineRoughSpecular(GBuffer, HasBackfaceDiffuse(Material), NoV, SpecularIndirectLighting, RoughSpecularIndirectLighting, SpecularColor);
#else
//SSGI、RTGI等其他GI方法的反射结果
IndirectLighting.Specular = AddContrastAndSpecularScale(SpecularIndirectLighting.xyz) * EnvBRDF(SpecularColor, GBuffer.Roughness, NoV);
#endif
}
}
#endif // STRATA_ENABLED
}
// Accumulate lighting into the final buffers
#if !STRATA_ENABLED
IndirectLighting.Specular *= GetSSSCheckerboadSpecularScale(PixelPos, Material.bNeedsSeparateLightAccumulation);
FLightAccumulator LightAccumulator = (FLightAccumulator)0;
LightAccumulator_Add(
LightAccumulator,
IndirectLighting.Diffuse + IndirectLighting.Specular,
IndirectLighting.Diffuse,
1.0f,
Material.bNeedsSeparateLightAccumulation);
OutAddColor = LightAccumulator_GetResult(LightAccumulator);
#endif // !STRATA_ENABLED
}
#endif
OutMultiplyColor = FinalAmbientOcclusion;
#if !ENABLE_DUAL_SRC_BLENDING && DIM_APPLY_DIFFUSE_INDIRECT
OutColor = SceneColor * OutMultiplyColor + OutAddColor;
#endif
}
```
PS.
1. 采样自DiffuseIndirect_Textures_2的RoughSpecularIndirectLighting只会用在Lumen的计算中。