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, abs_pos: vec3, rel_pos: vec3, scale: f32 }; @group(0) @binding(0) var camera: CameraUniform; @group(1) @binding(0) var origins: array>; const POINT_NORMALS = array( -0.5, 0.5 ); @vertex fn vs_main( model: VertexInput, ) -> VertexOutput { var out: VertexOutput; let index = model.index % 2u; let origin = vec3( origins[model.origin][0], origins[model.origin][1], origins[model.origin][2]); let model_pos = ((origin - camera.abs_pos - camera.rel_pos) + model.position) * camera.scale; let origin_pos = (origin - camera.abs_pos - camera.rel_pos) * camera.scale; let view = camera.view; let orbit_normal = normalize(model.position); var normal = orbit_normal; if length(model_pos - origin_pos) > 0.01 { normal *= POINT_NORMALS[index]; } 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 + normal * 0.005, 1.0); out.clip_position = point_view_pos; return out; } @fragment fn fs_main(in: VertexOutput ) -> @location(0) vec4 { return vec4(0.0, 0.5, 0.0, 1.0); }