335 lines
11 KiB
HLSL
335 lines
11 KiB
HLSL
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "/Engine/Private/DeferredShadingCommon.ush"
|
|
|
|
#define NDIGBUFFER_HAS_GBUFFER (FEATURE_LEVEL >= FEATURE_LEVEL_SM5)
|
|
#define NDIGBUFFER_USE_GBUFFER_VELOCITY (false && NDIGBUFFER_HAS_GBUFFER)
|
|
#define NDIGBUFFER_IS_MOBILE (FEATURE_LEVEL <= FEATURE_LEVEL_ES3_1)
|
|
|
|
#define NIAGARA_SAMPLE_SUBSTRATE (SUBTRATE_GBUFFER_FORMAT==1 && !NDIGBUFFER_IS_MOBILE)
|
|
|
|
#if NIAGARA_SAMPLE_SUBSTRATE
|
|
#define NEEDS_SCENE_TEXTURES 1
|
|
#define SCENE_TEXTURES_DISABLED 0
|
|
#define SubstratePublicStruct SubstratePublic
|
|
#include "/Engine/Public/SubstratePublic.ush"
|
|
#endif
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
Texture2D {ParameterName}_VelocityTexture;
|
|
SamplerState {ParameterName}_VelocityTextureSampler;
|
|
|
|
#if NIAGARA_SAMPLE_SUBSTRATE
|
|
FSubstrateGBuffer GetNiagaraSubstrateGBuffer_{ParameterName}(in float2 ScreenUV)
|
|
{
|
|
uint2 ScreenPos = uint2(ScreenUV * View.BufferSizeAndInvSize.xy);
|
|
return SubstratePublic_GetSubstrateGBufferFromFirstBSDF(ScreenPos);
|
|
}
|
|
#endif
|
|
|
|
float2 ApplyViewportOffset_{ParameterName}(float2 UV, bool bApplyViewportOffset)
|
|
{
|
|
if (bApplyViewportOffset)
|
|
{
|
|
UV = (UV * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f)) * View.ScreenPositionScaleBias.xy + View.ScreenPositionScaleBias.wz;
|
|
}
|
|
return UV;
|
|
}
|
|
|
|
void DecodeDiffuseColor_{ParameterName}(in float2 ScreenUV, in bool bApplyViewportOffset, out bool IsValid, out float3 OutValue)
|
|
{
|
|
#if NDIGBUFFER_HAS_GBUFFER
|
|
ScreenUV = ApplyViewportOffset_{ParameterName}(ScreenUV, bApplyViewportOffset);
|
|
IsValid = true;
|
|
|
|
#if NIAGARA_SAMPLE_SUBSTRATE
|
|
uint2 ScreenPos = uint2(ScreenUV * View.BufferSizeAndInvSize.xy);
|
|
OutValue = SubstratePublic_GetWorldNormal(ScreenPos);
|
|
#else
|
|
FGBufferData GBufferData = GetGBufferData(ScreenUV);
|
|
OutValue = GBufferData.DiffuseColor;
|
|
#endif
|
|
#else
|
|
IsValid = false;
|
|
OutValue = 0;
|
|
#endif
|
|
}
|
|
|
|
void DecodeWorldNormal_{ParameterName}(in float2 ScreenUV, in bool bApplyViewportOffset, out bool IsValid, out float3 OutValue)
|
|
{
|
|
#if NDIGBUFFER_HAS_GBUFFER
|
|
ScreenUV = ApplyViewportOffset_{ParameterName}(ScreenUV, bApplyViewportOffset);
|
|
IsValid = true;
|
|
|
|
#if NIAGARA_SAMPLE_SUBSTRATE
|
|
uint2 ScreenPos = uint2(ScreenUV * View.BufferSizeAndInvSize.xy);
|
|
OutValue = SubstratePublic_GetWorldNormal(ScreenPos);
|
|
#else
|
|
FGBufferData GBufferData = GetGBufferData(ScreenUV);
|
|
OutValue = GBufferData.WorldNormal;
|
|
#endif
|
|
#else
|
|
IsValid = false;
|
|
OutValue = 0;
|
|
#endif
|
|
}
|
|
|
|
void DecodeScreenVelocity_{ParameterName}(in float2 ScreenUV, in bool bApplyViewportOffset, out bool IsValid, out float3 OutValue)
|
|
{
|
|
IsValid = false;
|
|
OutValue = 0;
|
|
#if NDIGBUFFER_HAS_GBUFFER
|
|
ScreenUV = ApplyViewportOffset_{ParameterName}(ScreenUV, bApplyViewportOffset);
|
|
float4 EncodedVelocity = 0;
|
|
#if NDIGBUFFER_USE_GBUFFER_VELOCITY
|
|
EncodedVelocity = GetGBufferData(ScreenUV).Velocity;
|
|
#else
|
|
EncodedVelocity = {ParameterName}_VelocityTexture.SampleLevel({ParameterName}_VelocityTextureSampler, ScreenUV, 0);
|
|
#endif
|
|
IsValid = true;
|
|
if ( EncodedVelocity.x > 0 )
|
|
{
|
|
#if VELOCITY_ENCODE_DEPTH
|
|
OutValue = DecodeVelocityFromTexture(EncodedVelocity);
|
|
#else
|
|
OutValue.xy = DecodeVelocityFromTexture(EncodedVelocity).xy;
|
|
#endif
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void DecodeWorldVelocity_{ParameterName}(in float2 ScreenUV, in bool bApplyViewportOffset, out bool IsValid, out float3 OutValue)
|
|
{
|
|
IsValid = false;
|
|
OutValue = 0;
|
|
#if NDIGBUFFER_HAS_GBUFFER
|
|
ScreenUV = ApplyViewportOffset_{ParameterName}(ScreenUV, bApplyViewportOffset);
|
|
float4 EncodedVelocity = 0;
|
|
#if NDIGBUFFER_USE_GBUFFER_VELOCITY
|
|
EncodedVelocity = GetGBufferData(ScreenUV).Velocity;
|
|
#else
|
|
EncodedVelocity = {ParameterName}_VelocityTexture.SampleLevel({ParameterName}_VelocityTextureSampler, ScreenUV, 0);
|
|
#endif
|
|
IsValid = true;
|
|
if ( EncodedVelocity.x > 0 )
|
|
{
|
|
float3 Velocity = DecodeVelocityFromTexture(EncodedVelocity);
|
|
|
|
float SceneDeviceZ = LookupDeviceZ(ScreenUV);
|
|
float SceneDepth = ConvertFromDeviceZ(SceneDeviceZ);
|
|
float2 ScreenPosition = (ScreenUV - View.ScreenPositionScaleBias.wz) / View.ScreenPositionScaleBias.xy;
|
|
float3 TranslatedWorldPosition = mul(float4(GetScreenPositionForProjectionType(ScreenPosition, SceneDepth), SceneDepth, 1), PrimaryView.ScreenToTranslatedWorld).xyz;
|
|
|
|
float PrevSceneDepth = 0;
|
|
#if VELOCITY_ENCODE_DEPTH
|
|
PrevSceneDepth = ConvertFromDeviceZ(SceneDeviceZ - Velocity.z);
|
|
#else
|
|
// Ideally we would use CalcPrevSceneDepth(PrevScreenUV) here to get an accurate location, however we do not store PrevSceneDepth so this is a very rough approximation
|
|
PrevSceneDepth = SceneDepth; // CalcPrevSceneDepth(PrevScreenUV);
|
|
#endif
|
|
float2 PrevScreenPosition = ScreenPosition - Velocity.xy;
|
|
float3 PrevTranslatedWorldPosition = mul(float4(GetScreenPositionForProjectionType(PrevScreenPosition, PrevSceneDepth), PrevSceneDepth, 1), PrimaryView.PrevScreenToTranslatedWorld).xyz;
|
|
|
|
float3 PreViewTranslationOffset = DFFastLocalSubtractDemote(PrimaryView.PreViewTranslation, PrimaryView.PrevPreViewTranslation);
|
|
|
|
OutValue = TranslatedWorldPosition - PrevTranslatedWorldPosition - PreViewTranslationOffset;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void DecodeBaseColor_{ParameterName}(in float2 ScreenUV, in bool bApplyViewportOffset, out bool IsValid, out float3 OutValue)
|
|
{
|
|
#if NDIGBUFFER_HAS_GBUFFER
|
|
ScreenUV = ApplyViewportOffset_{ParameterName}(ScreenUV, bApplyViewportOffset);
|
|
IsValid = true;
|
|
|
|
#if NIAGARA_SAMPLE_SUBSTRATE
|
|
OutValue = GetNiagaraSubstrateGBuffer_{ParameterName}(ScreenUV).BaseColor;
|
|
#else
|
|
FGBufferData GBufferData = GetGBufferData(ScreenUV);
|
|
OutValue = GBufferData.BaseColor;
|
|
#endif
|
|
|
|
#else
|
|
IsValid = false;
|
|
OutValue = 0;
|
|
#endif
|
|
}
|
|
|
|
void DecodeMetallic_{ParameterName}(in float2 ScreenUV, in bool bApplyViewportOffset, out bool IsValid, out float OutValue)
|
|
{
|
|
#if NDIGBUFFER_HAS_GBUFFER
|
|
ScreenUV = ApplyViewportOffset_{ParameterName}(ScreenUV, bApplyViewportOffset);
|
|
IsValid = true;
|
|
|
|
#if NIAGARA_SAMPLE_SUBSTRATE
|
|
OutValue = GetNiagaraSubstrateGBuffer_{ParameterName}(ScreenUV).Metallic;
|
|
#else
|
|
FGBufferData GBufferData = GetGBufferData(ScreenUV);
|
|
OutValue = GBufferData.Metallic;
|
|
#endif
|
|
|
|
#else
|
|
IsValid = false;
|
|
OutValue = 0;
|
|
#endif
|
|
}
|
|
|
|
void DecodeSpecular_{ParameterName}(in float2 ScreenUV, in bool bApplyViewportOffset, out bool IsValid, out float OutValue)
|
|
{
|
|
#if NDIGBUFFER_HAS_GBUFFER
|
|
ScreenUV = ApplyViewportOffset_{ParameterName}(ScreenUV, bApplyViewportOffset);
|
|
IsValid = true;
|
|
|
|
#if NIAGARA_SAMPLE_SUBSTRATE
|
|
OutValue = GetNiagaraSubstrateGBuffer_{ParameterName}(ScreenUV).Specular;
|
|
#else
|
|
FGBufferData GBufferData = GetGBufferData(ScreenUV);
|
|
OutValue = GBufferData.Specular;
|
|
#endif
|
|
|
|
#else
|
|
IsValid = false;
|
|
OutValue = 0;
|
|
#endif
|
|
}
|
|
|
|
void DecodeRoughness_{ParameterName}(in float2 ScreenUV, in bool bApplyViewportOffset, out bool IsValid, out float OutValue)
|
|
{
|
|
#if NDIGBUFFER_HAS_GBUFFER
|
|
ScreenUV = ApplyViewportOffset_{ParameterName}(ScreenUV, bApplyViewportOffset);
|
|
IsValid = true;
|
|
|
|
#if NIAGARA_SAMPLE_SUBSTRATE
|
|
uint2 ScreenPos = uint2(ScreenUV * View.BufferSizeAndInvSize.xy);
|
|
OutValue = SubstratePublic_GetRoughness(ScreenPos);
|
|
#else
|
|
FGBufferData GBufferData = GetGBufferData(ScreenUV);
|
|
OutValue = GBufferData.Roughness;
|
|
#endif
|
|
|
|
#else
|
|
IsValid = false;
|
|
OutValue = 0;
|
|
#endif
|
|
}
|
|
|
|
void DecodeDepth_{ParameterName}(in float2 ScreenUV, in bool bApplyViewportOffset, out bool IsValid, out float OutValue)
|
|
{
|
|
#if NDIGBUFFER_HAS_GBUFFER
|
|
ScreenUV = ApplyViewportOffset_{ParameterName}(ScreenUV, bApplyViewportOffset);
|
|
FGBufferData GBufferData = GetGBufferData(ScreenUV);
|
|
IsValid = true;
|
|
OutValue = GBufferData.Depth;
|
|
#elif NDIGBUFFER_IS_MOBILE
|
|
IsValid = true;
|
|
OutValue = CalcSceneDepth(ScreenUV);
|
|
#else
|
|
IsValid = false;
|
|
OutValue = 0;
|
|
#endif
|
|
}
|
|
|
|
#if 0
|
|
// This has not been tested yet
|
|
void DecodeStencil_{ParameterName}(in float2 ScreenUV, in bool bApplyViewportOffset, out bool IsValid, out int OutValue)
|
|
{
|
|
#if NDIGBUFFER_HAS_GBUFFER
|
|
IsValid = true;
|
|
|
|
ScreenUV = ApplyViewportOffset_{ParameterName}(ScreenUV, bApplyViewportOffset);
|
|
uint2 IntUV = (uint2)(ScreenUV.xy * (float2)View.BufferSizeAndInvSize.xy);
|
|
uint Stencil = SceneStencilTexture.Load(uint3(IntUV, 0)) STENCIL_COMPONENT_SWIZZLE;
|
|
OutValue = int(Stencil);
|
|
#else
|
|
IsValid = false;
|
|
OutValue = 0;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
void DecodePartialDepth_{ParameterName}(in float2 ScreenUV, in bool bApplyViewportOffset, out bool IsValid, out float OutValue)
|
|
{
|
|
ScreenUV = ApplyViewportOffset_{ParameterName}(ScreenUV, bApplyViewportOffset);
|
|
#if NDIGBUFFER_HAS_GBUFFER
|
|
IsValid = true;
|
|
OutValue = ConvertFromDeviceZ(Texture2DSampleLevel(SceneTexturesStruct.ScenePartialDepthTexture, SceneTexturesStruct_ScenePartialDepthTextureSampler, ScreenUV, 0).r);
|
|
#elif NDIGBUFFER_IS_MOBILE
|
|
IsValid = true;
|
|
OutValue = ConvertFromDeviceZ(Texture2DSampleLevel(MobileSceneTextures.ScenePartialDepthTexture, MobileSceneTextures.ScenePartialDepthTextureSampler, ScreenUV, 0).r);
|
|
#else
|
|
IsValid = false;
|
|
OutValue = 0;
|
|
#endif
|
|
}
|
|
|
|
|
|
void DecodeCustomDepth_{ParameterName}(in float2 ScreenUV, in bool bApplyViewportOffset, out bool IsValid, out float OutValue)
|
|
{
|
|
#if NDIGBUFFER_HAS_GBUFFER
|
|
ScreenUV = ApplyViewportOffset_{ParameterName}(ScreenUV, bApplyViewportOffset);
|
|
FGBufferData GBufferData = GetGBufferData(ScreenUV);
|
|
IsValid = true;
|
|
OutValue = GBufferData.CustomDepth;
|
|
#elif NDIGBUFFER_IS_MOBILE
|
|
IsValid = true;
|
|
OutValue = ConvertFromDeviceZ(Texture2DSampleLevel(MobileSceneTextures.CustomDepthTexture, MobileSceneTextures.CustomDepthTextureSampler, ScreenUV, 0).r);
|
|
#else
|
|
IsValid = false;
|
|
OutValue = 0;
|
|
#endif
|
|
}
|
|
|
|
void DecodeCustomStencil_{ParameterName}(in float2 ScreenUV, in bool bApplyViewportOffset, out bool IsValid, out int OutValue)
|
|
{
|
|
#if NDIGBUFFER_HAS_GBUFFER
|
|
ScreenUV = ApplyViewportOffset_{ParameterName}(ScreenUV, bApplyViewportOffset);
|
|
FGBufferData GBufferData = GetGBufferData(ScreenUV);
|
|
IsValid = true;
|
|
OutValue = GBufferData.CustomStencil;
|
|
#elif NDIGBUFFER_IS_MOBILE
|
|
IsValid = true;
|
|
OutValue = MobileSceneTextures.CustomStencilTexture.Load(int3(ScreenUV, 0)) STENCIL_COMPONENT_SWIZZLE;
|
|
#else
|
|
IsValid = false;
|
|
OutValue = 0;
|
|
#endif
|
|
}
|
|
|
|
void DecodeSceneColor_{ParameterName}(in float2 ScreenUV, in bool bApplyViewportOffset, out bool IsValid, out float4 OutValue)
|
|
{
|
|
#if NDIGBUFFER_HAS_GBUFFER
|
|
IsValid = true;
|
|
ScreenUV = ApplyViewportOffset_{ParameterName}(ScreenUV, bApplyViewportOffset);
|
|
OutValue = Texture2DSampleLevel(SceneTexturesStruct_SceneColorTexture, SceneTexturesStruct_SceneColorTextureSampler, ScreenUV, 0);
|
|
OutValue.rgb *= View.OneOverPreExposure.xxx;
|
|
#elif NDIGBUFFER_IS_MOBILE
|
|
IsValid = true;
|
|
OutValue = Texture2DSampleLevel(MobileSceneTextures.SceneColorTexture, MobileSceneTextures.SceneColorTextureSampler, ScreenUV, 0);
|
|
OutValue.rgb *= View.OneOverPreExposure.xxx;
|
|
#else
|
|
IsValid = false;
|
|
OutValue = 0;
|
|
#endif
|
|
}
|
|
|
|
void DecodeShadingModelID_{ParameterName}(in float2 ScreenUV, in bool bApplyViewportOffset, out bool IsValid, out int OutValue)
|
|
{
|
|
#if NDIGBUFFER_HAS_GBUFFER
|
|
ScreenUV = ApplyViewportOffset_{ParameterName}(ScreenUV, bApplyViewportOffset);
|
|
IsValid = true;
|
|
|
|
#if NIAGARA_SAMPLE_SUBSTRATE
|
|
OutValue = int(GetNiagaraSubstrateGBuffer_{ParameterName}(ScreenUV).ShadingModelID);
|
|
#else
|
|
FGBufferData GBufferData = GetGBufferData(ScreenUV);
|
|
OutValue = GBufferData.ShadingModelID;
|
|
#endif
|
|
|
|
#else
|
|
IsValid = false;
|
|
OutValue = 0;
|
|
#endif
|
|
}
|