Skip to content

Commit

Permalink
0618 GPUOpen-LibrariesAndSDKs#19 gi10 bugfixes + split channel denoising
Browse files Browse the repository at this point in the history
  • Loading branch information
Hineven committed Jun 18, 2024
1 parent f1e2dcd commit e7e3630
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 51 deletions.
2 changes: 1 addition & 1 deletion src/core/src/render_techniques/gi10/gi10.comp
Original file line number Diff line number Diff line change
Expand Up @@ -1623,7 +1623,7 @@ void InterpolateScreenProbes(in uint2 did : SV_DispatchThreadID)
{
uint2 probe = ScreenProbes_UnpackSeed(probes[j]) / g_ScreenProbesConstants.probe_size;

irradiance += w[j] * ScreenProbes_CalculateSHIrradiance_BentCone(normal, ao, probe);
irradiance += FOUR_PI * w[j] * ScreenProbes_CalculateSHIrradiance_BentCone(normal, ao, probe);
}

float denoiser_hint = (use_backup ? 0.0f : 1.0f); // hint to the denoiser that we should ideally not keep this sample...
Expand Down
4 changes: 2 additions & 2 deletions src/core/src/render_techniques/migi/hash_grid_cache.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ THE SOFTWARE.
#define kHashGridCache_TileDecay 50

// The amount of float quantization for atomic updates of the hash cells as integer:
#define kHashGridCache_FloatQuantize (MIGI_QUANTILIZE_RADIANCE_MULTIPLIER)
#define kHashGridCache_FloatQuantize (1e3f)

//!
//! Hash-grid radiance cache structures.
Expand Down Expand Up @@ -375,7 +375,7 @@ float3 HashGridCache_UnpackDirection(in uint packed_direction)

