2#import bevy_render::view::View 4@group(0) @binding(0) var<uniform> view: View; 7struct LineGizmoUniform { 10#ifdef SIXTEEN_BYTE_ALIGNMENT 16@group(1) @binding(0) var<uniform> line_gizmo: LineGizmoUniform; 19 @location(0) position_a: vec3<f32>, 20 @location(1) position_b: vec3<f32>, 21 @location(2) color_a: vec4<f32>, 22 @location(3) color_b: vec4<f32>, 23 @builtin(vertex_index) index: u32, 27 @builtin(position) clip_position: vec4<f32>, 28 @location(0) color: vec4<f32>, 32const EPSILON: f32 = 4.88e-04; 35fn vertex(vertex: VertexInput) -> VertexOutput { 36 var positions = array<vec2<f32>, 6>( 44 let position = positions[vertex.index]; 47 var clip_a = view.clip_from_world * vec4(vertex.position_a, 1.); 48 var clip_b = view.clip_from_world * vec4(vertex.position_b, 1.); 51 clip_a = clip_near_plane(clip_a, clip_b); 52 clip_b = clip_near_plane(clip_b, clip_a); 53 let clip = mix(clip_a, clip_b, position.y); 55 let resolution = view.viewport.zw; 56 let screen_a = resolution * (0.5 * clip_a.xy / clip_a.w + 0.5); 57 let screen_b = resolution * (0.5 * clip_b.xy / clip_b.w + 0.5); 59 let y_basis = normalize(screen_b - screen_a); 60 let x_basis = vec2(-y_basis.y, y_basis.x); 62 var color = mix(vertex.color_a, vertex.color_b, position.y); 64 var line_width = line_gizmo.line_width; 72 let pos0 = view.view_from_clip * vec4(0, -1, 0, 1); 73 let pos1 = view.view_from_clip * vec4(0, 1, 0, 1); 74 let near_clipping_plane_height = length(pos0.xyz - pos1.xyz); 77 let position_a = view.world_from_clip * clip_a; 78 let position_b = view.world_from_clip * clip_b; 79 let world_distance = length(position_a.xyz - position_b.xyz); 82 let clipped_offset = length(position_a.xyz - vertex.position_a); 84 uv = (clipped_offset + position.y * world_distance) * resolution.y / near_clipping_plane_height / line_gizmo.line_width; 87 let camera_b = view.view_from_clip * clip_b; 91 var depth_adaptment: f32; 92 if (clip_b.w == 1.0) { 93 depth_adaptment = 1.0; 96 depth_adaptment = -camera_b.z; 98 uv = position.y * depth_adaptment * length(screen_b - screen_a) / line_gizmo.line_width; 102 if line_width > 0.0 && line_width < 1. { 103 color.a *= line_width; 107 let x_offset = line_width * position.x * x_basis; 108 let screen = mix(screen_a, screen_b, position.y) + x_offset; 111 if line_gizmo.depth_bias >= 0. { 112 depth = clip.z * (1. - line_gizmo.depth_bias); 121 depth = clip.z * exp2(-line_gizmo.depth_bias * log2(clip.w / clip.z - EPSILON)); 124 var clip_position = vec4(clip.w * ((2. * screen) / resolution - 1.), depth, clip.w); 126 return VertexOutput(clip_position, color, uv); 129fn clip_near_plane(a: vec4<f32>, b: vec4<f32>) -> vec4<f32> { 131 if a.z > a.w && b.z <= b.w { 133 let distance_a = a.z - a.w; 134 let distance_b = b.z - b.w; 137 let t = distance_a / (distance_a - distance_b) + EPSILON; 143struct FragmentInput { 144 @builtin(position) position: vec4<f32>, 145 @location(0) color: vec4<f32>, 146 @location(1) uv: f32, 149struct FragmentOutput { 150 @location(0) color: vec4<f32>, 154fn fragment_solid(in: FragmentInput) -> FragmentOutput { 155 return FragmentOutput(in.color); 158fn fragment_dotted(in: FragmentInput) -> FragmentOutput { 161 alpha = 1 - floor(in.uv % 2.0); 163 alpha = 1 - floor((in.uv * in.position.w) % 2.0); 166 return FragmentOutput(vec4(in.color.xyz, in.color.w * alpha));