Skip to content

Commit 1e8ae9c

Browse files
authored
Merge pull request #19 from ThomasAbbink/fbm-grass
created new fbm grass sketch
2 parents c418900 + 5d66658 commit 1e8ae9c

File tree

4 files changed

+143
-0
lines changed

4 files changed

+143
-0
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { getCanvasSize } from '../../../utility/canvas'
2+
import { backgroundColor } from '../../../style/colors'
3+
import p5 from 'p5'
4+
5+
import vert from './shader.vert'
6+
import frag from './shader.frag'
7+
8+
const fmbGrass = (p5: p5) => {
9+
let shader: p5.Shader
10+
const { width, height } = getCanvasSize()
11+
p5.setup = () => {
12+
const { width, height } = getCanvasSize()
13+
p5.createCanvas(width, height, p5.WEBGL)
14+
p5.background(backgroundColor)
15+
p5.pixelDensity(1)
16+
shader = p5.createShader(vert, frag)
17+
}
18+
19+
p5.windowResized = () => {
20+
const { width, height } = getCanvasSize()
21+
p5.resizeCanvas(width, height)
22+
}
23+
24+
p5.draw = () => {
25+
shader.setUniform('u_resolution', [width, height])
26+
shader.setUniform('u_time', p5.frameCount * 0.02)
27+
p5.shader(shader)
28+
p5.rect(0, 0, width, height)
29+
}
30+
}
31+
32+
fmbGrass.date = '2025-2-28'
33+
export { fmbGrass }
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#ifdef GL_ES
2+
precision mediump float;
3+
#endif
4+
5+
// Import fbm from Lygia
6+
#include "/node_modules/lygia/generative/fbm.glsl"
7+
8+
uniform vec2 u_resolution;
9+
uniform float u_time;
10+
11+
void main() {
12+
vec2 st = gl_FragCoord.xy / u_resolution.xy;
13+
vec3 color = vec3(0.1294, 0.1294, 0.1569);
14+
15+
// Number of tentacles
16+
const int numLines = 100;
17+
18+
// Base line width (thicker lines)
19+
float baseLineWidth = 3.0 / u_resolution.x;
20+
21+
// For each tentacle
22+
for(int i = 0; i < numLines; i++) {
23+
// Calculate position with non-uniform spacing
24+
float t = float(i) / float(numLines - 1);
25+
26+
// Restrict tentacles to the center portion of the screen
27+
// Map t from [0,1] to [0.2,0.8] to leave edges empty
28+
float centerMargin = 0.1; // 20% margin on each side
29+
float restrictedT = mix(centerMargin, 1.0 - centerMargin, t);
30+
31+
// Add some non-uniform variation within the center area
32+
float linePosition = restrictedT + 0.04 * sin(t * 6.28) + 0.02 * sin(t * 12.56);
33+
34+
// Ensure linePosition stays within our desired range
35+
linePosition = clamp(linePosition, centerMargin, 1.0 - centerMargin);
36+
37+
// Normalize y coordinate for the full screen height
38+
float normalizedY = st.y;
39+
40+
// Vary the amplitude slightly for each tentacle
41+
float amplitude = 0.25 + normalizedY / 3.0;
42+
amplitude *= 1.2 + 0.8 * sin(linePosition * 6.28 + u_time * 0.5);
43+
44+
// Create a variable speed for the frequency change
45+
float timeScale = 1.0 + 1.5 * fbm(vec2(u_time * 0.2 + linePosition, 0.0));
46+
47+
// Combine slow and fast movements with phase offset based on position
48+
float slowComponent = sin(u_time * 0.5 + linePosition * 5.0);
49+
float fastComponent = sin(u_time * 3.0 + linePosition * 4.0);
50+
51+
// Mix between slow and fast movement
52+
float mixFactor = 0.5 + 0.5 * sin(u_time * 0.15 + linePosition);
53+
float frequency = 0.8 * mix(slowComponent, fastComponent, mixFactor) * normalizedY;
54+
55+
// Calculate the center of this tentacle
56+
float baseX = linePosition;
57+
float waveCenterX = baseX + amplitude * frequency * 0.5;
58+
59+
// Vary line width slightly
60+
float lineWidth = baseLineWidth * (1.2 + 0.6 * sin(linePosition * 8.0));
61+
62+
// Calculate distance to the wave center for glow effect
63+
float distToCenter = abs(st.x - waveCenterX);
64+
65+
// Create a wider glow effect with time-based variation
66+
float glowPulse = 8.0 + 4.0 * sin(u_time * 0.8 + linePosition * 6.28);
67+
float glowWidth = lineWidth * glowPulse;
68+
float glow = smoothstep(glowWidth, 0.0, distToCenter);
69+
70+
// Apply vertical fade to the glow - stronger at the bottom, fading as it goes up
71+
float verticalFade = smoothstep(1.0, 0.0, st.y);
72+
glow *= mix(0.6, 1.0, verticalFade);
73+
74+
// Create the main line with smooth edges
75+
float line = smoothstep(waveCenterX - lineWidth/2.0, waveCenterX, st.x) -
76+
smoothstep(waveCenterX, waveCenterX + lineWidth/2.0, st.x);
77+
78+
// Vary color slightly based on position
79+
vec3 neonColor = vec3(1.0, 0.41, 0.0);
80+
// Add slight hue variation
81+
neonColor = mix(neonColor, vec3(1.0, 0.2, 0.6), sin(linePosition * 3.14) * 0.5 + 0.5);
82+
83+
// Apply the glow and the line
84+
color = mix(color, neonColor * 0.7, glow * 0.7);
85+
color = mix(color, neonColor, line);
86+
}
87+
88+
gl_FragColor = vec4(color, 1.0);
89+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#ifdef GL_ES
2+
precision mediump float;
3+
#endif
4+
5+
attribute vec3 aPosition;
6+
7+
// Always include this to get the position of the pixel and map the shader correctly onto the shape
8+
9+
10+
void main() {
11+
12+
// Copy the position data into a vec4, adding 1.0 as the w parameter
13+
vec4 positionVec4 = vec4(aPosition, 1.0);
14+
15+
// Scale to make the output fit the canvas
16+
positionVec4.xy = positionVec4.xy * 2.0 - 1.0;
17+
18+
// Send the vertex information on to the fragment shader
19+
gl_Position = positionVec4;
20+
}

src/sketches/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ export { bezierLines } from './generative/bezier-lines'
2222
export { fbmFire } from './generative/fbm-fire/fbm-fire'
2323
export { fbmGrid } from './generative/fbm-grid/fbm-grid'
2424
export { fbmBlob } from './generative/fbm-blob/fbm-blob'
25+
export { fmbGrass } from './generative/fbm-grass/fbm-grass'

0 commit comments

Comments
 (0)