1+ shader_type canvas_item ;
2+
3+ uniform float fillLevel : hint_range (0.0 , 1.0 ) = 0.5 ;
4+ uniform float waveIntensity : hint_range (0.0 , 3.0 ) = 1.0 ;
5+ uniform sampler2D waveGradient ;
6+ uniform vec4 backWaveTint : source_color = vec4 (0.7 , 0.7 , 0.8 , 1.0 );
7+
8+ void fragment () {
9+ vec2 centeredUV = UV * 2.0 - 1.0 ;
10+
11+ vec4 outputColor = vec4 (0.0 , 0.0 , 0.0 , 1.0 );
12+
13+ //Only do stuff if the bar is filled
14+ if (fillLevel > 0.0 ) {
15+
16+ ////**** Gradient Texture Sampling ****////
17+
18+ //Gets the centered pos of the fillLevel
19+ float centeredFillLevel = mix (1.0 , - 1.0 , fillLevel );
20+
21+ //Calculate where we should sample the gradient for this section of the water
22+ float gradientPosition = fillLevel - (centeredUV .y - centeredFillLevel ) / 2.0 ;
23+
24+ //Finally get the color from the gradient
25+ vec4 sampledColorFromGradient = texture (waveGradient , vec2 (gradientPosition , 0.5 ));
26+
27+ ////**** Wave Sim ****////
28+
29+ float waveBase = smoothstep (0.1 , 0.9 , sin (centeredUV .x * 2.0 + PI * 0.5 ) - 0.3 );
30+
31+ float centerWaveAmp = 0.05 * waveIntensity ; //How much larger the center wave should be
32+ float mainWaveAmp = 0.04 * waveIntensity ; //Overall sin amplitude
33+ float surfaceRippleAmp = 0.03 * waveIntensity ; //How much the two waves should vary
34+ float verticalMovement = 0.03 * waveIntensity ; //How much it moves vertically
35+
36+ //Flatten stuff out if the bar is full
37+ if (fillLevel > 0.9999 ) {
38+ centerWaveAmp = 0.0 ;
39+ mainWaveAmp = 0.0 ;
40+ surfaceRippleAmp = 0.0 ;
41+ verticalMovement = 0.0 ;
42+ }
43+
44+ //How far from the the bottom the waves should appear
45+ float waveHeight = mix (1.0 , - 1.0 , fillLevel ) + sin (TIME * PI * 0.5 ) * verticalMovement ;
46+
47+ //Offset wave position and change direction
48+ float frontWaveYOffset = sin ((TIME * 2.0 + centeredUV .x * 3.0 ) * 2.0 ) * mainWaveAmp ;
49+ float backWaveYOffset = sin ((TIME * - 2.0 + centeredUV .x * 3.0 + PI ) * 2.0 ) * mainWaveAmp ;
50+
51+ //Calc surface ripples
52+ float surfaceAmplitudes = sin (TIME * 3.0 ) * surfaceRippleAmp * waveBase ;
53+
54+ //Final Y positions of the waves
55+ float frontWaveY = waveHeight - (surfaceAmplitudes + frontWaveYOffset );
56+ float backWaveY = waveHeight - (- surfaceAmplitudes + backWaveYOffset );
57+
58+ //Determine which wave is in front for this fragment
59+ float isBelowFrontWave = step (frontWaveY , centeredUV .y );
60+ float isBelowBackWave = step (backWaveY , centeredUV .y );
61+
62+ float backOnlyVisibility = clamp (isBelowBackWave - isBelowFrontWave , 0.0 , 1.0 );
63+
64+ if (isBelowFrontWave > 0.5 ) {
65+ outputColor = sampledColorFromGradient ; //Just assign the color
66+ } else if (backOnlyVisibility > 0.5 ) {
67+ outputColor = vec4 (sampledColorFromGradient .rgb * backWaveTint .rgb ,sampledColorFromGradient .a * backWaveTint .a );
68+ }
69+ }
70+
71+ COLOR = outputColor ;
72+ }
0 commit comments