115 lines
3.3 KiB
HLSL
115 lines
3.3 KiB
HLSL
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "/Engine/Private/Common.ush"
|
|
#include "/Engine/Private/Substrate/Substrate.ush"
|
|
|
|
#if SUBSTRATE_ENABLED
|
|
|
|
struct FSubstrateSampledMaterial
|
|
{
|
|
float3 WorldNormal;
|
|
float3 WorldTangent;
|
|
float Roughness;
|
|
float3 DiffuseAlbedo;
|
|
float3 SpecularAlbedo;
|
|
float Anisotropy;
|
|
float PDF;
|
|
uint ClosureIndex;
|
|
uint IrradianceAO;
|
|
|
|
bool bIsSimple;
|
|
bool bIsSingle;
|
|
bool bIsValid;
|
|
bool bIsHair;
|
|
bool bIsSLW;
|
|
bool bAllowSpatialFilter;
|
|
bool bNeedsSeparateSubsurfaceLightAccumulation;
|
|
bool bIsFirstPerson;
|
|
bool bHasSecondSpecularLobe;
|
|
bool bHasBackScattering;
|
|
};
|
|
|
|
FSubstrateSampledMaterial UnpackSampledMaterial(uint4 In)
|
|
{
|
|
const float4 DataY = UnpackRGBA8(In.y);
|
|
const float4 DataZ = UnpackRGBA8(In.z);
|
|
|
|
FSubstrateSampledMaterial Out;
|
|
// Can't use last 8 bit as we store 24bit normal or 32bit normal/tangent
|
|
Out.WorldNormal = SubstrateUnpackNormal24(In.x);
|
|
Out.WorldTangent = 0;
|
|
|
|
Out.DiffuseAlbedo = DataY.xyz;
|
|
Out.Roughness = DataY.w;
|
|
|
|
Out.SpecularAlbedo = DataZ.xyz;
|
|
const uint Type = BitFieldExtractU32(In.z, 3, 24);
|
|
Out.bIsFirstPerson = BitFieldExtractU32(In.z, 1, 27);
|
|
Out.bHasSecondSpecularLobe= BitFieldExtractU32(In.z, 1, 28);
|
|
Out.bAllowSpatialFilter= BitFieldExtractU32(In.z, 1, 29);
|
|
Out.bHasBackScattering = BitFieldExtractU32(In.z, 1, 30);
|
|
Out.bNeedsSeparateSubsurfaceLightAccumulation = BitFieldExtractU32(In.z, 1, 31);
|
|
Out.bIsValid = Type > 0;
|
|
Out.bIsSimple = Type == 1;
|
|
Out.bIsSingle = Type == 2;
|
|
Out.bIsHair = Type == 4;
|
|
Out.bIsSLW = Type == 5;
|
|
|
|
Out.PDF = Unpack10F(In.w);
|
|
Out.ClosureIndex = BitFieldExtractU32(In.w, 3, 10);
|
|
Out.IrradianceAO = BitFieldExtractU32(In.w, 8, 16);
|
|
uint PackedAniso8bits = BitFieldExtractU32(In.w, 8, 24);
|
|
Out.Anisotropy = UnpackR8(PackedAniso8bits & 0xFE);
|
|
Out.Anisotropy *= (PackedAniso8bits & 1u) ? 1.f : -1.f;
|
|
|
|
if (Out.Anisotropy != 0)
|
|
{
|
|
SubstrateUnpackNormalAndTangent(Out.WorldNormal, Out.WorldTangent, In.x);
|
|
}
|
|
return Out;
|
|
}
|
|
|
|
uint4 PackSampledMaterial(FSubstrateSampledMaterial In)
|
|
{
|
|
uint Type = 0;
|
|
if (In.bIsSimple) { Type = 1; }
|
|
if (In.bIsSingle) { Type = 2; }
|
|
if (In.bIsHair) { Type = 4; }
|
|
if (In.bIsSLW) { Type = 5; }
|
|
if (In.bIsValid && Type == 0) { Type = 3; /*bIsComplex*/ }
|
|
|
|
uint DataX;
|
|
if (In.Anisotropy == 0)
|
|
{
|
|
DataX = SubstratePackNormal24(In.WorldNormal);
|
|
}
|
|
else
|
|
{
|
|
DataX = SubstratePackNormalAndTangent(In.WorldNormal, In.WorldTangent);
|
|
}
|
|
|
|
const uint PackedAniso8bits = (PackR8(abs(In.Anisotropy)) & 0xFE) | (In.Anisotropy > 0 ? 1u : 0u);
|
|
const uint DataZ =
|
|
((Type & 0x3) << 24) |
|
|
((In.bIsFirstPerson ? 0x1 : 0x0) << 27) |
|
|
((In.bHasSecondSpecularLobe ? 0x1 : 0x0) << 28) |
|
|
((In.bAllowSpatialFilter ? 0x1 : 0x0) << 29) |
|
|
((In.bHasBackScattering ? 0x1 : 0x0) << 30) |
|
|
((In.bNeedsSeparateSubsurfaceLightAccumulation ? 0x1 : 0x0) << 31);
|
|
const uint DataW =
|
|
Pack10F(In.PDF) |
|
|
((In.ClosureIndex & 0x3u) << 10) |
|
|
((In.IrradianceAO & 0xFF) << 16) |
|
|
(PackedAniso8bits << 24);
|
|
|
|
uint4 Out;
|
|
Out.x = DataX;
|
|
Out.y = PackRGBA8(float4(In.DiffuseAlbedo, In.Roughness));
|
|
Out.z = PackRGBA8(float4(In.SpecularAlbedo, 0)) | DataZ;
|
|
Out.w = DataW;
|
|
return Out;
|
|
}
|
|
|
|
#endif |