You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
Now header is only uint and extra data is only read if needed. #rb none #preflight https://horde.devtools.epicgames.com/job/62821984046b81bf9393b136 #fyi charles.derousiers [CL 20221584 by Sebastien Hillaire in ue5-main branch]
72 lines
2.7 KiB
Plaintext
72 lines
2.7 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"
|
|
|
|
half GetSubsurfaceOpacityFromGbuffer(uint2 PixelPos)
|
|
{
|
|
half Opacity = 1.0;
|
|
|
|
#if STRATA_ENABLED
|
|
Opacity = StrataGetOpacityFromSubSurface(StrataLoadSubsurfaceHeader(Strata.SSSTexture, 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.
|
|
*/
|
|
half ComputeSimpleSubsurfaceTransmissionFromVirtualShadowMap(
|
|
int VirtualShadowMapId,
|
|
float3 TranslatedWorldPosition,
|
|
half 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;
|
|
}
|