1import package::sprite_mesh::{ 3 SPRITE_MATERIAL_FLAGS_ALPHA_MODE_RESERVED_BITS, 4 SPRITE_MATERIAL_FLAGS_ALPHA_MODE_OPAQUE, 5 SPRITE_MATERIAL_FLAGS_ALPHA_MODE_MASK, 6 SPRITE_MATERIAL_FLAGS_FLIP_X, 7 SPRITE_MATERIAL_FLAGS_FLIP_Y, 8 SPRITE_MATERIAL_FLAGS_TILE_X, 9 SPRITE_MATERIAL_FLAGS_TILE_Y, 14import package::sprite_mesh::bindings::material_indices; 16import package::sprite_mesh::bindings::{texture, texture_sampler}; 17import package::mesh2d::bindings::mesh; 18import bevy_render::bindless::{bindless_samplers_filtering, bindless_textures_2d}; 21fn sample_final_color(uv: vec2<f32>, instance_index: u32) -> vec4<f32> { 22 let sprite_color = sample_sprite_texture(uv, instance_index); 23 return get_final_color(sprite_color, instance_index); 27fn sample_sprite_texture(uv: vec2<f32>, instance_index: u32) -> vec4<f32> { 28 let final_uv = get_final_uv(uv, instance_index); 30 let slot = mesh[instance_index].material_bind_group_slot; 33 bindless_textures_2d[material_indices[slot].texture], 34 bindless_samplers_filtering[material_indices[slot].texture_sampler], 38 return textureSample(texture, texture_sampler, final_uv); 42fn get_final_color(sprite_color: vec4<f32>, instance_index: u32) -> vec4<f32> { 43 var output_color = apply_tint(sprite_color, instance_index); 44 output_color = alpha_discard(output_color, instance_index); 49fn get_final_uv(uv: vec2<f32>, instance_index: u32) -> vec2<f32> { 51 out = apply_flip(out, instance_index); 52 out = apply_tiling(out, instance_index); 53 out = apply_slicing(out, instance_index); 54 out = apply_uv_transform(out, instance_index); 59fn apply_flip(uv: vec2<f32>, instance_index: u32) -> vec2<f32> { 61 let slot = mesh[instance_index].material_bind_group_slot; 63 let flags = material[material_indices[slot].material].flags; 65 let flags = material.flags; 68 if (flags & SPRITE_MATERIAL_FLAGS_FLIP_X) != 0u { 71 if (flags & SPRITE_MATERIAL_FLAGS_FLIP_Y) != 0u { 79fn apply_tiling(uv: vec2<f32>, instance_index: u32) -> vec2<f32> { 81 let slot = mesh[instance_index].material_bind_group_slot; 83 let flags = material[material_indices[slot].material].flags; 85 let flags = material.flags; 87 let tile_stretch_value = material[material_indices[slot].material].tile_stretch_value; 89 let tile_stretch_value = material.tile_stretch_value; 92 if (flags & SPRITE_MATERIAL_FLAGS_TILE_X) != 0u { 93 out.x = (out.x - tile_stretch_value.x * floor(out.x / tile_stretch_value.x)) / tile_stretch_value.x; 95 if (flags & SPRITE_MATERIAL_FLAGS_TILE_Y) != 0u { 96 out.y = (out.y - tile_stretch_value.y * floor(out.y / tile_stretch_value.y)) / tile_stretch_value.y; 105fn apply_uv_transform(uv: vec2<f32>, instance_index: u32) -> vec2<f32> { 107 let slot = mesh[instance_index].material_bind_group_slot; 109 let uv_transform = material[material_indices[slot].material].uv_transform; 111 let uv_transform = material.uv_transform; 113 return (uv_transform * vec3(uv, 1.0)).xy; 117fn apply_slicing(uv: vec2<f32>, instance_index: u32) -> vec2<f32> { 119 let slot = mesh[instance_index].material_bind_group_slot; 121 let scale = material[material_indices[slot].material].scale; 123 let scale = material.scale; 125 let min_inset = material[material_indices[slot].material].min_inset; 127 let min_inset = material.min_inset; 129 let max_inset = material[material_indices[slot].material].max_inset; 131 let max_inset = material.max_inset; 133 let side_stretch_value = material[material_indices[slot].material].side_stretch_value; 135 let side_stretch_value = material.side_stretch_value; 137 let center_stretch_value = material[material_indices[slot].material].center_stretch_value; 139 let center_stretch_value = material.center_stretch_value; 146 let min_inset_scaled = min_inset / scale; 147 let max_inset_scaled = max_inset / scale; 149 let left = uv.x < min_inset_scaled.x; 150 let right = uv.x > 1.0 - max_inset_scaled.x; 151 let top = uv.y < min_inset_scaled.y; 152 let bottom = uv.y > 1.0 - max_inset_scaled.y; 162 1.0 - (1.0 - uv.x) * scale.x, 171 1.0 - (1.0 - uv.y) * scale.y 177 return vec2<f32>(1.0) - (vec2<f32>(1.0) - uv) * scale; 183 tile_or_stretch(uv.x, min_inset_scaled.x, 1.0 - max_inset_scaled.x, min_inset.x, 1.0 - max_inset.x, side_stretch_value.x), 191 tile_or_stretch(uv.x, min_inset_scaled.x, 1.0 - max_inset_scaled.x, min_inset.x, 1.0 - max_inset.x, side_stretch_value.x), 192 1.0 - (1.0 - uv.y) * scale.y 200 tile_or_stretch(uv.y, min_inset_scaled.y, 1.0 - max_inset_scaled.y, min_inset.y, 1.0 - max_inset.y, side_stretch_value.y) 207 1.0 - (1.0 - uv.x) * scale.x, 208 tile_or_stretch(uv.y, min_inset_scaled.y, 1.0 - max_inset_scaled.y, min_inset.y, 1.0 - max_inset.y, side_stretch_value.y) 214 tile_or_stretch(uv.x, min_inset_scaled.x, 1.0 - max_inset_scaled.x, min_inset.x, 1.0 - max_inset.x, center_stretch_value.x), 215 tile_or_stretch(uv.y, min_inset_scaled.y, 1.0 - max_inset_scaled.y, min_inset.y, 1.0 - max_inset.y, center_stretch_value.y) 220fn apply_tint(sprite_color: vec4<f32>, instance_index: u32) -> vec4<f32> { 222 let slot = mesh[instance_index].material_bind_group_slot; 224 let color = material[material_indices[slot].material].color; 226 let color = material.color; 228 return sprite_color * color; 232fn alpha_discard(output_color: vec4<f32>, instance_index: u32) -> vec4<f32> { 234 let slot = mesh[instance_index].material_bind_group_slot; 236 let flags = material[material_indices[slot].material].flags; 238 let flags = material.flags; 240 let alpha_cutoff = material[material_indices[slot].material].alpha_cutoff; 242 let alpha_cutoff = material.alpha_cutoff; 244 var color = output_color; 245 let alpha_mode = flags & SPRITE_MATERIAL_FLAGS_ALPHA_MODE_RESERVED_BITS; 247 if alpha_mode == SPRITE_MATERIAL_FLAGS_ALPHA_MODE_OPAQUE { 254 if alpha_mode == SPRITE_MATERIAL_FLAGS_ALPHA_MODE_MASK { 255 if color.a >= alpha_cutoff { 269fn tile_or_stretch(p: f32, a: f32, b: f32, c: f32, d: f32, stretch_value: f32) -> f32 { 270 if stretch_value == 0.0 { 271 return stretch_interval(p, a, b, c, d); 273 return tile_interval(p, a, b, c, d, stretch_value); 277fn tile_interval(p: f32, a: f32, b: f32, c: f32, d: f32, stretch_value: f32) -> f32 { 278 let value = (p - a) / (b - a); 279 let tile_value = (value - stretch_value * floor(value / stretch_value)) / stretch_value; 280 return tile_value * (d - c) + c; 284fn stretch_interval(p: f32, a: f32, b: f32, c: f32, d: f32) -> f32 { 285 return (p - a) / (b - a) * (d - c) + c;