159 lines
5.6 KiB
HLSL
159 lines
5.6 KiB
HLSL
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
// Experimental - Stochastic lighting for Substrate
|
|
// Select and light stochastically a single Slab for material containing several layers
|
|
#define SUBSTRATE_STOCHASTIC_LIGHTING 0
|
|
|
|
#include "MegaLights.ush"
|
|
#include "MegaLightsMaterial.ush"
|
|
|
|
FDeferredLightingSplit GetMegaLightsSplitLighting(
|
|
float3 TranslatedWorldPosition,
|
|
float3 CameraVector,
|
|
FMegaLightsMaterial Material,
|
|
float AmbientOcclusion,
|
|
FDeferredLightData LightData,
|
|
float4 LightAttenuation,
|
|
float Dither,
|
|
uint2 ScreenCoord,
|
|
inout float SurfaceShadow)
|
|
#if SUBSTRATE_ENABLED && !INPUT_TYPE == INPUT_TYPE_HAIRSTRANDS
|
|
{
|
|
const uint2 PixelCoord = ScreenCoord;
|
|
|
|
FDeferredLightingSplit Out = (FDeferredLightingSplit)0;
|
|
#if SUBSTRATE_GBUFFER_FORMAT==1 && SUBSTRATE_LOAD_FROM_MATERIALCONTAINER
|
|
FSubstrateAddressing SubstrateAddressing = GetSubstratePixelDataByteOffset(PixelCoord, uint2(View.BufferSizeAndInvSize.xy), Substrate.MaxBytesPerPixel);
|
|
FSubstratePixelHeader SubstratePixelHeader = UnpackSubstrateHeaderIn(Substrate.MaterialTextureArray, SubstrateAddressing, Substrate.TopLayerTexture);
|
|
const bool bIsValid = SubstratePixelHeader.ClosureCount > 0;
|
|
#else
|
|
const bool bIsValid = Material.IsValid();
|
|
#endif
|
|
|
|
BRANCH
|
|
if (bIsValid)
|
|
{
|
|
float3 V = -CameraVector;
|
|
float3 L = LightData.Direction; // Already normalized
|
|
float3 ToLight = L;
|
|
float LightMask = 1;
|
|
if (LightData.bRadialLight)
|
|
{
|
|
LightMask = GetLocalLightAttenuation(TranslatedWorldPosition, LightData, ToLight, L);
|
|
#if ADAPTIVE_VOLUMETRIC_SHADOW_MAP
|
|
//LightAttenuation *= ComputeTransmittance(TranslatedWorldPosition, LightData.TranslatedWorldPosition, 256);
|
|
LightAttenuation *= AVSM_SampleTransmittance(TranslatedWorldPosition, LightData.TranslatedWorldPosition);
|
|
#endif // ADAPTIVE_VOLUMETRIC_SHADOW_MAP
|
|
}
|
|
|
|
if (LightMask > 0)
|
|
{
|
|
FSubstrateShadowTermInputParameters SubstrateShadowTermInputParameters = GetInitialisedSubstrateShadowTermInputParameters();
|
|
SubstrateShadowTermInputParameters.bEvaluateShadowTerm = true;
|
|
SubstrateShadowTermInputParameters.SceneDepth = Material.Depth;
|
|
SubstrateShadowTermInputParameters.PrecomputedShadowFactors = 1.f; //SubstrateReadPrecomputedShadowFactors(SubstratePixelHeader, PixelCoord, SceneTexturesStruct.GBufferETexture);
|
|
SubstrateShadowTermInputParameters.TranslatedWorldPosition = TranslatedWorldPosition;
|
|
SubstrateShadowTermInputParameters.LightAttenuation = LightAttenuation;
|
|
SubstrateShadowTermInputParameters.Dither = Dither;
|
|
|
|
// When using stochastic material selection,
|
|
// * Seek the selected closure
|
|
// * Force single closure evaluation
|
|
const bool bStochasticLighting = Substrate.bStochasticLighting > 0;
|
|
#if SUBSTRATE_STOCHASTIC_LIGHTING && SUBSTRATE_LOAD_FROM_MATERIALCONTAINER
|
|
if (bStochasticLighting)
|
|
{
|
|
#if SUBSTRATE_MATERIAL_CLOSURE_COUNT > 1
|
|
if (SubstratePixelHeader.ClosureCount > 1)
|
|
{
|
|
const uint AddressOffset = UnpackClosureOffsetAtIndex(Substrate.ClosureOffsetTexture[SubstrateAddressing.PixelCoords], Material.ClosureIndex, SubstratePixelHeader.ClosureCount);
|
|
SubstrateSeekClosure(SubstrateAddressing, AddressOffset);
|
|
}
|
|
#endif
|
|
SubstratePixelHeader.ClosureCount = 1;
|
|
}
|
|
#endif
|
|
|
|
FSubstrateDeferredLighting SubstrateLighting = SubstrateDeferredLighting(
|
|
LightData,
|
|
V,
|
|
L,
|
|
ToLight,
|
|
LightMask,
|
|
SubstrateShadowTermInputParameters,
|
|
#if SUBSTRATE_GBUFFER_FORMAT==1 && SUBSTRATE_LOAD_FROM_MATERIALCONTAINER
|
|
Substrate.MaterialTextureArray,
|
|
SubstrateAddressing,
|
|
SubstratePixelHeader
|
|
#else
|
|
Material.BSDF,
|
|
Material.BSDFTangentBasis,
|
|
Material.BSDFAO
|
|
#endif
|
|
);
|
|
|
|
// SUBSTRATE_TODO - Add support for SUBSTRATE_OPAQUE_ROUGH_REFRACTION_ENABLED
|
|
Out.DiffuseLighting = float4(SubstrateLighting.TotalDiffuseLighting, 0);
|
|
Out.SpecularLighting = float4(SubstrateLighting.TotalSpecularLighting, 0);
|
|
// SUBSTRATE_TODO - Accumulate Luminance separately
|
|
Out.LightingLuminance = Luminance(SubstrateLighting.TotalDiffuseLighting + SubstrateLighting.TotalSpecularLighting);
|
|
|
|
#if SUBSTRATE_STOCHASTIC_LIGHTING
|
|
// Account for the probability of having chosen this slab
|
|
if (bStochasticLighting)
|
|
{
|
|
const float InvPdf = 1.f / Material.PDF;
|
|
Out.DiffuseLighting *= InvPdf;
|
|
Out.SpecularLighting *= InvPdf;
|
|
Out.LightingLuminance *= InvPdf;
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
return Out;
|
|
}
|
|
#else // INPUT_TYPE == INPUT_TYPE_GBUFFER || INPUT_TYPE == INPUT_TYPE_HAIRSTRANDS
|
|
{
|
|
return GetDynamicLightingSplit(
|
|
TranslatedWorldPosition, CameraVector, Material.GBuffer, AmbientOcclusion,
|
|
LightData, LightAttenuation, Dither, ScreenCoord,
|
|
SurfaceShadow);
|
|
}
|
|
#endif // SUBSTRATE_ENABLED
|
|
|
|
#if INPUT_TYPE == INPUT_TYPE_HAIRSTRANDS
|
|
|
|
#include "../HairStrands/HairStrandsVisibilityCommon.ush"
|
|
#include "../HairStrands/HairStrandsVisibilityUtils.ush"
|
|
#include "../HairStrands/HairStrandsCommon.ush"
|
|
#include "../HairStrands/HairStrandsDeepTransmittanceCommon.ush"
|
|
#include "../HairStrands/HairStrandsDeepTransmittanceDualScattering.ush"
|
|
|
|
// Compute transmittance data from a transmittance mask
|
|
FHairTransmittanceData GetTransmittanceDataFromTransmitttanceMask(
|
|
FDeferredLightData LightData,
|
|
FMegaLightsMaterial Material,
|
|
FHairTransmittanceMask TransmittanceMask,
|
|
float3 TranslatedWorldPosition,
|
|
float3 CameraVector)
|
|
{
|
|
float3 L = LightData.Direction;
|
|
if (LightData.bRadialLight)
|
|
{
|
|
L = normalize(LightData.TranslatedWorldPosition - TranslatedWorldPosition);
|
|
}
|
|
const float3 V = normalize(-CameraVector);
|
|
|
|
return GetHairTransmittance(
|
|
V,
|
|
L,
|
|
Material.GBuffer,
|
|
TransmittanceMask,
|
|
View.HairScatteringLUTTexture,
|
|
HairScatteringLUTSampler,
|
|
View.HairComponents);
|
|
}
|
|
#endif
|