284 lines
8.7 KiB
HLSL
284 lines
8.7 KiB
HLSL
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "SSDDefinitions.ush"
|
|
#include "../Common.ush"
|
|
#include "../SceneTextureParameters.ush"
|
|
#include "/Engine/Public/WaveBroadcastIntrinsics.ush"
|
|
|
|
|
|
//------------------------------------------------------- SHARED CONSTANTS DEPENDING ON CONFIG OF SHADER
|
|
|
|
#define MAX_COMPRESSED_METADATA_VGPRS 6
|
|
|
|
|
|
//------------------------------------------------------- SHARED FUNCTION
|
|
|
|
void DecompressDevizeZAndN(uint Compressed, out float DevizeZ, out float3 N)
|
|
{
|
|
DevizeZ = f16tof32(Compressed & 0x3FFF);
|
|
|
|
uint FaceN = (Compressed >> 15) & 0x7;
|
|
|
|
N.x = float((Compressed >> 18) & 0x7F) * rcp(127);
|
|
N.y = float((Compressed >> 25) & 0x7F) * rcp(127);
|
|
N.z = 0.0;
|
|
|
|
DecodeNormal(/* inout */ N, FaceN);
|
|
}
|
|
|
|
uint CompressDevizeZAndN(float DevizeZ, float3 N)
|
|
{
|
|
uint FaceN;
|
|
EncodeNormal(/* inout */ N, /* out */ FaceN);
|
|
|
|
uint2 FaceCood = uint2(clamp(round(127.0 * N.xy), 0, 127.0));
|
|
uint Compressed = f32tof16(DevizeZ) | (FaceN << 15) | (FaceCood.x << 18) | (FaceCood.y << 25);
|
|
return Compressed;
|
|
}
|
|
|
|
/** Return whether this shading model id should be denoised or not. */
|
|
bool DenoiseShadingModelID(uint ShadingModelID)
|
|
{
|
|
return ShadingModelID != SHADINGMODELID_UNLIT;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------- COMMON SCENE INFOS
|
|
|
|
/** olds commonly used information of the scene of a given sample. */
|
|
struct FSSDCompressedSceneInfos
|
|
{
|
|
/** Raw compressed buffer, kept fully compressed to have minimal VGPR footprint. */
|
|
uint VGPR[MAX_COMPRESSED_METADATA_VGPRS];
|
|
};
|
|
|
|
|
|
FSSDCompressedSceneInfos CreateCompressedSceneInfos()
|
|
{
|
|
FSSDCompressedSceneInfos CompressedInfos;
|
|
UNROLL_N(MAX_COMPRESSED_METADATA_VGPRS)
|
|
for (uint i = 0; i < MAX_COMPRESSED_METADATA_VGPRS; i++)
|
|
{
|
|
CompressedInfos.VGPR[i] = 0;
|
|
}
|
|
return CompressedInfos;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------- UNCOMPRESSED SCENE INFOS
|
|
|
|
/** olds commonly used information of the scene of a given sample. */
|
|
struct FSSDSampleSceneInfos
|
|
{
|
|
/** Raw screen position of the sample. */
|
|
float2 ScreenPosition;
|
|
|
|
/** The raw device Z. */
|
|
float DeviceZ;
|
|
|
|
/** Raw pixel depth in world space. */
|
|
float WorldDepth;
|
|
|
|
/** Roughness of the pixel. */
|
|
float Roughness;
|
|
|
|
/** Normal of the pixel in world space. */
|
|
float3 WorldNormal;
|
|
|
|
/** Normal of the pixel in view space. */
|
|
float3 ViewNormal;
|
|
|
|
/** Position of the pixel in the translated world frame to save VALU. */
|
|
float3 TranslatedWorldPosition;
|
|
|
|
/** Shading model of the scene pixel. */
|
|
uint ShadingModelID;
|
|
};
|
|
|
|
FSSDSampleSceneInfos CreateSampleSceneInfos()
|
|
{
|
|
FSSDSampleSceneInfos Infos;
|
|
Infos.WorldDepth = 0;
|
|
Infos.ScreenPosition = 0;
|
|
Infos.Roughness = 0;
|
|
Infos.WorldNormal = 0;
|
|
Infos.ViewNormal = 0;
|
|
Infos.TranslatedWorldPosition = 0;
|
|
Infos.ShadingModelID = SHADINGMODELID_DEFAULT_LIT;
|
|
return Infos;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------- UNCOMPRESSED SCENE INFOS
|
|
|
|
// SUBSTRATE_TODO
|
|
ISOLATE
|
|
FSSDSampleSceneInfos UncompressSampleSceneInfo(
|
|
const uint CompressedLayout, const bool bIsPrevFrame,
|
|
float2 ScreenPosition,
|
|
FSSDCompressedSceneInfos CompressedInfos)
|
|
{
|
|
FSSDSampleSceneInfos Infos = CreateSampleSceneInfos();
|
|
|
|
Infos.ScreenPosition = ScreenPosition;
|
|
|
|
if (CompressedLayout == METADATA_BUFFER_LAYOUT_DISABLED)
|
|
{
|
|
Infos.WorldDepth = asfloat(CompressedInfos.VGPR[0]);
|
|
Infos.WorldNormal.x = asfloat(CompressedInfos.VGPR[1]);
|
|
Infos.WorldNormal.y = asfloat(CompressedInfos.VGPR[2]);
|
|
Infos.WorldNormal.z = asfloat(CompressedInfos.VGPR[3]);
|
|
Infos.Roughness = asfloat(CompressedInfos.VGPR[4]);
|
|
Infos.ShadingModelID = CompressedInfos.VGPR[5];
|
|
|
|
Infos.DeviceZ = ConvertToDeviceZ(Infos.WorldDepth);
|
|
Infos.ViewNormal = mul(float4(Infos.WorldNormal, 0), View.TranslatedWorldToView).xyz;
|
|
}
|
|
else if (CompressedLayout == METADATA_BUFFER_LAYOUT_DEPTH_NORMAL)
|
|
{
|
|
DecompressDevizeZAndN(CompressedInfos.VGPR[0], /* out */ Infos.DeviceZ, /* out */ Infos.WorldNormal);
|
|
|
|
Infos.WorldDepth = ConvertFromDeviceZ(Infos.DeviceZ);
|
|
Infos.ViewNormal = mul(float4(Infos.WorldNormal, 0), View.TranslatedWorldToView).xyz;
|
|
}
|
|
else if (CompressedLayout == METADATA_BUFFER_LAYOUT_DEPTH_VIEWNORMAL)
|
|
{
|
|
float3 DecodedViewNormal;
|
|
DecompressDevizeZAndN(CompressedInfos.VGPR[0], /* out */ Infos.DeviceZ, /* out */ DecodedViewNormal);
|
|
|
|
Infos.WorldDepth = ConvertFromDeviceZ(Infos.DeviceZ);
|
|
|
|
if (bIsPrevFrame)
|
|
{
|
|
Infos.WorldNormal = mul(float4(DecodedViewNormal, 0), View.PrevViewToTranslatedWorld).xyz;
|
|
|
|
// TODO(Denoiser): PrevViewToView.
|
|
Infos.ViewNormal = mul(float4(Infos.WorldNormal, 0), View.TranslatedWorldToView).xyz;
|
|
}
|
|
else
|
|
{
|
|
Infos.ViewNormal = DecodedViewNormal;
|
|
Infos.WorldNormal = mul(float4(Infos.ViewNormal, 0), View.ViewToTranslatedWorld).xyz;
|
|
}
|
|
}
|
|
else if (CompressedLayout == METADATA_BUFFER_LAYOUT_FED_DEPTH_SHADINGMODEL)
|
|
{
|
|
Infos.DeviceZ = asfloat(CompressedInfos.VGPR[0]);
|
|
Infos.WorldDepth = ConvertFromDeviceZ(Infos.DeviceZ);
|
|
Infos.ShadingModelID = CompressedInfos.VGPR[1];
|
|
}
|
|
else if (CompressedLayout == METADATA_BUFFER_LAYOUT_WORLD_POS_SHADINGMODEL)
|
|
{
|
|
Infos.TranslatedWorldPosition.x = asfloat(CompressedInfos.VGPR[0]);
|
|
Infos.TranslatedWorldPosition.y = asfloat(CompressedInfos.VGPR[1]);
|
|
Infos.TranslatedWorldPosition.z = asfloat(CompressedInfos.VGPR[2]);
|
|
Infos.ShadingModelID = CompressedInfos.VGPR[3];
|
|
|
|
if (bIsPrevFrame)
|
|
{
|
|
Infos.WorldDepth = mul(float4(Infos.TranslatedWorldPosition, 1.0), View.TranslatedWorldToView).z;
|
|
}
|
|
else
|
|
{
|
|
Infos.WorldDepth = mul(float4(Infos.TranslatedWorldPosition, 1.0), View.PrevTranslatedWorldToView).z;
|
|
}
|
|
Infos.DeviceZ = ConvertToDeviceZ(Infos.WorldDepth);
|
|
|
|
return Infos;
|
|
}
|
|
else
|
|
{
|
|
// ERROR
|
|
}
|
|
|
|
// Compute translated world position.
|
|
{
|
|
float4 ClipPosition = float4(GetScreenPositionForProjectionType(ScreenPosition, Infos.WorldDepth), Infos.WorldDepth, 1);
|
|
|
|
if (bIsPrevFrame)
|
|
{
|
|
float3 PreViewTranslationOffset = DFFastLocalSubtractDemote(PrimaryView.PreViewTranslation, PrimaryView.PrevPreViewTranslation);
|
|
Infos.TranslatedWorldPosition = mul(ClipPosition, View.PrevScreenToTranslatedWorld).xyz + PreViewTranslationOffset;
|
|
}
|
|
else
|
|
{
|
|
Infos.TranslatedWorldPosition = mul(ClipPosition, View.ScreenToTranslatedWorld).xyz;
|
|
}
|
|
}
|
|
return Infos;
|
|
}
|
|
|
|
// SUBSTRATE_TODO
|
|
FSSDCompressedSceneInfos CompressSampleSceneInfo(
|
|
const uint CompressedLayout,
|
|
FSSDSampleSceneInfos Infos)
|
|
{
|
|
FSSDCompressedSceneInfos CompressedInfos = CreateCompressedSceneInfos();
|
|
|
|
if (CompressedLayout == METADATA_BUFFER_LAYOUT_DISABLED)
|
|
{
|
|
CompressedInfos.VGPR[0] = asuint(Infos.WorldDepth);
|
|
CompressedInfos.VGPR[1] = asuint(Infos.WorldNormal.x);
|
|
CompressedInfos.VGPR[2] = asuint(Infos.WorldNormal.y);
|
|
CompressedInfos.VGPR[3] = asuint(Infos.WorldNormal.z);
|
|
CompressedInfos.VGPR[4] = asuint(Infos.Roughness);
|
|
CompressedInfos.VGPR[5] = asuint(Infos.ShadingModelID);
|
|
}
|
|
else if (CompressedLayout == METADATA_BUFFER_LAYOUT_DEPTH_NORMAL)
|
|
{
|
|
CompressedInfos.VGPR[0] = CompressDevizeZAndN(Infos.DeviceZ, Infos.WorldNormal);
|
|
}
|
|
else if (CompressedLayout == METADATA_BUFFER_LAYOUT_DEPTH_VIEWNORMAL)
|
|
{
|
|
CompressedInfos.VGPR[0] = CompressDevizeZAndN(Infos.DeviceZ, Infos.ViewNormal);
|
|
}
|
|
else if (CompressedLayout == METADATA_BUFFER_LAYOUT_FED_DEPTH_SHADINGMODEL)
|
|
{
|
|
CompressedInfos.VGPR[0] = asuint(Infos.DeviceZ);
|
|
CompressedInfos.VGPR[1] = Infos.ShadingModelID;
|
|
}
|
|
else if (CompressedLayout == METADATA_BUFFER_LAYOUT_WORLD_POS_SHADINGMODEL)
|
|
{
|
|
CompressedInfos.VGPR[0] = asuint(Infos.TranslatedWorldPosition.x);
|
|
CompressedInfos.VGPR[1] = asuint(Infos.TranslatedWorldPosition.y);
|
|
CompressedInfos.VGPR[2] = asuint(Infos.TranslatedWorldPosition.z);
|
|
CompressedInfos.VGPR[3] = Infos.ShadingModelID;
|
|
}
|
|
else
|
|
{
|
|
// ERROR
|
|
}
|
|
|
|
return CompressedInfos;
|
|
}
|
|
|
|
float3 GetWorldNormal(FSSDSampleSceneInfos SceneMetadata)
|
|
{
|
|
return SceneMetadata.WorldNormal;
|
|
}
|
|
|
|
float GetWorldDepth(FSSDSampleSceneInfos SceneMetadata)
|
|
{
|
|
return SceneMetadata.WorldDepth;
|
|
}
|
|
|
|
float3 GetTranslatedWorldPosition(FSSDSampleSceneInfos SceneMetadata)
|
|
{
|
|
return SceneMetadata.TranslatedWorldPosition;
|
|
}
|
|
|
|
|
|
FSSDSampleSceneInfos WaveBroadcastSceneMetadata(const FWaveBroadcastSettings Settings, FSSDSampleSceneInfos SceneMetadata)
|
|
{
|
|
FSSDSampleSceneInfos NewSceneMetadata;
|
|
NewSceneMetadata.WorldDepth = WaveBroadcast(Settings, SceneMetadata.WorldDepth);
|
|
NewSceneMetadata.ScreenPosition = WaveBroadcast(Settings, SceneMetadata.ScreenPosition);
|
|
NewSceneMetadata.Roughness = WaveBroadcast(Settings, SceneMetadata.Roughness);
|
|
NewSceneMetadata.WorldNormal = WaveBroadcast(Settings, SceneMetadata.WorldNormal);
|
|
NewSceneMetadata.ViewNormal = WaveBroadcast(Settings, SceneMetadata.ViewNormal);
|
|
NewSceneMetadata.TranslatedWorldPosition = WaveBroadcast(Settings, SceneMetadata.TranslatedWorldPosition);
|
|
return NewSceneMetadata;
|
|
}
|