An Interest In:
Web News this Week
- April 24, 2024
- April 23, 2024
- April 22, 2024
- April 21, 2024
- April 20, 2024
- April 19, 2024
- April 18, 2024
December 14, 2021 01:46 pm GMT
Original Link: https://dev.to/nordicbeaver/making-rain-animation-with-webgl-shaders-in-threejs-4ic5
Making a rain animation with WebGL shaders in Three.js.
I made a small shader that resembles rain on a window. You can try it here.
Check out the full code here:
The most interesting part is the fragment shader, where the magic happens. I tried to add some comments, so it's easier to read.
in vec2 uvInterpolator;uniform float u_time;uniform sampler2D u_texture;// Generate a random float from a single input and seed.float Random11(float inputValue, float seed) { return fract(sin(inputValue * 345.456) * seed);}// Generate a random float from a 2d input and seed.float Random21(vec2 inputValue, float seed) { return fract(sin(dot(inputValue, vec2(123.456, 43.12))) * seed);}// Generate drops as distortions, that can be applied to UV coordinatesvec2 Drops(vec2 uv, float seed) { // Randmply move everything float shiftY = Random11(0.5, seed); uv.y += shiftY; // Split UV spac into cells. Each cell will contain a drop. float cellsResolution = 10.0; uv *= cellsResolution; // Move each row randomly. float rowIndex = floor(uv.y); float shiftX = Random11(rowIndex, seed); uv.x += shiftX; vec2 cellIndex = floor(uv); vec2 cellUv = fract(uv); vec2 cellCenter = vec2(0.5); float distanceFromCenter = distance(cellUv, cellCenter); // We don't want to show every drop. So randomly remove some of them. float isDropShown = step(0.8, Random21(cellIndex, seed + 14244.324)); // Decrease each drop intensity with time. Then make it appear again. float dropIntensity = 1.0 - fract(u_time * 0.1 + Random21(cellIndex, seed + 32132.432) * 2.0) * 2.0; dropIntensity = sign(dropIntensity) * abs(dropIntensity * dropIntensity * dropIntensity * dropIntensity); dropIntensity = clamp(dropIntensity, 0.0, 1.0); // We only need results from inside a specefec radius of a drop. float isInsideDrop = 1.0 - step(0.1, distanceFromCenter); vec2 vecToCenter = normalize(cellCenter - cellUv); // Drop value is a vector to the center that increases with distance form it. vec2 dropValue = vecToCenter * distanceFromCenter * distanceFromCenter * 40.0; vec2 drop = dropValue * isInsideDrop * isDropShown * dropIntensity; return drop;}void main() { vec2 uv = uvInterpolator; // Run the Drop function 10 times to create seemingly random pattern. vec2 drops = vec2(0.0); for(int i = 0; i < 10; i++) { drops += Drops(uv, 42424.43 + float(i) * 12313.432); } // Distort UV. uv += drops; // Sample the texture after distorting the UV space. vec4 color = texture2D(u_texture, uv); gl_FragColor = color;}
Basically, all I do is generate drops at random positions. For every pixel around the drop I then calculate how much I need to distort the background. And then I apply the distortion to the UV space and sample the texture with the updated coordinates.
It's way easier to explain visually, so I made a video of the whole process of making this.
Original Link: https://dev.to/nordicbeaver/making-rain-animation-with-webgl-shaders-in-threejs-4ic5
Share this article:
Tweet
View Full Article
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To