Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const vertShader = `
- precision highp float;
- attribute vec3 aPosition;
- attribute vec2 aTexCoord;
- varying vec2 vTexCoord;
- void main() {
- vTexCoord = aTexCoord;
- vec4 positionVec4 = vec4(aPosition, 1.0);
- positionVec4.xy = positionVec4.xy * 2.0 - 1.0;
- gl_Position = positionVec4;
- }
- `;
- const fragShader = `
- precision highp float;
- varying vec2 vTexCoord;
- uniform vec2 u_resolution;
- uniform float u_time;
- // 2D Random pseudo-number generator
- vec2 random2(vec2 st){
- st = vec2(dot(st,vec2(127.1,311.7)), dot(st,vec2(269.5,183.3)));
- return -1.0 + 2.0*fract(sin(st)*43758.5453123);
- }
- // 2D Noise function
- float noise(vec2 st) {
- vec2 i = floor(st);
- vec2 f = fract(st);
- vec2 u = f*f*(3.0-2.0*f);
- return mix( mix( dot( random2(i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
- dot( random2(i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
- mix( dot( random2(i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
- dot( random2(i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
- }
- // Fractional Brownian Motion (fBm) with a "ridge" modifier for web-like cracks
- float ridgeFBM(vec2 uv) {
- float total = 0.0;
- float amp = 0.6;
- float freq = 2.0;
- // Diagonal flow matrix
- mat2 m = mat2( 0.80, 0.60, -0.60, 0.80 );
- for(int i = 0; i < 5; i++) {
- // Calculate noise and invert it to get sharp ridges
- float n = noise(uv * freq + u_time * 0.15);
- n = 1.0 - abs(n); // sharp ridges
- n = n * n; // sharpen falloff, makes lines thinner
- total += n * amp;
- uv = m * uv; // rotate for organic diagonal variation
- freq *= 2.0;
- amp *= 0.5;
- }
- return total;
- }
- // Smooth undulating noise for the underlying water/bed geometry
- float smoothFBM(vec2 uv) {
- float total = 0.0;
- float amp = 0.5;
- float freq = 1.0;
- for(int i = 0; i < 3; i++) {
- total += noise(uv * freq - u_time * 0.05) * amp;
- freq *= 2.0;
- amp *= 0.5;
- }
- return total;
- }
- void main() {
- vec2 uv = gl_FragCoord.xy / u_resolution.xy;
- // Correct aspect ratio
- uv.x *= u_resolution.x / u_resolution.y;
- // Apply global diagonal rotation to the coordinates
- // to match the top-left to bottom-right flow in the video
- float angle = 0.785398; // ~45 degrees
- mat2 rot = mat2(cos(angle), -sin(angle), sin(angle), cos(angle));
- vec2 rotatedUV = rot * uv;
- // Stretch the UVs slightly on one axis to create long striations
- rotatedUV.x *= 0.5;
- rotatedUV.y *= 1.5;
- // Generate patterns
- float smoothVolume = smoothFBM(rotatedUV * 1.5);
- float ridges = ridgeFBM(rotatedUV * 1.2);
- // Color Palette based on the video (Deep dark greens to pale teal)
- vec3 darkGreen = vec3(0.04, 0.14, 0.13);
- vec3 midGreen = vec3(0.09, 0.28, 0.26);
- vec3 lightTeal = vec3(0.2, 0.45, 0.42);
- vec3 brightCaustic = vec3(0.5, 0.7, 0.65);
- // Light gradient across the screen (light source top left)
- float gradientLight = smoothstep(1.5, -0.5, uv.x + uv.y);
- // Mix base colors using the smooth background noise
- vec3 color = mix(darkGreen, midGreen, smoothVolume + 0.5);
- // Add light direction gradient
- color = mix(color, lightTeal, gradientLight * 0.5 * (smoothVolume + 0.5));
- // Overlay the sharp ridged caustics
- // The ridges are multiplied by the gradient light so they fade out into the dark shadows
- float causticMask = smoothstep(0.1, 1.2, ridges) * (gradientLight + 0.2);
- color = mix(color, brightCaustic, causticMask * 0.8);
- gl_FragColor = vec4(color, 1.0);
- }
- `;
- let organicShader;
- function setup() {
- createCanvas(windowWidth, windowHeight, WEBGL);
- organicShader = createShader(vertShader, fragShader);
- noStroke();
- }
- function draw() {
- shader(organicShader);
- // Send uniforms (variables) to the shader
- organicShader.setUniform('u_resolution', [width, height]);
- organicShader.setUniform('u_time', millis() / 1000.0);
- // Draw a rectangle over the whole canvas to display the shader
- rect(0, 0, width, height);
- }
- function windowResized() {
- resizeCanvas(windowWidth, windowHeight);
- }
Advertisement
Add Comment
Please, Sign In to add comment