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_sprite_render::{mesh2d::vertex_output::VertexOutput, sprite_mesh::functions as sprite_fn};
3struct DissolveMaterial {
4 burn_edge_color: vec4<f32>,
5 amount: f32,
6 burn_edge: f32,
8 // WebGL2 requires structs to be aligned to 16 bytes
9 @if(SIXTEEN_BYTE_ALIGNMENT)
10 _webgl2_padding_12b: u32,
11 @if(SIXTEEN_BYTE_ALIGNMENT)
12 _webgl2_padding_16b: u32,
15@group(constants::MATERIAL_BIND_GROUP) @binding(20) var<uniform> material: DissolveMaterial;
17@fragment
18fn fragment(input: VertexOutput) -> @location(0) vec4<f32> {
19 // Sample some simplex noise with the UV coordinates scaled up by 2 to make the noise denser
20 var noise = fbm_simplex_2d(input.uv * 2.0);
21 // Change the noise's range from 0..1 to burn_edge..1 - burn_edge
22 // in order to avoid the burn edge showing up when the sprite is fully visible or fully hidden
23 noise = mix(material.burn_edge, 1.0 - material.burn_edge, noise);
25 // If this value is 0..burn_edge, the pixel is part of the burn edge
26 // If it's >= burn_edge, the pixel is visible
27 // Otherwise, it's hidden
28 let difference = noise - material.amount;
29 // Get the sprite's color
30 let sprite_color = sprite_fn::sample_sprite_texture(input.uv, input.instance_index);
32 var color = vec4(0.0);
33 let burn_edge = difference >= 0 && difference < material.burn_edge;
34 let visible = difference >= material.burn_edge;
35 if burn_edge {
36 color = material.burn_edge_color;
37 color.a = sprite_color.a;
38 } else if visible {
39 color = sprite_color;
40 }
42 // Apply alpha discard and tint
43 color = sprite_fn::get_final_color(color, input.instance_index);
44 return color;
47/// An implementation of the simplex noise algorithm to generate noise for the dissolve effect. Credit to <https://crates.io/crates/noisy_bevy>.
48///
49/// Note that usually sampling the noise from a prebaked texture is better for performance.
50/// However, to avoid increasing the size of the bevy git repository, we generate the noise in the shader.
51fn simplex_noise_2d(v: vec2<f32>) -> f32 {
52 let C = vec4(
53 0.211324865405187, // (3.0 - sqrt(3.0)) / 6.0
54 0.366025403784439, // 0.5 * (sqrt(3.0) - 1.0)
55 -0.577350269189626, // -1.0 + 2.0 * C.x
56 0.024390243902439 // 1.0 / 41.0
57 );
59 // first corner
60 var i = floor(v + dot(v, C.yy));
61 let x0 = v - i + dot(i, C.xx);
63 // other corners
64 var i1 = select(vec2(0., 1.), vec2(1., 0.), x0.x > x0.y);
65 var x12 = x0.xyxy + C.xxzz - vec4(i1, 0., 0.);
67 // permutations
68 i = i % vec2(289.);
70 let p = permute_3_(permute_3_(i.y + vec3(0., i1.y, 1.)) + i.x + vec3(0., i1.x, 1.));
71 var m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), vec3(0.));
72 m *= m;
73 m *= m;
75 // gradients: 41 points uniformly over a line, mapped onto a diamond
76 // the ring size, 17*17 = 289, is close to a multiple of 41 (41*7 = 287)
77 let x = 2. * fract(p * C.www) - 1.;
78 let h = abs(x) - 0.5;
79 let ox = floor(x + 0.5);
80 let a0 = x - ox;
82 // normalize gradients implicitly by scaling m
83 // approximation of: m *= inversesqrt(a0 * a0 + h * h);
84 m = m * (1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h));
86 // compute final noise value at P
87 let g = vec3(a0.x * x0.x + h.x * x0.y, a0.yz * x12.xz + h.yz * x12.yw);
88 return (130. * dot(m, g) + 1.) / 2.;
91/// Fractional brownian motion using simplex noise. This approach makes the noise look more detailed.
92fn fbm_simplex_2d(pos: vec2<f32>) -> f32 {
93 const octaves = 3;
94 const lacunarity = 2.0;
95 const gain = 0.5;
96 // Sum of the geometric series with `octaves` as the amount of terms and `gain` as the factor
97 // This is the maximum possible value that the noise can reach
98 const max = (1 - pow(gain, octaves)) / (1 - gain);
100 var sum = 0.;
101 var amplitude = 1.;
102 var frequency = 1.;
104 for (var i = 0; i < octaves; i+= 1) {
105 sum += simplex_noise_2d(pos * frequency) * amplitude;
106 amplitude *= gain;
107 frequency *= lacunarity;
108 }
110 // Map the noise back to the 0..1 range.
111 return sum / max;
114fn permute_3_(x: vec3<f32>) -> vec3<f32> {
115 return (((x * 34.) + 1.) * x) % vec3(289.);
Contents