image-color-grading 1.0.2 → 1.0.3
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/README.md +156 -35
- package/dist/index.cjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -51,6 +51,26 @@ const dataUrl = processor.toDataURL();
|
|
|
51
51
|
const blob = await processor.toBlob({ format: 'image/jpeg', quality: 0.9 });
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
+
### 使用自动修复
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
// 自动分析图像并优化
|
|
58
|
+
const settings = processor.autoFix();
|
|
59
|
+
console.log(settings); // 返回应用的设置参数
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 使用预设滤镜
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
// 应用预设滤镜
|
|
66
|
+
processor.applyPreset('pop'); // 流行风格
|
|
67
|
+
processor.applyPreset('vintage'); // 复古风格
|
|
68
|
+
processor.applyPreset('cinematic'); // 电影风格
|
|
69
|
+
processor.applyPreset('blackAndWhite'); // 黑白
|
|
70
|
+
processor.applyPreset('vivid'); // 鲜艳
|
|
71
|
+
processor.applyPreset('auto'); // 自动优化(等同于 autoFix)
|
|
72
|
+
```
|
|
73
|
+
|
|
54
74
|
## API 文档
|
|
55
75
|
|
|
56
76
|
### ImageColorGrading
|
|
@@ -216,6 +236,86 @@ if (processor.isLoaded()) {
|
|
|
216
236
|
processor.dispose();
|
|
217
237
|
```
|
|
218
238
|
|
|
239
|
+
##### autoFix(): ColorGradingSettings
|
|
240
|
+
|
|
241
|
+
自动分析图像并优化。会根据图像的色阶分布和鲜艳度自动调整参数。
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
const settings = processor.autoFix();
|
|
245
|
+
// settings 包含自动计算的 whites、blacks、vibrance 等参数
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
**工作原理:**
|
|
249
|
+
1. 分析图像的直方图,找出有效的黑白色阶范围
|
|
250
|
+
2. 根据色阶范围自动调整 `whites` 和 `blacks` 参数
|
|
251
|
+
3. 分析图像的平均鲜艳度,如果不够鲜艳则自动增加 `vibrance`
|
|
252
|
+
|
|
253
|
+
##### applyPreset(preset: PresetType): ColorGradingSettings
|
|
254
|
+
|
|
255
|
+
应用预设滤镜效果。
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
// 应用流行风格
|
|
259
|
+
const settings = processor.applyPreset('pop');
|
|
260
|
+
|
|
261
|
+
// 应用黑白效果
|
|
262
|
+
processor.applyPreset('blackAndWhite');
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
**可用预设:**
|
|
266
|
+
|
|
267
|
+
| 预设名 | 说明 | 主要参数 |
|
|
268
|
+
|--------|------|----------|
|
|
269
|
+
| `auto` | 自动优化 | 根据图像分析自动调整 |
|
|
270
|
+
| `blackAndWhite` | 黑白 | 去色 + 对比度增强 |
|
|
271
|
+
| `pop` | 流行 | 高对比 + 高饱和 |
|
|
272
|
+
| `vintage` | 复古 | 褪色 + 暖色调 + 颗粒 |
|
|
273
|
+
| `vivid` | 鲜艳 | 高饱和 + 高清晰度 |
|
|
274
|
+
| `cinematic` | 电影 | 高对比 + 冷色调 + 暗角 |
|
|
275
|
+
|
|
276
|
+
### 图像分析函数
|
|
277
|
+
|
|
278
|
+
库还导出了独立的图像分析函数,可用于自定义分析逻辑。
|
|
279
|
+
|
|
280
|
+
##### analyzeImageLevels(imageData: ImageData): ImageLevels
|
|
281
|
+
|
|
282
|
+
分析图像的色阶分布。
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
import { analyzeImageLevels } from 'image-color-grading';
|
|
286
|
+
|
|
287
|
+
const canvas = document.querySelector('canvas');
|
|
288
|
+
const ctx = canvas.getContext('2d');
|
|
289
|
+
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
290
|
+
|
|
291
|
+
const levels = analyzeImageLevels(imageData);
|
|
292
|
+
console.log(levels.black); // 最暗有效像素值 (0-100)
|
|
293
|
+
console.log(levels.white); // 最亮有效像素值 (155-255)
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
##### analyzeImageVibrance(imageData: ImageData): number
|
|
297
|
+
|
|
298
|
+
分析图像的鲜艳度。
|
|
299
|
+
|
|
300
|
+
```typescript
|
|
301
|
+
import { analyzeImageVibrance } from 'image-color-grading';
|
|
302
|
+
|
|
303
|
+
const vibrance = analyzeImageVibrance(imageData);
|
|
304
|
+
console.log(vibrance); // 0-1 之间,值越高越鲜艳
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
##### analyzeImage(imageData: ImageData): ImageAnalysis
|
|
308
|
+
|
|
309
|
+
综合分析图像(包含色阶和鲜艳度)。
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
import { analyzeImage } from 'image-color-grading';
|
|
313
|
+
|
|
314
|
+
const analysis = analyzeImage(imageData);
|
|
315
|
+
console.log(analysis.levels); // { black, white }
|
|
316
|
+
console.log(analysis.vibrance); // 0-1
|
|
317
|
+
```
|
|
318
|
+
|
|
219
319
|
### 调色参数
|
|
220
320
|
|
|
221
321
|
所有参数的默认值为 `0`。
|
|
@@ -280,6 +380,21 @@ interface ExportOptions {
|
|
|
280
380
|
format?: 'image/png' | 'image/jpeg' | 'image/webp';
|
|
281
381
|
quality?: number; // 0-1, 仅对 jpeg/webp 有效
|
|
282
382
|
}
|
|
383
|
+
|
|
384
|
+
// 预设滤镜类型
|
|
385
|
+
type PresetType = 'auto' | 'blackAndWhite' | 'pop' | 'vintage' | 'vivid' | 'cinematic';
|
|
386
|
+
|
|
387
|
+
// 图像色阶分析结果
|
|
388
|
+
interface ImageLevels {
|
|
389
|
+
black: number; // 最暗有效像素值 (0-100)
|
|
390
|
+
white: number; // 最亮有效像素值 (155-255)
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// 图像分析结果
|
|
394
|
+
interface ImageAnalysis {
|
|
395
|
+
levels: ImageLevels;
|
|
396
|
+
vibrance: number; // 0-1
|
|
397
|
+
}
|
|
283
398
|
```
|
|
284
399
|
|
|
285
400
|
## 示例
|
|
@@ -392,43 +507,49 @@ async function batchProcess(imageUrls: string[], settings: Partial<ColorGradingS
|
|
|
392
507
|
}
|
|
393
508
|
```
|
|
394
509
|
|
|
395
|
-
###
|
|
510
|
+
### 使用内置预设滤镜
|
|
396
511
|
|
|
397
512
|
```typescript
|
|
398
|
-
import { ImageColorGrading,
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
//
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
513
|
+
import { ImageColorGrading, presets } from 'image-color-grading';
|
|
514
|
+
|
|
515
|
+
const processor = new ImageColorGrading();
|
|
516
|
+
await processor.loadImage('/sample.jpg');
|
|
517
|
+
|
|
518
|
+
// 方式1:使用 applyPreset 方法
|
|
519
|
+
processor.applyPreset('pop');
|
|
520
|
+
|
|
521
|
+
// 方式2:直接使用 presets 配置
|
|
522
|
+
console.log(presets.pop);
|
|
523
|
+
// { highlights: 50, shadows: -50, vibrance: 50, saturation: 20, exposure: 20, clarity: 20 }
|
|
524
|
+
|
|
525
|
+
// 自定义预设(基于内置预设扩展)
|
|
526
|
+
processor.setSettings({
|
|
527
|
+
...presets.vintage,
|
|
528
|
+
grain: 50, // 增加颗粒感
|
|
529
|
+
});
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
### 自动修复示例
|
|
533
|
+
|
|
534
|
+
```typescript
|
|
535
|
+
import { ImageColorGrading, analyzeImage } from 'image-color-grading';
|
|
536
|
+
|
|
537
|
+
const processor = new ImageColorGrading();
|
|
538
|
+
await processor.loadImage('/photo.jpg');
|
|
539
|
+
|
|
540
|
+
// 方式1:一键自动修复
|
|
541
|
+
processor.autoFix();
|
|
542
|
+
|
|
543
|
+
// 方式2:手动分析并自定义调整
|
|
544
|
+
const imageData = processor.getImageData();
|
|
545
|
+
const analysis = analyzeImage(imageData);
|
|
546
|
+
|
|
547
|
+
if (analysis.vibrance < 0.5) {
|
|
548
|
+
// 图像非常暗淡,需要更强的增强
|
|
549
|
+
processor.setSettings({
|
|
550
|
+
vibrance: 60,
|
|
551
|
+
saturation: 30,
|
|
552
|
+
});
|
|
432
553
|
}
|
|
433
554
|
```
|
|
434
555
|
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e="\nprecision highp float;\nattribute vec2 aPosition;\nattribute vec2 aTexCoord;\nvarying vec2 vUv;\nvoid main() {\n vUv = aTexCoord;\n gl_Position = vec4(aPosition, 0.0, 1.0);\n}\n",n="\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform vec2 uTexel;\nuniform float uKernel[9];\nuniform float uAmount;\nvoid main(void) {\n vec4 c11 = texture2D(uTexture, vUv - uTexel);\n vec4 c12 = texture2D(uTexture, vec2(vUv.x, vUv.y - uTexel.y));\n vec4 c13 = texture2D(uTexture, vec2(vUv.x + uTexel.x, vUv.y - uTexel.y));\n vec4 c21 = texture2D(uTexture, vec2(vUv.x - uTexel.x, vUv.y));\n vec4 c22 = texture2D(uTexture, vUv);\n vec4 c23 = texture2D(uTexture, vec2(vUv.x + uTexel.x, vUv.y));\n vec4 c31 = texture2D(uTexture, vec2(vUv.x - uTexel.x, vUv.y + uTexel.y));\n vec4 c32 = texture2D(uTexture, vec2(vUv.x, vUv.y + uTexel.y));\n vec4 c33 = texture2D(uTexture, vUv + uTexel);\n vec4 color = c11 * uKernel[0] + c12 * uKernel[1] + c13 * uKernel[2] +\n c21 * uKernel[3] + c22 * uKernel[4] + c23 * uKernel[5] +\n c31 * uKernel[6] + c32 * uKernel[7] + c33 * uKernel[8];\n gl_FragColor = color * uAmount + (c22 * (1.0 - uAmount));\n}\n";function t(e,n,t){const r=e.createShader(n);return r?(e.shaderSource(r,t),e.compileShader(r),e.getShaderParameter(r,e.COMPILE_STATUS)?r:(e.deleteShader(r),null)):null}function r(e,n,r,o){const a=t(e,e.VERTEX_SHADER,n),i=t(e,e.FRAGMENT_SHADER,r);if(!a||!i)throw new Error("Shader compile failed.");const c=function(e,n,t){const r=e.createProgram();return r?(e.attachShader(r,n),e.attachShader(r,t),e.linkProgram(r),e.getProgramParameter(r,e.LINK_STATUS)?r:(e.deleteProgram(r),null)):null}(e,a,i);if(!c)throw new Error("Program link failed.");const u={aPosition:e.getAttribLocation(c,"aPosition"),aTexCoord:e.getAttribLocation(c,"aTexCoord"),apos:e.getAttribLocation(c,"apos"),auv:e.getAttribLocation(c,"auv")},l={};return o.forEach(n=>{l[n]=e.getUniformLocation(c,n)}),{program:c,attribs:u,uniforms:l}}function o(e,n,t){const r=e.createTexture();if(!r)throw new Error("Unable to create texture");e.bindTexture(e.TEXTURE_2D,r),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,n,t,0,e.RGBA,e.UNSIGNED_BYTE,null),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE);const o=e.createFramebuffer();if(!o)throw new Error("Unable to create framebuffer");return e.bindFramebuffer(e.FRAMEBUFFER,o),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,r,0),{framebuffer:o,texture:r}}var a=e=>Math.min(1,Math.max(0,e)),i=(e,n,t,r,o)=>{const a=1-e;return a*a*a*n+3*a*a*e*t+3*a*e*e*r+e*e*e*o},c=e=>{const n=Math.max(-100,Math.min(100,e))/100;return(e=>{const n=new Uint8Array(768);for(let t=0;t<256;t+=1){const r=i(t/255,0,e,.66,1),o=Math.round(255*a(r)),c=3*t;n[c]=o,n[c+1]=o,n[c+2]=o}return n})(a(.33-.35*n))},u={vibrance:0,saturation:0,temperature:0,tint:0,hue:0,brightness:0,exposure:0,contrast:0,blacks:0,whites:0,highlights:0,shadows:0,dehaze:0,bloom:0,glamour:0,clarity:0,sharpen:0,smooth:0,blur:0,vignette:0,grain:0},l={auto:{},blackAndWhite:{saturation:-100,contrast:20,exposure:10,clarity:10},pop:{highlights:50,shadows:-50,vibrance:50,saturation:20,exposure:20,clarity:20},vintage:{saturation:-20,contrast:10,temperature:15,grain:30,vignette:25},vivid:{vibrance:40,saturation:20,contrast:15,clarity:20},cinematic:{contrast:25,highlights:-20,shadows:15,temperature:-10,vignette:30}};function s(e){const{data:n,width:t,height:r}=e,o=new Array(256).fill(0);for(let e=0;e<n.length;e+=4)o[n[e]]+=1,o[n[e+1]]+=1,o[n[e+2]]+=1;const a=Math.round(t*r/1e3);let i=0;for(let e=0;e<256;e++)if(o[e]>a){i=e;break}let c=255;for(let e=255;e>=0;e--)if(o[e]>a){c=e;break}return i>100&&(i=100),c<155&&(c=155),{black:i,white:c}}function v(e){const{data:n,width:t,height:r}=e;let o=1,a=1;for(let e=0;e<n.length;e+=4){const t=n[e],r=n[e+1],i=n[e+2],c=Math.min(t,r,i),u=Math.max(t,r,i);a+=u/255;const l=u-c;l>0&&(o+=l/u)}return(o+a)/(t*r*2)}function m(e){return{levels:s(e),vibrance:v(e)}}exports.ImageColorGrading=class{constructor(e){this.resources=null,this.settings={...u},this.imageLoaded=!1,this.canvas=e||document.createElement("canvas")}getCanvas(){return this.canvas}getSettings(){return{...this.settings}}setSettings(e){this.settings={...this.settings,...e},this.resources&&this.render()}resetSettings(){this.settings={...u},this.resources&&this.render()}loadImage(e){return new Promise((n,t)=>{const r=new Image;r.crossOrigin="anonymous",r.onload=()=>{this.initFromImage(r),n()},r.onerror=()=>{t(new Error(`Failed to load image: ${e}`))},r.src=e})}loadFromImage(e){this.initFromImage(e)}loadFromFile(e){return new Promise((n,t)=>{const r=URL.createObjectURL(e);this.loadImage(r).then(()=>{URL.revokeObjectURL(r),n()}).catch(e=>{URL.revokeObjectURL(r),t(e)})})}loadFromImageData(e){const{width:n,height:t,data:r}=e;this.canvas.width=n,this.canvas.height=t;const o=this.getWebGLContext();if(!o)throw new Error("WebGL not supported");this.disposeResources(),o.viewport(0,0,n,t),o.pixelStorei(o.UNPACK_FLIP_Y_WEBGL,1);const a=o.createTexture();if(!a)throw new Error("Failed to create texture");o.bindTexture(o.TEXTURE_2D,a),o.texImage2D(o.TEXTURE_2D,0,o.RGBA,n,t,0,o.RGBA,o.UNSIGNED_BYTE,r),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_MIN_FILTER,o.LINEAR),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_MAG_FILTER,o.LINEAR),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_WRAP_S,o.CLAMP_TO_EDGE),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_WRAP_T,o.CLAMP_TO_EDGE),this.initResources(o,n,t,a)}render(){this.resources&&this.drawFrame(this.resources,this.settings)}toDataURL(e){const n=e?.format||"image/png",t=e?.quality;return this.canvas.toDataURL(n,t)}toBlob(e){return new Promise((n,t)=>{const r=e?.format||"image/png",o=e?.quality;this.canvas.toBlob(e=>{e?n(e):t(new Error("Failed to create blob"))},r,o)})}getImageData(){const e=this.canvas.getContext("2d");if(e)return e.getImageData(0,0,this.canvas.width,this.canvas.height);const n=this.canvas.getContext("webgl");if(n){const e=new Uint8ClampedArray(this.canvas.width*this.canvas.height*4);return n.readPixels(0,0,this.canvas.width,this.canvas.height,n.RGBA,n.UNSIGNED_BYTE,e),new ImageData(e,this.canvas.width,this.canvas.height)}throw new Error("Cannot get ImageData")}getSize(){return{width:this.canvas.width,height:this.canvas.height}}isLoaded(){return this.imageLoaded}dispose(){this.disposeResources(),this.imageLoaded=!1}analyze(){if(!this.imageLoaded)throw new Error("No image loaded");const e={...this.settings};this.settings={...u},this.render();const n=m(this.getImageData());return this.settings=e,this.render(),n}autoFix(){if(!this.imageLoaded)throw new Error("No image loaded");this.settings={...u},this.render();const e=this.getImageData(),n=s(e),t=v(e),r={...u};if(r.whites=Math.round(255-n.white),r.blacks=Math.round(n.black),t<.7){const e=Math.round(100*(.7-t));r.vibrance=Math.min(e,50)}return this.settings=r,this.render(),r}applyPreset(e){if("auto"===e)return this.autoFix();const n=l[e],t={...u,...n};return this.settings=t,this.resources&&this.render(),t}getWebGLContext(){return this.canvas.getContext("webgl",{antialias:!0,premultipliedAlpha:!1,preserveDrawingBuffer:!0})}initFromImage(e){const n=e.naturalWidth||e.width,t=e.naturalHeight||e.height;this.canvas.width=n,this.canvas.height=t;const r=this.getWebGLContext();if(!r)throw new Error("WebGL not supported");this.disposeResources(),r.disable(r.DEPTH_TEST),r.viewport(0,0,n,t),r.pixelStorei(r.UNPACK_FLIP_Y_WEBGL,1);const o=r.createTexture();if(!o)throw new Error("Failed to create texture");r.bindTexture(r.TEXTURE_2D,o),r.texImage2D(r.TEXTURE_2D,0,r.RGBA,r.RGBA,r.UNSIGNED_BYTE,e),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_MIN_FILTER,r.LINEAR),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_MAG_FILTER,r.LINEAR),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_WRAP_S,r.CLAMP_TO_EDGE),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_WRAP_T,r.CLAMP_TO_EDGE),this.initResources(r,n,t,o)}initResources(t,a,i,u){const l=((e,n)=>{const t=e.createTexture();if(!t)throw new Error("Unable to create palette texture");return e.bindTexture(e.TEXTURE_2D,t),e.texImage2D(e.TEXTURE_2D,0,e.RGB,256,1,0,e.RGB,e.UNSIGNED_BYTE,n),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),t})(t,c(0)),s=t.createBuffer(),v=t.createBuffer();if(!s||!v)throw new Error("Failed to create buffers");t.bindBuffer(t.ARRAY_BUFFER,s),t.bufferData(t.ARRAY_BUFFER,new Float32Array([-1,-1,1,-1,-1,1,1,1]),t.STATIC_DRAW),t.bindBuffer(t.ARRAY_BUFFER,v),t.bufferData(t.ARRAY_BUFFER,new Float32Array([0,0,1,0,0,1,1,1]),t.STATIC_DRAW);const m={pass:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nvoid main() {\n gl_FragColor = texture2D(uTexture, vUv);\n}\n",["uTexture"]),vibrance:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uAmount;\nvoid main() {\n vec4 col = texture2D(uTexture, vUv);\n vec3 color = col.rgb;\n float luminance = color.r * 0.299 + color.g * 0.587 + color.b * 0.114;\n float mn = min(min(color.r, color.g), color.b);\n float mx = max(max(color.r, color.g), color.b);\n float sat = (1.0 - (mx - mn)) * (1.0 - mx) * luminance * 5.0;\n vec3 lightness = vec3((mn + mx) / 2.0);\n color = mix(color, mix(color, lightness, -uAmount), sat);\n gl_FragColor = vec4(\n mix(color, lightness, (1.0 - lightness) * (1.0 - uAmount) / 2.0 * abs(uAmount)),\n col.a\n );\n}\n",["uTexture","uAmount"]),saturation:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uMatrix[20];\nvoid main(void) {\n vec4 c = texture2D(uTexture, vUv);\n gl_FragColor.r = uMatrix[0] * c.r + uMatrix[1] * c.g + uMatrix[2] * c.b + uMatrix[3] * c.a + uMatrix[4];\n gl_FragColor.g = uMatrix[5] * c.r + uMatrix[6] * c.g + uMatrix[7] * c.b + uMatrix[8] * c.a + uMatrix[9];\n gl_FragColor.b = uMatrix[10] * c.r + uMatrix[11] * c.g + uMatrix[12] * c.b + uMatrix[13] * c.a + uMatrix[14];\n gl_FragColor.a = uMatrix[15] * c.r + uMatrix[16] * c.g + uMatrix[17] * c.b + uMatrix[18] * c.a + uMatrix[19];\n}\n",["uTexture","uMatrix[0]"]),temperature:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uAmount;\nvoid main() {\n vec4 color = texture2D(uTexture, vUv);\n color.r = clamp(color.r + uAmount, 0.0, 1.0);\n color.b = clamp(color.b - uAmount, 0.0, 1.0);\n gl_FragColor = color;\n}\n",["uTexture","uAmount"]),tint:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uAmount;\nvoid main() {\n vec4 color = texture2D(uTexture, vUv);\n color.g = clamp(color.g + uAmount, 0.0, 1.0);\n gl_FragColor = color;\n}\n",["uTexture","uAmount"]),hue:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uRotation;\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 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}\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}\nvoid main() {\n lowp vec4 base = texture2D(uTexture, vUv);\n vec3 hsv = rgb2hsv(base.rgb);\n hsv.x = fract(hsv.x + uRotation);\n gl_FragColor = vec4(hsv2rgb(hsv), base.a);\n}\n",["uTexture","uRotation"]),brightness:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uAmount;\nconst float PI = 3.1415926535897932384626433832795;\nvoid main() {\n vec4 color = texture2D(uTexture, vUv);\n if (uAmount >= 0.0) {\n color.r = color.r + uAmount * sin(color.r * PI);\n color.g = color.g + uAmount * sin(color.g * PI);\n color.b = color.b + uAmount * sin(color.b * PI);\n } else {\n color.r = (1.0 + uAmount) * color.r;\n color.g = (1.0 + uAmount) * color.g;\n color.b = (1.0 + uAmount) * color.b;\n }\n gl_FragColor = color;\n}\n",["uTexture","uAmount"]),exposure:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uAmount;\nconst float epsilon = 0.000001;\nconst float mx = 1.0 - epsilon;\nconst mat3 matRGBtoROMM = mat3(\n 0.5293459296226501, 0.3300727903842926, 0.14058130979537964,\n 0.09837432950735092, 0.8734610080718994, 0.028164653107523918,\n 0.01688321679830551, 0.11767247319221497, 0.8654443025588989\n);\nconst mat3 matROMMtoRGB = mat3(\n 2.0340757369995117, -0.727334201335907, -0.3067416846752167,\n -0.22881317138671875, 1.2317301034927368, -0.0029169507324695587,\n -0.008569774217903614, -0.1532866358757019, 1.1618564128875732\n);\nfloat ramp(in float t) {\n t *= 2.0;\n if (t >= 1.0) {\n t -= 1.0;\n t = log(0.5) / log(0.5 * (1.0 - t) + 0.9332 * t);\n }\n return clamp(t, 0.001, 10.0);\n}\nvec3 rgb2hsv(in 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 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}\nvec3 hsv2rgb(in 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}\nvec3 setHue(in vec3 res, in vec3 base) {\n vec3 hsv = rgb2hsv(base);\n vec3 res_hsv = rgb2hsv(res);\n return hsv2rgb(vec3(hsv.x, res_hsv.y, res_hsv.z));\n}\nvoid main() {\n lowp vec4 col = texture2D(uTexture, vUv);\n vec3 base = col.rgb * matRGBtoROMM;\n float a = abs(uAmount) * col.a + epsilon;\n float v = pow(2.0, a * 2.0 + 1.0) - 2.0;\n float m = mx - exp(-v);\n vec3 res = (uAmount > 0.0) ? (1.0 - exp(-v * base)) / m : log(1.0 - base * m) / -v;\n res = mix(base, res, min(a * 100.0, 1.0));\n res = setHue(res, base);\n res = pow(res, vec3(ramp(1.0 - (0.0 * col.a + 1.0) / 2.0)));\n res = res * matROMMtoRGB;\n gl_FragColor = vec4(res, col.a);\n}\n",["uTexture","uAmount"]),contrast:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uMatrix[20];\nvoid main(void) {\n vec4 c = texture2D(uTexture, vUv);\n gl_FragColor.r = uMatrix[0] * c.r + uMatrix[1] * c.g + uMatrix[2] * c.b + uMatrix[3] * c.a + uMatrix[4];\n gl_FragColor.g = uMatrix[5] * c.r + uMatrix[6] * c.g + uMatrix[7] * c.b + uMatrix[8] * c.a + uMatrix[9];\n gl_FragColor.b = uMatrix[10] * c.r + uMatrix[11] * c.g + uMatrix[12] * c.b + uMatrix[13] * c.a + uMatrix[14];\n gl_FragColor.a = uMatrix[15] * c.r + uMatrix[16] * c.g + uMatrix[17] * c.b + uMatrix[18] * c.a + uMatrix[19];\n}\n",["uTexture","uMatrix[0]"]),blacks:r(t,"\nprecision highp float;\nattribute vec2 apos;\nattribute vec2 auv;\nvarying vec2 uv;\nuniform vec4 transform;\nvoid main(void) {\n uv = auv;\n gl_Position = vec4(\n apos.x * transform.x + transform.z,\n apos.y * transform.y + transform.w,\n 0.0,\n 1.0\n );\n}\n","\nprecision highp float;\nvarying vec2 uv;\nuniform sampler2D uTexture;\nuniform sampler2D uPaletteMap;\nvoid main() {\n lowp vec4 base = texture2D(uTexture, uv.xy);\n float r = texture2D(uPaletteMap, vec2(base.r, 0.0)).r;\n float g = texture2D(uPaletteMap, vec2(base.g, 0.0)).g;\n float b = texture2D(uPaletteMap, vec2(base.b, 0.0)).b;\n gl_FragColor = vec4(r, g, b, base.a);\n}\n",["uTexture","uPaletteMap","transform"]),whites:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uAmount;\nconst vec3 RGB2Y = vec3(0.2126, 0.7152, 0.0722);\nvoid main() {\n vec4 base = texture2D(uTexture, vUv.xy);\n vec3 color = base.rgb;\n float lum = dot(color, RGB2Y);\n float whiteMask = smoothstep(0.5, 1.0, lum);\n color += uAmount * whiteMask;\n gl_FragColor = vec4(clamp(color, 0.0, 1.0), base.a);\n}\n",["uTexture","uAmount"]),highlights:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uAmount;\nconst float epsilon = 0.000001;\nconst float mx = 1.0 - epsilon;\nconst float PI = 3.1415926535897932384626433832795;\nconst mat3 matRGBtoROMM = mat3(\n 0.5293459296226501, 0.3300727903842926, 0.14058130979537964,\n 0.09837432950735092, 0.8734610080718994, 0.028164653107523918,\n 0.01688321679830551, 0.11767247319221497, 0.8654443025588989\n);\nconst mat3 matROMMtoRGB = mat3(\n 2.0340757369995117, -0.727334201335907, -0.3067416846752167,\n -0.22881317138671875, 1.2317301034927368, -0.0029169507324695587,\n -0.008569774217903614, -0.1532866358757019, 1.1618564128875732\n);\nfloat luma_romm(in vec3 color) {\n return dot(color, vec3(0.242655, 0.755158, 0.002187));\n}\nfloat luma(in vec3 color) {\n return dot(color, vec3(0.298839, 0.586811, 0.11435));\n}\nvec3 rgb2hsv(in 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 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}\nvec3 hsv2rgb(in 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}\nvec3 setHue(in vec3 res, in vec3 base) {\n vec3 hsv = rgb2hsv(base);\n vec3 res_hsv = rgb2hsv(res);\n return hsv2rgb(vec3(hsv.x, res_hsv.y, res_hsv.z));\n}\nfloat gaussian(in float x) {\n return 1.0 - exp(-PI * 2.0 * x * x);\n}\nvoid main() {\n lowp vec4 col = texture2D(uTexture, vUv);\n lowp vec3 map = col.rgb;\n vec3 base = col.rgb * matRGBtoROMM;\n float base_lum = luma(col.rgb);\n float map_lum = luma_romm(map * matRGBtoROMM);\n float exposure = mix(uAmount, 0.0, 1.0 - map_lum) * col.a;\n float a = abs(exposure) * col.a + epsilon;\n float v = pow(2.0, a + 1.0) - 2.0;\n float m = mx - exp(-v);\n vec3 res = (exposure > 0.0) ? (1.0 - exp(-v * base)) / m : log(1.0 - base * m) / -v;\n res = mix(base, res, min(a * 100.0, 1.0));\n res = setHue(res, base);\n res = res * matROMMtoRGB;\n gl_FragColor = vec4(res, col.a);\n}\n",["uTexture","uAmount"]),shadows:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uAmount;\nconst float epsilon = 0.000001;\nconst float mx = 1.0 - epsilon;\nconst float PI = 3.1415926535897932384626433832795;\nconst mat3 matRGBtoROMM = mat3(\n 0.5293459296226501, 0.3300727903842926, 0.14058130979537964,\n 0.09837432950735092, 0.8734610080718994, 0.028164653107523918,\n 0.01688321679830551, 0.11767247319221497, 0.8654443025588989\n);\nconst mat3 matROMMtoRGB = mat3(\n 2.0340757369995117, -0.727334201335907, -0.3067416846752167,\n -0.22881317138671875, 1.2317301034927368, -0.0029169507324695587,\n -0.008569774217903614, -0.1532866358757019, 1.1618564128875732\n);\nfloat luma_romm(in vec3 color) {\n return dot(color, vec3(0.242655, 0.755158, 0.002187));\n}\nfloat luma(in vec3 color) {\n return dot(color, vec3(0.298839, 0.586811, 0.11435));\n}\nvec3 rgb2hsv(in 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 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}\nvec3 hsv2rgb(in 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}\nvec3 setHue(in vec3 res, in vec3 base) {\n vec3 hsv = rgb2hsv(base);\n vec3 res_hsv = rgb2hsv(res);\n return hsv2rgb(vec3(hsv.x, res_hsv.y, res_hsv.z));\n}\nfloat gaussian(in float x) {\n return 1.0 - exp(-PI * 2.0 * x * x);\n}\nvoid main() {\n lowp vec4 col = texture2D(uTexture, vUv);\n lowp vec3 map = col.rgb;\n vec3 base = col.rgb * matRGBtoROMM;\n float base_lum = luma(col.rgb);\n float map_lum = luma_romm(map * matRGBtoROMM);\n float exposure = mix(0.0, uAmount, 1.0 - map_lum) * col.a;\n float a = abs(exposure) * col.a + epsilon;\n float v = pow(2.0, a + 1.0) - 2.0;\n float m = mx - exp(-v);\n vec3 res = (exposure > 0.0) ? (1.0 - exp(-v * base)) / m : log(1.0 - base * m) / -v;\n res = mix(base, res, min(a * 100.0, 1.0));\n res = setHue(res, base);\n res = res * matROMMtoRGB;\n gl_FragColor = vec4(res, col.a);\n}\n",["uTexture","uAmount"]),dehaze:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uAmount;\nuniform vec2 uSize;\n\nfloat hazeMap(vec2 coord) {\n vec3 color = vec3(1.0);\n vec2 stepSize = vec2(1.0 / uSize.x, 1.0 / uSize.y);\n for (int i = -1; i <= 1; ++i) {\n for (int j = -1; j <= 1; ++j) {\n vec2 offset = vec2(float(i), float(j)) * stepSize;\n vec2 uv = clamp(coord + offset, 0.0, 1.0);\n vec3 sample = texture2D(uTexture, uv).rgb;\n color = min(color, sample);\n }\n }\n return min(color.r, min(color.g, color.b));\n}\n\nvoid main() {\n vec4 base = texture2D(uTexture, vUv);\n float haze = hazeMap(vUv);\n float transmission = 1.0 - 0.95 * haze;\n const float A = 0.95;\n const float t0 = 0.1;\n float t = mix(1.0, max(t0, transmission), uAmount);\n vec3 J = (base.rgb - A) / t + A;\n gl_FragColor = vec4(J, base.a);\n}\n",["uTexture","uAmount","uSize"]),bloom:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uAmount;\nuniform vec2 uTexel;\nuniform float uThreshold;\n\nvoid main() {\n vec4 sum = vec4(0.0);\n int j = -2;\n for (int i = -2; i <= 2; i++) sum += texture2D(uTexture, vUv + vec2(float(i), float(j)) * uTexel);\n j = -1;\n for (int i = -2; i <= 2; i++) sum += texture2D(uTexture, vUv + vec2(float(i), float(j)) * uTexel);\n j = 0;\n for (int i = -2; i <= 2; i++) sum += texture2D(uTexture, vUv + vec2(float(i), float(j)) * uTexel);\n j = 1;\n for (int i = -2; i <= 2; i++) sum += texture2D(uTexture, vUv + vec2(float(i), float(j)) * uTexel);\n j = 2;\n for (int i = -2; i <= 2; i++) sum += texture2D(uTexture, vUv + vec2(float(i), float(j)) * uTexel);\n sum /= 25.0;\n vec4 base = texture2D(uTexture, vUv);\n if (length(sum.rgb) > uThreshold) {\n base += sum * uAmount;\n }\n gl_FragColor = base;\n}\n",["uTexture","uAmount","uTexel","uThreshold"]),glamour:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uAmount;\nuniform vec2 uTexel;\n\nfloat normpdf(in float x, in float sigma) {\n return 0.39894 * exp(-0.5 * x * x / (sigma * sigma)) / sigma;\n}\n\nvec3 blurMap() {\n const int mSize = 11;\n const int kSize = (mSize - 1) / 2;\n float kernel[mSize];\n vec3 final_colour = vec3(0.0);\n float sigma = 7.0;\n float Z = 0.0;\n for (int j = 0; j <= kSize; ++j) {\n kernel[kSize + j] = kernel[kSize - j] = normpdf(float(j), sigma);\n }\n for (int j = 0; j < mSize; ++j) {\n Z += kernel[j];\n }\n for (int i = -kSize; i <= kSize; ++i) {\n for (int j = -kSize; j <= kSize; ++j) {\n final_colour += kernel[kSize + j] * kernel[kSize + i] *\n texture2D(uTexture, vUv + vec2(float(i), float(j)) * uTexel).rgb;\n }\n }\n return vec3(final_colour / (Z * Z));\n}\n\nfloat luma(vec3 color) {\n return dot(color, vec3(0.299, 0.587, 0.114));\n}\n\nvoid main() {\n vec4 base = texture2D(uTexture, vUv);\n vec3 color = blurMap();\n color = vec3(luma(color));\n color = vec3(\n (base.r <= 0.5) ? (2.0 * base.r * color.r) : (1.0 - 2.0 * (1.0 - base.r) * (1.0 - color.r)),\n (base.g <= 0.5) ? (2.0 * base.g * color.g) : (1.0 - 2.0 * (1.0 - base.g) * (1.0 - color.g)),\n (base.b <= 0.5) ? (2.0 * base.b * color.b) : (1.0 - 2.0 * (1.0 - base.b) * (1.0 - color.b))\n );\n gl_FragColor = mix(base, vec4(color, base.a), uAmount);\n}\n",["uTexture","uAmount","uTexel"]),clarity:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uAmount;\nuniform vec2 uTexel;\n\nfloat Lum(vec3 c) {\n return 0.299 * c.r + 0.587 * c.g + 0.114 * c.b;\n}\nfloat BlendOverlayf(float base, float blend) {\n return (base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend)));\n}\nvec3 BlendOverlay(vec3 base, vec3 blend) {\n return vec3(BlendOverlayf(base.r, blend.r), BlendOverlayf(base.g, blend.g), BlendOverlayf(base.b, blend.b));\n}\nfloat BlendVividLightf(float base, float blend) {\n float BlendColorBurnf = (((2.0 * blend) == 0.0) ? (2.0 * blend) : max((1.0 - ((1.0 - base) / (2.0 * blend))), 0.0));\n float BlendColorDodgef = (((2.0 * (blend - 0.5)) == 1.0) ? (2.0 * (blend - 0.5)) : min(base / (1.0 - (2.0 * (blend - 0.5))), 1.0));\n return ((blend < 0.5) ? BlendColorBurnf : BlendColorDodgef);\n}\nvec3 BlendVividLight(vec3 base, vec3 blend) {\n return vec3(BlendVividLightf(base.r, blend.r), BlendVividLightf(base.g, blend.g), BlendVividLightf(base.b, blend.b));\n}\nfloat normpdf(in float x, in float sigma) {\n return 0.39894 * exp(-0.5 * x * x / (sigma * sigma)) / sigma;\n}\nvec3 blurMap() {\n const int mSize = 11;\n const int kSize = (mSize - 1) / 2;\n float kernel[mSize];\n vec3 final_colour = vec3(0.0);\n float sigma = 7.0;\n float Z = 0.0;\n for (int j = 0; j <= kSize; ++j) {\n kernel[kSize + j] = kernel[kSize - j] = normpdf(float(j), sigma);\n }\n for (int j = 0; j < mSize; ++j) {\n Z += kernel[j];\n }\n for (int i = -kSize; i <= kSize; ++i) {\n for (int j = -kSize; j <= kSize; ++j) {\n final_colour += kernel[kSize + j] * kernel[kSize + i] *\n texture2D(uTexture, vUv + vec2(float(i), float(j)) * uTexel).rgb;\n }\n }\n return vec3(final_colour / (Z * Z));\n}\nvoid main() {\n vec4 base4 = texture2D(uTexture, vUv);\n vec3 blur = blurMap();\n vec3 base = base4.rgb;\n float intensity = (uAmount < 0.0) ? (uAmount / 2.0) : uAmount;\n float lum = Lum(base);\n vec3 col = vec3(lum);\n vec3 mask = vec3(1.0 - pow(lum, 1.8));\n vec3 layer = vec3(1.0 - Lum(blur));\n vec3 detail = clamp(BlendVividLight(col, layer), 0.0, 1.0);\n vec3 inverse = mix(1.0 - detail, detail, (intensity + 1.0) / 2.0);\n gl_FragColor = vec4(BlendOverlay(base, mix(vec3(0.5), inverse, mask)), base4.a);\n}\n",["uTexture","uAmount","uTexel"]),sharpen:r(t,e,n,["uTexture","uTexel","uKernel[0]","uAmount"]),smooth:r(t,e,n,["uTexture","uTexel","uKernel[0]","uAmount"]),blur:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform vec2 uSize;\nfloat random(vec3 scale, float seed) {\n return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);\n}\nvoid main() {\n vec4 color = vec4(0.0);\n float total = 0.0;\n float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);\n for (int t = -30; t <= 30; t++) {\n float percent = (float(t) + offset - 0.5) / 30.0;\n float weight = 1.0 - abs(percent);\n vec4 sample = texture2D(uTexture, vUv + uSize * percent);\n sample.rgb *= sample.a;\n color += sample * weight;\n total += weight;\n }\n gl_FragColor = color / total;\n gl_FragColor.rgb /= gl_FragColor.a + 0.00001;\n}\n",["uTexture","uSize"]),vignette:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uAmount;\nuniform float uSize;\nvoid main() {\n vec4 color = texture2D(uTexture, vUv);\n float dist = distance(vUv, vec2(0.5, 0.5));\n float amt = clamp(uAmount, -1.0, 1.0);\n float edge = dist * (abs(amt) * 0.75 + uSize * 2.0);\n float vignette = smoothstep(0.8, uSize * 0.799, edge);\n if (amt < 0.0) {\n vignette = 1.0 + (1.0 - vignette) * (-amt);\n } else {\n vignette = mix(1.0, vignette, amt);\n }\n color.rgb *= vignette;\n gl_FragColor = color;\n}\n",["uTexture","uAmount","uSize"]),grain:r(t,e,"\nprecision highp float;\nuniform sampler2D uTexture;\nvarying vec2 vUv;\nuniform vec2 uResolution;\nuniform float uAmount;\nuniform float uTime;\nconst float permTexUnit = 1.0 / 256.0;\nconst float permTexUnitHalf = 0.5 / 256.0;\nfloat grainsize = 1.8;\nfloat lumamount = 1.0;\n\nvec4 rnm(in vec2 tc) {\n float noise = sin(dot(tc + vec2(uTime, uTime), vec2(12.9898, 78.233))) * 43758.5453;\n float noiseR = fract(noise) * 2.0 - 1.0;\n float noiseG = fract(noise * 1.2154) * 2.0 - 1.0;\n float noiseB = fract(noise * 1.3453) * 2.0 - 1.0;\n float noiseA = fract(noise * 1.3647) * 2.0 - 1.0;\n return vec4(noiseR, noiseG, noiseB, noiseA);\n}\nfloat fade(in float t) {\n return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);\n}\nfloat pnoise3D(in vec3 p) {\n vec3 pi = permTexUnit * floor(p) + permTexUnitHalf;\n vec3 pf = fract(p);\n float perm00 = rnm(pi.xy).a;\n vec3 grad000 = rnm(vec2(perm00, pi.z)).rgb * 4.0 - 1.0;\n float n000 = dot(grad000, pf);\n vec3 grad001 = rnm(vec2(perm00, pi.z + permTexUnit)).rgb * 4.0 - 1.0;\n float n001 = dot(grad001, pf - vec3(0.0, 0.0, 1.0));\n float perm01 = rnm(pi.xy + vec2(0.0, permTexUnit)).a;\n vec3 grad010 = rnm(vec2(perm01, pi.z)).rgb * 4.0 - 1.0;\n float n010 = dot(grad010, pf - vec3(0.0, 1.0, 0.0));\n vec3 grad011 = rnm(vec2(perm01, pi.z + permTexUnit)).rgb * 4.0 - 1.0;\n float n011 = dot(grad011, pf - vec3(0.0, 1.0, 1.0));\n float perm10 = rnm(pi.xy + vec2(permTexUnit, 0.0)).a;\n vec3 grad100 = rnm(vec2(perm10, pi.z)).rgb * 4.0 - 1.0;\n float n100 = dot(grad100, pf - vec3(1.0, 0.0, 0.0));\n vec3 grad101 = rnm(vec2(perm10, pi.z + permTexUnit)).rgb * 4.0 - 1.0;\n float n101 = dot(grad101, pf - vec3(1.0, 0.0, 1.0));\n float perm11 = rnm(pi.xy + vec2(permTexUnit, permTexUnit)).a;\n vec3 grad110 = rnm(vec2(perm11, pi.z)).rgb * 4.0 - 1.0;\n float n110 = dot(grad110, pf - vec3(1.0, 1.0, 0.0));\n vec3 grad111 = rnm(vec2(perm11, pi.z + permTexUnit)).rgb * 4.0 - 1.0;\n float n111 = dot(grad111, pf - vec3(1.0, 1.0, 1.0));\n vec4 n_x = mix(vec4(n000, n001, n010, n011), vec4(n100, n101, n110, n111), fade(pf.x));\n vec2 n_xy = mix(n_x.xy, n_x.zw, fade(pf.y));\n float n_xyz = mix(n_xy.x, n_xy.y, fade(pf.z));\n return n_xyz;\n}\nvec2 coordRot(in vec2 tc, in float angle) {\n float aspect = uResolution.x / uResolution.y;\n float rotX = ((tc.x * 2.0 - 1.0) * aspect * cos(angle)) - ((tc.y * 2.0 - 1.0) * sin(angle));\n float rotY = ((tc.y * 2.0 - 1.0) * cos(angle)) + ((tc.x * 2.0 - 1.0) * aspect * sin(angle));\n rotX = ((rotX / aspect) * 0.5 + 0.5);\n rotY = rotY * 0.5 + 0.5;\n return vec2(rotX, rotY);\n}\nvoid main() {\n vec3 rotOffset = vec3(1.425, 3.892, 5.835);\n vec2 rotCoordsR = coordRot(vUv, uTime + rotOffset.x);\n vec3 noise = vec3(pnoise3D(vec3(rotCoordsR * vec2(uResolution.x / grainsize, uResolution.y / grainsize), 0.0)));\n vec4 tex = texture2D(uTexture, vUv);\n vec3 col = tex.rgb;\n vec3 lumcoeff = vec3(0.299, 0.587, 0.114);\n float luminance = mix(0.0, dot(col, lumcoeff), lumamount);\n float lum = smoothstep(0.2, 0.0, luminance);\n lum += luminance;\n noise = mix(noise, vec3(0.0), pow(lum, 4.0));\n col = col + noise * uAmount;\n gl_FragColor = vec4(col, tex.a);\n}\n",["uTexture","uResolution","uAmount","uTime"])},x=[o(t,a,i),o(t,a,i)];this.resources={gl:t,width:a,height:i,sourceTexture:u,blackPalette:l,quad:{positionBuffer:s,texCoordBuffer:v},programs:m,targets:x},this.imageLoaded=!0,this.render()}disposeResources(){if(!this.resources)return;const{gl:e,sourceTexture:n,blackPalette:t,quad:r,programs:o,targets:a}=this.resources;e.deleteTexture(n),e.deleteTexture(t),e.deleteBuffer(r.positionBuffer),e.deleteBuffer(r.texCoordBuffer),a.forEach(n=>{e.deleteFramebuffer(n.framebuffer),e.deleteTexture(n.texture)}),Object.values(o).forEach(n=>{e.deleteProgram(n.program)}),this.resources=null}drawFrame(e,n){const{gl:t,width:r,height:o,sourceTexture:a,blackPalette:i,quad:u,programs:l,targets:s}=e;t.viewport(0,0,r,o);const v=[1/r,1/o];let m=a,x=0;const f=(e,n,r)=>{t.useProgram(e.program),(e=>{t.bindBuffer(t.ARRAY_BUFFER,u.positionBuffer);const n=e.attribs.aPosition>=0?e.attribs.aPosition:e.attribs.apos;n>=0&&(t.enableVertexAttribArray(n),t.vertexAttribPointer(n,2,t.FLOAT,!1,0,0)),t.bindBuffer(t.ARRAY_BUFFER,u.texCoordBuffer);const r=e.attribs.aTexCoord>=0?e.attribs.aTexCoord:e.attribs.auv;r>=0&&(t.enableVertexAttribArray(r),t.vertexAttribPointer(r,2,t.FLOAT,!1,0,0))})(e),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,m);const o=e.uniforms.uTexture;o&&t.uniform1i(o,0),n(),t.bindFramebuffer(t.FRAMEBUFFER,r?r.framebuffer:null),t.drawArrays(t.TRIANGLE_STRIP,0,4),m=r?r.texture:m},g=()=>{const e=s[x%2];return x+=1,e};Math.abs(n.vibrance)>.5&&f(l.vibrance,()=>{t.uniform1f(l.vibrance.uniforms.uAmount,n.vibrance/100)},g()),Math.abs(n.saturation)>.5&&f(l.saturation,()=>{const e=(e=>{const n=1+Math.max(-100,Math.min(100,e))/100,t=.299,r=.587,o=.114,a=1-n;return new Float32Array([a*t+n,a*r,a*o,0,0,a*t,a*r+n,a*o,0,0,a*t,a*r,a*o+n,0,0,0,0,0,1,0])})(n.saturation);t.uniform1fv(l.saturation.uniforms["uMatrix[0]"],e)},g()),Math.abs(n.temperature)>.5&&f(l.temperature,()=>{t.uniform1f(l.temperature.uniforms.uAmount,n.temperature/500)},g()),Math.abs(n.tint)>.5&&f(l.tint,()=>{t.uniform1f(l.tint.uniforms.uAmount,n.tint/500)},g()),Math.abs(n.hue)>.5&&f(l.hue,()=>{t.uniform1f(l.hue.uniforms.uRotation,n.hue/200)},g()),f(l.brightness,()=>{t.uniform1f(l.brightness.uniforms.uAmount,n.brightness/200)},g()),Math.abs(n.exposure)>.5&&f(l.exposure,()=>{t.uniform1f(l.exposure.uniforms.uAmount,n.exposure/100)},g()),Math.abs(n.contrast)>.5&&f(l.contrast,()=>{const e=(e=>{const n=1+Math.max(-100,Math.min(100,e))/100,t=.5*(1-n);return new Float32Array([n,0,0,0,t,0,n,0,0,t,0,0,n,0,t,0,0,0,1,0])})(n.contrast);t.uniform1fv(l.contrast.uniforms["uMatrix[0]"],e)},g()),Math.abs(n.blacks)>.5&&(((e,n,t)=>{e.bindTexture(e.TEXTURE_2D,n),e.texSubImage2D(e.TEXTURE_2D,0,0,0,256,1,e.RGB,e.UNSIGNED_BYTE,t)})(t,i,c(n.blacks)),f(l.blacks,()=>{t.activeTexture(t.TEXTURE1),t.bindTexture(t.TEXTURE_2D,i),t.uniform1i(l.blacks.uniforms.uPaletteMap,1),t.uniform4f(l.blacks.uniforms.transform,1,1,0,0),t.activeTexture(t.TEXTURE0)},g())),Math.abs(n.whites)>.5&&f(l.whites,()=>{t.uniform1f(l.whites.uniforms.uAmount,n.whites/400)},g()),Math.abs(n.highlights)>.5&&f(l.highlights,()=>{t.uniform1f(l.highlights.uniforms.uAmount,n.highlights/100)},g()),Math.abs(n.shadows)>.5&&f(l.shadows,()=>{t.uniform1f(l.shadows.uniforms.uAmount,n.shadows/100)},g()),Math.abs(n.dehaze)>.5&&f(l.dehaze,()=>{t.uniform1f(l.dehaze.uniforms.uAmount,n.dehaze/100),t.uniform2f(l.dehaze.uniforms.uSize,r,o)},g()),n.bloom>.5&&f(l.bloom,()=>{t.uniform1f(l.bloom.uniforms.uAmount,n.bloom/100),t.uniform2f(l.bloom.uniforms.uTexel,v[0],v[1]),t.uniform1f(l.bloom.uniforms.uThreshold,.5)},g()),n.glamour>.5&&f(l.glamour,()=>{t.uniform1f(l.glamour.uniforms.uAmount,n.glamour/100),t.uniform2f(l.glamour.uniforms.uTexel,v[0],v[1])},g()),Math.abs(n.clarity)>.5&&f(l.clarity,()=>{t.uniform1f(l.clarity.uniforms.uAmount,n.clarity/100),t.uniform2f(l.clarity.uniforms.uTexel,v[0],v[1])},g()),n.sharpen>.5&&f(l.sharpen,()=>{t.uniform2f(l.sharpen.uniforms.uTexel,v[0],v[1]),t.uniform1f(l.sharpen.uniforms.uAmount,n.sharpen/100),t.uniform1fv(l.sharpen.uniforms["uKernel[0]"],new Float32Array([0,-1,0,-1,5,-1,0,-1,0]))},g()),n.smooth>.5&&f(l.smooth,()=>{t.uniform2f(l.smooth.uniforms.uTexel,v[0],v[1]),t.uniform1f(l.smooth.uniforms.uAmount,n.smooth/100),t.uniform1fv(l.smooth.uniforms["uKernel[0]"],new Float32Array([1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9]))},g());const p=n.blur;f(l.blur,()=>{t.uniform2f(l.blur.uniforms.uSize,p/r,0)},g()),f(l.blur,()=>{t.uniform2f(l.blur.uniforms.uSize,0,p/o)},g()),f(l.vignette,()=>{t.uniform1f(l.vignette.uniforms.uAmount,n.vignette/100),t.uniform1f(l.vignette.uniforms.uSize,.25)},g()),f(l.grain,()=>{t.uniform2f(l.grain.uniforms.uResolution,r,o),t.uniform1f(l.grain.uniforms.uAmount,n.grain/800),t.uniform1f(l.grain.uniforms.uTime,0)},g()),f(l.pass,()=>{},null)}},exports.analyzeImage=m,exports.analyzeImageLevels=s,exports.analyzeImageVibrance=v,exports.defaultSettings=u,exports.presets=l;
|
|
1
|
+
"use strict";var e="\nprecision highp float;\nattribute vec2 aPosition;\nattribute vec2 aTexCoord;\nvarying vec2 vUv;\nvoid main() {\n vUv = aTexCoord;\n gl_Position = vec4(aPosition, 0.0, 1.0);\n}\n",n="\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform vec2 uTexel;\nuniform float uKernel[9];\nuniform float uAmount;\nvoid main(void) {\n vec4 c11 = texture2D(uTexture, vUv - uTexel);\n vec4 c12 = texture2D(uTexture, vec2(vUv.x, vUv.y - uTexel.y));\n vec4 c13 = texture2D(uTexture, vec2(vUv.x + uTexel.x, vUv.y - uTexel.y));\n vec4 c21 = texture2D(uTexture, vec2(vUv.x - uTexel.x, vUv.y));\n vec4 c22 = texture2D(uTexture, vUv);\n vec4 c23 = texture2D(uTexture, vec2(vUv.x + uTexel.x, vUv.y));\n vec4 c31 = texture2D(uTexture, vec2(vUv.x - uTexel.x, vUv.y + uTexel.y));\n vec4 c32 = texture2D(uTexture, vec2(vUv.x, vUv.y + uTexel.y));\n vec4 c33 = texture2D(uTexture, vUv + uTexel);\n vec4 color = c11 * uKernel[0] + c12 * uKernel[1] + c13 * uKernel[2] +\n c21 * uKernel[3] + c22 * uKernel[4] + c23 * uKernel[5] +\n c31 * uKernel[6] + c32 * uKernel[7] + c33 * uKernel[8];\n gl_FragColor = color * uAmount + (c22 * (1.0 - uAmount));\n}\n";function t(e,n,t){const r=e.createShader(n);return r?(e.shaderSource(r,t),e.compileShader(r),e.getShaderParameter(r,e.COMPILE_STATUS)?r:(e.deleteShader(r),null)):null}function r(e,n,r,o){const a=t(e,e.VERTEX_SHADER,n),i=t(e,e.FRAGMENT_SHADER,r);if(!a||!i)throw new Error("Shader compile failed.");const c=function(e,n,t){const r=e.createProgram();return r?(e.attachShader(r,n),e.attachShader(r,t),e.linkProgram(r),e.getProgramParameter(r,e.LINK_STATUS)?r:(e.deleteProgram(r),null)):null}(e,a,i);if(!c)throw new Error("Program link failed.");const u={aPosition:e.getAttribLocation(c,"aPosition"),aTexCoord:e.getAttribLocation(c,"aTexCoord"),apos:e.getAttribLocation(c,"apos"),auv:e.getAttribLocation(c,"auv")},l={};return o.forEach(n=>{l[n]=e.getUniformLocation(c,n)}),{program:c,attribs:u,uniforms:l}}function o(e,n,t){const r=e.createTexture();if(!r)throw new Error("Unable to create texture");e.bindTexture(e.TEXTURE_2D,r),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,n,t,0,e.RGBA,e.UNSIGNED_BYTE,null),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE);const o=e.createFramebuffer();if(!o)throw new Error("Unable to create framebuffer");return e.bindFramebuffer(e.FRAMEBUFFER,o),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,r,0),{framebuffer:o,texture:r}}var a=e=>Math.min(1,Math.max(0,e)),i=(e,n,t,r,o)=>{const a=1-e;return a*a*a*n+3*a*a*e*t+3*a*e*e*r+e*e*e*o},c=e=>{const n=Math.max(-100,Math.min(100,e))/100;return(e=>{const n=new Uint8Array(768);for(let t=0;t<256;t+=1){const r=i(t/255,0,e,.66,1),o=Math.round(255*a(r)),c=3*t;n[c]=o,n[c+1]=o,n[c+2]=o}return n})(a(.33-.35*n))},u={vibrance:0,saturation:0,temperature:0,tint:0,hue:0,brightness:0,exposure:0,contrast:0,blacks:0,whites:0,highlights:0,shadows:0,dehaze:0,bloom:0,glamour:0,clarity:0,sharpen:0,smooth:0,blur:0,vignette:0,grain:0},l={auto:{},blackAndWhite:{saturation:-100,contrast:20,exposure:10,clarity:10},pop:{highlights:50,shadows:-50,vibrance:50,saturation:20,exposure:20,clarity:20},vintage:{saturation:-20,contrast:10,temperature:15,grain:30,vignette:25},vivid:{vibrance:40,saturation:20,contrast:15,clarity:20},cinematic:{contrast:25,highlights:-20,shadows:15,temperature:-10,vignette:30}};function s(e){const{data:n,width:t,height:r}=e,o=new Array(256).fill(0);for(let e=0;e<n.length;e+=4)o[n[e]]+=1,o[n[e+1]]+=1,o[n[e+2]]+=1;const a=Math.round(t*r/1e3);let i=0;for(let e=0;e<256;e++)if(o[e]>a){i=e;break}let c=255;for(let e=255;e>=0;e--)if(o[e]>a){c=e;break}return i>100&&(i=100),c<155&&(c=155),{black:i,white:c}}function v(e){const{data:n,width:t,height:r}=e;let o=1,a=1;for(let e=0;e<n.length;e+=4){const t=n[e],r=n[e+1],i=n[e+2],c=Math.min(t,r,i),u=Math.max(t,r,i);a+=u/255;const l=u-c;l>0&&(o+=l/u)}return(o+a)/(t*r*2)}function m(e){return{levels:s(e),vibrance:v(e)}}exports.ImageColorGrading=class{constructor(e){this.resources=null,this.settings={...u},this.imageLoaded=!1,this.canvas=e||document.createElement("canvas")}getCanvas(){return this.canvas}getSettings(){return{...this.settings}}setSettings(e){this.settings={...this.settings,...e},this.resources&&this.render()}resetSettings(){this.settings={...u},this.resources&&this.render()}loadImage(e){return new Promise((n,t)=>{const r=new Image;r.crossOrigin="anonymous",r.onload=()=>{this.initFromImage(r),n()},r.onerror=()=>{t(new Error(`Failed to load image: ${e}`))},r.src=e})}loadFromImage(e){this.initFromImage(e)}loadFromFile(e){return new Promise((n,t)=>{const r=URL.createObjectURL(e);this.loadImage(r).then(()=>{URL.revokeObjectURL(r),n()}).catch(e=>{URL.revokeObjectURL(r),t(e)})})}loadFromImageData(e){const{width:n,height:t,data:r}=e;this.canvas.width=n,this.canvas.height=t;const o=this.getWebGLContext();if(!o)throw new Error("WebGL not supported");this.disposeResources(),o.viewport(0,0,n,t),o.pixelStorei(o.UNPACK_FLIP_Y_WEBGL,1);const a=o.createTexture();if(!a)throw new Error("Failed to create texture");o.bindTexture(o.TEXTURE_2D,a),o.texImage2D(o.TEXTURE_2D,0,o.RGBA,n,t,0,o.RGBA,o.UNSIGNED_BYTE,r),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_MIN_FILTER,o.LINEAR),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_MAG_FILTER,o.LINEAR),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_WRAP_S,o.CLAMP_TO_EDGE),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_WRAP_T,o.CLAMP_TO_EDGE),this.initResources(o,n,t,a)}render(){this.resources&&this.drawFrame(this.resources,this.settings)}toDataURL(e){const n=e?.format||"image/png",t=e?.quality;return this.canvas.toDataURL(n,t)}toBlob(e){return new Promise((n,t)=>{const r=e?.format||"image/png",o=e?.quality;this.canvas.toBlob(e=>{e?n(e):t(new Error("Failed to create blob"))},r,o)})}getImageData(){const e=this.canvas.getContext("2d");if(e)return e.getImageData(0,0,this.canvas.width,this.canvas.height);const n=this.canvas.getContext("webgl");if(n){const e=new Uint8ClampedArray(this.canvas.width*this.canvas.height*4);return n.readPixels(0,0,this.canvas.width,this.canvas.height,n.RGBA,n.UNSIGNED_BYTE,e),new ImageData(e,this.canvas.width,this.canvas.height)}throw new Error("Cannot get ImageData")}getSize(){return{width:this.canvas.width,height:this.canvas.height}}isLoaded(){return this.imageLoaded}dispose(){this.disposeResources(),this.imageLoaded=!1}analyze(){if(!this.imageLoaded)throw new Error("No image loaded");const e={...this.settings};this.settings={...u},this.render();const n=m(this.getImageData());return this.settings=e,this.render(),n}autoFix(){if(!this.imageLoaded)throw new Error("No image loaded");this.settings={...u},this.render();const e=this.getImageData(),n=s(e),t=v(e),r={...u};if(r.whites=Math.round(255-n.white),r.blacks=Math.round(n.black),t<.7){const e=Math.round(100*(.7-t));r.vibrance=Math.min(e,50)}return this.settings=r,this.render(),r}applyPreset(e){if("auto"===e)return this.autoFix();const n=l[e],t={...u,...n};return this.settings=t,this.resources&&this.render(),t}getWebGLContext(){return this.canvas.getContext("webgl",{antialias:!0,premultipliedAlpha:!1,preserveDrawingBuffer:!0})}initFromImage(e){const n=e.naturalWidth||e.width,t=e.naturalHeight||e.height;this.canvas.width=n,this.canvas.height=t;const r=this.getWebGLContext();if(!r)throw new Error("WebGL not supported");this.disposeResources(),r.disable(r.DEPTH_TEST),r.viewport(0,0,n,t),r.pixelStorei(r.UNPACK_FLIP_Y_WEBGL,1);const o=r.createTexture();if(!o)throw new Error("Failed to create texture");r.bindTexture(r.TEXTURE_2D,o),r.texImage2D(r.TEXTURE_2D,0,r.RGBA,r.RGBA,r.UNSIGNED_BYTE,e),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_MIN_FILTER,r.LINEAR),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_MAG_FILTER,r.LINEAR),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_WRAP_S,r.CLAMP_TO_EDGE),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_WRAP_T,r.CLAMP_TO_EDGE),this.initResources(r,n,t,o)}initResources(t,a,i,u){const l=((e,n)=>{const t=e.createTexture();if(!t)throw new Error("Unable to create palette texture");return e.bindTexture(e.TEXTURE_2D,t),e.texImage2D(e.TEXTURE_2D,0,e.RGB,256,1,0,e.RGB,e.UNSIGNED_BYTE,n),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),t})(t,c(0)),s=t.createBuffer(),v=t.createBuffer();if(!s||!v)throw new Error("Failed to create buffers");t.bindBuffer(t.ARRAY_BUFFER,s),t.bufferData(t.ARRAY_BUFFER,new Float32Array([-1,-1,1,-1,-1,1,1,1]),t.STATIC_DRAW),t.bindBuffer(t.ARRAY_BUFFER,v),t.bufferData(t.ARRAY_BUFFER,new Float32Array([0,0,1,0,0,1,1,1]),t.STATIC_DRAW);const m={pass:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nvoid main() {\n gl_FragColor = texture2D(uTexture, vUv);\n}\n",["uTexture"]),vibrance:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uAmount;\nvoid main() {\n vec4 col = texture2D(uTexture, vUv);\n vec3 color = col.rgb;\n float luminance = color.r * 0.299 + color.g * 0.587 + color.b * 0.114;\n float mn = min(min(color.r, color.g), color.b);\n float mx = max(max(color.r, color.g), color.b);\n float sat = (1.0 - (mx - mn)) * (1.0 - mx) * luminance * 5.0;\n vec3 lightness = vec3((mn + mx) / 2.0);\n color = mix(color, mix(color, lightness, -uAmount), sat);\n gl_FragColor = vec4(\n mix(color, lightness, (1.0 - lightness) * (1.0 - uAmount) / 2.0 * abs(uAmount)),\n col.a\n );\n}\n",["uTexture","uAmount"]),saturation:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uMatrix[20];\nvoid main(void) {\n vec4 c = texture2D(uTexture, vUv);\n gl_FragColor.r = uMatrix[0] * c.r + uMatrix[1] * c.g + uMatrix[2] * c.b + uMatrix[3] * c.a + uMatrix[4];\n gl_FragColor.g = uMatrix[5] * c.r + uMatrix[6] * c.g + uMatrix[7] * c.b + uMatrix[8] * c.a + uMatrix[9];\n gl_FragColor.b = uMatrix[10] * c.r + uMatrix[11] * c.g + uMatrix[12] * c.b + uMatrix[13] * c.a + uMatrix[14];\n gl_FragColor.a = uMatrix[15] * c.r + uMatrix[16] * c.g + uMatrix[17] * c.b + uMatrix[18] * c.a + uMatrix[19];\n}\n",["uTexture","uMatrix[0]"]),temperature:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uAmount;\nvoid main() {\n vec4 color = texture2D(uTexture, vUv);\n color.r = clamp(color.r + uAmount, 0.0, 1.0);\n color.b = clamp(color.b - uAmount, 0.0, 1.0);\n gl_FragColor = color;\n}\n",["uTexture","uAmount"]),tint:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uAmount;\nvoid main() {\n vec4 color = texture2D(uTexture, vUv);\n color.g = clamp(color.g + uAmount, 0.0, 1.0);\n gl_FragColor = color;\n}\n",["uTexture","uAmount"]),hue:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uRotation;\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 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}\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}\nvoid main() {\n lowp vec4 base = texture2D(uTexture, vUv);\n vec3 hsv = rgb2hsv(base.rgb);\n hsv.x = fract(hsv.x + uRotation);\n gl_FragColor = vec4(hsv2rgb(hsv), base.a);\n}\n",["uTexture","uRotation"]),brightness:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uAmount;\nconst float PI = 3.1415926535897932384626433832795;\nvoid main() {\n vec4 color = texture2D(uTexture, vUv);\n if (uAmount >= 0.0) {\n color.r = color.r + uAmount * sin(color.r * PI);\n color.g = color.g + uAmount * sin(color.g * PI);\n color.b = color.b + uAmount * sin(color.b * PI);\n } else {\n color.r = (1.0 + uAmount) * color.r;\n color.g = (1.0 + uAmount) * color.g;\n color.b = (1.0 + uAmount) * color.b;\n }\n gl_FragColor = color;\n}\n",["uTexture","uAmount"]),exposure:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uAmount;\nconst float epsilon = 0.000001;\nconst float mx = 1.0 - epsilon;\nconst mat3 matRGBtoROMM = mat3(\n 0.5293459296226501, 0.3300727903842926, 0.14058130979537964,\n 0.09837432950735092, 0.8734610080718994, 0.028164653107523918,\n 0.01688321679830551, 0.11767247319221497, 0.8654443025588989\n);\nconst mat3 matROMMtoRGB = mat3(\n 2.0340757369995117, -0.727334201335907, -0.3067416846752167,\n -0.22881317138671875, 1.2317301034927368, -0.0029169507324695587,\n -0.008569774217903614, -0.1532866358757019, 1.1618564128875732\n);\nfloat ramp(in float t) {\n t *= 2.0;\n if (t >= 1.0) {\n t -= 1.0;\n t = log(0.5) / log(0.5 * (1.0 - t) + 0.9332 * t);\n }\n return clamp(t, 0.001, 10.0);\n}\nvec3 rgb2hsv(in 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 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}\nvec3 hsv2rgb(in 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}\nvec3 setHue(in vec3 res, in vec3 base) {\n vec3 hsv = rgb2hsv(base);\n vec3 res_hsv = rgb2hsv(res);\n return hsv2rgb(vec3(hsv.x, res_hsv.y, res_hsv.z));\n}\nvoid main() {\n lowp vec4 col = texture2D(uTexture, vUv);\n vec3 base = col.rgb * matRGBtoROMM;\n float a = abs(uAmount) * col.a + epsilon;\n float v = pow(2.0, a * 2.0 + 1.0) - 2.0;\n float m = mx - exp(-v);\n vec3 res = (uAmount > 0.0) ? (1.0 - exp(-v * base)) / m : log(1.0 - base * m) / -v;\n res = mix(base, res, min(a * 100.0, 1.0));\n res = setHue(res, base);\n res = pow(res, vec3(ramp(1.0 - (0.0 * col.a + 1.0) / 2.0)));\n res = res * matROMMtoRGB;\n gl_FragColor = vec4(res, col.a);\n}\n",["uTexture","uAmount"]),contrast:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uMatrix[20];\nvoid main(void) {\n vec4 c = texture2D(uTexture, vUv);\n gl_FragColor.r = uMatrix[0] * c.r + uMatrix[1] * c.g + uMatrix[2] * c.b + uMatrix[3] * c.a + uMatrix[4];\n gl_FragColor.g = uMatrix[5] * c.r + uMatrix[6] * c.g + uMatrix[7] * c.b + uMatrix[8] * c.a + uMatrix[9];\n gl_FragColor.b = uMatrix[10] * c.r + uMatrix[11] * c.g + uMatrix[12] * c.b + uMatrix[13] * c.a + uMatrix[14];\n gl_FragColor.a = uMatrix[15] * c.r + uMatrix[16] * c.g + uMatrix[17] * c.b + uMatrix[18] * c.a + uMatrix[19];\n}\n",["uTexture","uMatrix[0]"]),blacks:r(t,"\nprecision highp float;\nattribute vec2 apos;\nattribute vec2 auv;\nvarying vec2 uv;\nuniform vec4 transform;\nvoid main(void) {\n uv = auv;\n gl_Position = vec4(\n apos.x * transform.x + transform.z,\n apos.y * transform.y + transform.w,\n 0.0,\n 1.0\n );\n}\n","\nprecision highp float;\nvarying vec2 uv;\nuniform sampler2D uTexture;\nuniform sampler2D uPaletteMap;\nvoid main() {\n lowp vec4 base = texture2D(uTexture, uv.xy);\n float r = texture2D(uPaletteMap, vec2(base.r, 0.0)).r;\n float g = texture2D(uPaletteMap, vec2(base.g, 0.0)).g;\n float b = texture2D(uPaletteMap, vec2(base.b, 0.0)).b;\n gl_FragColor = vec4(r, g, b, base.a);\n}\n",["uTexture","uPaletteMap","transform"]),whites:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uAmount;\nconst vec3 RGB2Y = vec3(0.2126, 0.7152, 0.0722);\nvoid main() {\n vec4 base = texture2D(uTexture, vUv.xy);\n vec3 color = base.rgb;\n float lum = dot(color, RGB2Y);\n float whiteMask = smoothstep(0.5, 1.0, lum);\n color += uAmount * whiteMask;\n gl_FragColor = vec4(clamp(color, 0.0, 1.0), base.a);\n}\n",["uTexture","uAmount"]),highlights:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uAmount;\nconst float epsilon = 0.000001;\nconst float mx = 1.0 - epsilon;\nconst float PI = 3.1415926535897932384626433832795;\nconst mat3 matRGBtoROMM = mat3(\n 0.5293459296226501, 0.3300727903842926, 0.14058130979537964,\n 0.09837432950735092, 0.8734610080718994, 0.028164653107523918,\n 0.01688321679830551, 0.11767247319221497, 0.8654443025588989\n);\nconst mat3 matROMMtoRGB = mat3(\n 2.0340757369995117, -0.727334201335907, -0.3067416846752167,\n -0.22881317138671875, 1.2317301034927368, -0.0029169507324695587,\n -0.008569774217903614, -0.1532866358757019, 1.1618564128875732\n);\nfloat luma_romm(in vec3 color) {\n return dot(color, vec3(0.242655, 0.755158, 0.002187));\n}\nfloat luma(in vec3 color) {\n return dot(color, vec3(0.298839, 0.586811, 0.11435));\n}\nvec3 rgb2hsv(in 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 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}\nvec3 hsv2rgb(in 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}\nvec3 setHue(in vec3 res, in vec3 base) {\n vec3 hsv = rgb2hsv(base);\n vec3 res_hsv = rgb2hsv(res);\n return hsv2rgb(vec3(hsv.x, res_hsv.y, res_hsv.z));\n}\nfloat gaussian(in float x) {\n return 1.0 - exp(-PI * 2.0 * x * x);\n}\nvoid main() {\n lowp vec4 col = texture2D(uTexture, vUv);\n lowp vec3 map = col.rgb;\n vec3 base = col.rgb * matRGBtoROMM;\n float base_lum = luma(col.rgb);\n float map_lum = luma_romm(map * matRGBtoROMM);\n float exposure = mix(uAmount, 0.0, 1.0 - map_lum) * col.a;\n float a = abs(exposure) * col.a + epsilon;\n float v = pow(2.0, a + 1.0) - 2.0;\n float m = mx - exp(-v);\n vec3 res = (exposure > 0.0) ? (1.0 - exp(-v * base)) / m : log(1.0 - base * m) / -v;\n res = mix(base, res, min(a * 100.0, 1.0));\n res = setHue(res, base);\n res = res * matROMMtoRGB;\n gl_FragColor = vec4(res, col.a);\n}\n",["uTexture","uAmount"]),shadows:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uAmount;\nconst float epsilon = 0.000001;\nconst float mx = 1.0 - epsilon;\nconst float PI = 3.1415926535897932384626433832795;\nconst mat3 matRGBtoROMM = mat3(\n 0.5293459296226501, 0.3300727903842926, 0.14058130979537964,\n 0.09837432950735092, 0.8734610080718994, 0.028164653107523918,\n 0.01688321679830551, 0.11767247319221497, 0.8654443025588989\n);\nconst mat3 matROMMtoRGB = mat3(\n 2.0340757369995117, -0.727334201335907, -0.3067416846752167,\n -0.22881317138671875, 1.2317301034927368, -0.0029169507324695587,\n -0.008569774217903614, -0.1532866358757019, 1.1618564128875732\n);\nfloat luma_romm(in vec3 color) {\n return dot(color, vec3(0.242655, 0.755158, 0.002187));\n}\nfloat luma(in vec3 color) {\n return dot(color, vec3(0.298839, 0.586811, 0.11435));\n}\nvec3 rgb2hsv(in 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 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}\nvec3 hsv2rgb(in 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}\nvec3 setHue(in vec3 res, in vec3 base) {\n vec3 hsv = rgb2hsv(base);\n vec3 res_hsv = rgb2hsv(res);\n return hsv2rgb(vec3(hsv.x, res_hsv.y, res_hsv.z));\n}\nfloat gaussian(in float x) {\n return 1.0 - exp(-PI * 2.0 * x * x);\n}\nvoid main() {\n lowp vec4 col = texture2D(uTexture, vUv);\n lowp vec3 map = col.rgb;\n vec3 base = col.rgb * matRGBtoROMM;\n float base_lum = luma(col.rgb);\n float map_lum = luma_romm(map * matRGBtoROMM);\n float exposure = mix(0.0, uAmount, 1.0 - map_lum) * col.a;\n float a = abs(exposure) * col.a + epsilon;\n float v = pow(2.0, a + 1.0) - 2.0;\n float m = mx - exp(-v);\n vec3 res = (exposure > 0.0) ? (1.0 - exp(-v * base)) / m : log(1.0 - base * m) / -v;\n res = mix(base, res, min(a * 100.0, 1.0));\n res = setHue(res, base);\n res = res * matROMMtoRGB;\n gl_FragColor = vec4(res, col.a);\n}\n",["uTexture","uAmount"]),dehaze:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uAmount;\nuniform vec2 uSize;\n\nfloat hazeMap(vec2 coord) {\n vec3 color = vec3(1.0);\n vec2 stepSize = vec2(1.0 / uSize.x, 1.0 / uSize.y);\n for (int i = -1; i <= 1; ++i) {\n for (int j = -1; j <= 1; ++j) {\n vec2 offset = vec2(float(i), float(j)) * stepSize;\n vec2 uv = clamp(coord + offset, 0.0, 1.0);\n vec3 sample = texture2D(uTexture, uv).rgb;\n color = min(color, sample);\n }\n }\n return min(color.r, min(color.g, color.b));\n}\n\nvoid main() {\n vec4 base = texture2D(uTexture, vUv);\n float haze = hazeMap(vUv);\n float transmission = 1.0 - 0.95 * haze;\n const float A = 0.95;\n const float t0 = 0.1;\n float t = mix(1.0, max(t0, transmission), uAmount);\n vec3 J = (base.rgb - A) / t + A;\n gl_FragColor = vec4(J, base.a);\n}\n",["uTexture","uAmount","uSize"]),bloom:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uAmount;\nuniform vec2 uTexel;\nuniform float uThreshold;\n\nvoid main() {\n vec4 sum = vec4(0.0);\n int j = -2;\n for (int i = -2; i <= 2; i++) sum += texture2D(uTexture, vUv + vec2(float(i), float(j)) * uTexel);\n j = -1;\n for (int i = -2; i <= 2; i++) sum += texture2D(uTexture, vUv + vec2(float(i), float(j)) * uTexel);\n j = 0;\n for (int i = -2; i <= 2; i++) sum += texture2D(uTexture, vUv + vec2(float(i), float(j)) * uTexel);\n j = 1;\n for (int i = -2; i <= 2; i++) sum += texture2D(uTexture, vUv + vec2(float(i), float(j)) * uTexel);\n j = 2;\n for (int i = -2; i <= 2; i++) sum += texture2D(uTexture, vUv + vec2(float(i), float(j)) * uTexel);\n sum /= 25.0;\n vec4 base = texture2D(uTexture, vUv);\n if (length(sum.rgb) > uThreshold) {\n base += sum * uAmount;\n }\n gl_FragColor = base;\n}\n",["uTexture","uAmount","uTexel","uThreshold"]),glamour:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uAmount;\nuniform vec2 uTexel;\n\nfloat normpdf(in float x, in float sigma) {\n return 0.39894 * exp(-0.5 * x * x / (sigma * sigma)) / sigma;\n}\n\nvec3 blurMap() {\n const int mSize = 11;\n const int kSize = (mSize - 1) / 2;\n float kernel[mSize];\n vec3 final_colour = vec3(0.0);\n float sigma = 7.0;\n float Z = 0.0;\n for (int j = 0; j <= kSize; ++j) {\n kernel[kSize + j] = kernel[kSize - j] = normpdf(float(j), sigma);\n }\n for (int j = 0; j < mSize; ++j) {\n Z += kernel[j];\n }\n for (int i = -kSize; i <= kSize; ++i) {\n for (int j = -kSize; j <= kSize; ++j) {\n final_colour += kernel[kSize + j] * kernel[kSize + i] *\n texture2D(uTexture, vUv + vec2(float(i), float(j)) * uTexel).rgb;\n }\n }\n return vec3(final_colour / (Z * Z));\n}\n\nfloat luma(vec3 color) {\n return dot(color, vec3(0.299, 0.587, 0.114));\n}\n\nvoid main() {\n vec4 base = texture2D(uTexture, vUv);\n vec3 color = blurMap();\n color = vec3(luma(color));\n color = vec3(\n (base.r <= 0.5) ? (2.0 * base.r * color.r) : (1.0 - 2.0 * (1.0 - base.r) * (1.0 - color.r)),\n (base.g <= 0.5) ? (2.0 * base.g * color.g) : (1.0 - 2.0 * (1.0 - base.g) * (1.0 - color.g)),\n (base.b <= 0.5) ? (2.0 * base.b * color.b) : (1.0 - 2.0 * (1.0 - base.b) * (1.0 - color.b))\n );\n gl_FragColor = mix(base, vec4(color, base.a), uAmount);\n}\n",["uTexture","uAmount","uTexel"]),clarity:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uAmount;\nuniform vec2 uTexel;\n\nfloat Lum(vec3 c) {\n return 0.299 * c.r + 0.587 * c.g + 0.114 * c.b;\n}\nfloat BlendOverlayf(float base, float blend) {\n return (base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend)));\n}\nvec3 BlendOverlay(vec3 base, vec3 blend) {\n return vec3(BlendOverlayf(base.r, blend.r), BlendOverlayf(base.g, blend.g), BlendOverlayf(base.b, blend.b));\n}\nfloat BlendVividLightf(float base, float blend) {\n float BlendColorBurnf = (((2.0 * blend) == 0.0) ? (2.0 * blend) : max((1.0 - ((1.0 - base) / (2.0 * blend))), 0.0));\n float BlendColorDodgef = (((2.0 * (blend - 0.5)) == 1.0) ? (2.0 * (blend - 0.5)) : min(base / (1.0 - (2.0 * (blend - 0.5))), 1.0));\n return ((blend < 0.5) ? BlendColorBurnf : BlendColorDodgef);\n}\nvec3 BlendVividLight(vec3 base, vec3 blend) {\n return vec3(BlendVividLightf(base.r, blend.r), BlendVividLightf(base.g, blend.g), BlendVividLightf(base.b, blend.b));\n}\nfloat normpdf(in float x, in float sigma) {\n return 0.39894 * exp(-0.5 * x * x / (sigma * sigma)) / sigma;\n}\nvec3 blurMap() {\n const int mSize = 11;\n const int kSize = (mSize - 1) / 2;\n float kernel[mSize];\n vec3 final_colour = vec3(0.0);\n float sigma = 7.0;\n float Z = 0.0;\n for (int j = 0; j <= kSize; ++j) {\n kernel[kSize + j] = kernel[kSize - j] = normpdf(float(j), sigma);\n }\n for (int j = 0; j < mSize; ++j) {\n Z += kernel[j];\n }\n for (int i = -kSize; i <= kSize; ++i) {\n for (int j = -kSize; j <= kSize; ++j) {\n final_colour += kernel[kSize + j] * kernel[kSize + i] *\n texture2D(uTexture, vUv + vec2(float(i), float(j)) * uTexel).rgb;\n }\n }\n return vec3(final_colour / (Z * Z));\n}\nvoid main() {\n vec4 base4 = texture2D(uTexture, vUv);\n vec3 blur = blurMap();\n vec3 base = base4.rgb;\n float intensity = (uAmount < 0.0) ? (uAmount / 2.0) : uAmount;\n float lum = Lum(base);\n vec3 col = vec3(lum);\n vec3 mask = vec3(1.0 - pow(lum, 1.8));\n vec3 layer = vec3(1.0 - Lum(blur));\n vec3 detail = clamp(BlendVividLight(col, layer), 0.0, 1.0);\n vec3 inverse = mix(1.0 - detail, detail, (intensity + 1.0) / 2.0);\n gl_FragColor = vec4(BlendOverlay(base, mix(vec3(0.5), inverse, mask)), base4.a);\n}\n",["uTexture","uAmount","uTexel"]),sharpen:r(t,e,n,["uTexture","uTexel","uKernel[0]","uAmount"]),smooth:r(t,e,n,["uTexture","uTexel","uKernel[0]","uAmount"]),blur:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform vec2 uSize;\nfloat random(vec3 scale, float seed) {\n return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);\n}\nvoid main() {\n vec4 color = vec4(0.0);\n float total = 0.0;\n float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);\n for (int t = -30; t <= 30; t++) {\n float percent = (float(t) + offset - 0.5) / 30.0;\n float weight = 1.0 - abs(percent);\n vec4 sample = texture2D(uTexture, vUv + uSize * percent);\n sample.rgb *= sample.a;\n color += sample * weight;\n total += weight;\n }\n gl_FragColor = color / total;\n gl_FragColor.rgb /= gl_FragColor.a + 0.00001;\n}\n",["uTexture","uSize"]),vignette:r(t,e,"\nprecision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform float uAmount;\nuniform float uSize;\nvoid main() {\n vec4 color = texture2D(uTexture, vUv);\n float dist = distance(vUv, vec2(0.5, 0.5));\n float amt = clamp(uAmount, -1.0, 1.0);\n float edge = dist * (abs(amt) * 0.75 + uSize * 2.0);\n float vignette = smoothstep(0.8, uSize * 0.799, edge);\n if (amt < 0.0) {\n vignette = 1.0 + (1.0 - vignette) * (-amt);\n } else {\n vignette = mix(1.0, vignette, amt);\n }\n color.rgb *= vignette;\n gl_FragColor = color;\n}\n",["uTexture","uAmount","uSize"]),grain:r(t,e,"\nprecision highp float;\nuniform sampler2D uTexture;\nvarying vec2 vUv;\nuniform vec2 uResolution;\nuniform float uAmount;\nuniform float uTime;\nconst float permTexUnit = 1.0 / 256.0;\nconst float permTexUnitHalf = 0.5 / 256.0;\nfloat grainsize = 1.8;\nfloat lumamount = 1.0;\n\nvec4 rnm(in vec2 tc) {\n float noise = sin(dot(tc + vec2(uTime, uTime), vec2(12.9898, 78.233))) * 43758.5453;\n float noiseR = fract(noise) * 2.0 - 1.0;\n float noiseG = fract(noise * 1.2154) * 2.0 - 1.0;\n float noiseB = fract(noise * 1.3453) * 2.0 - 1.0;\n float noiseA = fract(noise * 1.3647) * 2.0 - 1.0;\n return vec4(noiseR, noiseG, noiseB, noiseA);\n}\nfloat fade(in float t) {\n return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);\n}\nfloat pnoise3D(in vec3 p) {\n vec3 pi = permTexUnit * floor(p) + permTexUnitHalf;\n vec3 pf = fract(p);\n float perm00 = rnm(pi.xy).a;\n vec3 grad000 = rnm(vec2(perm00, pi.z)).rgb * 4.0 - 1.0;\n float n000 = dot(grad000, pf);\n vec3 grad001 = rnm(vec2(perm00, pi.z + permTexUnit)).rgb * 4.0 - 1.0;\n float n001 = dot(grad001, pf - vec3(0.0, 0.0, 1.0));\n float perm01 = rnm(pi.xy + vec2(0.0, permTexUnit)).a;\n vec3 grad010 = rnm(vec2(perm01, pi.z)).rgb * 4.0 - 1.0;\n float n010 = dot(grad010, pf - vec3(0.0, 1.0, 0.0));\n vec3 grad011 = rnm(vec2(perm01, pi.z + permTexUnit)).rgb * 4.0 - 1.0;\n float n011 = dot(grad011, pf - vec3(0.0, 1.0, 1.0));\n float perm10 = rnm(pi.xy + vec2(permTexUnit, 0.0)).a;\n vec3 grad100 = rnm(vec2(perm10, pi.z)).rgb * 4.0 - 1.0;\n float n100 = dot(grad100, pf - vec3(1.0, 0.0, 0.0));\n vec3 grad101 = rnm(vec2(perm10, pi.z + permTexUnit)).rgb * 4.0 - 1.0;\n float n101 = dot(grad101, pf - vec3(1.0, 0.0, 1.0));\n float perm11 = rnm(pi.xy + vec2(permTexUnit, permTexUnit)).a;\n vec3 grad110 = rnm(vec2(perm11, pi.z)).rgb * 4.0 - 1.0;\n float n110 = dot(grad110, pf - vec3(1.0, 1.0, 0.0));\n vec3 grad111 = rnm(vec2(perm11, pi.z + permTexUnit)).rgb * 4.0 - 1.0;\n float n111 = dot(grad111, pf - vec3(1.0, 1.0, 1.0));\n vec4 n_x = mix(vec4(n000, n001, n010, n011), vec4(n100, n101, n110, n111), fade(pf.x));\n vec2 n_xy = mix(n_x.xy, n_x.zw, fade(pf.y));\n float n_xyz = mix(n_xy.x, n_xy.y, fade(pf.z));\n return n_xyz;\n}\nvec2 coordRot(in vec2 tc, in float angle) {\n float aspect = uResolution.x / uResolution.y;\n float rotX = ((tc.x * 2.0 - 1.0) * aspect * cos(angle)) - ((tc.y * 2.0 - 1.0) * sin(angle));\n float rotY = ((tc.y * 2.0 - 1.0) * cos(angle)) + ((tc.x * 2.0 - 1.0) * aspect * sin(angle));\n rotX = ((rotX / aspect) * 0.5 + 0.5);\n rotY = rotY * 0.5 + 0.5;\n return vec2(rotX, rotY);\n}\nvoid main() {\n vec3 rotOffset = vec3(1.425, 3.892, 5.835);\n vec2 rotCoordsR = coordRot(vUv, uTime + rotOffset.x);\n vec3 noise = vec3(pnoise3D(vec3(rotCoordsR * vec2(uResolution.x / grainsize, uResolution.y / grainsize), 0.0)));\n vec4 tex = texture2D(uTexture, vUv);\n vec3 col = tex.rgb;\n vec3 lumcoeff = vec3(0.299, 0.587, 0.114);\n float luminance = mix(0.0, dot(col, lumcoeff), lumamount);\n float lum = smoothstep(0.2, 0.0, luminance);\n lum += luminance;\n noise = mix(noise, vec3(0.0), pow(lum, 4.0));\n col = col + noise * uAmount;\n gl_FragColor = vec4(col, tex.a);\n}\n",["uTexture","uResolution","uAmount","uTime"])},x=[o(t,a,i),o(t,a,i)];this.resources={gl:t,width:a,height:i,sourceTexture:u,blackPalette:l,quad:{positionBuffer:s,texCoordBuffer:v},programs:m,targets:x},this.imageLoaded=!0,this.render()}disposeResources(){if(!this.resources)return;const{gl:e,sourceTexture:n,blackPalette:t,quad:r,programs:o,targets:a}=this.resources;e.deleteTexture(n),e.deleteTexture(t),e.deleteBuffer(r.positionBuffer),e.deleteBuffer(r.texCoordBuffer),a.forEach(n=>{e.deleteFramebuffer(n.framebuffer),e.deleteTexture(n.texture)}),Object.values(o).forEach(n=>{e.deleteProgram(n.program)}),this.resources=null}drawFrame(e,n){const{gl:t,width:r,height:o,sourceTexture:a,blackPalette:i,quad:u,programs:l,targets:s}=e;t.viewport(0,0,r,o);const v=[1/r,1/o];let m=a,x=0;const f=(e,n,r)=>{t.useProgram(e.program),(e=>{t.bindBuffer(t.ARRAY_BUFFER,u.positionBuffer);const n=e.attribs.aPosition>=0?e.attribs.aPosition:e.attribs.apos;n>=0&&(t.enableVertexAttribArray(n),t.vertexAttribPointer(n,2,t.FLOAT,!1,0,0)),t.bindBuffer(t.ARRAY_BUFFER,u.texCoordBuffer);const r=e.attribs.aTexCoord>=0?e.attribs.aTexCoord:e.attribs.auv;r>=0&&(t.enableVertexAttribArray(r),t.vertexAttribPointer(r,2,t.FLOAT,!1,0,0))})(e),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,m);const o=e.uniforms.uTexture;o&&t.uniform1i(o,0),n(),t.bindFramebuffer(t.FRAMEBUFFER,r?r.framebuffer:null),t.drawArrays(t.TRIANGLE_STRIP,0,4),m=r?r.texture:m},g=()=>{const e=s[x%2];return x+=1,e};Math.abs(n.vibrance)>.5&&f(l.vibrance,()=>{t.uniform1f(l.vibrance.uniforms.uAmount,n.vibrance/100)},g()),Math.abs(n.saturation)>.5&&f(l.saturation,()=>{const e=(e=>{const n=1+Math.max(-100,Math.min(100,e))/100,t=.299,r=.587,o=.114,a=1-n;return new Float32Array([a*t+n,a*r,a*o,0,0,a*t,a*r+n,a*o,0,0,a*t,a*r,a*o+n,0,0,0,0,0,1,0])})(n.saturation);t.uniform1fv(l.saturation.uniforms["uMatrix[0]"],e)},g()),Math.abs(n.temperature)>.5&&f(l.temperature,()=>{t.uniform1f(l.temperature.uniforms.uAmount,n.temperature/500)},g()),Math.abs(n.tint)>.5&&f(l.tint,()=>{t.uniform1f(l.tint.uniforms.uAmount,n.tint/500)},g()),Math.abs(n.hue)>.5&&f(l.hue,()=>{t.uniform1f(l.hue.uniforms.uRotation,n.hue/200)},g()),f(l.brightness,()=>{t.uniform1f(l.brightness.uniforms.uAmount,n.brightness/200)},g()),Math.abs(n.exposure)>.5&&f(l.exposure,()=>{t.uniform1f(l.exposure.uniforms.uAmount,n.exposure/100)},g()),Math.abs(n.contrast)>.5&&f(l.contrast,()=>{const e=(e=>{const n=1+Math.max(-100,Math.min(100,e))/100,t=.5*(1-n);return new Float32Array([n,0,0,0,t,0,n,0,0,t,0,0,n,0,t,0,0,0,1,0])})(n.contrast);t.uniform1fv(l.contrast.uniforms["uMatrix[0]"],e)},g()),Math.abs(n.blacks)>.5&&(((e,n,t)=>{e.bindTexture(e.TEXTURE_2D,n),e.texSubImage2D(e.TEXTURE_2D,0,0,0,256,1,e.RGB,e.UNSIGNED_BYTE,t)})(t,i,c(n.blacks)),f(l.blacks,()=>{t.activeTexture(t.TEXTURE1),t.bindTexture(t.TEXTURE_2D,i),t.uniform1i(l.blacks.uniforms.uPaletteMap,1),t.uniform4f(l.blacks.uniforms.transform,1,1,0,0),t.activeTexture(t.TEXTURE0)},g())),Math.abs(n.whites)>.5&&f(l.whites,()=>{t.uniform1f(l.whites.uniforms.uAmount,n.whites/400)},g()),Math.abs(n.highlights)>.5&&f(l.highlights,()=>{t.uniform1f(l.highlights.uniforms.uAmount,n.highlights/100)},g()),Math.abs(n.shadows)>.5&&f(l.shadows,()=>{t.uniform1f(l.shadows.uniforms.uAmount,n.shadows/100)},g()),Math.abs(n.dehaze)>.5&&f(l.dehaze,()=>{t.uniform1f(l.dehaze.uniforms.uAmount,n.dehaze/100),t.uniform2f(l.dehaze.uniforms.uSize,r,o)},g()),n.bloom>.5&&f(l.bloom,()=>{t.uniform1f(l.bloom.uniforms.uAmount,n.bloom/100),t.uniform2f(l.bloom.uniforms.uTexel,v[0],v[1]),t.uniform1f(l.bloom.uniforms.uThreshold,.5)},g()),n.glamour>.5&&f(l.glamour,()=>{t.uniform1f(l.glamour.uniforms.uAmount,n.glamour/100),t.uniform2f(l.glamour.uniforms.uTexel,v[0],v[1])},g()),Math.abs(n.clarity)>.5&&f(l.clarity,()=>{t.uniform1f(l.clarity.uniforms.uAmount,n.clarity/100),t.uniform2f(l.clarity.uniforms.uTexel,v[0],v[1])},g()),n.sharpen>.5&&f(l.sharpen,()=>{t.uniform2f(l.sharpen.uniforms.uTexel,v[0],v[1]),t.uniform1f(l.sharpen.uniforms.uAmount,n.sharpen/100),t.uniform1fv(l.sharpen.uniforms["uKernel[0]"],new Float32Array([0,-1,0,-1,5,-1,0,-1,0]))},g()),n.smooth>.5&&f(l.smooth,()=>{t.uniform2f(l.smooth.uniforms.uTexel,v[0],v[1]),t.uniform1f(l.smooth.uniforms.uAmount,n.smooth/100),t.uniform1fv(l.smooth.uniforms["uKernel[0]"],new Float32Array([1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9]))},g());const p=n.blur;f(l.blur,()=>{t.uniform2f(l.blur.uniforms.uSize,p/r,0)},g()),f(l.blur,()=>{t.uniform2f(l.blur.uniforms.uSize,0,p/o)},g()),f(l.vignette,()=>{t.uniform1f(l.vignette.uniforms.uAmount,n.vignette/100),t.uniform1f(l.vignette.uniforms.uSize,.25)},g()),f(l.grain,()=>{t.uniform2f(l.grain.uniforms.uResolution,r,o),t.uniform1f(l.grain.uniforms.uAmount,n.grain/800),t.uniform1f(l.grain.uniforms.uTime,0)},g()),f(l.pass,()=>{},null)}},exports.analyzeImage=m,exports.analyzeImageLevels=s,exports.analyzeImageVibrance=v,exports.defaultSettings=u,exports.presets=l;
|