summaryrefslogtreecommitdiff
path: root/cnn_v3/shaders/gbuf_view.wgsl
diff options
context:
space:
mode:
Diffstat (limited to 'cnn_v3/shaders/gbuf_view.wgsl')
-rw-r--r--cnn_v3/shaders/gbuf_view.wgsl127
1 files changed, 127 insertions, 0 deletions
diff --git a/cnn_v3/shaders/gbuf_view.wgsl b/cnn_v3/shaders/gbuf_view.wgsl
new file mode 100644
index 0000000..3e7d1ff
--- /dev/null
+++ b/cnn_v3/shaders/gbuf_view.wgsl
@@ -0,0 +1,127 @@
+// G-buffer channel visualization — 4×5 grid of 20 feature channels.
+// Takes feat_tex0 (rgba32uint, ch 0-7 f16) and feat_tex1 (rgba32uint, ch 8-19 unorm8).
+// Outputs tiled channel view to a standard rgba8unorm render target.
+//
+// Channel layout (row×col):
+// Row 0: ch0(alb.r) ch1(alb.g) ch2(alb.b) ch3(nrm.x)
+// Row 1: ch4(nrm.y) ch5(depth) ch6(dzdx) ch7(dzdy)
+// Row 2: ch8(matid) ch9(prv.r) ch10(prv.g) ch11(prv.b)
+// Row 3: ch12(m1.r) ch13(m1.g) ch14(m1.b) ch15(m2.r)
+// Row 4: ch16(m2.g) ch17(m2.b) ch18(shdw) ch19(trns)
+
+#include "debug/debug_print"
+
+struct GBufViewUniforms { resolution: vec2f }
+
+@group(0) @binding(0) var feat0: texture_2d<u32>;
+@group(0) @binding(1) var feat1: texture_2d<u32>;
+@group(0) @binding(2) var<uniform> u: GBufViewUniforms;
+
+@vertex
+fn vs_main(@builtin(vertex_index) vid: u32) -> @builtin(position) vec4f {
+ var corners = array<vec2f, 3>(
+ vec2f(-1.0, -1.0), vec2f(3.0, -1.0), vec2f(-1.0, 3.0));
+ return vec4f(corners[vid], 0.0, 1.0);
+}
+
+@fragment
+fn fs_main(@builtin(position) pos: vec4f) -> @location(0) vec4f {
+ let uv = pos.xy / u.resolution;
+
+ let COLS = 4.0;
+ let ROWS = 5.0;
+ let col = u32(uv.x * COLS);
+ let row = u32(uv.y * ROWS);
+ let ch = row * 4u + col;
+
+ if (col >= 4u || ch >= 20u) {
+ return vec4f(0.05, 0.05, 0.05, 1.0);
+ }
+
+ // 1-pixel grid lines (thin border per cell)
+ let lx = fract(uv.x * COLS);
+ let ly = fract(uv.y * ROWS);
+ if (lx < 0.005 || lx > 0.995 || ly < 0.005 || ly > 0.995) {
+ return vec4f(0.25, 0.25, 0.25, 1.0);
+ }
+
+ // Map local UV to texel coordinate
+ let dim = vec2i(textureDimensions(feat0));
+ let tc = clamp(vec2i(vec2f(lx, ly) * vec2f(dim)), vec2i(0), dim - vec2i(1));
+
+ var v: f32 = 0.0;
+
+ if (ch < 8u) {
+ // feat0: 4 × pack2x16float — each u32 component holds two f16 values
+ let t = textureLoad(feat0, tc, 0);
+ let pair_idx = ch >> 1u;
+ let sub = ch & 1u;
+ var p: vec2f;
+ if (pair_idx == 0u) { p = unpack2x16float(t.x); }
+ else if (pair_idx == 1u) { p = unpack2x16float(t.y); }
+ else if (pair_idx == 2u) { p = unpack2x16float(t.z); }
+ else { p = unpack2x16float(t.w); }
+ v = select(p.y, p.x, sub == 0u);
+ } else {
+ // feat1: 3 × pack4x8unorm — components .x/.y/.z hold 4 u8 values each
+ let t = textureLoad(feat1, tc, 0);
+ let ch1 = ch - 8u;
+ let comp_idx = ch1 / 4u;
+ let sub = ch1 % 4u;
+ var bytes: vec4f;
+ if (comp_idx == 0u) { bytes = unpack4x8unorm(t.x); }
+ else if (comp_idx == 1u) { bytes = unpack4x8unorm(t.y); }
+ else { bytes = unpack4x8unorm(t.z); }
+ var ba = array<f32, 4>(bytes.x, bytes.y, bytes.z, bytes.w);
+ v = ba[sub];
+ }
+
+ // Channel-specific normalization for display clarity
+ var disp: f32;
+ if (ch <= 2u) {
+ // Albedo: already [0,1]
+ disp = clamp(v, 0.0, 1.0);
+ } else if (ch == 3u || ch == 4u) {
+ // Normals oct-encoded in [-1,1] → remap to [0,1]
+ disp = clamp(v * 0.5 + 0.5, 0.0, 1.0);
+ } else if (ch == 5u) {
+ // Depth [0,1]: invert so near=white, far=dark
+ disp = clamp(1.0 - v, 0.0, 1.0);
+ } else if (ch == 6u || ch == 7u) {
+ // Depth gradients (signed, small values): amplify × 20 + 0.5 for visibility
+ disp = clamp(v * 20.0 + 0.5, 0.0, 1.0);
+ } else {
+ // Everything else: clamp to [0,1]
+ disp = clamp(v, 0.0, 1.0);
+ }
+
+ var out = vec4f(disp, disp, disp, 1.0);
+
+ // Label at top-left of each tile
+ let tile_w = u.resolution.x / 4.0;
+ let tile_h = u.resolution.y / 5.0;
+ let origin = vec2f(f32(col) * tile_w + 4.0, f32(row) * tile_h + 4.0);
+ switch ch {
+ case 0u: { out = debug_str(out, pos.xy, origin, vec4u(0x616C622Eu, 0x72000000u, 0u, 0u), 5u); } // alb.r
+ case 1u: { out = debug_str(out, pos.xy, origin, vec4u(0x616C622Eu, 0x67000000u, 0u, 0u), 5u); } // alb.g
+ case 2u: { out = debug_str(out, pos.xy, origin, vec4u(0x616C622Eu, 0x62000000u, 0u, 0u), 5u); } // alb.b
+ case 3u: { out = debug_str(out, pos.xy, origin, vec4u(0x6E726D2Eu, 0x78000000u, 0u, 0u), 5u); } // nrm.x
+ case 4u: { out = debug_str(out, pos.xy, origin, vec4u(0x6E726D2Eu, 0x79000000u, 0u, 0u), 5u); } // nrm.y
+ case 5u: { out = debug_str(out, pos.xy, origin, vec4u(0x64657074u, 0x68000000u, 0u, 0u), 5u); } // depth
+ case 6u: { out = debug_str(out, pos.xy, origin, vec4u(0x647A6478u, 0u, 0u, 0u), 4u); } // dzdx
+ case 7u: { out = debug_str(out, pos.xy, origin, vec4u(0x647A6479u, 0u, 0u, 0u), 4u); } // dzdy
+ case 8u: { out = debug_str(out, pos.xy, origin, vec4u(0x6D617469u, 0x64000000u, 0u, 0u), 5u); } // matid
+ case 9u: { out = debug_str(out, pos.xy, origin, vec4u(0x7072762Eu, 0x72000000u, 0u, 0u), 5u); } // prv.r
+ case 10u: { out = debug_str(out, pos.xy, origin, vec4u(0x7072762Eu, 0x67000000u, 0u, 0u), 5u); } // prv.g
+ case 11u: { out = debug_str(out, pos.xy, origin, vec4u(0x7072762Eu, 0x62000000u, 0u, 0u), 5u); } // prv.b
+ case 12u: { out = debug_str(out, pos.xy, origin, vec4u(0x6D312E72u, 0u, 0u, 0u), 4u); } // m1.r
+ case 13u: { out = debug_str(out, pos.xy, origin, vec4u(0x6D312E67u, 0u, 0u, 0u), 4u); } // m1.g
+ case 14u: { out = debug_str(out, pos.xy, origin, vec4u(0x6D312E62u, 0u, 0u, 0u), 4u); } // m1.b
+ case 15u: { out = debug_str(out, pos.xy, origin, vec4u(0x6D322E72u, 0u, 0u, 0u), 4u); } // m2.r
+ case 16u: { out = debug_str(out, pos.xy, origin, vec4u(0x6D322E67u, 0u, 0u, 0u), 4u); } // m2.g
+ case 17u: { out = debug_str(out, pos.xy, origin, vec4u(0x6D322E62u, 0u, 0u, 0u), 4u); } // m2.b
+ case 18u: { out = debug_str(out, pos.xy, origin, vec4u(0x73686477u, 0u, 0u, 0u), 4u); } // shdw
+ default: { out = debug_str(out, pos.xy, origin, vec4u(0x74726E73u, 0u, 0u, 0u), 4u); } // trns
+ }
+ return out;
+}