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_mod_outline::common::VertexOutput
6struct Instance {
7 world_from_local: mat3x4<f32>,
8 world_plane_origin: vec3<f32>,
9 world_plane_offset: vec3<f32>,
10 volume_colour: vec4<f32>,
11 volume_offset: f32,
12 stencil_offset: f32,
13 alpha_mask_threshold: f32,
14 first_vertex_index: u32,
15};
17struct Vertex {
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>,
22#endif
23#ifdef ALPHA_MASK_TEXTURE
24 @location(2) uv: vec2<f32>,
25#endif
26#ifdef SKINNED
27 @location(5) joint_indices: vec4<u32>,
28 @location(6) joint_weights: vec4<f32>,
29#endif
30#ifdef MORPH_TARGETS
31 @builtin(vertex_index) index: u32,
32#endif
33};
35struct OutlineViewUniform {
36 @align(16)
37 clip_from_world: mat4x4<f32>,
38 world_from_view_a: mat2x4<f32>,
39 world_from_view_b: f32,
40 aspect: f32,
41 scale: vec2<f32>,
42};
44@group(0) @binding(0)
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>;
52#else
53@group(2) @binding(0) var<storage> mesh: array<Instance>;
54#endif
56#ifdef MORPH_TARGETS
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);
65 if weight == 0.0 {
66 continue;
67 }
68 vertex.position += weight * bevy_pbr::morph::morph(vertex_index, bevy_pbr::morph::position_offset, i);
69 }
70 return vertex;
72#endif
74fn mat4to3(m: mat4x4<f32>) -> mat3x3<f32> {
75 return mat3x3<f32>(
76 m[0].xyz, m[1].xyz, m[2].xyz
77 );
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);
85 return zw.x / zw.y;
88@vertex
89fn vertex(vertex_no_morph: Vertex) -> VertexOutput {
90 let iid = vertex_no_morph.instance_index;
91#ifdef MORPH_TARGETS
92 var vertex = morph_vertex(vertex_no_morph);
93#else
94 var vertex = vertex_no_morph;
95#endif
96#ifdef SKINNED
97 let model = bevy_pbr::skinning::skin_model(vertex.joint_indices, vertex.joint_weights, vertex_no_morph.instance_index);
98#else
99 let model = bevy_render::maths::affine3_to_square(mesh[iid].world_from_local);
100#endif
101 let clip_pos = view_uniform.clip_from_world * (model * vec4<f32>(vertex.position, 1.0));
102#ifdef VOLUME
103 let offset = mesh[iid].volume_offset;
104#else
105 let offset = mesh[iid].stencil_offset;
106#endif
107#ifdef VERTEX_OFFSET_ZERO
108 let out_xy = clip_pos.xy;
109#else
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;
114#endif
115 var out: VertexOutput;
116 out.position = vec4<f32>(out_xy, clip_pos.zw);
117#ifdef FLAT_DEPTH
118#ifdef PLANE_OFFSET_ZERO
119 let world_plane = mesh[iid].world_plane_origin;
120#else
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;
124#endif
125 out.flat_depth = model_origin_z(world_plane, view_uniform.clip_from_world);
126#endif
127#ifdef VOLUME
128 out.volume_colour = mesh[iid].volume_colour;
129#endif
130#ifdef ALPHA_MASK_TEXTURE
131 out.alpha_mask_threshold = mesh[iid].alpha_mask_threshold;
132 out.uv = vertex.uv;
133#endif
134 return out;
Contents