shaderz 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,229 @@
1
+ 'use client';
2
+ import React, { useRef, useEffect } from 'react';
3
+
4
+ const OceanWavesShader: React.FC = () => {
5
+ const canvasRef = useRef<HTMLCanvasElement>(null);
6
+ const containerRef = useRef<HTMLDivElement>(null);
7
+ const animationRef = useRef<number | null>(null);
8
+
9
+ useEffect(() => {
10
+ const canvas = canvasRef.current;
11
+ const container = containerRef.current;
12
+ if (!canvas || !container) return;
13
+
14
+ const gl = canvas.getContext('webgl2') || canvas.getContext('webgl');
15
+ if (!gl) return;
16
+
17
+ const resizeCanvas = () => {
18
+ const rect = container.getBoundingClientRect();
19
+ canvas.width = rect.width;
20
+ canvas.height = rect.height;
21
+ gl.viewport(0, 0, canvas.width, canvas.height);
22
+ };
23
+
24
+ resizeCanvas();
25
+ window.addEventListener('resize', resizeCanvas);
26
+
27
+ const vertexShaderSource = `
28
+ attribute vec2 position;
29
+ void main() {
30
+ gl_Position = vec4(position, 0.0, 1.0);
31
+ }
32
+ `;
33
+
34
+ const fragmentShaderSource = `
35
+ precision highp float;
36
+ uniform vec2 resolution;
37
+ uniform float time;
38
+
39
+ // Hash function for pseudo-random values
40
+ float hash(vec2 p) {
41
+ p = fract(p * vec2(123.34, 456.21));
42
+ p += dot(p, p + 45.32);
43
+ return fract(p.x * p.y);
44
+ }
45
+
46
+ // 2D noise function
47
+ float noise(vec2 p) {
48
+ vec2 i = floor(p);
49
+ vec2 f = fract(p);
50
+ f = f * f * (3.0 - 2.0 * f);
51
+
52
+ float a = hash(i);
53
+ float b = hash(i + vec2(1.0, 0.0));
54
+ float c = hash(i + vec2(0.0, 1.0));
55
+ float d = hash(i + vec2(1.0, 1.0));
56
+
57
+ return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
58
+ }
59
+
60
+ // Fractal Brownian Motion
61
+ float fbm(vec2 p) {
62
+ float value = 0.0;
63
+ float amplitude = 0.5;
64
+ float frequency = 1.0;
65
+
66
+ for(int i = 0; i < 6; i++) {
67
+ value += amplitude * noise(p * frequency);
68
+ frequency *= 2.0;
69
+ amplitude *= 0.5;
70
+ }
71
+ return value;
72
+ }
73
+
74
+ // Ocean wave function
75
+ float wave(vec2 p, float time) {
76
+ float w = 0.0;
77
+
78
+ // Large rolling waves
79
+ w += sin(p.x * 0.5 + time * 0.3) * 0.3;
80
+ w += sin(p.x * 0.3 - p.y * 0.2 + time * 0.2) * 0.2;
81
+
82
+ // Medium waves
83
+ w += sin(p.x * 1.0 + p.y * 0.5 + time * 0.5) * 0.15;
84
+ w += sin(p.x * 1.5 - p.y * 0.8 + time * 0.4) * 0.1;
85
+
86
+ // Small ripples
87
+ w += fbm(p * 2.0 + vec2(time * 0.1, time * 0.05)) * 0.1;
88
+
89
+ return w;
90
+ }
91
+
92
+ void main() {
93
+ vec2 uv = gl_FragCoord.xy / resolution.xy;
94
+ vec2 p = (uv - 0.5) * 2.0;
95
+ p.x *= resolution.x / resolution.y;
96
+
97
+ // Create wave motion
98
+ float waves = wave(p * 2.0, time);
99
+
100
+ // Add foam patterns
101
+ float foam = fbm(p * 4.0 + vec2(time * 0.2, waves * 2.0));
102
+ foam = smoothstep(0.5, 0.7, foam);
103
+
104
+ // Ocean colors
105
+ vec3 deepWater = vec3(0.0, 0.2, 0.4); // Deep blue
106
+ vec3 shallowWater = vec3(0.0, 0.4, 0.6); // Lighter blue
107
+ vec3 foamColor = vec3(0.7, 0.9, 1.0); // White-blue foam
108
+
109
+ // Mix colors based on wave height
110
+ float waveHeight = waves * 0.5 + 0.5;
111
+ vec3 color = mix(deepWater, shallowWater, waveHeight);
112
+
113
+ // Add foam highlights
114
+ color = mix(color, foamColor, foam * 0.4);
115
+
116
+ // Add depth gradient
117
+ float depth = smoothstep(0.0, 1.0, 1.0 - uv.y);
118
+ color = mix(color, deepWater, depth * 0.3);
119
+
120
+ // Add shimmer effect
121
+ float shimmer = fbm(p * 8.0 + vec2(time * 0.5, time * 0.3));
122
+ shimmer = pow(shimmer, 3.0) * 0.2;
123
+ color += vec3(shimmer);
124
+
125
+ // Vignette effect
126
+ float vignette = 1.0 - length(uv - 0.5) * 0.5;
127
+ color *= vignette;
128
+
129
+ gl_FragColor = vec4(color, 1.0);
130
+ }
131
+ `;
132
+
133
+ const createShader = (gl: WebGLRenderingContext, type: number, source: string) => {
134
+ const shader = gl.createShader(type);
135
+ if (!shader) return null;
136
+
137
+ gl.shaderSource(shader, source);
138
+ gl.compileShader(shader);
139
+
140
+ if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
141
+ console.error('Shader compile error:', gl.getShaderInfoLog(shader));
142
+ gl.deleteShader(shader);
143
+ return null;
144
+ }
145
+
146
+ return shader;
147
+ };
148
+
149
+ const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
150
+ const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
151
+
152
+ if (!vertexShader || !fragmentShader) return;
153
+
154
+ const program = gl.createProgram();
155
+ if (!program) return;
156
+
157
+ gl.attachShader(program, vertexShader);
158
+ gl.attachShader(program, fragmentShader);
159
+ gl.linkProgram(program);
160
+
161
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
162
+ console.error('Program link error:', gl.getProgramInfoLog(program));
163
+ return;
164
+ }
165
+
166
+ const positionBuffer = gl.createBuffer();
167
+ gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
168
+ gl.bufferData(
169
+ gl.ARRAY_BUFFER,
170
+ new Float32Array([
171
+ -1, -1,
172
+ 1, -1,
173
+ -1, 1,
174
+ 1, 1,
175
+ ]),
176
+ gl.STATIC_DRAW
177
+ );
178
+
179
+ const positionLocation = gl.getAttribLocation(program, 'position');
180
+ const resolutionLocation = gl.getUniformLocation(program, 'resolution');
181
+ const timeLocation = gl.getUniformLocation(program, 'time');
182
+
183
+ let startTime = Date.now();
184
+
185
+ const render = () => {
186
+ if (!gl || !canvas) return;
187
+
188
+ gl.clearColor(0, 0, 0, 1);
189
+ gl.clear(gl.COLOR_BUFFER_BIT);
190
+
191
+ gl.useProgram(program);
192
+
193
+ gl.enableVertexAttribArray(positionLocation);
194
+ gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
195
+ gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
196
+
197
+ gl.uniform2f(resolutionLocation, canvas.width, canvas.height);
198
+ gl.uniform1f(timeLocation, (Date.now() - startTime) / 1000);
199
+
200
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
201
+
202
+ animationRef.current = requestAnimationFrame(render);
203
+ };
204
+
205
+ render();
206
+
207
+ return () => {
208
+ window.removeEventListener('resize', resizeCanvas);
209
+ if (animationRef.current) {
210
+ cancelAnimationFrame(animationRef.current);
211
+ }
212
+ gl.deleteProgram(program);
213
+ gl.deleteShader(vertexShader);
214
+ gl.deleteShader(fragmentShader);
215
+ gl.deleteBuffer(positionBuffer);
216
+ };
217
+ }, []);
218
+
219
+ return (
220
+ <div ref={containerRef} className="absolute inset-0 w-full h-full bg-black overflow-hidden">
221
+ <canvas
222
+ ref={canvasRef}
223
+ className="absolute top-0 left-0 w-full h-full"
224
+ />
225
+ </div>
226
+ );
227
+ };
228
+
229
+ export default OceanWavesShader;
@@ -0,0 +1,174 @@
1
+ 'use client';
2
+ import { useEffect, useRef } from 'react';
3
+
4
+ function PlasmaShader() {
5
+ const canvasRef = useRef<HTMLCanvasElement>(null);
6
+ const glRef = useRef<WebGLRenderingContext | null>(null);
7
+ const programRef = useRef<WebGLProgram | null>(null);
8
+ const animationRef = useRef<number | null>(null);
9
+
10
+ useEffect(() => {
11
+ const canvas = canvasRef.current;
12
+ if (!canvas) return;
13
+
14
+ const gl = canvas.getContext('webgl');
15
+ glRef.current = gl;
16
+
17
+ if (!gl) {
18
+ console.error('WebGL not supported');
19
+ return;
20
+ }
21
+
22
+ const resizeCanvas = () => {
23
+ canvas.width = window.innerWidth;
24
+ canvas.height = window.innerHeight;
25
+ gl.viewport(0, 0, canvas.width, canvas.height);
26
+ };
27
+
28
+ resizeCanvas();
29
+ window.addEventListener('resize', resizeCanvas);
30
+
31
+ const vertexShaderSource = `
32
+ attribute vec2 position;
33
+ void main() {
34
+ gl_Position = vec4(position, 0.0, 1.0);
35
+ }
36
+ `;
37
+
38
+ const fragmentShaderSource = `
39
+ precision highp float;
40
+ uniform vec2 resolution;
41
+ uniform float time;
42
+
43
+ vec3 plasma(vec2 uv, float time) {
44
+ float v = 0.0;
45
+ vec2 c = uv;
46
+
47
+ v += sin((c.x + time) * 2.0);
48
+ v += sin((c.y + time) * 3.0);
49
+ v += sin((c.x + c.y + time) * 2.0);
50
+
51
+ c += vec2(sin(time * 0.5) * 2.0, cos(time * 0.3) * 2.0);
52
+ v += sin(sqrt(c.x * c.x + c.y * c.y + 1.0) + time);
53
+
54
+ return vec3(
55
+ sin(v * 3.14159),
56
+ sin(v * 3.14159 + 2.094),
57
+ sin(v * 3.14159 + 4.188)
58
+ ) * 0.5 + 0.5;
59
+ }
60
+
61
+ void main() {
62
+ vec2 uv = (gl_FragCoord.xy - 0.5 * resolution.xy) / resolution.y;
63
+ uv *= 2.0;
64
+
65
+ vec3 color = plasma(uv, time * 0.8);
66
+
67
+ // Add some glow effect
68
+ float glow = 1.0 - length(uv) * 0.3;
69
+ color *= glow;
70
+
71
+ // Purple-pink gradient overlay
72
+ vec3 purpleGradient = mix(
73
+ vec3(0.4, 0.1, 0.8),
74
+ vec3(0.8, 0.2, 0.6),
75
+ (uv.y + 1.0) * 0.5
76
+ );
77
+
78
+ color = mix(color, purpleGradient, 0.3);
79
+
80
+ gl_FragColor = vec4(color, 0.9);
81
+ }
82
+ `;
83
+
84
+ const createShader = (gl: WebGLRenderingContext, type: number, source: string) => {
85
+ const shader = gl.createShader(type);
86
+ if (!shader) return null;
87
+
88
+ gl.shaderSource(shader, source);
89
+ gl.compileShader(shader);
90
+
91
+ if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
92
+ console.error('Shader compile error:', gl.getShaderInfoLog(shader));
93
+ gl.deleteShader(shader);
94
+ return null;
95
+ }
96
+ return shader;
97
+ };
98
+
99
+ const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
100
+ const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
101
+
102
+ if (!vertexShader || !fragmentShader) return;
103
+
104
+ const program = gl.createProgram();
105
+ if (!program) return;
106
+
107
+ gl.attachShader(program, vertexShader);
108
+ gl.attachShader(program, fragmentShader);
109
+ gl.linkProgram(program);
110
+
111
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
112
+ console.error('Program link error:', gl.getProgramInfoLog(program));
113
+ return;
114
+ }
115
+
116
+ programRef.current = program;
117
+
118
+ const positionBuffer = gl.createBuffer();
119
+ gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
120
+ const positions = new Float32Array([
121
+ -1, -1,
122
+ 1, -1,
123
+ -1, 1,
124
+ 1, 1
125
+ ]);
126
+ gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
127
+
128
+ const positionLocation = gl.getAttribLocation(program, 'position');
129
+ const resolutionLocation = gl.getUniformLocation(program, 'resolution');
130
+ const timeLocation = gl.getUniformLocation(program, 'time');
131
+
132
+ gl.enable(gl.BLEND);
133
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
134
+
135
+ const render = (time: number) => {
136
+ time *= 0.001;
137
+
138
+ gl.clearColor(0, 0, 0, 0);
139
+ gl.clear(gl.COLOR_BUFFER_BIT);
140
+ gl.useProgram(program);
141
+
142
+ gl.enableVertexAttribArray(positionLocation);
143
+ gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
144
+ gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
145
+
146
+ gl.uniform2f(resolutionLocation, canvas.width, canvas.height);
147
+ gl.uniform1f(timeLocation, time);
148
+
149
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
150
+
151
+ animationRef.current = requestAnimationFrame(render);
152
+ };
153
+
154
+ animationRef.current = requestAnimationFrame(render);
155
+
156
+ return () => {
157
+ window.removeEventListener('resize', resizeCanvas);
158
+ if (animationRef.current) {
159
+ cancelAnimationFrame(animationRef.current);
160
+ }
161
+ };
162
+ }, []);
163
+
164
+ return (
165
+ <div className="absolute inset-0 w-full h-full bg-black overflow-hidden">
166
+ <canvas
167
+ ref={canvasRef}
168
+ className="absolute top-0 left-0 w-full h-full pointer-events-none opacity-95"
169
+ />
170
+ </div>
171
+ );
172
+ }
173
+
174
+ export default PlasmaShader;
@@ -0,0 +1,281 @@
1
+ 'use client';
2
+ import React, { useRef, useEffect } from 'react';
3
+
4
+ const SilkFlowShader: React.FC = () => {
5
+ const canvasRef = useRef<HTMLCanvasElement>(null);
6
+ const containerRef = useRef<HTMLDivElement>(null);
7
+ const animationRef = useRef<number | null>(null);
8
+
9
+ useEffect(() => {
10
+ const canvas = canvasRef.current;
11
+ const container = containerRef.current;
12
+ if (!canvas || !container) return;
13
+
14
+ const gl = canvas.getContext('webgl2') || canvas.getContext('webgl');
15
+ if (!gl) return;
16
+
17
+ const resizeCanvas = () => {
18
+ const rect = container.getBoundingClientRect();
19
+ canvas.width = rect.width;
20
+ canvas.height = rect.height;
21
+ gl.viewport(0, 0, canvas.width, canvas.height);
22
+ };
23
+
24
+ resizeCanvas();
25
+ window.addEventListener('resize', resizeCanvas);
26
+
27
+ const vertexShaderSource = `
28
+ attribute vec2 position;
29
+ void main() {
30
+ gl_Position = vec4(position, 0.0, 1.0);
31
+ }
32
+ `;
33
+
34
+ const fragmentShaderSource = `
35
+ precision highp float;
36
+ uniform vec2 resolution;
37
+ uniform float time;
38
+
39
+ float hash(vec3 p) {
40
+ p = fract(p * 0.3183099 + 0.1);
41
+ p *= 17.0;
42
+ return fract(p.x * p.y * p.z * (p.x + p.y + p.z));
43
+ }
44
+
45
+ float noise(vec3 x) {
46
+ vec3 p = floor(x);
47
+ vec3 f = fract(x);
48
+ f = f * f * (3.0 - 2.0 * f);
49
+
50
+ return mix(
51
+ mix(mix(hash(p), hash(p + vec3(1,0,0)), f.x),
52
+ mix(hash(p + vec3(0,1,0)), hash(p + vec3(1,1,0)), f.x), f.y),
53
+ mix(mix(hash(p + vec3(0,0,1)), hash(p + vec3(1,0,1)), f.x),
54
+ mix(hash(p + vec3(0,1,1)), hash(p + vec3(1,1,1)), f.x), f.y),
55
+ f.z);
56
+ }
57
+
58
+ float fbm(vec3 p) {
59
+ float value = 0.0;
60
+ float amplitude = 0.5;
61
+
62
+ for(int i = 0; i < 6; i++) {
63
+ value += amplitude * noise(p);
64
+ p *= 2.0;
65
+ amplitude *= 0.5;
66
+ }
67
+ return value;
68
+ }
69
+
70
+ // Vertical silk ribbons
71
+ float silkRibbon(vec2 p, float offset, float time) {
72
+ float xPos = offset;
73
+
74
+ // Vertical flowing motion
75
+ float flow = p.y - time * 0.5;
76
+
77
+ // Wavy horizontal displacement
78
+ float wave = sin(flow * 3.0 + offset * 5.0) * 0.15;
79
+ wave += sin(flow * 5.0 - offset * 3.0) * 0.08;
80
+
81
+ // Distance from ribbon center
82
+ float dist = abs(p.x - (xPos + wave));
83
+
84
+ // Ribbon width
85
+ float width = 0.12 + sin(flow * 2.0 + offset) * 0.03;
86
+
87
+ return smoothstep(width, width * 0.3, dist);
88
+ }
89
+
90
+ void main() {
91
+ vec2 uv = gl_FragCoord.xy / resolution.xy;
92
+ vec2 p = (uv - 0.5) * 2.0;
93
+ p.x *= resolution.x / resolution.y;
94
+
95
+ float t = time * 0.4;
96
+
97
+ // Add subtle noise distortion
98
+ vec3 noisePos = vec3(p * 2.0, t * 0.3);
99
+ float noiseVal = fbm(noisePos) - 0.5;
100
+ vec2 distorted = p + vec2(noiseVal * 0.1);
101
+
102
+ // Create multiple silk ribbons
103
+ vec3 finalColor = vec3(0.0);
104
+ float totalMask = 0.0;
105
+
106
+ float ribbonOffsets[7];
107
+ ribbonOffsets[0] = -0.9;
108
+ ribbonOffsets[1] = -0.6;
109
+ ribbonOffsets[2] = -0.3;
110
+ ribbonOffsets[3] = 0.0;
111
+ ribbonOffsets[4] = 0.3;
112
+ ribbonOffsets[5] = 0.6;
113
+ ribbonOffsets[6] = 0.9;
114
+
115
+ for(int i = 0; i < 7; i++) {
116
+ float offset = ribbonOffsets[i];
117
+ float fi = float(i);
118
+
119
+ // Calculate ribbon with individual time offset
120
+ float ribbon = silkRibbon(distorted, offset, t + fi * 0.3);
121
+
122
+ // Flow position for color
123
+ float flowPos = distorted.y - t * 0.5 + fi * 0.5;
124
+
125
+ // Color gradient - blue to magenta
126
+ vec3 blueColor = vec3(0.0, 0.3, 1.0); // Bright blue
127
+ vec3 cyanColor = vec3(0.0, 0.7, 1.0); // Cyan
128
+ vec3 magentaColor = vec3(1.0, 0.0, 0.8); // Magenta
129
+ vec3 purpleColor = vec3(0.6, 0.1, 1.0); // Purple
130
+
131
+ // Vertical gradient based on flow
132
+ float colorPhase = fract(flowPos * 0.5);
133
+ vec3 color = mix(blueColor, cyanColor, colorPhase);
134
+ color = mix(color, magentaColor, smoothstep(0.3, 0.7, colorPhase));
135
+ color = mix(color, purpleColor, smoothstep(0.7, 1.0, colorPhase));
136
+
137
+ // Add position-based variation
138
+ float posVariation = sin(offset * 10.0 + t) * 0.5 + 0.5;
139
+ color = mix(color, magentaColor, posVariation * 0.3);
140
+
141
+ // Silk sheen effect - bright highlights
142
+ float sheen = pow(abs(sin(flowPos * 8.0 + offset * 5.0)), 6.0);
143
+ vec3 sheenColor = vec3(0.8, 0.9, 1.0);
144
+ color += sheenColor * sheen * ribbon * 0.5;
145
+
146
+ // Edge glow
147
+ float edgeDist = ribbon * (1.0 - ribbon) * 4.0;
148
+ vec3 edgeColor = mix(cyanColor, magentaColor, posVariation);
149
+ color += edgeColor * edgeDist * 0.4;
150
+
151
+ // Translucent layering
152
+ finalColor = mix(finalColor, color, ribbon * 0.85);
153
+ totalMask += ribbon * 0.3;
154
+ }
155
+
156
+ // Add flowing particles/streaks
157
+ float streaks = 0.0;
158
+ for(int i = 0; i < 5; i++) {
159
+ float fi = float(i);
160
+ float streakX = sin(t * 0.7 + fi * 2.0) * 1.5;
161
+ float streakY = fract((distorted.y + t * 0.8 + fi * 0.2) * 0.5) * 4.0 - 2.0;
162
+
163
+ float streakDist = length(distorted - vec2(streakX, streakY));
164
+ streaks += (1.0 - smoothstep(0.0, 0.05, streakDist)) * 0.3;
165
+ }
166
+
167
+ finalColor += vec3(0.6, 0.8, 1.0) * streaks;
168
+
169
+ // Subtle shimmer
170
+ float shimmer = fbm(vec3(distorted * 6.0, t * 2.0));
171
+ shimmer = pow(shimmer, 5.0);
172
+ finalColor += vec3(0.7, 0.6, 1.0) * shimmer * totalMask * 0.2;
173
+
174
+ // Vignette
175
+ float vignette = 1.0 - length(vec2(uv.x - 0.5, (uv.y - 0.5) * 0.7)) * 0.5;
176
+ finalColor *= vignette;
177
+
178
+ // Enhance colors
179
+ finalColor *= 1.15;
180
+
181
+ gl_FragColor = vec4(finalColor, 1.0);
182
+ }
183
+ `;
184
+
185
+ const createShader = (gl: WebGLRenderingContext, type: number, source: string) => {
186
+ const shader = gl.createShader(type);
187
+ if (!shader) return null;
188
+
189
+ gl.shaderSource(shader, source);
190
+ gl.compileShader(shader);
191
+
192
+ if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
193
+ console.error('Shader compile error:', gl.getShaderInfoLog(shader));
194
+ gl.deleteShader(shader);
195
+ return null;
196
+ }
197
+
198
+ return shader;
199
+ };
200
+
201
+ const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
202
+ const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
203
+
204
+ if (!vertexShader || !fragmentShader) return;
205
+
206
+ const program = gl.createProgram();
207
+ if (!program) return;
208
+
209
+ gl.attachShader(program, vertexShader);
210
+ gl.attachShader(program, fragmentShader);
211
+ gl.linkProgram(program);
212
+
213
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
214
+ console.error('Program link error:', gl.getProgramInfoLog(program));
215
+ return;
216
+ }
217
+
218
+ const positionBuffer = gl.createBuffer();
219
+ gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
220
+ gl.bufferData(
221
+ gl.ARRAY_BUFFER,
222
+ new Float32Array([
223
+ -1, -1,
224
+ 1, -1,
225
+ -1, 1,
226
+ 1, 1,
227
+ ]),
228
+ gl.STATIC_DRAW
229
+ );
230
+
231
+ const positionLocation = gl.getAttribLocation(program, 'position');
232
+ const resolutionLocation = gl.getUniformLocation(program, 'resolution');
233
+ const timeLocation = gl.getUniformLocation(program, 'time');
234
+
235
+ let startTime = Date.now();
236
+
237
+ const render = () => {
238
+ if (!gl || !canvas) return;
239
+
240
+ gl.clearColor(0, 0, 0, 1);
241
+ gl.clear(gl.COLOR_BUFFER_BIT);
242
+
243
+ gl.useProgram(program);
244
+
245
+ gl.enableVertexAttribArray(positionLocation);
246
+ gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
247
+ gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
248
+
249
+ gl.uniform2f(resolutionLocation, canvas.width, canvas.height);
250
+ gl.uniform1f(timeLocation, (Date.now() - startTime) / 1000);
251
+
252
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
253
+
254
+ animationRef.current = requestAnimationFrame(render);
255
+ };
256
+
257
+ render();
258
+
259
+ return () => {
260
+ window.removeEventListener('resize', resizeCanvas);
261
+ if (animationRef.current) {
262
+ cancelAnimationFrame(animationRef.current);
263
+ }
264
+ gl.deleteProgram(program);
265
+ gl.deleteShader(vertexShader);
266
+ gl.deleteShader(fragmentShader);
267
+ gl.deleteBuffer(positionBuffer);
268
+ };
269
+ }, []);
270
+
271
+ return (
272
+ <div ref={containerRef} className="absolute inset-0 w-full h-full bg-black overflow-hidden">
273
+ <canvas
274
+ ref={canvasRef}
275
+ className="absolute top-0 left-0 w-full h-full"
276
+ />
277
+ </div>
278
+ );
279
+ };
280
+
281
+ export default SilkFlowShader;