#pragma only_renderers d3d11 vulkan metal glcore
RWTexture2D<float4> g_LightmapInOut;
int g_TextureWidth;
int g_TextureHeight;
RWTexture2D<float4> g_DirectionalInOut;
Texture2D<float4> g_InputSampleCountInW;
Texture2D<float4> g_Normals;
#pragma kernel NormalizeValidity
[numthreads(8, 8, 1)]
void NormalizeValidity(
in uint3 gidx : SV_DispatchThreadID,
in uint lidx : SV_GroupIndex)
{
if (gidx.x >= (uint) g_TextureWidth || gidx.y >= (uint) g_TextureHeight || gidx.z >= 1)
return;
const float4 validity = g_LightmapInOut[gidx.xy];
const float sampleCount = max(validity.w, 1.0f);
const float4 normalizedValidity = float4(validity.xyz * (1.f / sampleCount), 1.f);
g_LightmapInOut[gidx.xy] = validity.w > 0.0f ? normalizedValidity : 0.0f;
}
#pragma kernel NormalizeAO
[numthreads(8, 8, 1)]
void NormalizeAO(
in uint3 gidx : SV_DispatchThreadID,
in uint lidx : SV_GroupIndex)
{
if (gidx.x >= (uint) g_TextureWidth || gidx.y >= (uint) g_TextureHeight || gidx.z >= 1)
return;
const float4 occlusion = g_LightmapInOut[gidx.xy];
const float4 vZero = 0.0f;
const float sampleCount = max(occlusion.w, 1.0f);
const float4 normalizedOcclusion = float4(1.f - (occlusion.xyz * (1.f / sampleCount)), 1.f);
g_LightmapInOut[gidx.xy] = occlusion.w > 0.0f ? normalizedOcclusion : vZero;
}
#pragma kernel NormalizeRadiance
[numthreads(8, 8, 1)]
void NormalizeRadiance(
in uint3 gidx : SV_DispatchThreadID,
in uint lidx : SV_GroupIndex)
{
if (gidx.x >= (uint) g_TextureWidth || gidx.y >= (uint) g_TextureHeight || gidx.z >= 1)
return;
const float4 radiance = g_LightmapInOut[gidx.xy];
const float4 vZero = 0.0f;
const float sampleCount = max(radiance.w, 1.0f);
const float4 normalizedRadiance = float4(radiance.xyz * (1.f / sampleCount), 1.f);
g_LightmapInOut[gidx.xy] = radiance.w > 0.0f ? normalizedRadiance : vZero;
}
#pragma kernel NormalizeDirection
[numthreads(8, 8, 1)]
void NormalizeDirection(
in uint3 gidx : SV_DispatchThreadID,
in uint lidx : SV_GroupIndex)
{
if (gidx.x >= (uint) g_TextureWidth || gidx.y >= (uint) g_TextureHeight || gidx.z >= 1)
return;
const float4 vHalf = 0.5f;
const bool valid = g_InputSampleCountInW[gidx.xy].w > 0.0f;
if (!valid)
{
g_DirectionalInOut[gidx.xy] = vHalf;
return;
}
const float4 epsilon = 0.001f;
const float3 normal = g_Normals[gidx.xy].xyz;
float4 directionality = g_DirectionalInOut[gidx.xy];
directionality *= 1.0f / max(epsilon, directionality.wwww);
directionality.w = dot(normal, directionality.xyz);
g_DirectionalInOut[gidx.xy] = directionality * vHalf + vHalf;
}
#pragma kernel NormalizeShadowMask
[numthreads(8, 8, 1)]
void NormalizeShadowMask(
in uint3 gidx : SV_DispatchThreadID,
in uint lidx : SV_GroupIndex)
{
if (gidx.x >= (uint) g_TextureWidth || gidx.y >= (uint) g_TextureHeight || gidx.z >= 1)
return;
const float4 shadow = g_LightmapInOut[gidx.xy];
const float4 vZero = 0.0f;
const float sampleCount = max(g_InputSampleCountInW[gidx.xy].w, 1.0f);
const float4 normalizedShadow = float4(shadow * (1.f / sampleCount));
g_LightmapInOut[gidx.xy] = g_InputSampleCountInW[gidx.xy].w > 0.0f ? normalizedShadow : vZero;
}