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::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
68fn map_axis_with_repeat(
69 // normalized distance along the axis
70 p: f32,
71 // target min dividing point
72 il: f32,
73 // target max dividing point
74 ih: f32,
75 // slice min dividing point
76 tl: f32,
77 // slice max dividing point
78 th: f32,
79 // number of times to repeat the slice for sides and the center
80 r: f32,
81) -> f32 {
82 if p < il {
83 // inside one of the two left (horizontal axis) or top (vertical axis) corners
84 return (p / il) * tl;
85 } else if ih < p {
86 // inside one of the two (horizontal axis) or top (vertical axis) corners
87 return th + ((p - ih) / (1 - ih)) * (1 - th);
88 } else {
89 // not inside a corner, repeat the texture
90 return tl + fract((r * (p - il)) / (ih - il)) * (th - tl);
91 }
94fn map_uvs_to_slice(
95 uv: vec2<f32>,
96 target_slices: vec4<f32>,
97 texture_slices: vec4<f32>,
98 repeat: vec4<f32>,
99) -> vec2<f32> {
100 var r: vec2<f32>;
101 if target_slices.x <= uv.x && uv.x <= target_slices.z && target_slices.y <= uv.y && uv.y <= target_slices.w {
102 // use the center repeat values if the uv coords are inside the center slice of the target
103 r = repeat.zw;
104 } else {
105 // use the side repeat values if the uv coords are outside the center slice
106 r = repeat.xy;
107 }
109 // map horizontal axis
110 let x = map_axis_with_repeat(uv.x, target_slices.x, target_slices.z, texture_slices.x, texture_slices.z, r.x);
112 // map vertical axis
113 let y = map_axis_with_repeat(uv.y, target_slices.y, target_slices.w, texture_slices.y, texture_slices.w, r.y);
115 return vec2(x, y);
118@fragment
119fn fragment(in: UiVertexOutput) -> @location(0) vec4<f32> {
120 // map the target uvs to slice coords
121 let uv = map_uvs_to_slice(in.uv, in.target_slices, in.texture_slices, in.repeat);
123 // map the slice coords to texture coords
124 let atlas_uv = in.atlas_rect.xy + uv * (in.atlas_rect.zw - in.atlas_rect.xy);
126 return in.color * textureSample(sprite_texture, sprite_sampler, atlas_uv);
Contents