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#define_import_path bevy_pbr::morph
3#ifdef MORPH_TARGETS
5#import bevy_pbr::mesh_types::{MorphAttributes, MorphDescriptor, MorphWeights}
6#import bevy_pbr::mesh_bindings::mesh
8#ifdef SKINS_USE_UNIFORM_BUFFERS
10@group(2) @binding(2) var<uniform> morph_weights: MorphWeights;
11@group(2) @binding(3) var morph_targets: texture_3d<f32>;
12@group(2) @binding(7) var<uniform> prev_morph_weights: MorphWeights;
14#else // SKINS_USE_UNIFORM_BUFFERS
16@group(2) @binding(2) var<storage> morph_weights: array<f32>;
17@group(2) @binding(3) var<storage> morph_targets: array<MorphAttributes>;
18@group(2) @binding(7) var<storage> prev_morph_weights: array<f32>;
19@group(2) @binding(8) var<storage> morph_descriptors: array<MorphDescriptor>;
21#endif // SKINS_USE_UNIFORM_BUFFERS
23// NOTE: Those are the "hardcoded" values found in `MorphAttributes` struct
24// in crates/bevy_render/src/mesh/morph/visitors.rs
25// In an ideal world, the offsets are established dynamically and passed as #defines
26// to the shader, but it's out of scope for the initial implementation of morph targets.
27const position_offset: u32 = 0u;
28const normal_offset: u32 = 3u;
29const tangent_offset: u32 = 6u;
30const total_component_count: u32 = 9u;
32fn layer_count(instance_index: u32) -> u32 {
33#ifdef SKINS_USE_UNIFORM_BUFFERS
34 let dimensions = textureDimensions(morph_targets);
35 return u32(dimensions.z);
36#else // SKINS_USE_UNIFORM_BUFFERS
37 let morph_descriptor_index = mesh[instance_index].morph_descriptor_index;
38 return morph_descriptors[morph_descriptor_index].weight_count;
39#endif // SKINS_USE_UNIFORM_BUFFERS
42#ifdef SKINS_USE_UNIFORM_BUFFERS
43fn component_texture_coord(vertex_index: u32, component_offset: u32) -> vec2<u32> {
44 let width = u32(textureDimensions(morph_targets).x);
45 let component_index = total_component_count * vertex_index + component_offset;
46 return vec2<u32>(component_index % width, component_index / width);
48#endif // SKINS_USE_UNIFORM_BUFFERS
50fn weight_at(weight_index: u32, instance_index: u32) -> f32 {
51#ifdef SKINS_USE_UNIFORM_BUFFERS
52 let i = weight_index;
53 return morph_weights.weights[i / 4u][i % 4u];
54#else // SKINS_USE_UNIFORM_BUFFERS
55 let morph_descriptor_index = mesh[instance_index].morph_descriptor_index;
56 let weights_offset = morph_descriptors[morph_descriptor_index].current_weights_offset;
57 return morph_weights[weights_offset + weight_index];
58#endif // SKINS_USE_UNIFORM_BUFFERS
61fn prev_weight_at(weight_index: u32, instance_index: u32) -> f32 {
62#ifdef SKINS_USE_UNIFORM_BUFFERS
63 let i = weight_index;
64 return prev_morph_weights.weights[i / 4u][i % 4u];
65#else // SKINS_USE_UNIFORM_BUFFERS
66 let morph_descriptor_index = mesh[instance_index].morph_descriptor_index;
67 let weights_offset = morph_descriptors[morph_descriptor_index].prev_weights_offset;
68 return prev_morph_weights[weights_offset + weight_index];
69#endif // SKINS_USE_UNIFORM_BUFFERS
72#ifdef SKINS_USE_UNIFORM_BUFFERS
74fn morph_pixel(vertex: u32, component: u32, weight: u32) -> f32 {
75 let coord = component_texture_coord(vertex, component);
76 // Due to https://gpuweb.github.io/gpuweb/wgsl/#texel-formats
77 // While the texture stores a f32, the textureLoad returns a vec4<>, where
78 // only the first component is set.
79 return textureLoad(morph_targets, vec3(coord, weight), 0).r;
82fn morph(vertex_index: u32, component_offset: u32, weight_index: u32) -> vec3<f32> {
83 return vec3<f32>(
84 morph_pixel(vertex_index, component_offset, weight_index),
85 morph_pixel(vertex_index, component_offset + 1u, weight_index),
86 morph_pixel(vertex_index, component_offset + 2u, weight_index),
87 );
90fn morph_position(vertex_index: u32, weight_index: u32, instance_index: u32) -> vec3<f32> {
91 return morph(vertex_index, position_offset, weight_index);
94fn morph_normal(vertex_index: u32, weight_index: u32, instance_index: u32) -> vec3<f32> {
95 return morph(vertex_index, normal_offset, weight_index);
98fn morph_tangent(vertex_index: u32, weight_index: u32, instance_index: u32) -> vec3<f32> {
99 return morph(vertex_index, tangent_offset, weight_index);
102#else // SKINS_USE_UNIFORM_BUFFERS
104fn get_morph_target(vertex_index: u32, weight_index: u32, instance_index: u32) -> MorphAttributes {
105 let morph_descriptor_index = mesh[instance_index].morph_descriptor_index;
106 let targets_offset = morph_descriptors[morph_descriptor_index].targets_offset;
107 let vertex_count = morph_descriptors[morph_descriptor_index].vertex_count;
108 return morph_targets[targets_offset + weight_index * vertex_count + vertex_index];
111fn morph_position(vertex_index: u32, weight_index: u32, instance_index: u32) -> vec3<f32> {
112 return get_morph_target(vertex_index, weight_index, instance_index).position;
115fn morph_normal(vertex_index: u32, weight_index: u32, instance_index: u32) -> vec3<f32> {
116 return get_morph_target(vertex_index, weight_index, instance_index).normal;
119fn morph_tangent(vertex_index: u32, weight_index: u32, instance_index: u32) -> vec3<f32> {
120 return get_morph_target(vertex_index, weight_index, instance_index).tangent;
123#endif // SKINS_USE_UNIFORM_BUFFERS
125#endif // MORPH_TARGETS
Contents