1#import bevy_render::view::View 3@group(0) @binding(0) var<uniform> view: View; 6struct LineGizmoUniform { 10#ifdef SIXTEEN_BYTE_ALIGNMENT 16@group(1) @binding(0) var<uniform> joints_gizmo: LineGizmoUniform; 19 @location(0) position_a: vec3<f32>, 20 @location(1) position_b: vec3<f32>, 21 @location(2) position_c: vec3<f32>, 22 @location(3) color: vec4<f32>, 23 @builtin(vertex_index) index: u32, 27 @builtin(position) clip_position: vec4<f32>, 28 @location(0) color: vec4<f32>, 31const EPSILON: f32 = 4.88e-04; 34fn vertex_bevel(vertex: VertexInput) -> VertexOutput { 35 var positions = array<vec2<f32>, 3>( 40 var position = positions[vertex.index]; 42 var clip_a = view.clip_from_world * vec4(vertex.position_a, 1.); 43 var clip_b = view.clip_from_world * vec4(vertex.position_b, 1.); 44 var clip_c = view.clip_from_world * vec4(vertex.position_c, 1.); 47 clip_a = clip_near_plane(clip_a, clip_c); 48 clip_b = clip_near_plane(clip_b, clip_a); 49 clip_c = clip_near_plane(clip_c, clip_b); 50 clip_a = clip_near_plane(clip_a, clip_c); 52 let resolution = view.viewport.zw; 53 let screen_a = resolution * (0.5 * clip_a.xy / clip_a.w + 0.5); 54 let screen_b = resolution * (0.5 * clip_b.xy / clip_b.w + 0.5); 55 let screen_c = resolution * (0.5 * clip_c.xy / clip_c.w + 0.5); 57 var color = vertex.color; 58 var line_width = joints_gizmo.line_width; 61 line_width /= clip_b.w; 65 if line_width > 0.0 && line_width < 1. { 66 color.a *= line_width; 70 let ab = normalize(screen_b - screen_a); 71 let cb = normalize(screen_b - screen_c); 72 let ab_norm = vec2(-ab.y, ab.x); 73 let cb_norm = vec2(cb.y, -cb.x); 74 let tangent = normalize(ab - cb); 75 let normal = vec2(-tangent.y, tangent.x); 76 let sigma = sign(dot(ab + cb, normal)); 78 var p0 = line_width * sigma * ab_norm; 79 var p1 = line_width * sigma * cb_norm; 81 let screen = screen_b + position.x * p0 + position.y * p1; 83 let depth = depth(clip_b); 85 var clip_position = vec4(clip_b.w * ((2. * screen) / resolution - 1.), depth, clip_b.w); 86 return VertexOutput(clip_position, color); 90fn vertex_miter(vertex: VertexInput) -> VertexOutput { 91 var positions = array<vec3<f32>, 6>( 99 var position = positions[vertex.index]; 101 var clip_a = view.clip_from_world * vec4(vertex.position_a, 1.); 102 var clip_b = view.clip_from_world * vec4(vertex.position_b, 1.); 103 var clip_c = view.clip_from_world * vec4(vertex.position_c, 1.); 106 clip_a = clip_near_plane(clip_a, clip_c); 107 clip_b = clip_near_plane(clip_b, clip_a); 108 clip_c = clip_near_plane(clip_c, clip_b); 109 clip_a = clip_near_plane(clip_a, clip_c); 111 let resolution = view.viewport.zw; 112 let screen_a = resolution * (0.5 * clip_a.xy / clip_a.w + 0.5); 113 let screen_b = resolution * (0.5 * clip_b.xy / clip_b.w + 0.5); 114 let screen_c = resolution * (0.5 * clip_c.xy / clip_c.w + 0.5); 116 var color = vertex.color; 117 var line_width = joints_gizmo.line_width; 120 line_width /= clip_b.w; 124 if line_width > 0.0 && line_width < 1. { 125 color.a *= line_width; 129 let ab = normalize(screen_b - screen_a); 130 let cb = normalize(screen_b - screen_c); 131 let ab_norm = vec2(-ab.y, ab.x); 132 let cb_norm = vec2(cb.y, -cb.x); 133 let tangent = normalize(ab - cb); 134 let normal = vec2(-tangent.y, tangent.x); 135 let sigma = sign(dot(ab + cb, normal)); 137 var p0 = line_width * sigma * ab_norm; 138 var p1 = line_width * sigma * normal / dot(normal, ab_norm); 139 var p2 = line_width * sigma * cb_norm; 141 var screen = screen_b + position.x * p0 + position.y * p1 + position.z * p2; 143 var depth = depth(clip_b); 145 var clip_position = vec4(clip_b.w * ((2. * screen) / resolution - 1.), depth, clip_b.w); 146 return VertexOutput(clip_position, color); 150fn vertex_round(vertex: VertexInput) -> VertexOutput { 151 var clip_a = view.clip_from_world * vec4(vertex.position_a, 1.); 152 var clip_b = view.clip_from_world * vec4(vertex.position_b, 1.); 153 var clip_c = view.clip_from_world * vec4(vertex.position_c, 1.); 156 clip_a = clip_near_plane(clip_a, clip_c); 157 clip_b = clip_near_plane(clip_b, clip_a); 158 clip_c = clip_near_plane(clip_c, clip_b); 159 clip_a = clip_near_plane(clip_a, clip_c); 161 let resolution = view.viewport.zw; 162 let screen_a = resolution * (0.5 * clip_a.xy / clip_a.w + 0.5); 163 let screen_b = resolution * (0.5 * clip_b.xy / clip_b.w + 0.5); 164 let screen_c = resolution * (0.5 * clip_c.xy / clip_c.w + 0.5); 166 var color = vertex.color; 167 var line_width = joints_gizmo.line_width; 170 line_width /= clip_b.w; 174 if line_width > 0.0 && line_width < 1. { 175 color.a *= line_width; 179 let ab = normalize(screen_b - screen_a); 180 let cb = normalize(screen_b - screen_c); 181 let ab_norm = vec2(-ab.y, ab.x); 182 let cb_norm = vec2(cb.y, -cb.x); 188 var in_triangle_index = f32(vertex.index) % 3.0; 189 var tri_index = floor(f32(vertex.index) / 3.0); 190 var radius = sign(in_triangle_index) * 0.5 * line_width; 191 var theta = acos(dot(ab_norm, cb_norm)); 192 let sigma = sign(dot(ab_norm, cb)); 193 var angle = theta * (tri_index + in_triangle_index - 1) / f32(joints_gizmo.resolution); 194 var position_x = sigma * radius * cos(angle); 195 var position_y = radius * sin(angle); 197 var screen = screen_b + position_x * ab_norm + position_y * ab; 199 var depth = depth(clip_b); 201 var clip_position = vec4(clip_b.w * ((2. * screen) / resolution - 1.), depth, clip_b.w); 202 return VertexOutput(clip_position, color); 205fn clip_near_plane(a: vec4<f32>, b: vec4<f32>) -> vec4<f32> { 207 if a.z > a.w && b.z <= b.w { 209 let distance_a = a.z - a.w; 210 let distance_b = b.z - b.w; 213 let t = distance_a / (distance_a - distance_b) + EPSILON; 219fn depth(clip: vec4<f32>) -> f32 { 221 if joints_gizmo.depth_bias >= 0. { 222 depth = clip.z * (1. - joints_gizmo.depth_bias); 231 depth = clip.z * exp2(-joints_gizmo.depth_bias * log2(clip.w / clip.z - EPSILON)); 236struct FragmentInput { 237 @location(0) color: vec4<f32>, 240struct FragmentOutput { 241 @location(0) color: vec4<f32>, 245fn fragment(in: FragmentInput) -> FragmentOutput { 247 return FragmentOutput(in.color);