skybox.wgsl (1542B)
1 struct Globals { 2 time: f32, 3 _pad0: f32, 4 resolution: vec2<f32>, 5 6 cam_pos: vec3<f32>, 7 _pad3: f32, 8 9 light_dir: vec3<f32>, 10 _pad1: f32, 11 12 light_color: vec3<f32>, 13 _pad2: f32, 14 15 fill_light_dir: vec3<f32>, 16 _pad4: f32, 17 18 fill_light_color: vec3<f32>, 19 _pad5: f32, 20 21 view_proj: mat4x4<f32>, 22 inv_view_proj: mat4x4<f32>, 23 light_view_proj: mat4x4<f32>, 24 }; 25 26 @group(0) @binding(0) var<uniform> globals: Globals; 27 @group(3) @binding(1) var ibl_sampler: sampler; 28 @group(3) @binding(2) var prefiltered_map: texture_cube<f32>; 29 30 struct VSOut { 31 @builtin(position) clip: vec4<f32>, 32 @location(0) ray_dir: vec3<f32>, 33 }; 34 35 @vertex 36 fn vs_main(@builtin(vertex_index) vi: u32) -> VSOut { 37 var out: VSOut; 38 39 // Fullscreen triangle: vertices at (-1,-1), (3,-1), (-1,3) 40 let x = f32((vi << 1u) & 2u) * 2.0 - 1.0; 41 let y = f32(vi & 2u) * 2.0 - 1.0; 42 out.clip = vec4<f32>(x, y, 1.0, 1.0); 43 44 // Unproject to get ray direction 45 let near = globals.inv_view_proj * vec4<f32>(x, y, 0.0, 1.0); 46 let far = globals.inv_view_proj * vec4<f32>(x, y, 1.0, 1.0); 47 out.ray_dir = normalize(far.xyz / far.w - near.xyz / near.w); 48 49 return out; 50 } 51 52 @fragment 53 fn fs_main(in: VSOut) -> @location(0) vec4<f32> { 54 // Sample prefiltered map at slight blur level (mip 1 of 5) 55 let hdr = textureSampleLevel(prefiltered_map, ibl_sampler, in.ray_dir, 1.0).rgb; 56 57 // Reinhard tonemap 58 let col = hdr / (hdr + vec3<f32>(1.0)); 59 60 return vec4<f32>(clamp(col, vec3<f32>(0.0), vec3<f32>(1.0)), 1.0); 61 }