vault backup: 2025-03-25 17:18:11
This commit is contained in:
parent
938eab3068
commit
39586e089b
@ -548,6 +548,287 @@ float3 CompositeReflectionCapturesAndSkylightTWS(
|
||||
8. 应用GI到渲染结果上。
|
||||
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的计算中。
|
Loading…
x
Reference in New Issue
Block a user