struct VertexOutput { @builtin(position) clip_position: vec4, @location(0) grid_position: vec2, @location(1) grid_scale: f32, }; struct CameraUniform { view: mat4x4, proj: mat4x4, scale: f32 }; @group(0) @binding(0) var camera: CameraUniform; const QUAD_VERTICES = array,6>( vec3(-1.0, 0.0, -1.0), vec3(-1.0, 0.0, 1.0), vec3(1.0, 0.0, 1.0), vec3(1.0, 0.0, 1.0), vec3(1.0, 0.0, -1.0), vec3(-1.0, 0.0, -1.0), ); @vertex fn vs_main( @builtin(vertex_index) index: u32 ) -> VertexOutput { var out: VertexOutput; let model_pos = QUAD_VERTICES[index] * 50.0; let world_pos = camera.proj * camera.view * vec4(model_pos.xyz, 1.0); out.clip_position = world_pos; out.grid_position = vec2(model_pos.x, model_pos.z); out.grid_scale = camera.scale * 1e6; return out; } fn modulus(a: f32, b: f32) -> f32 { return a - b * floor(a / b); } fn mod_vec2(a: vec2, b: vec2) -> vec2 { return a - b * floor(a / b); } const cell_line_thickness: f32 = 0.001; const subcell_line_thickness: f32 = 0.0001; const cell_line_color: vec4 = vec4(0.25, 0.25, 0.25, 0.5); const subcell_line_color: vec4 = vec4(0.125, 0.125, 0.125, 0.5); @fragment fn fs_main(in: VertexOutput ) -> @location(0) vec4 { let scale_mod = modulus(log(1.0 / in.grid_scale) * 10.0, 10.0) + 1.0; let cell_size = 1.0 / scale_mod; let half_cell_size = cell_size * 0.5; let subcell_size = 0.1 / scale_mod; let half_subcell_size = subcell_size * 0.5; //Position relative to the center of the quad. let frag_pos_rel = (in.grid_position / 2.0); let cell_pos = mod_vec2(frag_pos_rel, vec2(cell_size)); let subcell_pos = mod_vec2(frag_pos_rel, vec2(subcell_size)); let cell_dist = abs(cell_pos); let subcell_dist = abs(subcell_pos); let d = fwidth(in.grid_position); let clt_real = 0.5 * (cell_line_thickness + d); let sclt_real = 0.5 * (subcell_line_thickness + d); let center_distance = length(in.grid_position); let falloff = smoothstep(1.0, 0.0, center_distance / 2.0); let subcell_falloff = smoothstep(1.0, 0.5, scale_mod / 11.0); var color = vec4(0.0); if subcell_dist.x < sclt_real.x || subcell_dist.y < sclt_real.y { color = subcell_line_color * subcell_falloff; } if cell_dist.x < clt_real.x || cell_dist.y < clt_real.y { color = cell_line_color; } return color * falloff; }