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.
1import bevy_render::view::View;
2import bevy_render::globals::Globals;
4@group(0) @binding(0)
5var<uniform> view: View;
6@group(0) @binding(1)
7var<uniform> globals: Globals;
9@group(1) @binding(0) var sprite_texture: texture_2d<f32>;
10@group(1) @binding(1) var sprite_sampler: sampler;
12struct UiVertexOutput {
13 @location(0) uv: vec2<f32>,
14 @location(1) color: vec4<f32>,
16 /// Defines the dividing line that are used to split the texture atlas rect into corner, side and center slices
17 /// The distances are normalized and from the top left corner of the texture atlas rect
18 /// x = distance of the left vertical dividing line
19 /// y = distance of the top horizontal dividing line
20 /// z = distance of the right vertical dividing line
21 /// w = distance of the bottom horizontal dividing line
22 @location(2) @interpolate(flat) texture_slices: vec4<f32>,
24 /// Defines the dividing line that are used to split the render target into corner, side and center slices
25 /// The distances are normalized and from the top left corner of the render target
26 /// x = distance of left vertical dividing line
27 /// y = distance of top horizontal dividing line
28 /// z = distance of right vertical dividing line
29 /// w = distance of bottom horizontal dividing line
30 @location(3) @interpolate(flat) target_slices: vec4<f32>,
32 /// The number of times the side or center texture slices should be repeated when mapping them to the border slices
33 /// x = number of times to repeat along the horizontal axis for the side textures
34 /// y = number of times to repeat along the vertical axis for the side textures
35 /// z = number of times to repeat along the horizontal axis for the center texture
36 /// w = number of times to repeat along the vertical axis for the center texture
37 @location(4) @interpolate(flat) repeat: vec4<f32>,
39 /// normalized texture atlas rect coordinates
40 /// x, y = top, left corner of the atlas rect
41 /// z, w = bottom, right corner of the atlas rect
42 @location(5) @interpolate(flat) atlas_rect: vec4<f32>,
43 @builtin(position) position: vec4<f32>,
46@vertex
47fn vertex(
48 @location(0) vertex_position: vec3<f32>,
49 @location(1) vertex_uv: vec2<f32>,
50 @location(2) vertex_color: vec4<f32>,
51 @location(3) texture_slices: vec4<f32>,
52 @location(4) target_slices: vec4<f32>,
53 @location(5) repeat: vec4<f32>,
54 @location(6) atlas_rect: vec4<f32>,
55) -> UiVertexOutput {
56 var out: UiVertexOutput;
57 out.uv = vertex_uv;
58 out.color = vertex_color;
59 out.position = view.clip_from_world * vec4<f32>(vertex_position, 1.0);
60 out.texture_slices = texture_slices;
61 out.target_slices = target_slices;
62 out.repeat = repeat;
63 out.atlas_rect = atlas_rect;
64 return out;
67/// maps a point along the axis of the render target to slice coordinates
68/// Arguments:
69/// - p: normalized distance along the axis
70/// - il: target min dividing point
71/// - ih: target max dividing point
72/// - tl: slice min dividing point
73/// - th: slice max dividing point
74/// - r: number of times to repeat the slice for sides and the center
75fn map_axis_with_repeat(
76 p: f32,
77 il: f32,
78 ih: f32,
79 tl: f32,
80 th: f32,
81 r: f32,
82) -> f32 {
83 if p < il {
84 // inside one of the two left (horizontal axis) or top (vertical axis) corners
85 return (p / il) * tl;
86 } else if ih < p {
87 // inside one of the two (horizontal axis) or top (vertical axis) corners
88 return th + ((p - ih) / (1 - ih)) * (1 - th);
89 } else {
90 // not inside a corner, repeat the texture
91 return tl + fract((r * (p - il)) / (ih - il)) * (th - tl);
92 }
95fn map_uvs_to_slice(
96 uv: vec2<f32>,
97 target_slices: vec4<f32>,
98 texture_slices: vec4<f32>,
99 repeat: vec4<f32>,
100) -> vec2<f32> {
101 var r: vec2<f32>;
102 if target_slices.x <= uv.x && uv.x <= target_slices.z && target_slices.y <= uv.y && uv.y <= target_slices.w {
103 // use the center repeat values if the uv coords are inside the center slice of the target
104 r = repeat.zw;
105 } else {
106 // use the side repeat values if the uv coords are outside the center slice
107 r = repeat.xy;
108 }
110 // map horizontal axis
111 let x = map_axis_with_repeat(uv.x, target_slices.x, target_slices.z, texture_slices.x, texture_slices.z, r.x);
113 // map vertical axis
114 let y = map_axis_with_repeat(uv.y, target_slices.y, target_slices.w, texture_slices.y, texture_slices.w, r.y);
116 return vec2(x, y);
119@fragment
120fn fragment(in: UiVertexOutput) -> @location(0) vec4<f32> {
121 // map the target uvs to slice coords
122 let uv = map_uvs_to_slice(in.uv, in.target_slices, in.texture_slices, in.repeat);
124 // map the slice coords to texture coords
125 let atlas_uv = in.atlas_rect.xy + uv * (in.atlas_rect.zw - in.atlas_rect.xy);
127 return in.color * textureSample(sprite_texture, sprite_sampler, atlas_uv);
Contents