struct VertexInput { @builtin(vertex_index) index: u32, @location(0) origin: u32, @location(1) position: vec3, }; struct VertexOutput { @builtin(position) clip_position: vec4, }; struct CameraUniform { view: mat4x4, proj: mat4x4, pos: vec3, scale: f32 }; @group(0) @binding(0) var camera: CameraUniform; @group(1) @binding(0) var origins: array>; const POINT_NORMALS = array,4>( vec2(0.0, -0.5), vec2(0.0, 0.5), vec2(0.5, -0.5), vec2(0.5, 0.5) ); @vertex fn vs_main( model: VertexInput, ) -> VertexOutput { var out: VertexOutput; let index = model.index % 4u; let normal = POINT_NORMALS[index]; let origin = vec3( origins[model.origin][0], origins[model.origin][1], origins[model.origin][2]); let model_pos = (origin + model.position - camera.pos) * camera.scale; let view_proj = camera.proj * camera.view; //Scale the world around the camera scale and translate about the camera's //absolute (/target) position let point_view_pos = view_proj * vec4(model_pos, 1.0); out.clip_position = point_view_pos; out.clip_position += vec4(normal * 0.01, 0.0, 0.0) * point_view_pos.w; return out; } @fragment fn fs_main(in: VertexOutput ) -> @location(0) vec4 { return vec4(0.25, 1.0, 0.25, 1.0); }