struct InstanceInput { @location(0) position: vec3, @location(1) origin: vec3, @location(2) radius: f32 }; struct VertexOutput { @builtin(position) clip_position: vec4, @location(0) local_position: vec3, }; struct CameraUniform { view: mat4x4, proj: mat4x4, abs_pos: vec3, rel_pos: vec3, scale: f32, }; @group(0) @binding(0) var camera: CameraUniform; const QUAD_VERTICES = array,6>( vec3(-1.0, -1.0, 0.0), vec3(-1.0, 1.0 , 0.0), vec3(1.0, 1.0 , 0.0), vec3(1.0, 1.0 , 0.0), vec3(1.0, -1.0, 0.0), vec3(-1.0, -1.0, 0.0), ); @vertex fn vs_main( @builtin(vertex_index) index: u32, instance: InstanceInput ) -> VertexOutput { var out: VertexOutput; let model = QUAD_VERTICES[index]; var view = camera.view; out.local_position = model; let min_size = 0.025; let real_radius = max(min_size / 2.0, instance.radius * camera.scale); //Scale the world around the camera scale and translate about the camera's //absolute (/target) position let relative_pos = instance.position; let origin_pos = instance.origin - camera.abs_pos - camera.rel_pos; let view_proj = camera.proj * view; let origin_vp_pos = view_proj * vec4(origin_pos * camera.scale, 1.0); let offset_vp = view_proj * vec4(relative_pos * camera.scale, 0.0); let center_vp_pos = origin_vp_pos + offset_vp; let offset_ndc = offset_vp.xy / origin_vp_pos.w; if (length(offset_ndc) < 2.0 * min_size){ if all(offset_vp != vec4(0.0)) { out.clip_position = vec4(0.0, 0.0, 0.0, 1.0); return out; } } let model_proj = camera.proj * vec4(model.xy, 0.0, 0.0); let vertex_vp_pos = center_vp_pos + vec4(model_proj.xy * instance.radius * camera.scale, 0.0, 0.0); let vertex_dist = length(vertex_vp_pos - center_vp_pos) / center_vp_pos.w; if vertex_dist < min_size { out.clip_position = center_vp_pos / center_vp_pos.w; out.clip_position += model_proj * (min_size / 2.0); }else{ out.clip_position = vertex_vp_pos; } return out; } @fragment fn fs_main(in: VertexOutput ) -> @location(0) vec4 { let point_dist = length(in.local_position); var alpha = 1.0; if point_dist > 1.0 { alpha = 0.0; } let color = vec3(1.0); return vec4(color, alpha); }