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// A shader that creates water ripples by overlaying 4 normal maps on top of one
2// another.
3//
4// This is used in the `ssr` example. It only supports deferred rendering.
6#import bevy_pbr::{
7 pbr_deferred_functions::deferred_output,
8 pbr_fragment::pbr_input_from_standard_material,
9 prepass_io::{VertexOutput, FragmentOutput},
11#import bevy_render::globals::Globals
13// Parameters to the water shader.
14struct WaterSettings {
15 // How much to displace each octave each frame, in the u and v directions.
16 // Two octaves are packed into each `vec4`.
17 octave_vectors: array<vec4<f32>, 2>,
18 // How wide the waves are in each octave.
19 octave_scales: vec4<f32>,
20 // How high the waves are in each octave.
21 octave_strengths: vec4<f32>,
24@group(0) @binding(1) var<uniform> globals: Globals;
26@group(#{MATERIAL_BIND_GROUP}) @binding(100) var water_normals_texture: texture_2d<f32>;
27@group(#{MATERIAL_BIND_GROUP}) @binding(101) var water_normals_sampler: sampler;
28@group(#{MATERIAL_BIND_GROUP}) @binding(102) var<uniform> water_settings: WaterSettings;
30// Samples a single octave of noise and returns the resulting normal.
31fn sample_noise_octave(uv: vec2<f32>, strength: f32) -> vec3<f32> {
32 let N = textureSample(water_normals_texture, water_normals_sampler, uv).rbg * 2.0 - 1.0;
33 // This isn't slerp, but it's good enough.
34 return normalize(mix(vec3(0.0, 1.0, 0.0), N, strength));
37// Samples all four octaves of noise and returns the resulting normal.
38fn sample_noise(uv: vec2<f32>, time: f32) -> vec3<f32> {
39 let uv0 = uv * water_settings.octave_scales[0] + water_settings.octave_vectors[0].xy * time;
40 let uv1 = uv * water_settings.octave_scales[1] + water_settings.octave_vectors[0].zw * time;
41 let uv2 = uv * water_settings.octave_scales[2] + water_settings.octave_vectors[1].xy * time;
42 let uv3 = uv * water_settings.octave_scales[3] + water_settings.octave_vectors[1].zw * time;
43 return normalize(
44 sample_noise_octave(uv0, water_settings.octave_strengths[0]) +
45 sample_noise_octave(uv1, water_settings.octave_strengths[1]) +
46 sample_noise_octave(uv2, water_settings.octave_strengths[2]) +
47 sample_noise_octave(uv3, water_settings.octave_strengths[3])
48 );
51@fragment
52fn fragment(in: VertexOutput, @builtin(front_facing) is_front: bool) -> FragmentOutput {
53 // Create the PBR input.
54 var pbr_input = pbr_input_from_standard_material(in, is_front);
55 // Bump the normal.
56 pbr_input.N = sample_noise(in.uv, globals.time);
57 // Send the rest to the deferred shader.
58 return deferred_output(in, pbr_input);
Contents