Files
UnrealEngineUWP/Engine/Shaders/Private/VirtualShadowMaps/VirtualShadowMapTransmissionCommon.ush
Sebastien Hillaire e27b68cc9b Strata - moving SSSData at the end of the strata material buffer to reduce UAV count limitation on dx11.
Fixed a bug wehre loadiung fast material would not be done correctly inside the classification pass for the sharedmemeory path.
#rb none
#jira UE-161415
#preflight https://horde.devtools.epicgames.com/job/630909b9987e7155b1af0aec
#fyi charles.derousiers

[CL 21661992 by Sebastien Hillaire in ue5-main branch]
2022-08-29 02:55:17 -04:00

72 lines
2.8 KiB
Plaintext

// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
VirtualShadowMaps/VirtualShadowMapTransmissionCommon.ush:
=============================================================================*/
#pragma once
#include "../Common.ush"
#include "../SceneTexturesCommon.ush"
#include "../DeferredShadingCommon.ush"
#include "VirtualShadowMapProjectionCommon.ush"
float GetSubsurfaceOpacityFromGbuffer(uint2 PixelPos)
{
float Opacity = 1.0;
#if STRATA_ENABLED
Opacity = StrataGetOpacityFromSubSurface(StrataLoadSubsurfaceHeader(Strata.MaterialTextureArray, Strata.FirstSliceStoringStrataSSSData, PixelPos));
#else // STRATA_ENABLED
FGBufferData GBufferData = GetGBufferDataUint(PixelPos);
// TODO: SUBSURFACE_PROFILE with fancy transmission
if (GBufferData.ShadingModelID == SHADINGMODELID_SUBSURFACE ||
GBufferData.ShadingModelID == SHADINGMODELID_PREINTEGRATED_SKIN ||
GBufferData.ShadingModelID == SHADINGMODELID_TWOSIDED_FOLIAGE)
{
// This clamp aligns with SubsurfaceDensityFromOpacity
// Various engine paths treat these subsurface materials differently
// even when they have Opacity = 1 in the material shader, so this is
// important to avoid things like backface transmission being shadowed by
// contact shadows and so on.
Opacity = min(GBufferData.CustomData.a, 0.99f);
}
#endif // STRATA_ENABLED
return Opacity;
}
/**
* Sample VSM to determine approximate thickness and compute simple subsurface transmission matching the
* PCF path.
*/
float ComputeSimpleSubsurfaceTransmissionFromVirtualShadowMap(
int VirtualShadowMapId,
float3 TranslatedWorldPosition,
float SubsurfaceOpacity)
{
// If the receiver is a subsurface material, we do a very simple transmission approximation
// This matches the logic in the PCF kernel (ShadowFilteringCommon.ush) and the contact
// shadows trace (DeferredLightingCommon.ush). Ideally these should all be unified in a single location.
// Could optimize this in the case where we are doing single-sample VSM lookup anyways, but we would need
// exclude contact shadows overwriting the occluder distance. Single sample direct shadows are not currently
// a common case.
// Do a separate unfiltered lookup to get approximate occluder distance
FVirtualShadowMapSampleResult SSSResult = SampleVirtualShadowMapTranslatedWorld(
VirtualShadowMapId,
TranslatedWorldPosition,
0.0f // RayStartDistance
);
if ( SSSResult.bValid && SSSResult.ShadowFactor < 1.0f )
{
float Density = SubsurfaceDensityFromOpacity( SubsurfaceOpacity );
float Occlusion = 1.0f - saturate( exp( -Density * SSSResult.OccluderDistance ) );
// NOTE: This square is arbitrary, but we have to be consistent with the PCF path
return Square( 1.0f - Occlusion * ( 1.0f - SSSResult.ShadowFactor ) );
}
return 1.0f;
}