summaryrefslogtreecommitdiff
path: root/cnn_v3/shaders/gbuf_raster.wgsl
diff options
context:
space:
mode:
Diffstat (limited to 'cnn_v3/shaders/gbuf_raster.wgsl')
-rw-r--r--cnn_v3/shaders/gbuf_raster.wgsl105
1 files changed, 105 insertions, 0 deletions
diff --git a/cnn_v3/shaders/gbuf_raster.wgsl b/cnn_v3/shaders/gbuf_raster.wgsl
new file mode 100644
index 0000000..c762db2
--- /dev/null
+++ b/cnn_v3/shaders/gbuf_raster.wgsl
@@ -0,0 +1,105 @@
+// G-buffer rasterization shader for CNN v3
+// Pass 1: Proxy geometry → MRT (albedo rgba16float, normal_mat rgba16float, depth32)
+// Uses GlobalUniforms, ObjectData, ObjectsBuffer from common_uniforms.
+
+#include "common_uniforms"
+
+@group(0) @binding(0) var<uniform> globals: GlobalUniforms;
+@group(0) @binding(1) var<storage, read> object_data: ObjectsBuffer;
+
+struct VertexOutput {
+ @builtin(position) position: vec4f,
+ @location(0) world_pos: vec3f,
+ @location(1) world_normal: vec3f,
+ @location(2) color: vec4f,
+ @location(3) @interpolate(flat) instance_index: u32,
+}
+
+// Octahedral encoding: maps unit normal to [-1,1]^2
+fn oct_encode(n: vec3f) -> vec2f {
+ let inv_l1 = 1.0 / (abs(n.x) + abs(n.y) + abs(n.z));
+ var p = n.xy * inv_l1;
+ // Fold lower hemisphere
+ if (n.z < 0.0) {
+ let s = vec2f(
+ select(-1.0, 1.0, p.x >= 0.0),
+ select(-1.0, 1.0, p.y >= 0.0)
+ );
+ p = (1.0 - abs(p.yx)) * s;
+ }
+ return p; // in [-1, 1]
+}
+
+@vertex
+fn vs_main(
+ @builtin(vertex_index) vertex_index: u32,
+ @builtin(instance_index) instance_index: u32
+) -> VertexOutput {
+ // Proxy box vertices (same as renderer_3d.wgsl)
+ var pos = array<vec3f, 36>(
+ vec3f(-1.0, -1.0, 1.0), vec3f( 1.0, -1.0, 1.0), vec3f( 1.0, 1.0, 1.0),
+ vec3f(-1.0, -1.0, 1.0), vec3f( 1.0, 1.0, 1.0), vec3f(-1.0, 1.0, 1.0),
+ vec3f(-1.0, -1.0, -1.0), vec3f(-1.0, 1.0, -1.0), vec3f( 1.0, 1.0, -1.0),
+ vec3f(-1.0, -1.0, -1.0), vec3f( 1.0, 1.0, -1.0), vec3f( 1.0, -1.0, -1.0),
+ vec3f(-1.0, 1.0, -1.0), vec3f(-1.0, 1.0, 1.0), vec3f( 1.0, 1.0, 1.0),
+ vec3f(-1.0, 1.0, -1.0), vec3f( 1.0, 1.0, 1.0), vec3f( 1.0, 1.0, -1.0),
+ vec3f(-1.0, -1.0, -1.0), vec3f( 1.0, -1.0, -1.0), vec3f( 1.0, -1.0, 1.0),
+ vec3f(-1.0, -1.0, -1.0), vec3f( 1.0, -1.0, 1.0), vec3f(-1.0, -1.0, 1.0),
+ vec3f( 1.0, -1.0, -1.0), vec3f( 1.0, 1.0, -1.0), vec3f( 1.0, 1.0, 1.0),
+ vec3f( 1.0, -1.0, -1.0), vec3f( 1.0, 1.0, 1.0), vec3f( 1.0, -1.0, 1.0),
+ vec3f(-1.0, -1.0, -1.0), vec3f(-1.0, -1.0, 1.0), vec3f(-1.0, 1.0, 1.0),
+ vec3f(-1.0, -1.0, -1.0), vec3f(-1.0, 1.0, 1.0), vec3f(-1.0, 1.0, -1.0)
+ );
+
+ // Proxy face normals (one per 2 triangles = 6 faces × 6 verts = 36)
+ var nrm = array<vec3f, 36>(
+ vec3f(0,0,1), vec3f(0,0,1), vec3f(0,0,1),
+ vec3f(0,0,1), vec3f(0,0,1), vec3f(0,0,1),
+ vec3f(0,0,-1), vec3f(0,0,-1), vec3f(0,0,-1),
+ vec3f(0,0,-1), vec3f(0,0,-1), vec3f(0,0,-1),
+ vec3f(0,1,0), vec3f(0,1,0), vec3f(0,1,0),
+ vec3f(0,1,0), vec3f(0,1,0), vec3f(0,1,0),
+ vec3f(0,-1,0), vec3f(0,-1,0), vec3f(0,-1,0),
+ vec3f(0,-1,0), vec3f(0,-1,0), vec3f(0,-1,0),
+ vec3f(1,0,0), vec3f(1,0,0), vec3f(1,0,0),
+ vec3f(1,0,0), vec3f(1,0,0), vec3f(1,0,0),
+ vec3f(-1,0,0), vec3f(-1,0,0), vec3f(-1,0,0),
+ vec3f(-1,0,0), vec3f(-1,0,0), vec3f(-1,0,0)
+ );
+
+ let obj = object_data.objects[instance_index];
+ let p = pos[vertex_index];
+ let n = nrm[vertex_index];
+
+ let world_pos = obj.model * vec4f(p, 1.0);
+ let clip_pos = globals.view_proj * world_pos;
+ // Transform normal by inverse-transpose (upper-left 3×3 of inv_model^T)
+ let world_normal = normalize((obj.inv_model * vec4f(n, 0.0)).xyz);
+
+ var out: VertexOutput;
+ out.position = clip_pos;
+ out.world_pos = world_pos.xyz;
+ out.world_normal = world_normal;
+ out.color = obj.color;
+ out.instance_index = instance_index;
+ return out;
+}
+
+struct GBufOutput {
+ @location(0) albedo: vec4f, // rgba16float: material color
+ @location(1) normal_mat: vec4f, // rgba16float: oct-normal XY in RG, mat_id/255 in B
+}
+
+@fragment
+fn fs_main(in: VertexOutput) -> GBufOutput {
+ let obj = object_data.objects[in.instance_index];
+ let mat_id = f32(in.instance_index) / 255.0;
+
+ // Oct-encode world normal, remap [-1,1] → [0,1] for storage
+ let oct = oct_encode(normalize(in.world_normal)) * 0.5 + vec2f(0.5);
+
+ var out: GBufOutput;
+ out.albedo = vec4f(in.color.rgb, 1.0);
+ out.normal_mat = vec4f(oct.x, oct.y, mat_id, 0.0);
+ return out;
+}