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到渲染结果上。
|
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的计算中。
|
Loading…
x
Reference in New Issue
Block a user