|
| 1 | +/* |
| 2 | +Copyright(c) 2015-2026 Panos Karabelas |
| 3 | +
|
| 4 | +Permission is hereby granted, free of charge, to any person obtaining a copy |
| 5 | +of this software and associated documentation files (the "Software"), to deal |
| 6 | +in the Software without restriction, including without limitation the rights |
| 7 | +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell |
| 8 | +copies of the Software, and to permit persons to whom the Software is furnished |
| 9 | +to do so, subject to the following conditions : |
| 10 | +
|
| 11 | +The above copyright notice and this permission notice shall be included in |
| 12 | +all copies or substantial portions of the Software. |
| 13 | +
|
| 14 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 15 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS |
| 16 | +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR |
| 17 | +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER |
| 18 | +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| 19 | +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 20 | +*/ |
| 21 | + |
| 22 | +//= INCLUDES =================== |
| 23 | +#include "common.hlsl" |
| 24 | +#include "restir_reservoir.hlsl" |
| 25 | +//============================== |
| 26 | + |
| 27 | +// debug visualization for restir state |
| 28 | +// reads the denoised gi (rgb = color, alpha = variance from the svgf temporal pass), the previous frame reservoirs (M, W, confidence), and produces a viridis heatmap of the requested quantity |
| 29 | +// the result is written to tex_uav in place of the gi color so the composite remultiplies by albedo as usual, producing a tinted but readable overlay |
| 30 | +// |
| 31 | +// debug_mode values match the r.restir_pt_debug_mode cvar list in RenderOptions: |
| 32 | +// 1 = confidence (alpha of reservoir.tex4.w, mapped 0..1) |
| 33 | +// 2 = reservoir M (0..RESTIR_M_CAP) |
| 34 | +// 3 = reservoir W (log scaled since W has high dynamic range) |
| 35 | +// 4 = reuse ratio (placeholder, shows confidence for now) |
| 36 | +// 5 = temporal rejection (placeholder, shows 1 - confidence) |
| 37 | +// 6 = variance (alpha of the denoised gi, log scaled, the svgf per pixel luminance variance) |
| 38 | + |
| 39 | +// viridis colormap, approximated via a small polynomial fit, returns a perceptually uniform color from a [0,1] input |
| 40 | +float3 viridis(float t) |
| 41 | +{ |
| 42 | + t = saturate(t); |
| 43 | + float3 c0 = float3(0.2777f, 0.0054f, 0.3340f); |
| 44 | + float3 c1 = float3(0.1056f, 1.4046f, 1.3845f); |
| 45 | + float3 c2 = float3(-0.3308f, 0.2148f, 0.0950f); |
| 46 | + float3 c3 = float3(-4.6342f, -5.7991f, -19.3324f); |
| 47 | + float3 c4 = float3(6.2289f, 14.1799f, 56.6905f); |
| 48 | + float3 c5 = float3(4.7763f, -13.7451f, -65.3530f); |
| 49 | + float3 c6 = float3(-5.4354f, 4.6458f, 26.3124f); |
| 50 | + return saturate(c0 + t * (c1 + t * (c2 + t * (c3 + t * (c4 + t * (c5 + t * c6)))))); |
| 51 | +} |
| 52 | + |
| 53 | +[numthreads(THREAD_GROUP_COUNT_X, THREAD_GROUP_COUNT_Y, 1)] |
| 54 | +void main_cs(uint3 dispatch_id : SV_DispatchThreadID) |
| 55 | +{ |
| 56 | + uint2 pixel = dispatch_id.xy; |
| 57 | + uint resolution_x, resolution_y; |
| 58 | + tex_uav.GetDimensions(resolution_x, resolution_y); |
| 59 | + uint2 resolution = uint2(resolution_x, resolution_y); |
| 60 | + |
| 61 | + if (pixel.x >= resolution.x || pixel.y >= resolution.y) |
| 62 | + { |
| 63 | + return; |
| 64 | + } |
| 65 | + |
| 66 | + uint mode = uint(buffer_frame.restir_pt_debug_mode); |
| 67 | + if (mode == 0) |
| 68 | + { |
| 69 | + return; |
| 70 | + } |
| 71 | + |
| 72 | + // sample what we need based on the mode |
| 73 | + // reservoir packing matches pack_reservoir / unpack_reservoir in restir_reservoir.hlsl |
| 74 | + float visualization_t = 0.0f; |
| 75 | + [branch] switch (mode) |
| 76 | + { |
| 77 | + case 1: // confidence (high f16 of tex4.w) |
| 78 | + { |
| 79 | + uint age_conf = asuint(tex_reservoir_prev4[pixel].w); |
| 80 | + float confidence = saturate(f16tof32(age_conf >> 16u)); |
| 81 | + visualization_t = confidence; |
| 82 | + break; |
| 83 | + } |
| 84 | + case 2: // reservoir M, normalized by RESTIR_M_CAP for [0,1] |
| 85 | + { |
| 86 | + float M = tex_reservoir_prev2[pixel].w; |
| 87 | + visualization_t = saturate(M / float(RESTIR_M_CAP)); |
| 88 | + break; |
| 89 | + } |
| 90 | + case 3: // reservoir W, log scaled since W spans many decades |
| 91 | + { |
| 92 | + float W = tex_reservoir_prev3[pixel].x; |
| 93 | + visualization_t = saturate(log2(W + 1.0f) / 8.0f); |
| 94 | + break; |
| 95 | + } |
| 96 | + case 4: // reuse ratio placeholder, shows confidence (proxy for how much we have reused this reservoir) |
| 97 | + { |
| 98 | + uint age_conf = asuint(tex_reservoir_prev4[pixel].w); |
| 99 | + float confidence = saturate(f16tof32(age_conf >> 16u)); |
| 100 | + visualization_t = confidence; |
| 101 | + break; |
| 102 | + } |
| 103 | + case 5: // temporal rejection placeholder, shows 1 - confidence so freshly rejected pixels are hot |
| 104 | + { |
| 105 | + uint age_conf = asuint(tex_reservoir_prev4[pixel].w); |
| 106 | + float confidence = saturate(f16tof32(age_conf >> 16u)); |
| 107 | + visualization_t = saturate(1.0f - confidence); |
| 108 | + break; |
| 109 | + } |
| 110 | + case 6: // variance (alpha of the denoised gi, log scaled because per pixel variance spans several decades on disocclusion edges) |
| 111 | + { |
| 112 | + float variance = max(tex_uav[pixel].a, 0.0f); |
| 113 | + visualization_t = saturate(log2(variance + 1.0f) / 4.0f); |
| 114 | + break; |
| 115 | + } |
| 116 | + } |
| 117 | + |
| 118 | + // composition adds light_gi directly when restir is enabled, no albedo remultiply is done |
| 119 | + // so we write the viridis color straight into the gi slot, the confidence stored in alpha |
| 120 | + // is preserved so downstream bilateral upsampling still has a sane weight |
| 121 | + float3 heatmap = viridis(visualization_t); |
| 122 | + float alpha_in = tex_uav[pixel].a; |
| 123 | + tex_uav[pixel] = float4(heatmap, alpha_in); |
| 124 | +} |
0 commit comments