1#import bevy_render::view::View 2#import bevy_render::maths 3#import bevy_pbr::mesh_types::SkinnedMesh 4#import bevy_pbr::skinning::joint_matrices 5#import bevy_mod_outline::common::{OutlineViewUniform, VertexOutput} 8 world_from_local: mat3x4<f32>, 9 world_plane_origin: vec3<f32>, 10 world_plane_offset: vec3<f32>, 11 volume_colour: vec4<f32>, 14 alpha_mask_threshold: f32, 15 first_vertex_index: u32, 16 current_skin_index: u32, 20 @location(0) position: vec3<f32>, 21 @builtin(instance_index) instance_index: u32, 22#ifndef VERTEX_OFFSET_ZERO 23 @location(1) outline_normal: vec3<f32>, 25#ifdef ALPHA_MASK_TEXTURE 26 @location(2) uv: vec2<f32>, 29 @location(5) joint_indices: vec4<u32>, 30 @location(6) joint_weights: vec4<f32>, 33 @builtin(vertex_index) index: u32, 38var<uniform> view_uniform: OutlineViewUniform; 40#import bevy_pbr::skinning 41#import bevy_pbr::morph 43#ifdef INSTANCE_BATCH_SIZE 44@group(1) @binding(0) var<uniform> mesh: array<Instance, #{INSTANCE_BATCH_SIZE}u>; 46@group(1) @binding(0) var<storage> mesh: array<Instance>; 50fn morph_vertex(vertex_in: Vertex) -> Vertex { 51 var vertex = vertex_in; 52 let first_vertex = mesh[vertex.instance_index].first_vertex_index; 53 let vertex_index = vertex.index - first_vertex; 55 let weight_count = bevy_pbr::morph::layer_count(); 56 for (var i: u32 = 0u; i < weight_count; i ++) { 57 let weight = bevy_pbr::morph::weight_at(i); 61 vertex.position += weight * bevy_pbr::morph::morph(vertex_index, bevy_pbr::morph::position_offset, i); 73#ifdef SKINS_USE_UNIFORM_BUFFERS 74 return weights.x * joint_matrices.data[indexes.x] 75 + weights.y * joint_matrices.data[indexes.y] 76 + weights.z * joint_matrices.data[indexes.z] 77 + weights.w * joint_matrices.data[indexes.w]; 79 var skin_index = mesh[instance_index].current_skin_index; 80 return weights.x * joint_matrices[skin_index + indexes.x] 81 + weights.y * joint_matrices[skin_index + indexes.y] 82 + weights.z * joint_matrices[skin_index + indexes.z] 83 + weights.w * joint_matrices[skin_index + indexes.w]; 88fn mat4to3(m: mat4x4<f32>) -> mat3x3<f32> { 90 m[0].xyz, m[1].xyz, m[2].xyz 94fn model_origin_z(plane: vec3<f32>, view_proj: mat4x4<f32>) -> f32 { 95 var proj_zw = mat4x2<f32>( 96 view_proj[0].zw, view_proj[1].zw, 97 view_proj[2].zw, view_proj[3].zw); 98 var zw = proj_zw * vec4<f32>(plane, 1.0); 103fn vertex(vertex_no_morph: Vertex) -> VertexOutput { 104 let iid = vertex_no_morph.instance_index; 106 var vertex = morph_vertex(vertex_no_morph); 108 var vertex = vertex_no_morph; 111 let model = skin_model(vertex.joint_indices, vertex.joint_weights, iid); 113 let model = bevy_render::maths::affine3_to_square(mesh[iid].world_from_local); 115 let clip_pos = view_uniform.clip_from_world * (model * vec4<f32>(vertex.position, 1.0)); 117 let offset = mesh[iid].volume_offset; 119 let offset = mesh[iid].stencil_offset; 121#ifdef VERTEX_OFFSET_ZERO 122 let out_xy = clip_pos.xy; 124 let clip_norm = mat4to3(view_uniform.clip_from_world) * (mat4to3(model) * vertex.outline_normal); 125 let corrected_norm = normalize(clip_norm.xy * vec2<f32>(view_uniform.aspect, 1.0)); 126 let ndc_delta = offset * corrected_norm * view_uniform.scale_clip_from_logical * clip_pos.w; 127 let out_xy = clip_pos.xy + ndc_delta; 129 var out: VertexOutput; 130 out.position = vec4<f32>(out_xy, clip_pos.zw); 132#ifdef PLANE_OFFSET_ZERO 133 let world_plane = mesh[iid].world_plane_origin; 135 let world_from_view = bevy_render::maths::mat2x4_f32_to_mat3x3_unpack(view_uniform.world_from_view_a, view_uniform.world_from_view_b); 136 let model_eye = normalize(world_from_view * vec3<f32>(0.0, 0.0, -1.0)); 137 let world_plane = mesh[iid].world_plane_origin + model_eye * mesh[iid].world_plane_offset; 139 out.flat_depth = model_origin_z(world_plane, view_uniform.clip_from_world); 142 out.volume_colour = mesh[iid].volume_colour; 144#ifdef ALPHA_MASK_TEXTURE 145 out.alpha_mask_threshold = mesh[iid].alpha_mask_threshold;