1#import bevy_render::view::View 2#import bevy_render::maths 3#import bevy_pbr::mesh_types::SkinnedMesh 4#import bevy_mod_outline::common::VertexOutput 7 world_from_local: mat3x4<f32>, 8 world_plane_origin: vec3<f32>, 9 world_plane_offset: vec3<f32>, 11 volume_colour: vec4<f32>, 13 alpha_mask_threshold: f32, 14 first_vertex_index: u32, 18 @location(0) position: vec3<f32>, 19 @builtin(instance_index) instance_index: u32, 20#ifndef VERTEX_OFFSET_ZERO 21 @location(1) outline_normal: vec3<f32>, 23#ifdef ALPHA_MASK_TEXTURE 24 @location(2) uv: vec2<f32>, 27 @location(5) joint_indices: vec4<u32>, 28 @location(6) joint_weights: vec4<f32>, 31 @builtin(vertex_index) index: u32, 35struct OutlineViewUniform { 37 clip_from_world: mat4x4<f32>, 38 world_from_view_a: mat2x4<f32>, 39 world_from_view_b: f32, 45var<uniform> view_uniform: OutlineViewUniform; 47#import bevy_pbr::skinning 48#import bevy_pbr::morph 50#ifdef INSTANCE_BATCH_SIZE 51@group(2) @binding(0) var<uniform> mesh: array<Instance, #{INSTANCE_BATCH_SIZE}u>; 53@group(2) @binding(0) var<storage> mesh: array<Instance>; 57fn morph_vertex(vertex_in: Vertex) -> Vertex { 58 var vertex = vertex_in; 59 let first_vertex = mesh[vertex.instance_index].first_vertex_index; 60 let vertex_index = vertex.index - first_vertex; 62 let weight_count = bevy_pbr::morph::layer_count(); 63 for (var i: u32 = 0u; i < weight_count; i ++) { 64 let weight = bevy_pbr::morph::weight_at(i); 68 vertex.position += weight * bevy_pbr::morph::morph(vertex_index, bevy_pbr::morph::position_offset, i); 74fn mat4to3(m: mat4x4<f32>) -> mat3x3<f32> { 76 m[0].xyz, m[1].xyz, m[2].xyz 80fn model_origin_z(plane: vec3<f32>, view_proj: mat4x4<f32>) -> f32 { 81 var proj_zw = mat4x2<f32>( 82 view_proj[0].zw, view_proj[1].zw, 83 view_proj[2].zw, view_proj[3].zw); 84 var zw = proj_zw * vec4<f32>(plane, 1.0); 89fn vertex(vertex_no_morph: Vertex) -> VertexOutput { 90 let iid = vertex_no_morph.instance_index; 92 var vertex = morph_vertex(vertex_no_morph); 94 var vertex = vertex_no_morph; 97 let model = bevy_pbr::skinning::skin_model(vertex.joint_indices, vertex.joint_weights); 99 let model = bevy_render::maths::affine3_to_square(mesh[iid].world_from_local); 101 let clip_pos = view_uniform.clip_from_world * (model * vec4<f32>(vertex.position, 1.0)); 103 let offset = mesh[iid].volume_offset; 105 let offset = mesh[iid].stencil_offset; 107#ifdef VERTEX_OFFSET_ZERO 108 let out_xy = clip_pos.xy; 110 let clip_norm = mat4to3(view_uniform.clip_from_world) * (mat4to3(model) * vertex.outline_normal); 111 let corrected_norm = normalize(clip_norm.xy * vec2<f32>(view_uniform.aspect, 1.0)); 112 let ndc_delta = offset * corrected_norm * view_uniform.scale * clip_pos.w; 113 let out_xy = clip_pos.xy + ndc_delta; 115 var out: VertexOutput; 116 out.position = vec4<f32>(out_xy, clip_pos.zw); 118#ifdef PLANE_OFFSET_ZERO 119 let world_plane = mesh[iid].world_plane_origin; 121 let world_from_view = bevy_render::maths::mat2x4_f32_to_mat3x3_unpack(view_uniform.world_from_view_a, view_uniform.world_from_view_b); 122 let model_eye = normalize(world_from_view * vec3<f32>(0.0, 0.0, -1.0)); 123 let world_plane = mesh[iid].world_plane_origin + model_eye * mesh[iid].world_plane_offset; 125 out.flat_depth = model_origin_z(world_plane, view_uniform.clip_from_world); 128 out.volume_colour = mesh[iid].volume_colour; 130#ifdef ALPHA_MASK_TEXTURE 131 out.alpha_mask_threshold = mesh[iid].alpha_mask_threshold;