Refactor shadows rendering to use Shadow Map Atlas
This commit is contained in:
@@ -12,32 +12,57 @@
|
||||
#ifndef SHADOWS_QUALITY
|
||||
#define SHADOWS_QUALITY 0
|
||||
#endif
|
||||
#ifndef CSM_BLENDING
|
||||
#define CSM_BLENDING 0
|
||||
#endif
|
||||
|
||||
// Structure that contains information about light
|
||||
struct LightShadowData
|
||||
// Shadow data for the light
|
||||
struct ShadowData
|
||||
{
|
||||
float2 ShadowMapSize;
|
||||
float Sharpness;
|
||||
float Fade;
|
||||
|
||||
float FadeDistance;
|
||||
float NormalOffsetScale;
|
||||
float Bias;
|
||||
float FadeDistance;
|
||||
uint NumCascades;
|
||||
|
||||
uint TilesCount;
|
||||
float4 CascadeSplits;
|
||||
float4x4 ShadowVP[6];
|
||||
};
|
||||
|
||||
#ifdef PLATFORM_ANDROID
|
||||
// #AdrenoVK_CB_STRUCT_MEMBER_ACCESS_BUG
|
||||
#define DECLARE_LIGHTSHADOWDATA_ACCESS(uniformName) LightShadowData Get##uniformName##Data() { LightShadowData tmp; tmp.ShadowMapSize = uniformName.ShadowMapSize; tmp.Sharpness = uniformName.Sharpness; tmp.Fade = uniformName.Fade; tmp.NormalOffsetScale = uniformName.NormalOffsetScale; tmp.Bias = uniformName.Bias; tmp.FadeDistance = uniformName.FadeDistance; tmp.NumCascades = uniformName.NumCascades; tmp.CascadeSplits = uniformName.CascadeSplits; tmp.ShadowVP[0] = uniformName.ShadowVP[0]; tmp.ShadowVP[1] = uniformName.ShadowVP[1]; tmp.ShadowVP[2] = uniformName.ShadowVP[2]; tmp.ShadowVP[3] = uniformName.ShadowVP[3]; tmp.ShadowVP[4] = uniformName.ShadowVP[4]; tmp.ShadowVP[5] = uniformName.ShadowVP[5]; return tmp; }
|
||||
#else
|
||||
#define DECLARE_LIGHTSHADOWDATA_ACCESS(uniformName) LightShadowData Get##uniformName##Data() { return uniformName; }
|
||||
#endif
|
||||
// Shadow projection tile data for the light
|
||||
struct ShadowTileData
|
||||
{
|
||||
float4 ShadowToAtlas;
|
||||
float4x4 WorldToShadow;
|
||||
};
|
||||
|
||||
// Loads the shadow data of the light in the shadow buffer
|
||||
ShadowData LoadShadowsBuffer(Buffer<float4> shadowsBuffer, uint shadowsBufferAddress)
|
||||
{
|
||||
// This must match C++
|
||||
float4 vector0 = shadowsBuffer.Load(shadowsBufferAddress + 0);
|
||||
float4 vector1 = shadowsBuffer.Load(shadowsBufferAddress + 1);
|
||||
ShadowData shadow;
|
||||
uint packed0x = asuint(vector0.x);
|
||||
shadow.Sharpness = (packed0x & 0x000000ff) * (10.0f / 255.0f);
|
||||
shadow.Fade = ((packed0x & 0x0000ff00) >> 8) * (1.0f / 255.0f);
|
||||
shadow.TilesCount = ((packed0x & 0x00ff0000) >> 16);
|
||||
shadow.FadeDistance = vector0.y;
|
||||
shadow.NormalOffsetScale = vector0.z;
|
||||
shadow.Bias = vector0.w;
|
||||
shadow.CascadeSplits = vector1;
|
||||
return shadow;
|
||||
}
|
||||
|
||||
// Loads the shadow tile data of the light in the shadow buffer
|
||||
ShadowTileData LoadShadowsBufferTile(Buffer<float4> shadowsBuffer, uint shadowsBufferAddress, uint tileIndex)
|
||||
{
|
||||
// This must match C++
|
||||
shadowsBufferAddress += tileIndex * 5 + 2;
|
||||
ShadowTileData tile;
|
||||
tile.ShadowToAtlas = shadowsBuffer.Load(shadowsBufferAddress + 0);
|
||||
tile.WorldToShadow[0] = shadowsBuffer.Load(shadowsBufferAddress + 1);
|
||||
tile.WorldToShadow[1] = shadowsBuffer.Load(shadowsBufferAddress + 2);
|
||||
tile.WorldToShadow[2] = shadowsBuffer.Load(shadowsBufferAddress + 3);
|
||||
tile.WorldToShadow[3] = shadowsBuffer.Load(shadowsBufferAddress + 4);
|
||||
return tile;
|
||||
}
|
||||
|
||||
float3 GetShadowPositionOffset(float offsetScale, float NoL, float3 normal)
|
||||
{
|
||||
@@ -48,8 +73,16 @@ float3 GetShadowPositionOffset(float offsetScale, float NoL, float3 normal)
|
||||
float CalculateSubsurfaceOcclusion(float opacity, float sceneDepth, float shadowMapDepth)
|
||||
{
|
||||
float thickness = max(sceneDepth - shadowMapDepth, 0);
|
||||
float occlusion = 1 - thickness * lerp(1.0f, 100.0f, opacity);
|
||||
float occlusion = 1 - saturate(thickness * lerp(1.0f, 100.0f, opacity));
|
||||
return shadowMapDepth > 0.99f ? 1 : occlusion;
|
||||
}
|
||||
|
||||
float PostProcessShadow(ShadowData lightShadow, float shadow)
|
||||
{
|
||||
// Apply shadow fade and sharpness
|
||||
shadow = saturate((shadow - 0.5) * lightShadow.Sharpness + 0.5);
|
||||
shadow = lerp(1.0f, shadow, lightShadow.Fade);
|
||||
return shadow;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user