Search across packages, versions, files, declarations, and comments. Use multiple terms to narrow results (AND), and add @vertex, @fragment, or @compute to filter by shader stage.
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}
7struct Instance {
8 world_from_local: mat3x4<f32>,
9 world_plane_origin: vec3<f32>,
10 world_plane_offset: vec3<f32>,
11 volume_colour: vec4<f32>,
12 volume_offset: f32,
13 stencil_offset: f32,
14 alpha_mask_threshold: f32,
15 first_vertex_index: u32,
16 current_skin_index: u32,
17};
19struct Vertex {
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>,
24#endif
25#ifdef ALPHA_MASK_TEXTURE
26 @location(2) uv: vec2<f32>,
27#endif
28#ifdef SKINNED
29 @location(5) joint_indices: vec4<u32>,
30 @location(6) joint_weights: vec4<f32>,
31#endif
32#ifdef MORPH_TARGETS
33 @builtin(vertex_index) index: u32,
34#endif
35};
37@group(0) @binding(0)
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>;
45#else
46@group(1) @binding(0) var<storage> mesh: array<Instance>;
47#endif
49#ifdef MORPH_TARGETS
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);
58 if weight == 0.0 {
59 continue;
60 }
61 vertex.position += weight * bevy_pbr::morph::morph(vertex_index, bevy_pbr::morph::position_offset, i);
62 }
63 return vertex;
65#endif
67#ifdef SKINNED
68fn skin_model(
69 indexes: vec4<u32>,
70 weights: vec4<f32>,
71 instance_index: u32,
72) -> mat4x4<f32> {
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];
78#else
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];
84#endif
86#endif
88fn mat4to3(m: mat4x4<f32>) -> mat3x3<f32> {
89 return mat3x3<f32>(
90 m[0].xyz, m[1].xyz, m[2].xyz
91 );
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);
99 return zw.x / zw.y;
102@vertex
103fn vertex(vertex_no_morph: Vertex) -> VertexOutput {
104 let iid = vertex_no_morph.instance_index;
105#ifdef MORPH_TARGETS
106 var vertex = morph_vertex(vertex_no_morph);
107#else
108 var vertex = vertex_no_morph;
109#endif
110#ifdef SKINNED
111 let model = skin_model(vertex.joint_indices, vertex.joint_weights, iid);
112#else
113 let model = bevy_render::maths::affine3_to_square(mesh[iid].world_from_local);
114#endif
115 let clip_pos = view_uniform.clip_from_world * (model * vec4<f32>(vertex.position, 1.0));
116#ifdef VOLUME
117 let offset = mesh[iid].volume_offset;
118#else
119 let offset = mesh[iid].stencil_offset;
120#endif
121#ifdef VERTEX_OFFSET_ZERO
122 let out_xy = clip_pos.xy;
123#else
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;
128#endif
129 var out: VertexOutput;
130 out.position = vec4<f32>(out_xy, clip_pos.zw);
131#ifdef FLAT_DEPTH
132#ifdef PLANE_OFFSET_ZERO
133 let world_plane = mesh[iid].world_plane_origin;
134#else
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;
138#endif
139 out.flat_depth = model_origin_z(world_plane, view_uniform.clip_from_world);
140#endif
141#ifdef VOLUME
142 out.volume_colour = mesh[iid].volume_colour;
143#endif
144#ifdef ALPHA_MASK_TEXTURE
145 out.alpha_mask_threshold = mesh[iid].alpha_mask_threshold;
146 out.uv = vertex.uv;
147#endif
148 return out;
Contents