@clypra-studio/shaders 0.1.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.
- package/.turbo/turbo-build.log +23 -0
- package/.turbo/turbo-lint.log +4 -0
- package/.turbo/turbo-test.log +13 -0
- package/.turbo/turbo-typecheck.log +4 -0
- package/CHANGELOG.md +9 -0
- package/LICENSE +9 -0
- package/README.md +106 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +247 -0
- package/dist/index.js.map +1 -0
- package/dist/noise/index.d.ts +29 -0
- package/dist/noise/index.js +150 -0
- package/dist/noise/index.js.map +1 -0
- package/dist/utils/index.d.ts +19 -0
- package/dist/utils/index.js +97 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +46 -0
- package/src/index.ts +23 -0
- package/src/noise/index.ts +167 -0
- package/src/utils/index.ts +109 -0
- package/tsconfig.json +21 -0
- package/tsup.config.ts +15 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
|
|
2
|
+
> @clypra-studio/shaders@0.1.0 build /home/runner/work/clypra-studio/clypra-studio/packages/shaders
|
|
3
|
+
> tsup
|
|
4
|
+
|
|
5
|
+
[34mCLI[39m Building entry: {"index":"src/index.ts","utils/index":"src/utils/index.ts","noise/index":"src/noise/index.ts"}
|
|
6
|
+
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
7
|
+
[34mCLI[39m tsup v8.5.1
|
|
8
|
+
[34mCLI[39m Using tsup config: /home/runner/work/clypra-studio/clypra-studio/packages/shaders/tsup.config.ts
|
|
9
|
+
[34mCLI[39m Target: es2022
|
|
10
|
+
[34mCLI[39m Cleaning output folder
|
|
11
|
+
[34mESM[39m Build start
|
|
12
|
+
[32mESM[39m [1mdist/index.js [22m[32m5.42 KB[39m
|
|
13
|
+
[32mESM[39m [1mdist/utils/index.js [22m[32m2.32 KB[39m
|
|
14
|
+
[32mESM[39m [1mdist/noise/index.js [22m[32m3.13 KB[39m
|
|
15
|
+
[32mESM[39m [1mdist/index.js.map [22m[32m7.99 KB[39m
|
|
16
|
+
[32mESM[39m [1mdist/utils/index.js.map [22m[32m3.17 KB[39m
|
|
17
|
+
[32mESM[39m [1mdist/noise/index.js.map [22m[32m4.33 KB[39m
|
|
18
|
+
[32mESM[39m ⚡️ Build success in 358ms
|
|
19
|
+
[34mDTS[39m Build start
|
|
20
|
+
[32mDTS[39m ⚡️ Build success in 4708ms
|
|
21
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m482.00 B[39m
|
|
22
|
+
[32mDTS[39m [1mdist/noise/index.d.ts [22m[32m3.43 KB[39m
|
|
23
|
+
[32mDTS[39m [1mdist/utils/index.d.ts [22m[32m2.51 KB[39m
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
|
|
2
|
+
> @clypra-studio/shaders@0.1.0 test /home/runner/work/clypra-studio/clypra-studio/packages/shaders
|
|
3
|
+
> vitest run
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
[1m[46m RUN [49m[22m [36mv3.2.6 [39m[90m/home/runner/work/clypra-studio/clypra-studio/packages/shaders[39m
|
|
7
|
+
|
|
8
|
+
[31mNo test files found, exiting with code 1
|
|
9
|
+
[39m
|
|
10
|
+
[2minclude: [22m[33m**/*.{test,spec}.?(c|m)[jt]s?(x)[39m
|
|
11
|
+
[2mexclude: [22m[33m**/node_modules/**[2m, [22m**/dist/**[2m, [22m**/cypress/**[2m, [22m**/.{idea,git,cache,output,temp}/**[2m, [22m**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*[39m
|
|
12
|
+
|
|
13
|
+
ELIFECYCLE Test failed. See above for more details.
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# @clypra-studio/shaders
|
|
2
|
+
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 2c117a9: Renamed package from @clypra-studio/shader-library to @clypra-studio/shaders
|
|
8
|
+
|
|
9
|
+
This is the initial release of @clypra-studio/shaders at 0.1.0, replacing the deprecated @clypra-studio/shader-library package.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Abdulkabir Musa(AIEraDev)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# @clypra-studio/shaders
|
|
2
|
+
|
|
3
|
+
Reusable GLSL shader library for video effects. A collection of high-performance shaders for common video processing tasks.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @clypra-studio/shaders
|
|
9
|
+
# or
|
|
10
|
+
pnpm add @clypra-studio/shaders
|
|
11
|
+
# or
|
|
12
|
+
yarn add @clypra-studio/shaders
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { createShader } from "@clypra-studio/shaders";
|
|
19
|
+
import { BlurShader } from "@clypra-studio/shaders/blur";
|
|
20
|
+
import { ColorShader } from "@clypra-studio/shaders/color";
|
|
21
|
+
import { NoiseShader } from "@clypra-studio/shaders/noise";
|
|
22
|
+
import { shaderUtils } from "@clypra-studio/shaders/utils";
|
|
23
|
+
|
|
24
|
+
// Use a pre-built shader
|
|
25
|
+
const blurShader = BlurShader.create({ radius: 10 });
|
|
26
|
+
|
|
27
|
+
// Combine shaders
|
|
28
|
+
const composite = shaderUtils.compose(ColorShader.saturation(1.2), BlurShader.gaussian(5));
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Features
|
|
32
|
+
|
|
33
|
+
- ✅ **Color Effects** - Saturation, hue, brightness, contrast
|
|
34
|
+
- ✅ **Blur Effects** - Gaussian, box, and directional blur
|
|
35
|
+
- ✅ **Distortion** - Warp, ripple, and displacement effects
|
|
36
|
+
- ✅ **Noise** - Perlin, simplex, and cellular noise
|
|
37
|
+
- ✅ **Composite** - Blend modes and compositing operations
|
|
38
|
+
- ✅ **Utils** - Shader composition and common utilities
|
|
39
|
+
- ✅ **TypeScript** - Full type definitions
|
|
40
|
+
- ✅ **Tree-shakeable** - Import only what you need
|
|
41
|
+
|
|
42
|
+
## Available Shaders
|
|
43
|
+
|
|
44
|
+
### Color Shaders (`/color`)
|
|
45
|
+
|
|
46
|
+
- Saturation adjustment
|
|
47
|
+
- Hue rotation
|
|
48
|
+
- Brightness control
|
|
49
|
+
- Contrast adjustment
|
|
50
|
+
- Color grading
|
|
51
|
+
|
|
52
|
+
### Blur Shaders (`/blur`)
|
|
53
|
+
|
|
54
|
+
- Gaussian blur
|
|
55
|
+
- Box blur
|
|
56
|
+
- Directional blur
|
|
57
|
+
- Radial blur
|
|
58
|
+
|
|
59
|
+
### Distortion Shaders (`/distortion`)
|
|
60
|
+
|
|
61
|
+
- Warp effects
|
|
62
|
+
- Ripple effects
|
|
63
|
+
- Displacement mapping
|
|
64
|
+
|
|
65
|
+
### Noise Shaders (`/noise`)
|
|
66
|
+
|
|
67
|
+
- Perlin noise
|
|
68
|
+
- Simplex noise
|
|
69
|
+
- Cellular noise
|
|
70
|
+
- Fractal noise
|
|
71
|
+
|
|
72
|
+
### Composite Shaders (`/composite`)
|
|
73
|
+
|
|
74
|
+
- Blend modes (multiply, screen, overlay, etc.)
|
|
75
|
+
- Alpha compositing
|
|
76
|
+
- Masking operations
|
|
77
|
+
|
|
78
|
+
### Utilities (`/utils`)
|
|
79
|
+
|
|
80
|
+
- Shader composition helpers
|
|
81
|
+
- Common GLSL functions
|
|
82
|
+
- Coordinate transformations
|
|
83
|
+
|
|
84
|
+
## Entry Points
|
|
85
|
+
|
|
86
|
+
- **`@clypra-studio/shaders`** - Main exports
|
|
87
|
+
- **`@clypra-studio/shaders/color`** - Color effects
|
|
88
|
+
- **`@clypra-studio/shaders/blur`** - Blur effects
|
|
89
|
+
- **`@clypra-studio/shaders/distortion`** - Distortion effects
|
|
90
|
+
- **`@clypra-studio/shaders/composite`** - Compositing operations
|
|
91
|
+
- **`@clypra-studio/shaders/noise`** - Noise generators
|
|
92
|
+
- **`@clypra-studio/shaders/utils`** - Utilities and helpers
|
|
93
|
+
|
|
94
|
+
## License
|
|
95
|
+
|
|
96
|
+
MIT
|
|
97
|
+
|
|
98
|
+
## Links
|
|
99
|
+
|
|
100
|
+
- [GitHub Repository](https://github.com/AIEraDev/clypra-studio)
|
|
101
|
+
- [Report Issues](https://github.com/AIEraDev/clypra-studio/issues)
|
|
102
|
+
- [npm Package](https://www.npmjs.com/package/@clypra-studio/shaders)
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
> **Note:** This package was previously published as `@clypra-studio/shader-library`. Use `@clypra-studio/shaders` for new projects.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { createFragmentShader, glslUtils, standardVertexShader } from './utils/index.js';
|
|
2
|
+
export { cellularNoiseShader, filmGrainShader, noiseShaders, perlinNoiseShader, simplexNoiseShader } from './noise/index.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @clypra/shader-library
|
|
6
|
+
*
|
|
7
|
+
* Reusable GLSL shader library for video effects.
|
|
8
|
+
* All shaders are organized by category for easy reuse across effects.
|
|
9
|
+
*
|
|
10
|
+
* @packageDocumentation
|
|
11
|
+
*/
|
|
12
|
+
/** Package version */
|
|
13
|
+
declare const VERSION = "0.1.0";
|
|
14
|
+
|
|
15
|
+
export { VERSION };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
// src/utils/index.ts
|
|
2
|
+
var glslUtils = `
|
|
3
|
+
// Hash function for random number generation
|
|
4
|
+
float hash(vec2 p) {
|
|
5
|
+
return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// 2D noise function
|
|
9
|
+
float noise(vec2 p) {
|
|
10
|
+
vec2 i = floor(p);
|
|
11
|
+
vec2 f = fract(p);
|
|
12
|
+
|
|
13
|
+
f = f * f * (3.0 - 2.0 * f);
|
|
14
|
+
|
|
15
|
+
float a = hash(i);
|
|
16
|
+
float b = hash(i + vec2(1.0, 0.0));
|
|
17
|
+
float c = hash(i + vec2(0.0, 1.0));
|
|
18
|
+
float d = hash(i + vec2(1.0, 1.0));
|
|
19
|
+
|
|
20
|
+
return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Smooth minimum
|
|
24
|
+
float smin(float a, float b, float k) {
|
|
25
|
+
float h = clamp(0.5 + 0.5 * (b - a) / k, 0.0, 1.0);
|
|
26
|
+
return mix(b, a, h) - k * h * (1.0 - h);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Smooth step with adjustable edge
|
|
30
|
+
float smootherstep(float edge0, float edge1, float x) {
|
|
31
|
+
x = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
|
|
32
|
+
return x * x * x * (x * (x * 6.0 - 15.0) + 10.0);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Luminance calculation
|
|
36
|
+
float luminance(vec3 color) {
|
|
37
|
+
return dot(color, vec3(0.299, 0.587, 0.114));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// RGB to HSV
|
|
41
|
+
vec3 rgb2hsv(vec3 c) {
|
|
42
|
+
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
|
43
|
+
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
|
44
|
+
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
|
45
|
+
|
|
46
|
+
float d = q.x - min(q.w, q.y);
|
|
47
|
+
float e = 1.0e-10;
|
|
48
|
+
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// HSV to RGB
|
|
52
|
+
vec3 hsv2rgb(vec3 c) {
|
|
53
|
+
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
|
54
|
+
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
|
55
|
+
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Vignette effect
|
|
59
|
+
float vignette(vec2 uv, float intensity, float extent) {
|
|
60
|
+
vec2 center = uv * 2.0 - 1.0;
|
|
61
|
+
float dist = length(center);
|
|
62
|
+
return 1.0 - smoothstep(extent, extent + intensity, dist);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Posterize
|
|
66
|
+
vec3 posterize(vec3 color, float levels) {
|
|
67
|
+
return floor(color * levels) / levels;
|
|
68
|
+
}
|
|
69
|
+
`;
|
|
70
|
+
function createFragmentShader(mainCode) {
|
|
71
|
+
return `
|
|
72
|
+
precision highp float;
|
|
73
|
+
|
|
74
|
+
varying vec2 vTextureCoord;
|
|
75
|
+
|
|
76
|
+
${glslUtils}
|
|
77
|
+
|
|
78
|
+
${mainCode}
|
|
79
|
+
`;
|
|
80
|
+
}
|
|
81
|
+
var standardVertexShader = `
|
|
82
|
+
attribute vec2 aVertexPosition;
|
|
83
|
+
attribute vec2 aTextureCoord;
|
|
84
|
+
|
|
85
|
+
uniform mat3 projectionMatrix;
|
|
86
|
+
|
|
87
|
+
varying vec2 vTextureCoord;
|
|
88
|
+
|
|
89
|
+
void main() {
|
|
90
|
+
gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);
|
|
91
|
+
vTextureCoord = aTextureCoord;
|
|
92
|
+
}
|
|
93
|
+
`;
|
|
94
|
+
|
|
95
|
+
// src/noise/index.ts
|
|
96
|
+
var filmGrainShader = `
|
|
97
|
+
uniform sampler2D uTexture;
|
|
98
|
+
uniform float uIntensity;
|
|
99
|
+
uniform float uSize;
|
|
100
|
+
uniform float uTime;
|
|
101
|
+
|
|
102
|
+
float filmGrain(vec2 uv, float time) {
|
|
103
|
+
vec2 p = uv * uSize;
|
|
104
|
+
p += time * 1000.0;
|
|
105
|
+
|
|
106
|
+
float n = hash(p);
|
|
107
|
+
n = n * 2.0 - 1.0;
|
|
108
|
+
|
|
109
|
+
return n * uIntensity;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
void main() {
|
|
113
|
+
vec2 uv = vTextureCoord;
|
|
114
|
+
vec4 color = texture2D(uTexture, uv);
|
|
115
|
+
|
|
116
|
+
float grain = filmGrain(uv, uTime);
|
|
117
|
+
color.rgb += grain;
|
|
118
|
+
|
|
119
|
+
gl_FragColor = color;
|
|
120
|
+
}
|
|
121
|
+
`;
|
|
122
|
+
var perlinNoiseShader = `
|
|
123
|
+
vec2 fade(vec2 t) {
|
|
124
|
+
return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
float perlinNoise(vec2 p) {
|
|
128
|
+
vec2 i = floor(p);
|
|
129
|
+
vec2 f = fract(p);
|
|
130
|
+
|
|
131
|
+
vec2 u = fade(f);
|
|
132
|
+
|
|
133
|
+
float a = hash(i);
|
|
134
|
+
float b = hash(i + vec2(1.0, 0.0));
|
|
135
|
+
float c = hash(i + vec2(0.0, 1.0));
|
|
136
|
+
float d = hash(i + vec2(1.0, 1.0));
|
|
137
|
+
|
|
138
|
+
return mix(
|
|
139
|
+
mix(a, b, u.x),
|
|
140
|
+
mix(c, d, u.x),
|
|
141
|
+
u.y
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
float fbm(vec2 p) {
|
|
146
|
+
float value = 0.0;
|
|
147
|
+
float amplitude = 0.5;
|
|
148
|
+
float frequency = 1.0;
|
|
149
|
+
|
|
150
|
+
for (int i = 0; i < 5; i++) {
|
|
151
|
+
value += amplitude * perlinNoise(p * frequency);
|
|
152
|
+
amplitude *= 0.5;
|
|
153
|
+
frequency *= 2.0;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return value;
|
|
157
|
+
}
|
|
158
|
+
`;
|
|
159
|
+
var simplexNoiseShader = `
|
|
160
|
+
vec3 mod289(vec3 x) {
|
|
161
|
+
return x - floor(x * (1.0 / 289.0)) * 289.0;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
vec2 mod289(vec2 x) {
|
|
165
|
+
return x - floor(x * (1.0 / 289.0)) * 289.0;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
vec3 permute(vec3 x) {
|
|
169
|
+
return mod289(((x * 34.0) + 1.0) * x);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
float simplexNoise(vec2 v) {
|
|
173
|
+
const vec4 C = vec4(
|
|
174
|
+
0.211324865405187, // (3.0-sqrt(3.0))/6.0
|
|
175
|
+
0.366025403784439, // 0.5*(sqrt(3.0)-1.0)
|
|
176
|
+
-0.577350269189626, // -1.0 + 2.0 * C.x
|
|
177
|
+
0.024390243902439 // 1.0 / 41.0
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
vec2 i = floor(v + dot(v, C.yy));
|
|
181
|
+
vec2 x0 = v - i + dot(i, C.xx);
|
|
182
|
+
|
|
183
|
+
vec2 i1;
|
|
184
|
+
i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
|
|
185
|
+
vec4 x12 = x0.xyxy + C.xxzz;
|
|
186
|
+
x12.xy -= i1;
|
|
187
|
+
|
|
188
|
+
i = mod289(i);
|
|
189
|
+
vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0))
|
|
190
|
+
+ i.x + vec3(0.0, i1.x, 1.0));
|
|
191
|
+
|
|
192
|
+
vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0);
|
|
193
|
+
m = m * m;
|
|
194
|
+
m = m * m;
|
|
195
|
+
|
|
196
|
+
vec3 x = 2.0 * fract(p * C.www) - 1.0;
|
|
197
|
+
vec3 h = abs(x) - 0.5;
|
|
198
|
+
vec3 ox = floor(x + 0.5);
|
|
199
|
+
vec3 a0 = x - ox;
|
|
200
|
+
|
|
201
|
+
m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);
|
|
202
|
+
|
|
203
|
+
vec3 g;
|
|
204
|
+
g.x = a0.x * x0.x + h.x * x0.y;
|
|
205
|
+
g.yz = a0.yz * x12.xz + h.yz * x12.yw;
|
|
206
|
+
return 130.0 * dot(m, g);
|
|
207
|
+
}
|
|
208
|
+
`;
|
|
209
|
+
var cellularNoiseShader = `
|
|
210
|
+
vec2 random2(vec2 p) {
|
|
211
|
+
return fract(sin(vec2(dot(p, vec2(127.1, 311.7)), dot(p, vec2(269.5, 183.3)))) * 43758.5453);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
float cellularNoise(vec2 p) {
|
|
215
|
+
vec2 i_p = floor(p);
|
|
216
|
+
vec2 f_p = fract(p);
|
|
217
|
+
|
|
218
|
+
float minDist = 1.0;
|
|
219
|
+
|
|
220
|
+
for (int y = -1; y <= 1; y++) {
|
|
221
|
+
for (int x = -1; x <= 1; x++) {
|
|
222
|
+
vec2 neighbor = vec2(float(x), float(y));
|
|
223
|
+
vec2 point = random2(i_p + neighbor);
|
|
224
|
+
|
|
225
|
+
vec2 diff = neighbor + point - f_p;
|
|
226
|
+
float dist = length(diff);
|
|
227
|
+
|
|
228
|
+
minDist = min(minDist, dist);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return minDist;
|
|
233
|
+
}
|
|
234
|
+
`;
|
|
235
|
+
var noiseShaders = {
|
|
236
|
+
filmGrain: filmGrainShader,
|
|
237
|
+
perlin: perlinNoiseShader,
|
|
238
|
+
simplex: simplexNoiseShader,
|
|
239
|
+
cellular: cellularNoiseShader
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
// src/index.ts
|
|
243
|
+
var VERSION = "0.1.0";
|
|
244
|
+
|
|
245
|
+
export { VERSION, cellularNoiseShader, createFragmentShader, filmGrainShader, glslUtils, noiseShaders, perlinNoiseShader, simplexNoiseShader, standardVertexShader };
|
|
246
|
+
//# sourceMappingURL=index.js.map
|
|
247
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/index.ts","../src/noise/index.ts","../src/index.ts"],"names":[],"mappings":";AASO,IAAM,SAAA,GAAY;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAwElB,SAAS,qBAAqB,QAAA,EAA0B;AAC7D,EAAA,OAAO;AAAA;;AAAA;;AAAA,EAKP,SAAS;;AAAA,EAET,QAAQ;AAAA,CAAA;AAEV;AAKO,IAAM,oBAAA,GAAuB;AAAA;AAAA;;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACvF7B,IAAM,eAAA,GAAkB;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8BxB,IAAM,iBAAA,GAAoB;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyC1B,IAAM,kBAAA,GAAqB;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsD3B,IAAM,mBAAA,GAAsB;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2B5B,IAAM,YAAA,GAAe;AAAA,EAC1B,SAAA,EAAW,eAAA;AAAA,EACX,MAAA,EAAQ,iBAAA;AAAA,EACR,OAAA,EAAS,kBAAA;AAAA,EACT,QAAA,EAAU;AACZ;;;AC5JO,IAAM,OAAA,GAAU","file":"index.js","sourcesContent":["/**\n * @clypra/shader-library — GLSL Utility Functions\n *\n * Common utility functions used across shaders\n */\n\n/**\n * Common GLSL utility functions as a string\n */\nexport const glslUtils = `\n// Hash function for random number generation\nfloat hash(vec2 p) {\n return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);\n}\n\n// 2D noise function\nfloat noise(vec2 p) {\n vec2 i = floor(p);\n vec2 f = fract(p);\n \n f = f * f * (3.0 - 2.0 * f);\n \n float a = hash(i);\n float b = hash(i + vec2(1.0, 0.0));\n float c = hash(i + vec2(0.0, 1.0));\n float d = hash(i + vec2(1.0, 1.0));\n \n return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);\n}\n\n// Smooth minimum\nfloat smin(float a, float b, float k) {\n float h = clamp(0.5 + 0.5 * (b - a) / k, 0.0, 1.0);\n return mix(b, a, h) - k * h * (1.0 - h);\n}\n\n// Smooth step with adjustable edge\nfloat smootherstep(float edge0, float edge1, float x) {\n x = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n return x * x * x * (x * (x * 6.0 - 15.0) + 10.0);\n}\n\n// Luminance calculation\nfloat luminance(vec3 color) {\n return dot(color, vec3(0.299, 0.587, 0.114));\n}\n\n// RGB to HSV\nvec3 rgb2hsv(vec3 c) {\n vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));\n vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));\n \n float d = q.x - min(q.w, q.y);\n float e = 1.0e-10;\n return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n}\n\n// HSV to RGB\nvec3 hsv2rgb(vec3 c) {\n vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n}\n\n// Vignette effect\nfloat vignette(vec2 uv, float intensity, float extent) {\n vec2 center = uv * 2.0 - 1.0;\n float dist = length(center);\n return 1.0 - smoothstep(extent, extent + intensity, dist);\n}\n\n// Posterize\nvec3 posterize(vec3 color, float levels) {\n return floor(color * levels) / levels;\n}\n`;\n\n/**\n * Create a complete fragment shader with utilities\n */\nexport function createFragmentShader(mainCode: string): string {\n return `\nprecision highp float;\n\nvarying vec2 vTextureCoord;\n\n${glslUtils}\n\n${mainCode}\n`;\n}\n\n/**\n * Standard vertex shader\n */\nexport const standardVertexShader = `\nattribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\n\nuniform mat3 projectionMatrix;\n\nvarying vec2 vTextureCoord;\n\nvoid main() {\n gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\n vTextureCoord = aTextureCoord;\n}\n`;\n","/**\n * @clypra/shader-library — Noise Shaders\n *\n * Various noise generation functions for procedural effects\n */\n\n/**\n * Film grain shader\n */\nexport const filmGrainShader = `\nuniform sampler2D uTexture;\nuniform float uIntensity;\nuniform float uSize;\nuniform float uTime;\n\nfloat filmGrain(vec2 uv, float time) {\n vec2 p = uv * uSize;\n p += time * 1000.0;\n \n float n = hash(p);\n n = n * 2.0 - 1.0;\n \n return n * uIntensity;\n}\n\nvoid main() {\n vec2 uv = vTextureCoord;\n vec4 color = texture2D(uTexture, uv);\n \n float grain = filmGrain(uv, uTime);\n color.rgb += grain;\n \n gl_FragColor = color;\n}\n`;\n\n/**\n * Perlin noise shader\n */\nexport const perlinNoiseShader = `\nvec2 fade(vec2 t) {\n return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);\n}\n\nfloat perlinNoise(vec2 p) {\n vec2 i = floor(p);\n vec2 f = fract(p);\n \n vec2 u = fade(f);\n \n float a = hash(i);\n float b = hash(i + vec2(1.0, 0.0));\n float c = hash(i + vec2(0.0, 1.0));\n float d = hash(i + vec2(1.0, 1.0));\n \n return mix(\n mix(a, b, u.x),\n mix(c, d, u.x),\n u.y\n );\n}\n\nfloat fbm(vec2 p) {\n float value = 0.0;\n float amplitude = 0.5;\n float frequency = 1.0;\n \n for (int i = 0; i < 5; i++) {\n value += amplitude * perlinNoise(p * frequency);\n amplitude *= 0.5;\n frequency *= 2.0;\n }\n \n return value;\n}\n`;\n\n/**\n * Simplex noise (approximation)\n */\nexport const simplexNoiseShader = `\nvec3 mod289(vec3 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\n\nvec2 mod289(vec2 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\n\nvec3 permute(vec3 x) {\n return mod289(((x * 34.0) + 1.0) * x);\n}\n\nfloat simplexNoise(vec2 v) {\n const vec4 C = vec4(\n 0.211324865405187, // (3.0-sqrt(3.0))/6.0\n 0.366025403784439, // 0.5*(sqrt(3.0)-1.0)\n -0.577350269189626, // -1.0 + 2.0 * C.x\n 0.024390243902439 // 1.0 / 41.0\n );\n\n vec2 i = floor(v + dot(v, C.yy));\n vec2 x0 = v - i + dot(i, C.xx);\n\n vec2 i1;\n i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n vec4 x12 = x0.xyxy + C.xxzz;\n x12.xy -= i1;\n\n i = mod289(i);\n vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0))\n + i.x + vec3(0.0, i1.x, 1.0));\n\n vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0);\n m = m * m;\n m = m * m;\n\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\n vec3 h = abs(x) - 0.5;\n vec3 ox = floor(x + 0.5);\n vec3 a0 = x - ox;\n\n m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);\n\n vec3 g;\n g.x = a0.x * x0.x + h.x * x0.y;\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n return 130.0 * dot(m, g);\n}\n`;\n\n/**\n * Cellular/Worley noise\n */\nexport const cellularNoiseShader = `\nvec2 random2(vec2 p) {\n return fract(sin(vec2(dot(p, vec2(127.1, 311.7)), dot(p, vec2(269.5, 183.3)))) * 43758.5453);\n}\n\nfloat cellularNoise(vec2 p) {\n vec2 i_p = floor(p);\n vec2 f_p = fract(p);\n \n float minDist = 1.0;\n \n for (int y = -1; y <= 1; y++) {\n for (int x = -1; x <= 1; x++) {\n vec2 neighbor = vec2(float(x), float(y));\n vec2 point = random2(i_p + neighbor);\n \n vec2 diff = neighbor + point - f_p;\n float dist = length(diff);\n \n minDist = min(minDist, dist);\n }\n }\n \n return minDist;\n}\n`;\n\nexport const noiseShaders = {\n filmGrain: filmGrainShader,\n perlin: perlinNoiseShader,\n simplex: simplexNoiseShader,\n cellular: cellularNoiseShader,\n};\n","/**\n * @clypra/shader-library\n *\n * Reusable GLSL shader library for video effects.\n * All shaders are organized by category for easy reuse across effects.\n *\n * @packageDocumentation\n */\n\n/** Package version */\nexport const VERSION = \"0.1.0\";\n\n// Utilities\nexport * from \"./utils\";\n\n// Noise functions\nexport * from \"./noise\";\n\n// Note: Other shader categories will be added in subsequent phases\n// export * from './color';\n// export * from './blur';\n// export * from './distortion';\n// export * from './composite';\n"]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @clypra/shader-library — Noise Shaders
|
|
3
|
+
*
|
|
4
|
+
* Various noise generation functions for procedural effects
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Film grain shader
|
|
8
|
+
*/
|
|
9
|
+
declare const filmGrainShader = "\nuniform sampler2D uTexture;\nuniform float uIntensity;\nuniform float uSize;\nuniform float uTime;\n\nfloat filmGrain(vec2 uv, float time) {\n vec2 p = uv * uSize;\n p += time * 1000.0;\n \n float n = hash(p);\n n = n * 2.0 - 1.0;\n \n return n * uIntensity;\n}\n\nvoid main() {\n vec2 uv = vTextureCoord;\n vec4 color = texture2D(uTexture, uv);\n \n float grain = filmGrain(uv, uTime);\n color.rgb += grain;\n \n gl_FragColor = color;\n}\n";
|
|
10
|
+
/**
|
|
11
|
+
* Perlin noise shader
|
|
12
|
+
*/
|
|
13
|
+
declare const perlinNoiseShader = "\nvec2 fade(vec2 t) {\n return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);\n}\n\nfloat perlinNoise(vec2 p) {\n vec2 i = floor(p);\n vec2 f = fract(p);\n \n vec2 u = fade(f);\n \n float a = hash(i);\n float b = hash(i + vec2(1.0, 0.0));\n float c = hash(i + vec2(0.0, 1.0));\n float d = hash(i + vec2(1.0, 1.0));\n \n return mix(\n mix(a, b, u.x),\n mix(c, d, u.x),\n u.y\n );\n}\n\nfloat fbm(vec2 p) {\n float value = 0.0;\n float amplitude = 0.5;\n float frequency = 1.0;\n \n for (int i = 0; i < 5; i++) {\n value += amplitude * perlinNoise(p * frequency);\n amplitude *= 0.5;\n frequency *= 2.0;\n }\n \n return value;\n}\n";
|
|
14
|
+
/**
|
|
15
|
+
* Simplex noise (approximation)
|
|
16
|
+
*/
|
|
17
|
+
declare const simplexNoiseShader = "\nvec3 mod289(vec3 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\n\nvec2 mod289(vec2 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\n\nvec3 permute(vec3 x) {\n return mod289(((x * 34.0) + 1.0) * x);\n}\n\nfloat simplexNoise(vec2 v) {\n const vec4 C = vec4(\n 0.211324865405187, // (3.0-sqrt(3.0))/6.0\n 0.366025403784439, // 0.5*(sqrt(3.0)-1.0)\n -0.577350269189626, // -1.0 + 2.0 * C.x\n 0.024390243902439 // 1.0 / 41.0\n );\n\n vec2 i = floor(v + dot(v, C.yy));\n vec2 x0 = v - i + dot(i, C.xx);\n\n vec2 i1;\n i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n vec4 x12 = x0.xyxy + C.xxzz;\n x12.xy -= i1;\n\n i = mod289(i);\n vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0))\n + i.x + vec3(0.0, i1.x, 1.0));\n\n vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0);\n m = m * m;\n m = m * m;\n\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\n vec3 h = abs(x) - 0.5;\n vec3 ox = floor(x + 0.5);\n vec3 a0 = x - ox;\n\n m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);\n\n vec3 g;\n g.x = a0.x * x0.x + h.x * x0.y;\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n return 130.0 * dot(m, g);\n}\n";
|
|
18
|
+
/**
|
|
19
|
+
* Cellular/Worley noise
|
|
20
|
+
*/
|
|
21
|
+
declare const cellularNoiseShader = "\nvec2 random2(vec2 p) {\n return fract(sin(vec2(dot(p, vec2(127.1, 311.7)), dot(p, vec2(269.5, 183.3)))) * 43758.5453);\n}\n\nfloat cellularNoise(vec2 p) {\n vec2 i_p = floor(p);\n vec2 f_p = fract(p);\n \n float minDist = 1.0;\n \n for (int y = -1; y <= 1; y++) {\n for (int x = -1; x <= 1; x++) {\n vec2 neighbor = vec2(float(x), float(y));\n vec2 point = random2(i_p + neighbor);\n \n vec2 diff = neighbor + point - f_p;\n float dist = length(diff);\n \n minDist = min(minDist, dist);\n }\n }\n \n return minDist;\n}\n";
|
|
22
|
+
declare const noiseShaders: {
|
|
23
|
+
filmGrain: string;
|
|
24
|
+
perlin: string;
|
|
25
|
+
simplex: string;
|
|
26
|
+
cellular: string;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export { cellularNoiseShader, filmGrainShader, noiseShaders, perlinNoiseShader, simplexNoiseShader };
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
// src/noise/index.ts
|
|
2
|
+
var filmGrainShader = `
|
|
3
|
+
uniform sampler2D uTexture;
|
|
4
|
+
uniform float uIntensity;
|
|
5
|
+
uniform float uSize;
|
|
6
|
+
uniform float uTime;
|
|
7
|
+
|
|
8
|
+
float filmGrain(vec2 uv, float time) {
|
|
9
|
+
vec2 p = uv * uSize;
|
|
10
|
+
p += time * 1000.0;
|
|
11
|
+
|
|
12
|
+
float n = hash(p);
|
|
13
|
+
n = n * 2.0 - 1.0;
|
|
14
|
+
|
|
15
|
+
return n * uIntensity;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
void main() {
|
|
19
|
+
vec2 uv = vTextureCoord;
|
|
20
|
+
vec4 color = texture2D(uTexture, uv);
|
|
21
|
+
|
|
22
|
+
float grain = filmGrain(uv, uTime);
|
|
23
|
+
color.rgb += grain;
|
|
24
|
+
|
|
25
|
+
gl_FragColor = color;
|
|
26
|
+
}
|
|
27
|
+
`;
|
|
28
|
+
var perlinNoiseShader = `
|
|
29
|
+
vec2 fade(vec2 t) {
|
|
30
|
+
return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
float perlinNoise(vec2 p) {
|
|
34
|
+
vec2 i = floor(p);
|
|
35
|
+
vec2 f = fract(p);
|
|
36
|
+
|
|
37
|
+
vec2 u = fade(f);
|
|
38
|
+
|
|
39
|
+
float a = hash(i);
|
|
40
|
+
float b = hash(i + vec2(1.0, 0.0));
|
|
41
|
+
float c = hash(i + vec2(0.0, 1.0));
|
|
42
|
+
float d = hash(i + vec2(1.0, 1.0));
|
|
43
|
+
|
|
44
|
+
return mix(
|
|
45
|
+
mix(a, b, u.x),
|
|
46
|
+
mix(c, d, u.x),
|
|
47
|
+
u.y
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
float fbm(vec2 p) {
|
|
52
|
+
float value = 0.0;
|
|
53
|
+
float amplitude = 0.5;
|
|
54
|
+
float frequency = 1.0;
|
|
55
|
+
|
|
56
|
+
for (int i = 0; i < 5; i++) {
|
|
57
|
+
value += amplitude * perlinNoise(p * frequency);
|
|
58
|
+
amplitude *= 0.5;
|
|
59
|
+
frequency *= 2.0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return value;
|
|
63
|
+
}
|
|
64
|
+
`;
|
|
65
|
+
var simplexNoiseShader = `
|
|
66
|
+
vec3 mod289(vec3 x) {
|
|
67
|
+
return x - floor(x * (1.0 / 289.0)) * 289.0;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
vec2 mod289(vec2 x) {
|
|
71
|
+
return x - floor(x * (1.0 / 289.0)) * 289.0;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
vec3 permute(vec3 x) {
|
|
75
|
+
return mod289(((x * 34.0) + 1.0) * x);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
float simplexNoise(vec2 v) {
|
|
79
|
+
const vec4 C = vec4(
|
|
80
|
+
0.211324865405187, // (3.0-sqrt(3.0))/6.0
|
|
81
|
+
0.366025403784439, // 0.5*(sqrt(3.0)-1.0)
|
|
82
|
+
-0.577350269189626, // -1.0 + 2.0 * C.x
|
|
83
|
+
0.024390243902439 // 1.0 / 41.0
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
vec2 i = floor(v + dot(v, C.yy));
|
|
87
|
+
vec2 x0 = v - i + dot(i, C.xx);
|
|
88
|
+
|
|
89
|
+
vec2 i1;
|
|
90
|
+
i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
|
|
91
|
+
vec4 x12 = x0.xyxy + C.xxzz;
|
|
92
|
+
x12.xy -= i1;
|
|
93
|
+
|
|
94
|
+
i = mod289(i);
|
|
95
|
+
vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0))
|
|
96
|
+
+ i.x + vec3(0.0, i1.x, 1.0));
|
|
97
|
+
|
|
98
|
+
vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0);
|
|
99
|
+
m = m * m;
|
|
100
|
+
m = m * m;
|
|
101
|
+
|
|
102
|
+
vec3 x = 2.0 * fract(p * C.www) - 1.0;
|
|
103
|
+
vec3 h = abs(x) - 0.5;
|
|
104
|
+
vec3 ox = floor(x + 0.5);
|
|
105
|
+
vec3 a0 = x - ox;
|
|
106
|
+
|
|
107
|
+
m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);
|
|
108
|
+
|
|
109
|
+
vec3 g;
|
|
110
|
+
g.x = a0.x * x0.x + h.x * x0.y;
|
|
111
|
+
g.yz = a0.yz * x12.xz + h.yz * x12.yw;
|
|
112
|
+
return 130.0 * dot(m, g);
|
|
113
|
+
}
|
|
114
|
+
`;
|
|
115
|
+
var cellularNoiseShader = `
|
|
116
|
+
vec2 random2(vec2 p) {
|
|
117
|
+
return fract(sin(vec2(dot(p, vec2(127.1, 311.7)), dot(p, vec2(269.5, 183.3)))) * 43758.5453);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
float cellularNoise(vec2 p) {
|
|
121
|
+
vec2 i_p = floor(p);
|
|
122
|
+
vec2 f_p = fract(p);
|
|
123
|
+
|
|
124
|
+
float minDist = 1.0;
|
|
125
|
+
|
|
126
|
+
for (int y = -1; y <= 1; y++) {
|
|
127
|
+
for (int x = -1; x <= 1; x++) {
|
|
128
|
+
vec2 neighbor = vec2(float(x), float(y));
|
|
129
|
+
vec2 point = random2(i_p + neighbor);
|
|
130
|
+
|
|
131
|
+
vec2 diff = neighbor + point - f_p;
|
|
132
|
+
float dist = length(diff);
|
|
133
|
+
|
|
134
|
+
minDist = min(minDist, dist);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return minDist;
|
|
139
|
+
}
|
|
140
|
+
`;
|
|
141
|
+
var noiseShaders = {
|
|
142
|
+
filmGrain: filmGrainShader,
|
|
143
|
+
perlin: perlinNoiseShader,
|
|
144
|
+
simplex: simplexNoiseShader,
|
|
145
|
+
cellular: cellularNoiseShader
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
export { cellularNoiseShader, filmGrainShader, noiseShaders, perlinNoiseShader, simplexNoiseShader };
|
|
149
|
+
//# sourceMappingURL=index.js.map
|
|
150
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/noise/index.ts"],"names":[],"mappings":";AASO,IAAM,eAAA,GAAkB;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8BxB,IAAM,iBAAA,GAAoB;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyC1B,IAAM,kBAAA,GAAqB;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsD3B,IAAM,mBAAA,GAAsB;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2B5B,IAAM,YAAA,GAAe;AAAA,EAC1B,SAAA,EAAW,eAAA;AAAA,EACX,MAAA,EAAQ,iBAAA;AAAA,EACR,OAAA,EAAS,kBAAA;AAAA,EACT,QAAA,EAAU;AACZ","file":"index.js","sourcesContent":["/**\n * @clypra/shader-library — Noise Shaders\n *\n * Various noise generation functions for procedural effects\n */\n\n/**\n * Film grain shader\n */\nexport const filmGrainShader = `\nuniform sampler2D uTexture;\nuniform float uIntensity;\nuniform float uSize;\nuniform float uTime;\n\nfloat filmGrain(vec2 uv, float time) {\n vec2 p = uv * uSize;\n p += time * 1000.0;\n \n float n = hash(p);\n n = n * 2.0 - 1.0;\n \n return n * uIntensity;\n}\n\nvoid main() {\n vec2 uv = vTextureCoord;\n vec4 color = texture2D(uTexture, uv);\n \n float grain = filmGrain(uv, uTime);\n color.rgb += grain;\n \n gl_FragColor = color;\n}\n`;\n\n/**\n * Perlin noise shader\n */\nexport const perlinNoiseShader = `\nvec2 fade(vec2 t) {\n return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);\n}\n\nfloat perlinNoise(vec2 p) {\n vec2 i = floor(p);\n vec2 f = fract(p);\n \n vec2 u = fade(f);\n \n float a = hash(i);\n float b = hash(i + vec2(1.0, 0.0));\n float c = hash(i + vec2(0.0, 1.0));\n float d = hash(i + vec2(1.0, 1.0));\n \n return mix(\n mix(a, b, u.x),\n mix(c, d, u.x),\n u.y\n );\n}\n\nfloat fbm(vec2 p) {\n float value = 0.0;\n float amplitude = 0.5;\n float frequency = 1.0;\n \n for (int i = 0; i < 5; i++) {\n value += amplitude * perlinNoise(p * frequency);\n amplitude *= 0.5;\n frequency *= 2.0;\n }\n \n return value;\n}\n`;\n\n/**\n * Simplex noise (approximation)\n */\nexport const simplexNoiseShader = `\nvec3 mod289(vec3 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\n\nvec2 mod289(vec2 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\n\nvec3 permute(vec3 x) {\n return mod289(((x * 34.0) + 1.0) * x);\n}\n\nfloat simplexNoise(vec2 v) {\n const vec4 C = vec4(\n 0.211324865405187, // (3.0-sqrt(3.0))/6.0\n 0.366025403784439, // 0.5*(sqrt(3.0)-1.0)\n -0.577350269189626, // -1.0 + 2.0 * C.x\n 0.024390243902439 // 1.0 / 41.0\n );\n\n vec2 i = floor(v + dot(v, C.yy));\n vec2 x0 = v - i + dot(i, C.xx);\n\n vec2 i1;\n i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n vec4 x12 = x0.xyxy + C.xxzz;\n x12.xy -= i1;\n\n i = mod289(i);\n vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0))\n + i.x + vec3(0.0, i1.x, 1.0));\n\n vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0);\n m = m * m;\n m = m * m;\n\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\n vec3 h = abs(x) - 0.5;\n vec3 ox = floor(x + 0.5);\n vec3 a0 = x - ox;\n\n m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);\n\n vec3 g;\n g.x = a0.x * x0.x + h.x * x0.y;\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n return 130.0 * dot(m, g);\n}\n`;\n\n/**\n * Cellular/Worley noise\n */\nexport const cellularNoiseShader = `\nvec2 random2(vec2 p) {\n return fract(sin(vec2(dot(p, vec2(127.1, 311.7)), dot(p, vec2(269.5, 183.3)))) * 43758.5453);\n}\n\nfloat cellularNoise(vec2 p) {\n vec2 i_p = floor(p);\n vec2 f_p = fract(p);\n \n float minDist = 1.0;\n \n for (int y = -1; y <= 1; y++) {\n for (int x = -1; x <= 1; x++) {\n vec2 neighbor = vec2(float(x), float(y));\n vec2 point = random2(i_p + neighbor);\n \n vec2 diff = neighbor + point - f_p;\n float dist = length(diff);\n \n minDist = min(minDist, dist);\n }\n }\n \n return minDist;\n}\n`;\n\nexport const noiseShaders = {\n filmGrain: filmGrainShader,\n perlin: perlinNoiseShader,\n simplex: simplexNoiseShader,\n cellular: cellularNoiseShader,\n};\n"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @clypra/shader-library — GLSL Utility Functions
|
|
3
|
+
*
|
|
4
|
+
* Common utility functions used across shaders
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Common GLSL utility functions as a string
|
|
8
|
+
*/
|
|
9
|
+
declare const glslUtils = "\n// Hash function for random number generation\nfloat hash(vec2 p) {\n return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);\n}\n\n// 2D noise function\nfloat noise(vec2 p) {\n vec2 i = floor(p);\n vec2 f = fract(p);\n \n f = f * f * (3.0 - 2.0 * f);\n \n float a = hash(i);\n float b = hash(i + vec2(1.0, 0.0));\n float c = hash(i + vec2(0.0, 1.0));\n float d = hash(i + vec2(1.0, 1.0));\n \n return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);\n}\n\n// Smooth minimum\nfloat smin(float a, float b, float k) {\n float h = clamp(0.5 + 0.5 * (b - a) / k, 0.0, 1.0);\n return mix(b, a, h) - k * h * (1.0 - h);\n}\n\n// Smooth step with adjustable edge\nfloat smootherstep(float edge0, float edge1, float x) {\n x = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n return x * x * x * (x * (x * 6.0 - 15.0) + 10.0);\n}\n\n// Luminance calculation\nfloat luminance(vec3 color) {\n return dot(color, vec3(0.299, 0.587, 0.114));\n}\n\n// RGB to HSV\nvec3 rgb2hsv(vec3 c) {\n vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));\n vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));\n \n float d = q.x - min(q.w, q.y);\n float e = 1.0e-10;\n return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n}\n\n// HSV to RGB\nvec3 hsv2rgb(vec3 c) {\n vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n}\n\n// Vignette effect\nfloat vignette(vec2 uv, float intensity, float extent) {\n vec2 center = uv * 2.0 - 1.0;\n float dist = length(center);\n return 1.0 - smoothstep(extent, extent + intensity, dist);\n}\n\n// Posterize\nvec3 posterize(vec3 color, float levels) {\n return floor(color * levels) / levels;\n}\n";
|
|
10
|
+
/**
|
|
11
|
+
* Create a complete fragment shader with utilities
|
|
12
|
+
*/
|
|
13
|
+
declare function createFragmentShader(mainCode: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Standard vertex shader
|
|
16
|
+
*/
|
|
17
|
+
declare const standardVertexShader = "\nattribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\n\nuniform mat3 projectionMatrix;\n\nvarying vec2 vTextureCoord;\n\nvoid main() {\n gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\n vTextureCoord = aTextureCoord;\n}\n";
|
|
18
|
+
|
|
19
|
+
export { createFragmentShader, glslUtils, standardVertexShader };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// src/utils/index.ts
|
|
2
|
+
var glslUtils = `
|
|
3
|
+
// Hash function for random number generation
|
|
4
|
+
float hash(vec2 p) {
|
|
5
|
+
return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// 2D noise function
|
|
9
|
+
float noise(vec2 p) {
|
|
10
|
+
vec2 i = floor(p);
|
|
11
|
+
vec2 f = fract(p);
|
|
12
|
+
|
|
13
|
+
f = f * f * (3.0 - 2.0 * f);
|
|
14
|
+
|
|
15
|
+
float a = hash(i);
|
|
16
|
+
float b = hash(i + vec2(1.0, 0.0));
|
|
17
|
+
float c = hash(i + vec2(0.0, 1.0));
|
|
18
|
+
float d = hash(i + vec2(1.0, 1.0));
|
|
19
|
+
|
|
20
|
+
return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Smooth minimum
|
|
24
|
+
float smin(float a, float b, float k) {
|
|
25
|
+
float h = clamp(0.5 + 0.5 * (b - a) / k, 0.0, 1.0);
|
|
26
|
+
return mix(b, a, h) - k * h * (1.0 - h);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Smooth step with adjustable edge
|
|
30
|
+
float smootherstep(float edge0, float edge1, float x) {
|
|
31
|
+
x = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
|
|
32
|
+
return x * x * x * (x * (x * 6.0 - 15.0) + 10.0);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Luminance calculation
|
|
36
|
+
float luminance(vec3 color) {
|
|
37
|
+
return dot(color, vec3(0.299, 0.587, 0.114));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// RGB to HSV
|
|
41
|
+
vec3 rgb2hsv(vec3 c) {
|
|
42
|
+
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
|
43
|
+
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
|
44
|
+
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
|
45
|
+
|
|
46
|
+
float d = q.x - min(q.w, q.y);
|
|
47
|
+
float e = 1.0e-10;
|
|
48
|
+
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// HSV to RGB
|
|
52
|
+
vec3 hsv2rgb(vec3 c) {
|
|
53
|
+
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
|
54
|
+
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
|
55
|
+
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Vignette effect
|
|
59
|
+
float vignette(vec2 uv, float intensity, float extent) {
|
|
60
|
+
vec2 center = uv * 2.0 - 1.0;
|
|
61
|
+
float dist = length(center);
|
|
62
|
+
return 1.0 - smoothstep(extent, extent + intensity, dist);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Posterize
|
|
66
|
+
vec3 posterize(vec3 color, float levels) {
|
|
67
|
+
return floor(color * levels) / levels;
|
|
68
|
+
}
|
|
69
|
+
`;
|
|
70
|
+
function createFragmentShader(mainCode) {
|
|
71
|
+
return `
|
|
72
|
+
precision highp float;
|
|
73
|
+
|
|
74
|
+
varying vec2 vTextureCoord;
|
|
75
|
+
|
|
76
|
+
${glslUtils}
|
|
77
|
+
|
|
78
|
+
${mainCode}
|
|
79
|
+
`;
|
|
80
|
+
}
|
|
81
|
+
var standardVertexShader = `
|
|
82
|
+
attribute vec2 aVertexPosition;
|
|
83
|
+
attribute vec2 aTextureCoord;
|
|
84
|
+
|
|
85
|
+
uniform mat3 projectionMatrix;
|
|
86
|
+
|
|
87
|
+
varying vec2 vTextureCoord;
|
|
88
|
+
|
|
89
|
+
void main() {
|
|
90
|
+
gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);
|
|
91
|
+
vTextureCoord = aTextureCoord;
|
|
92
|
+
}
|
|
93
|
+
`;
|
|
94
|
+
|
|
95
|
+
export { createFragmentShader, glslUtils, standardVertexShader };
|
|
96
|
+
//# sourceMappingURL=index.js.map
|
|
97
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/index.ts"],"names":[],"mappings":";AASO,IAAM,SAAA,GAAY;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAwElB,SAAS,qBAAqB,QAAA,EAA0B;AAC7D,EAAA,OAAO;AAAA;;AAAA;;AAAA,EAKP,SAAS;;AAAA,EAET,QAAQ;AAAA,CAAA;AAEV;AAKO,IAAM,oBAAA,GAAuB;AAAA;AAAA;;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA","file":"index.js","sourcesContent":["/**\n * @clypra/shader-library — GLSL Utility Functions\n *\n * Common utility functions used across shaders\n */\n\n/**\n * Common GLSL utility functions as a string\n */\nexport const glslUtils = `\n// Hash function for random number generation\nfloat hash(vec2 p) {\n return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);\n}\n\n// 2D noise function\nfloat noise(vec2 p) {\n vec2 i = floor(p);\n vec2 f = fract(p);\n \n f = f * f * (3.0 - 2.0 * f);\n \n float a = hash(i);\n float b = hash(i + vec2(1.0, 0.0));\n float c = hash(i + vec2(0.0, 1.0));\n float d = hash(i + vec2(1.0, 1.0));\n \n return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);\n}\n\n// Smooth minimum\nfloat smin(float a, float b, float k) {\n float h = clamp(0.5 + 0.5 * (b - a) / k, 0.0, 1.0);\n return mix(b, a, h) - k * h * (1.0 - h);\n}\n\n// Smooth step with adjustable edge\nfloat smootherstep(float edge0, float edge1, float x) {\n x = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n return x * x * x * (x * (x * 6.0 - 15.0) + 10.0);\n}\n\n// Luminance calculation\nfloat luminance(vec3 color) {\n return dot(color, vec3(0.299, 0.587, 0.114));\n}\n\n// RGB to HSV\nvec3 rgb2hsv(vec3 c) {\n vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));\n vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));\n \n float d = q.x - min(q.w, q.y);\n float e = 1.0e-10;\n return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n}\n\n// HSV to RGB\nvec3 hsv2rgb(vec3 c) {\n vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n}\n\n// Vignette effect\nfloat vignette(vec2 uv, float intensity, float extent) {\n vec2 center = uv * 2.0 - 1.0;\n float dist = length(center);\n return 1.0 - smoothstep(extent, extent + intensity, dist);\n}\n\n// Posterize\nvec3 posterize(vec3 color, float levels) {\n return floor(color * levels) / levels;\n}\n`;\n\n/**\n * Create a complete fragment shader with utilities\n */\nexport function createFragmentShader(mainCode: string): string {\n return `\nprecision highp float;\n\nvarying vec2 vTextureCoord;\n\n${glslUtils}\n\n${mainCode}\n`;\n}\n\n/**\n * Standard vertex shader\n */\nexport const standardVertexShader = `\nattribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\n\nuniform mat3 projectionMatrix;\n\nvarying vec2 vTextureCoord;\n\nvoid main() {\n gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\n vTextureCoord = aTextureCoord;\n}\n`;\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@clypra-studio/shaders",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Reusable GLSL shader library for video effects",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./dist/index.js",
|
|
10
|
+
"./color": "./dist/color/index.js",
|
|
11
|
+
"./blur": "./dist/blur/index.js",
|
|
12
|
+
"./distortion": "./dist/distortion/index.js",
|
|
13
|
+
"./composite": "./dist/composite/index.js",
|
|
14
|
+
"./noise": "./dist/noise/index.js",
|
|
15
|
+
"./utils": "./dist/utils/index.js"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@types/node": "^22.14.0",
|
|
20
|
+
"tsup": "^8.3.5",
|
|
21
|
+
"typescript": "~5.8.2",
|
|
22
|
+
"vitest": "^3.2.4"
|
|
23
|
+
},
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "https://github.com/AIEraDev/clypra-studio.git",
|
|
27
|
+
"directory": "packages/shader-library"
|
|
28
|
+
},
|
|
29
|
+
"homepage": "https://github.com/AIEraDev/clypra-studio/tree/main/packages/shader-library#readme",
|
|
30
|
+
"bugs": {
|
|
31
|
+
"url": "https://github.com/AIEraDev/clypra-studio/issues"
|
|
32
|
+
},
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public",
|
|
35
|
+
"registry": "https://registry.npmjs.org/"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "tsup",
|
|
39
|
+
"dev": "tsup --watch",
|
|
40
|
+
"test": "vitest run",
|
|
41
|
+
"test:watch": "vitest",
|
|
42
|
+
"clean": "rm -rf dist",
|
|
43
|
+
"lint": "tsc --noEmit",
|
|
44
|
+
"typecheck": "tsc --noEmit"
|
|
45
|
+
}
|
|
46
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @clypra/shader-library
|
|
3
|
+
*
|
|
4
|
+
* Reusable GLSL shader library for video effects.
|
|
5
|
+
* All shaders are organized by category for easy reuse across effects.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** Package version */
|
|
11
|
+
export const VERSION = "0.1.0";
|
|
12
|
+
|
|
13
|
+
// Utilities
|
|
14
|
+
export * from "./utils";
|
|
15
|
+
|
|
16
|
+
// Noise functions
|
|
17
|
+
export * from "./noise";
|
|
18
|
+
|
|
19
|
+
// Note: Other shader categories will be added in subsequent phases
|
|
20
|
+
// export * from './color';
|
|
21
|
+
// export * from './blur';
|
|
22
|
+
// export * from './distortion';
|
|
23
|
+
// export * from './composite';
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @clypra/shader-library — Noise Shaders
|
|
3
|
+
*
|
|
4
|
+
* Various noise generation functions for procedural effects
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Film grain shader
|
|
9
|
+
*/
|
|
10
|
+
export const filmGrainShader = `
|
|
11
|
+
uniform sampler2D uTexture;
|
|
12
|
+
uniform float uIntensity;
|
|
13
|
+
uniform float uSize;
|
|
14
|
+
uniform float uTime;
|
|
15
|
+
|
|
16
|
+
float filmGrain(vec2 uv, float time) {
|
|
17
|
+
vec2 p = uv * uSize;
|
|
18
|
+
p += time * 1000.0;
|
|
19
|
+
|
|
20
|
+
float n = hash(p);
|
|
21
|
+
n = n * 2.0 - 1.0;
|
|
22
|
+
|
|
23
|
+
return n * uIntensity;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
void main() {
|
|
27
|
+
vec2 uv = vTextureCoord;
|
|
28
|
+
vec4 color = texture2D(uTexture, uv);
|
|
29
|
+
|
|
30
|
+
float grain = filmGrain(uv, uTime);
|
|
31
|
+
color.rgb += grain;
|
|
32
|
+
|
|
33
|
+
gl_FragColor = color;
|
|
34
|
+
}
|
|
35
|
+
`;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Perlin noise shader
|
|
39
|
+
*/
|
|
40
|
+
export const perlinNoiseShader = `
|
|
41
|
+
vec2 fade(vec2 t) {
|
|
42
|
+
return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
float perlinNoise(vec2 p) {
|
|
46
|
+
vec2 i = floor(p);
|
|
47
|
+
vec2 f = fract(p);
|
|
48
|
+
|
|
49
|
+
vec2 u = fade(f);
|
|
50
|
+
|
|
51
|
+
float a = hash(i);
|
|
52
|
+
float b = hash(i + vec2(1.0, 0.0));
|
|
53
|
+
float c = hash(i + vec2(0.0, 1.0));
|
|
54
|
+
float d = hash(i + vec2(1.0, 1.0));
|
|
55
|
+
|
|
56
|
+
return mix(
|
|
57
|
+
mix(a, b, u.x),
|
|
58
|
+
mix(c, d, u.x),
|
|
59
|
+
u.y
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
float fbm(vec2 p) {
|
|
64
|
+
float value = 0.0;
|
|
65
|
+
float amplitude = 0.5;
|
|
66
|
+
float frequency = 1.0;
|
|
67
|
+
|
|
68
|
+
for (int i = 0; i < 5; i++) {
|
|
69
|
+
value += amplitude * perlinNoise(p * frequency);
|
|
70
|
+
amplitude *= 0.5;
|
|
71
|
+
frequency *= 2.0;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return value;
|
|
75
|
+
}
|
|
76
|
+
`;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Simplex noise (approximation)
|
|
80
|
+
*/
|
|
81
|
+
export const simplexNoiseShader = `
|
|
82
|
+
vec3 mod289(vec3 x) {
|
|
83
|
+
return x - floor(x * (1.0 / 289.0)) * 289.0;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
vec2 mod289(vec2 x) {
|
|
87
|
+
return x - floor(x * (1.0 / 289.0)) * 289.0;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
vec3 permute(vec3 x) {
|
|
91
|
+
return mod289(((x * 34.0) + 1.0) * x);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
float simplexNoise(vec2 v) {
|
|
95
|
+
const vec4 C = vec4(
|
|
96
|
+
0.211324865405187, // (3.0-sqrt(3.0))/6.0
|
|
97
|
+
0.366025403784439, // 0.5*(sqrt(3.0)-1.0)
|
|
98
|
+
-0.577350269189626, // -1.0 + 2.0 * C.x
|
|
99
|
+
0.024390243902439 // 1.0 / 41.0
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
vec2 i = floor(v + dot(v, C.yy));
|
|
103
|
+
vec2 x0 = v - i + dot(i, C.xx);
|
|
104
|
+
|
|
105
|
+
vec2 i1;
|
|
106
|
+
i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
|
|
107
|
+
vec4 x12 = x0.xyxy + C.xxzz;
|
|
108
|
+
x12.xy -= i1;
|
|
109
|
+
|
|
110
|
+
i = mod289(i);
|
|
111
|
+
vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0))
|
|
112
|
+
+ i.x + vec3(0.0, i1.x, 1.0));
|
|
113
|
+
|
|
114
|
+
vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0);
|
|
115
|
+
m = m * m;
|
|
116
|
+
m = m * m;
|
|
117
|
+
|
|
118
|
+
vec3 x = 2.0 * fract(p * C.www) - 1.0;
|
|
119
|
+
vec3 h = abs(x) - 0.5;
|
|
120
|
+
vec3 ox = floor(x + 0.5);
|
|
121
|
+
vec3 a0 = x - ox;
|
|
122
|
+
|
|
123
|
+
m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);
|
|
124
|
+
|
|
125
|
+
vec3 g;
|
|
126
|
+
g.x = a0.x * x0.x + h.x * x0.y;
|
|
127
|
+
g.yz = a0.yz * x12.xz + h.yz * x12.yw;
|
|
128
|
+
return 130.0 * dot(m, g);
|
|
129
|
+
}
|
|
130
|
+
`;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Cellular/Worley noise
|
|
134
|
+
*/
|
|
135
|
+
export const cellularNoiseShader = `
|
|
136
|
+
vec2 random2(vec2 p) {
|
|
137
|
+
return fract(sin(vec2(dot(p, vec2(127.1, 311.7)), dot(p, vec2(269.5, 183.3)))) * 43758.5453);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
float cellularNoise(vec2 p) {
|
|
141
|
+
vec2 i_p = floor(p);
|
|
142
|
+
vec2 f_p = fract(p);
|
|
143
|
+
|
|
144
|
+
float minDist = 1.0;
|
|
145
|
+
|
|
146
|
+
for (int y = -1; y <= 1; y++) {
|
|
147
|
+
for (int x = -1; x <= 1; x++) {
|
|
148
|
+
vec2 neighbor = vec2(float(x), float(y));
|
|
149
|
+
vec2 point = random2(i_p + neighbor);
|
|
150
|
+
|
|
151
|
+
vec2 diff = neighbor + point - f_p;
|
|
152
|
+
float dist = length(diff);
|
|
153
|
+
|
|
154
|
+
minDist = min(minDist, dist);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return minDist;
|
|
159
|
+
}
|
|
160
|
+
`;
|
|
161
|
+
|
|
162
|
+
export const noiseShaders = {
|
|
163
|
+
filmGrain: filmGrainShader,
|
|
164
|
+
perlin: perlinNoiseShader,
|
|
165
|
+
simplex: simplexNoiseShader,
|
|
166
|
+
cellular: cellularNoiseShader,
|
|
167
|
+
};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @clypra/shader-library — GLSL Utility Functions
|
|
3
|
+
*
|
|
4
|
+
* Common utility functions used across shaders
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Common GLSL utility functions as a string
|
|
9
|
+
*/
|
|
10
|
+
export const glslUtils = `
|
|
11
|
+
// Hash function for random number generation
|
|
12
|
+
float hash(vec2 p) {
|
|
13
|
+
return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// 2D noise function
|
|
17
|
+
float noise(vec2 p) {
|
|
18
|
+
vec2 i = floor(p);
|
|
19
|
+
vec2 f = fract(p);
|
|
20
|
+
|
|
21
|
+
f = f * f * (3.0 - 2.0 * f);
|
|
22
|
+
|
|
23
|
+
float a = hash(i);
|
|
24
|
+
float b = hash(i + vec2(1.0, 0.0));
|
|
25
|
+
float c = hash(i + vec2(0.0, 1.0));
|
|
26
|
+
float d = hash(i + vec2(1.0, 1.0));
|
|
27
|
+
|
|
28
|
+
return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Smooth minimum
|
|
32
|
+
float smin(float a, float b, float k) {
|
|
33
|
+
float h = clamp(0.5 + 0.5 * (b - a) / k, 0.0, 1.0);
|
|
34
|
+
return mix(b, a, h) - k * h * (1.0 - h);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Smooth step with adjustable edge
|
|
38
|
+
float smootherstep(float edge0, float edge1, float x) {
|
|
39
|
+
x = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
|
|
40
|
+
return x * x * x * (x * (x * 6.0 - 15.0) + 10.0);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Luminance calculation
|
|
44
|
+
float luminance(vec3 color) {
|
|
45
|
+
return dot(color, vec3(0.299, 0.587, 0.114));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// RGB to HSV
|
|
49
|
+
vec3 rgb2hsv(vec3 c) {
|
|
50
|
+
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
|
51
|
+
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
|
52
|
+
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
|
53
|
+
|
|
54
|
+
float d = q.x - min(q.w, q.y);
|
|
55
|
+
float e = 1.0e-10;
|
|
56
|
+
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// HSV to RGB
|
|
60
|
+
vec3 hsv2rgb(vec3 c) {
|
|
61
|
+
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
|
62
|
+
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
|
63
|
+
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Vignette effect
|
|
67
|
+
float vignette(vec2 uv, float intensity, float extent) {
|
|
68
|
+
vec2 center = uv * 2.0 - 1.0;
|
|
69
|
+
float dist = length(center);
|
|
70
|
+
return 1.0 - smoothstep(extent, extent + intensity, dist);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Posterize
|
|
74
|
+
vec3 posterize(vec3 color, float levels) {
|
|
75
|
+
return floor(color * levels) / levels;
|
|
76
|
+
}
|
|
77
|
+
`;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Create a complete fragment shader with utilities
|
|
81
|
+
*/
|
|
82
|
+
export function createFragmentShader(mainCode: string): string {
|
|
83
|
+
return `
|
|
84
|
+
precision highp float;
|
|
85
|
+
|
|
86
|
+
varying vec2 vTextureCoord;
|
|
87
|
+
|
|
88
|
+
${glslUtils}
|
|
89
|
+
|
|
90
|
+
${mainCode}
|
|
91
|
+
`;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Standard vertex shader
|
|
96
|
+
*/
|
|
97
|
+
export const standardVertexShader = `
|
|
98
|
+
attribute vec2 aVertexPosition;
|
|
99
|
+
attribute vec2 aTextureCoord;
|
|
100
|
+
|
|
101
|
+
uniform mat3 projectionMatrix;
|
|
102
|
+
|
|
103
|
+
varying vec2 vTextureCoord;
|
|
104
|
+
|
|
105
|
+
void main() {
|
|
106
|
+
gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);
|
|
107
|
+
vTextureCoord = aTextureCoord;
|
|
108
|
+
}
|
|
109
|
+
`;
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"lib": ["ES2022"],
|
|
6
|
+
"moduleResolution": "bundler",
|
|
7
|
+
"resolveJsonModule": true,
|
|
8
|
+
"allowJs": true,
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"declaration": true,
|
|
14
|
+
"declarationMap": true,
|
|
15
|
+
"sourceMap": true,
|
|
16
|
+
"outDir": "./dist",
|
|
17
|
+
"rootDir": "./src"
|
|
18
|
+
},
|
|
19
|
+
"include": ["src/**/*"],
|
|
20
|
+
"exclude": ["node_modules", "dist", "**/*.test.ts"]
|
|
21
|
+
}
|
package/tsup.config.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { defineConfig } from "tsup";
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
entry: {
|
|
5
|
+
index: "src/index.ts",
|
|
6
|
+
"utils/index": "src/utils/index.ts",
|
|
7
|
+
"noise/index": "src/noise/index.ts",
|
|
8
|
+
},
|
|
9
|
+
format: ["esm"],
|
|
10
|
+
dts: true,
|
|
11
|
+
sourcemap: true,
|
|
12
|
+
clean: true,
|
|
13
|
+
splitting: false,
|
|
14
|
+
treeshake: true,
|
|
15
|
+
});
|