struct Camera { view_pos: vec4, view: mat4x4, view_proj: mat4x4, inv_proj: mat4x4, inv_view: mat4x4, } @group(0) @binding(0) var camera: Camera; @group(1) @binding(0) var env_map: texture_cube; @group(1) @binding(1) var env_sampler: sampler; struct VertexOutput { @builtin(position) frag_position: vec4, @location(0) clip_position: vec4, } @vertex fn vs_main( @builtin(vertex_index) id: u32, ) -> VertexOutput { let uv = vec2(vec2( id & 1u, (id >> 1u) & 1u, )); var out: VertexOutput; out.clip_position = vec4(uv * 4.0 - 1.0, 1.0, 1.0); out.frag_position = out.clip_position; return out; } @fragment fn fs_main(in: VertexOutput) -> @location(0) vec4 { let view_pos_homogeneous = camera.inv_proj * in.clip_position; let view_ray_direction = view_pos_homogeneous.xyz / view_pos_homogeneous.w; var ray_direction = normalize((camera.inv_view * vec4(view_ray_direction, 0.0)).xyz); let sample = textureSample(env_map, env_sampler, ray_direction); return sample; }