2021-09-09 20:42:29 -04:00

66 lines
2.6 KiB
HLSL

#ifndef UNITY_NORMAL_BUFFER_INCLUDED
#define UNITY_NORMAL_BUFFER_INCLUDED
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
// ----------------------------------------------------------------------------
// Encoding/decoding normal buffer functions
// ----------------------------------------------------------------------------
struct NormalData
{
float3 normalWS;
float perceptualRoughness;
};
// NormalBuffer texture declaration
TEXTURE2D_X(_NormalBufferTexture);
void EncodeIntoNormalBuffer(NormalData normalData, out float4 outNormalBuffer0)
{
// The sign of the Z component of the normal MUST round-trip through the G-Buffer, otherwise
// the reconstruction of the tangent frame for anisotropic GGX creates a seam along the Z axis.
// The constant was eye-balled to not cause artifacts.
// TODO: find a proper solution. E.g. we could re-shuffle the faces of the octahedron
// s.t. the sign of the Z component round-trips.
const float seamThreshold = 1.0 / 1024.0;
normalData.normalWS.z = CopySign(max(seamThreshold, abs(normalData.normalWS.z)), normalData.normalWS.z);
// RT1 - 8:8:8:8
// Our tangent encoding is based on our normal.
float2 octNormalWS = PackNormalOctQuadEncode(normalData.normalWS);
float3 packNormalWS = PackFloat2To888(saturate(octNormalWS * 0.5 + 0.5));
// We store perceptualRoughness instead of roughness because it is perceptually linear.
outNormalBuffer0 = float4(packNormalWS, normalData.perceptualRoughness);
}
void DecodeFromNormalBuffer(float4 normalBuffer, out NormalData normalData)
{
float3 packNormalWS = normalBuffer.rgb;
float2 octNormalWS = Unpack888ToFloat2(packNormalWS);
normalData.normalWS = UnpackNormalOctQuadEncode(octNormalWS * 2.0 - 1.0);
normalData.perceptualRoughness = normalBuffer.a;
}
void DecodeFromNormalBuffer(uint2 positionSS, out NormalData normalData)
{
float4 normalBuffer = LOAD_TEXTURE2D_X(_NormalBufferTexture, positionSS);
DecodeFromNormalBuffer(normalBuffer, normalData);
}
// Keep for compatibility with old code, no idea why there was a positionSS param
// Obsolete, don't used
void EncodeIntoNormalBuffer(NormalData normalData, uint2 positionSS, out float4 outNormalBuffer0)
{
EncodeIntoNormalBuffer(normalData, outNormalBuffer0);
}
// Obsolete, don't used
void DecodeFromNormalBuffer(float4 normalBuffer, uint2 positionSS, out NormalData normalData)
{
DecodeFromNormalBuffer(normalBuffer, normalData);
}
#endif // UNITY_NORMAL_BUFFER_INCLUDED