diff options
Diffstat (limited to 'cnn_v3/shaders/gbuf_raster.wgsl')
| -rw-r--r-- | cnn_v3/shaders/gbuf_raster.wgsl | 105 |
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; +} |