float4 HashGridCache_PackVisibility(HashGridCache_Visibility visibility)
{
// 1 + 15 + 16 + 32
// 1 + 15 + 16 + 32 + 32 x 2
return float4(
asfloat(visibility.geometry_index | (visibility.instance_index<<16) | (visibility.is_front_face ? 0 : 0x80000000u)),
asfloat(visibility.primitive_index),
Expand Down
141 changes: 93 additions & 48 deletions src/core/src/render_techniques/migi/migi.comp
Original file line number Diff line number Diff line change
Expand Up @@ -1152,12 +1152,8 @@ void ScreenCacheUpdateHandleHit(uint DispatchID, inout ScreenCacheUpdatePayload
bool is_new_tile;
uint cell_index = HashGridCache_InsertCell(data, tile_index, is_new_tile);

if (cell_index != kGI10_InvalidId)
{
// Bump the cell's decay to the max. now that it's been 'touched'
uint previous_tile_decay;
InterlockedExchange(g_HashGridCache_DecayTileBuffer[tile_index], MI.FrameIndex, previous_tile_decay);

// Write a visibility query no matter if we hit a cell or not
HashGridCache_Visibility visibility;
visibility.is_front_face = hit_info.frontFace;
visibility.instance_index = hit_info.instanceIndex;
Expand All @@ -1171,6 +1167,13 @@ void ScreenCacheUpdateHandleHit(uint DispatchID, inout ScreenCacheUpdatePayload
g_HashGridCache_VisibilityBuffer[visibility_index] = HashGridCache_PackVisibility(visibility);
g_HashGridCache_VisibilityCellBuffer[visibility_index] = cell_index;
g_HashGridCache_VisibilityQueryBuffer[visibility_index] = DispatchID;
}

if (cell_index != kGI10_InvalidId)
{
// Bump the cell's decay to the max. now that it's been 'touched'
uint previous_tile_decay;
InterlockedExchange(g_HashGridCache_DecayTileBuffer[tile_index], MI.FrameIndex, previous_tile_decay);

// Write out bounds of visibility
requestLightSampleLocation(data.hit_position);
Expand Down Expand Up @@ -1538,14 +1541,15 @@ void GenerateReservoirs(in uint DispatchID : SV_DispatchThreadID)
RayRadianceInvPdf.xyz += previous_lighting;
g_RWUpdateRayRadianceInvPdfBuffer[query_index] = PackFp16x4Safe(RayRadianceInvPdf);
#endif // ENABLE_INDIRECT
if (dot(previous_lighting, previous_lighting) > 0.0f)
{
InterlockedAdd(g_HashGridCache_UpdateCellValueBuffer[4 * cell_index + 0], quantized_radiance.x);
InterlockedAdd(g_HashGridCache_UpdateCellValueBuffer[4 * cell_index + 1], quantized_radiance.y);
InterlockedAdd(g_HashGridCache_UpdateCellValueBuffer[4 * cell_index + 2], quantized_radiance.z);
if (cell_index != kGI10_InvalidId) {
if(dot(previous_lighting, previous_lighting) > 0.0f)
{
InterlockedAdd(g_HashGridCache_UpdateCellValueBuffer[4 * cell_index + 0], quantized_radiance.x);
InterlockedAdd(g_HashGridCache_UpdateCellValueBuffer[4 * cell_index + 1], quantized_radiance.y);
InterlockedAdd(g_HashGridCache_UpdateCellValueBuffer[4 * cell_index + 2], quantized_radiance.z);
}
InterlockedAdd(g_HashGridCache_UpdateCellValueBuffer[4 * cell_index + 3], quantized_radiance.w);
}
InterlockedAdd(g_HashGridCache_UpdateCellValueBuffer[4 * cell_index + 3], quantized_radiance.w);

return; // we can skip the shadow ray for this sample :)
}
}
Expand Down Expand Up @@ -1835,15 +1839,17 @@ void PopulateCells(uint did)

// And update the hash-grid cell payload
uint cell_index = g_HashGridCache_VisibilityCellBuffer[visibility_index];
uint4 quantized_radiance = HashGridCache_QuantizeRadiance(payload.lighting, Q_Noise);
if(cell_index != kGI10_InvalidId) {
uint4 quantized_radiance = HashGridCache_QuantizeRadiance(payload.lighting, Q_Noise);

if (dot(payload.lighting, payload.lighting) > 0.0f)
{
InterlockedAdd(g_HashGridCache_UpdateCellValueBuffer[4 * cell_index + 0], quantized_radiance.x);
InterlockedAdd(g_HashGridCache_UpdateCellValueBuffer[4 * cell_index + 1], quantized_radiance.y);
InterlockedAdd(g_HashGridCache_UpdateCellValueBuffer[4 * cell_index + 2], quantized_radiance.z);
if (dot(payload.lighting, payload.lighting) > 0.0f)
{
InterlockedAdd(g_HashGridCache_UpdateCellValueBuffer[4 * cell_index + 0], quantized_radiance.x);
InterlockedAdd(g_HashGridCache_UpdateCellValueBuffer[4 * cell_index + 1], quantized_radiance.y);
InterlockedAdd(g_HashGridCache_UpdateCellValueBuffer[4 * cell_index + 2], quantized_radiance.z);
}
InterlockedAdd(g_HashGridCache_UpdateCellValueBuffer[4 * cell_index + 3], quantized_radiance.w);
}
InterlockedAdd(g_HashGridCache_UpdateCellValueBuffer[4 * cell_index + 3], quantized_radiance.w);

// In some cases, we want to bypass the cache to avoid light leaks;
// so we simply patch the screen probes directly and invalidate the
Expand Down Expand Up @@ -2034,6 +2040,9 @@ void ResolveCells(in uint did : SV_DispatchThreadID)
}

uint cell_index = g_HashGridCache_VisibilityCellBuffer[visibility_index];

if(cell_index == kGI10_InvalidId) return ;

uint query_index = g_HashGridCache_VisibilityQueryBuffer[visibility_index];

float4 radiance = HashGridCache_FilteredRadiance(cell_index, false);
Expand Down Expand Up @@ -2576,7 +2585,8 @@ void SSRC_IntegrateASG (int2 GroupID : SV_GroupID, int LocalID : SV_GroupThreadI
float3 FresnelTerm = fresnel(MaterialBRDFData.F0, dotSpecHV);
float3 DiffuseCompensation = diffuseCompensationTerm(FresnelTerm, dotSpecHV);

float3 HighFreq_All = 0.f.xxx;
float3 HighFreq_Diffuse = 0.f.xxx;
float3 HighFreq_Glossy = 0.f.xxx;
// HighFreq-AllFreq shading
[unroll(SSRC_MAX_NUM_BASIS_PER_PROBE * 4)]
for(int BasisRank = 0; BasisRank < BasisCount; BasisRank++) {
Expand All @@ -2601,8 +2611,10 @@ void SSRC_IntegrateASG (int2 GroupID : SV_GroupID, int LocalID : SV_GroupThreadI
float3 GGX_D_Li_Approx = SpecularTermASGWarp(SG, ShadingNormal, MaterialBRDFData.roughnessAlphaSqr, ViewDirection);
float VisibilityTerm = evaluateVisibilityGGX(MaterialBRDFData.roughnessAlphaSqr, dotNL, dotNV);
float3 GGXIntegrationApprox = (FresnelTerm / VisibilityTerm) * GGX_D_Li_Approx;
float3 LambertIntegration = SGDiffuseInnerProduct(SG, ShadingNormal, MaterialBRDFData.albedo)* DiffuseCompensation;
HighFreq_All += (GGXIntegrationApprox + LambertIntegration) * Sample.Weights[ProbeRank] * AO;
// Albedo is later applied for diffuse lighting
float3 Irradiance = SGDiffuseInnerProduct(SG, ShadingNormal, PI) * DiffuseCompensation;
HighFreq_Diffuse += Irradiance * Sample.Weights[ProbeRank] * AO;
HighFreq_Glossy += GGXIntegrationApprox * Sample.Weights[ProbeRank] * AO;
}
// LowFreq-Diffuse shading
float3 LowFreq_Diffuse = 0.f.xxx;
Expand All @@ -2615,28 +2627,28 @@ void SSRC_IntegrateASG (int2 GroupID : SV_GroupID, int LocalID : SV_GroupThreadI
}
}
// Decay the diffuse term with fresnel effect
LowFreq_Diffuse *= DiffuseCompensation * evaluateLambert(MaterialBRDFData.albedo);
LowFreq_Diffuse *= DiffuseCompensation;

// not implemented yet
float3 LowFreq_Specular = 0.f.xxx;

// Composite final lighting
float3 FarFieldGI = HighFreq_All + LowFreq_Diffuse + LowFreq_Specular;
float3 FarFieldIrradiance = HighFreq_Diffuse + LowFreq_Diffuse;
float3 NearFieldIrradiance = MI.UseNearFieldGI
? g_NearFieldGlobalIlluminationTexture.Load(int3(TexCoords, 0)).xyz
: 0.f;
float3 NearFieldGI = NearFieldIrradiance * evaluateLambert(MaterialBRDFData.albedo);
float3 Emission = EmissiveMaterialData.emissive;
float3 FinalLighting = FarFieldGI + NearFieldGI + Emission;
float3 FarFieldGlossySpecular = HighFreq_Glossy + LowFreq_Specular;

// Write to output
g_RWGlobalIlluminationOutput[TexCoords] =
float4(GIDenoiser_RemoveNaNs(FinalLighting), 1.0f);
g_RWIrradianceTexture[TexCoords] = float4(FarFieldIrradiance + NearFieldIrradiance, 1.f);
g_RWGlossySpecularTexture[TexCoords] = float4(FarFieldGlossySpecular, 1.f);
} else {
g_RWGlobalIlluminationOutput[TexCoords] = float4(0.f, 0.f, 0.f, 0.0f);
g_RWIrradianceTexture[TexCoords] = float4(0.f, 0.f, 0.f, 0.f);
g_RWGlossySpecularTexture[TexCoords] = float4(0.f, 0.f, 0.f, 0.f);
}
} else {
g_RWGlobalIlluminationOutput[TexCoords] = float4(0.f, 0.f, 0.f, 0.0f);
g_RWIrradianceTexture[TexCoords] = float4(0.f, 0.f, 0.f, 0.f);
g_RWGlossySpecularTexture[TexCoords] = float4(0.f, 0.f, 0.f, 0.f);
}
}
}
Expand Down Expand Up @@ -2691,10 +2703,14 @@ void SSRC_Denoise (int2 GroupID : SV_GroupID, int LocalID : SV_GroupThreadID) {
float3 ViewDirection = normalize(MI.CameraPosition - WorldPosition);


float4 NewLightingW = g_RWGlobalIlluminationOutput[TexCoords];
float3 NewLighting = NewLightingW.xyz;
float NewLightingValid = NewLightingW.w;
float3 HistoryLighting = 0.f;
float4 NewIrradianceW = g_RWIrradianceTexture[TexCoords];
float3 NewGlossySpecular = g_RWGlossySpecularTexture[TexCoords].xyz;
float3 NewIrradiance = NewIrradianceW.xyz;
float NewLightingValid = NewIrradianceW.w;
float3 HistoryIrradiance = 0.f;
float3 HistoryGlossySpecular = 0.f;
float3 DenoisedIrradiance = 0.f;
float3 DenoisedGlossySpecular = 0.f;
float Alpha = NewLightingValid > 0 ? 1.f : 0.f;
float TotalSamples = NewLightingValid > 0 ? 1.f : 0.f;

Expand Down Expand Up @@ -2774,36 +2790,65 @@ void SSRC_Denoise (int2 GroupID : SV_GroupID, int LocalID : SV_GroupThreadID) {
{
// Note: PrevCombinedGlobalIllumination includes the skybox, so we manually keep a copy of ours
float2 BaseUV = (PreviousBilinearPixelPos + 0.5f) * MI.ScreenDimensionsInv;
float3 HistoryLightingX00 = g_PreviousGlobalIlluminationTexture.SampleLevel(
float3 HistoryIrradianceX00 = g_PreviousIrradianceTexture.SampleLevel(
g_ClampedPointSampler, BaseUV, 0.f
).xyz;
float3 HistoryIrradianceX10 = g_PreviousIrradianceTexture.SampleLevel(
g_ClampedPointSampler, BaseUV + float2(PixelScale.x, 0), 0.f
).xyz;
float3 HistoryIrradianceX01 = g_PreviousIrradianceTexture.SampleLevel(
g_ClampedPointSampler, BaseUV + float2(0, PixelScale.y), 0.f
).xyz;
float3 HistoryIrradianceX11 = g_PreviousIrradianceTexture.SampleLevel(
g_ClampedPointSampler, BaseUV + float2(PixelScale.x, PixelScale.y), 0.f
).xyz;
HistoryIrradiance =
HistoryIrradianceX00 * BilinearWeights.x +
HistoryIrradianceX10 * BilinearWeights.y +
HistoryIrradianceX01 * BilinearWeights.z +
HistoryIrradianceX11 * BilinearWeights.w;

float3 HistoryGlossySpecularX00 = g_PreviousGlossySpecularTexture.SampleLevel(
g_ClampedPointSampler, BaseUV, 0.f
).xyz;
float3 HistoryLightingX10 = g_PreviousGlobalIlluminationTexture.SampleLevel(
float3 HistoryGlossySpecularX10 = g_PreviousGlossySpecularTexture.SampleLevel(
g_ClampedPointSampler, BaseUV + float2(PixelScale.x, 0), 0.f
).xyz;
float3 HistoryLightingX01 = g_PreviousGlobalIlluminationTexture.SampleLevel(
float3 HistoryGlossySpecularX01 = g_PreviousGlossySpecularTexture.SampleLevel(
g_ClampedPointSampler, BaseUV + float2(0, PixelScale.y), 0.f
).xyz;
float3 HistoryLightingX11 = g_PreviousGlobalIlluminationTexture.SampleLevel(
float3 HistoryGlossySpecularX11 = g_PreviousGlossySpecularTexture.SampleLevel(
g_ClampedPointSampler, BaseUV + float2(PixelScale.x, PixelScale.y), 0.f
).xyz;
HistoryLighting =
HistoryLightingX00 * BilinearWeights.x +
HistoryLightingX10 * BilinearWeights.y +
HistoryLightingX01 * BilinearWeights.z +
HistoryLightingX11 * BilinearWeights.w;
HistoryGlossySpecular =
HistoryGlossySpecularX00 * BilinearWeights.x +
HistoryGlossySpecularX10 * BilinearWeights.y +
HistoryGlossySpecularX01 * BilinearWeights.z +
HistoryGlossySpecularX11 * BilinearWeights.w;

}
}
if(MI.NoDenoiser) {
Alpha = NewLightingValid > 0 ? 1.f : 0.f;
}
g_RWGlobalIlluminationOutput[TexCoords] = float4(lerp(HistoryLighting, NewLighting, Alpha), 1.0f);
DenoisedIrradiance = lerp(HistoryIrradiance, NewIrradiance, Alpha);
DenoisedGlossySpecular = lerp(HistoryGlossySpecular, NewGlossySpecular, Alpha);
g_RWIrradianceTexture[TexCoords] = float4(DenoisedIrradiance, 1.0f);
g_RWGlossySpecularTexture[TexCoords] = float4(DenoisedGlossySpecular, 1.0f);
g_RWHistoryAccumulationTexture[TexCoords] = TotalSamples / MAX_TEMPORAL_ACCUMULATION;

// Shade
float3 Albedo = MaterialBRDFData.albedo;
g_RWGlobalIlluminationOutput[TexCoords] = float4(
DenoisedIrradiance * evaluateLambert(Albedo) + DenoisedGlossySpecular + EmissiveMaterialData.emissive,
1.0f
);
} else{
// Sky
g_RWHistoryAccumulationTexture[TexCoords] = 0.f;
}

g_RWGlobalIlluminationOutput[TexCoords] = 0.f.xxxx;
}
}

}

// [numthreads(WAVE_SIZE, 1, 1)]
Expand Down
5 changes: 5 additions & 0 deletions src/core/src/render_techniques/migi/migi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,10 @@ void MIGI::render(CapsaicinInternal &capsaicin) noexcept
gfxProgramSetParameter(gfx_, kernels_.program, "g_UpdateErrorSplatTexture", tex_.update_error_splat[flip]);
gfxProgramSetParameter(gfx_, kernels_.program, "g_PreviousUpdateErrorSplatTexture", tex_.update_error_splat[1 - flip]);

gfxProgramSetParameter(gfx_, kernels_.program, "g_RWIrradianceTexture", tex_.irradiance[flip]);
gfxProgramSetParameter(gfx_, kernels_.program, "g_PreviousIrradianceTexture", tex_.irradiance[1 - flip]);
gfxProgramSetParameter(gfx_, kernels_.program, "g_RWGlossySpecularTexture", tex_.glossy_specular[flip]);
gfxProgramSetParameter(gfx_, kernels_.program, "g_PreviousGlossySpecularTexture", tex_.glossy_specular[1 - flip]);
gfxProgramSetParameter(gfx_, kernels_.program, "g_RWHistoryAccumulationTexture", tex_.history_accumulation[flip]);
gfxProgramSetParameter(gfx_, kernels_.program, "g_PreviousHistoryAccumulationTexture", tex_.history_accumulation[1 - flip]);

Expand Down Expand Up @@ -336,6 +340,7 @@ void MIGI::render(CapsaicinInternal &capsaicin) noexcept
* GFX_MAX(1.0f / capsaicin.getHeight(),
(float)capsaicin.getHeight() / (capsaicin.getWidth() * capsaicin.getWidth())));
HashGridCacheConstants hash_grid_cache_constant_data = {};
// TODO use near-far plane to determine cell size
hash_grid_cache_constant_data.cell_size = cell_size;
hash_grid_cache_constant_data.min_cell_size = options_.hash_grid_cache.min_cell_size;
hash_grid_cache_constant_data.tile_size = cell_size * float(options_.hash_grid_cache.tile_cell_ratio);
Expand Down
2 changes: 2 additions & 0 deletions src/core/src/render_techniques/migi/migi.vert
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

#include "migi_probes.hlsl"

#include "hash_grid_cache.hlsl"

struct DebugIncidentRadiance_Output {
float4 Position : SV_Position;
float4 Color : COLOR;
Expand Down

0 comments on commit e7e3630

Please sign in to comment.