@flighthq/effects-canvas 0.1.0 → 0.2.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.
Files changed (104) hide show
  1. package/dist/canvasBlurEffect.d.ts +4 -0
  2. package/dist/canvasBlurEffect.d.ts.map +1 -0
  3. package/dist/canvasBlurEffect.js +14 -0
  4. package/dist/canvasBlurEffect.js.map +1 -0
  5. package/dist/canvasColorLutPass.d.ts +3 -0
  6. package/dist/canvasColorLutPass.d.ts.map +1 -0
  7. package/dist/canvasColorLutPass.js +20 -0
  8. package/dist/canvasColorLutPass.js.map +1 -0
  9. package/dist/canvasColorMatrixPass.d.ts +3 -0
  10. package/dist/canvasColorMatrixPass.d.ts.map +1 -0
  11. package/dist/canvasColorMatrixPass.js +43 -0
  12. package/dist/canvasColorMatrixPass.js.map +1 -0
  13. package/dist/canvasConvolutionEffect.d.ts +4 -0
  14. package/dist/canvasConvolutionEffect.d.ts.map +1 -0
  15. package/dist/canvasConvolutionEffect.js +11 -0
  16. package/dist/canvasConvolutionEffect.js.map +1 -0
  17. package/dist/canvasDropShadowEffect.d.ts +4 -0
  18. package/dist/canvasDropShadowEffect.d.ts.map +1 -0
  19. package/dist/canvasDropShadowEffect.js +14 -0
  20. package/dist/canvasDropShadowEffect.js.map +1 -0
  21. package/dist/canvasEffectDropShadowCss.d.ts +4 -0
  22. package/dist/canvasEffectDropShadowCss.d.ts.map +1 -0
  23. package/dist/canvasEffectDropShadowCss.js +36 -0
  24. package/dist/canvasEffectDropShadowCss.js.map +1 -0
  25. package/dist/canvasMedianEffect.d.ts +4 -0
  26. package/dist/canvasMedianEffect.d.ts.map +1 -0
  27. package/dist/canvasMedianEffect.js +11 -0
  28. package/dist/canvasMedianEffect.js.map +1 -0
  29. package/dist/canvasOuterGlowEffect.d.ts +4 -0
  30. package/dist/canvasOuterGlowEffect.d.ts.map +1 -0
  31. package/dist/canvasOuterGlowEffect.js +14 -0
  32. package/dist/canvasOuterGlowEffect.js.map +1 -0
  33. package/dist/canvasRenderEffectPipeline.d.ts +2 -2
  34. package/dist/canvasRenderEffectPipeline.d.ts.map +1 -1
  35. package/dist/canvasRenderEffectPipeline.js +51 -7
  36. package/dist/canvasRenderEffectPipeline.js.map +1 -1
  37. package/dist/canvasRenderEffectRegistration.d.ts +1 -0
  38. package/dist/canvasRenderEffectRegistration.d.ts.map +1 -1
  39. package/dist/canvasRenderEffectRegistration.js +33 -27
  40. package/dist/canvasRenderEffectRegistration.js.map +1 -1
  41. package/dist/index.d.ts +8 -10
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +8 -10
  44. package/dist/index.js.map +1 -1
  45. package/package.json +11 -7
  46. package/src/canvasBlurEffect.test.ts +13 -0
  47. package/src/canvasColorLutPass.test.ts +7 -0
  48. package/src/canvasColorMatrixPass.test.ts +7 -0
  49. package/src/canvasConvolutionEffect.test.ts +13 -0
  50. package/src/canvasDropShadowEffect.test.ts +13 -0
  51. package/src/canvasEffectDropShadowCss.test.ts +21 -0
  52. package/src/canvasMedianEffect.test.ts +13 -0
  53. package/src/canvasOuterGlowEffect.test.ts +13 -0
  54. package/src/canvasRenderEffectRegistration.test.ts +36 -22
  55. package/dist/canvasBrightnessContrastEffect.d.ts +0 -4
  56. package/dist/canvasBrightnessContrastEffect.d.ts.map +0 -1
  57. package/dist/canvasBrightnessContrastEffect.js +0 -13
  58. package/dist/canvasBrightnessContrastEffect.js.map +0 -1
  59. package/dist/canvasChannelMixerEffect.d.ts +0 -4
  60. package/dist/canvasChannelMixerEffect.d.ts.map +0 -1
  61. package/dist/canvasChannelMixerEffect.js +0 -11
  62. package/dist/canvasChannelMixerEffect.js.map +0 -1
  63. package/dist/canvasColorGradeEffect.d.ts +0 -4
  64. package/dist/canvasColorGradeEffect.d.ts.map +0 -1
  65. package/dist/canvasColorGradeEffect.js +0 -21
  66. package/dist/canvasColorGradeEffect.js.map +0 -1
  67. package/dist/canvasExposureEffect.d.ts +0 -4
  68. package/dist/canvasExposureEffect.d.ts.map +0 -1
  69. package/dist/canvasExposureEffect.js +0 -11
  70. package/dist/canvasExposureEffect.js.map +0 -1
  71. package/dist/canvasGrayscaleEffect.d.ts +0 -4
  72. package/dist/canvasGrayscaleEffect.d.ts.map +0 -1
  73. package/dist/canvasGrayscaleEffect.js +0 -10
  74. package/dist/canvasGrayscaleEffect.js.map +0 -1
  75. package/dist/canvasHueSaturationEffect.d.ts +0 -4
  76. package/dist/canvasHueSaturationEffect.d.ts.map +0 -1
  77. package/dist/canvasHueSaturationEffect.js +0 -13
  78. package/dist/canvasHueSaturationEffect.js.map +0 -1
  79. package/dist/canvasInvertEffect.d.ts +0 -4
  80. package/dist/canvasInvertEffect.d.ts.map +0 -1
  81. package/dist/canvasInvertEffect.js +0 -10
  82. package/dist/canvasInvertEffect.js.map +0 -1
  83. package/dist/canvasLiftGammaGainEffect.d.ts +0 -4
  84. package/dist/canvasLiftGammaGainEffect.d.ts.map +0 -1
  85. package/dist/canvasLiftGammaGainEffect.js +0 -11
  86. package/dist/canvasLiftGammaGainEffect.js.map +0 -1
  87. package/dist/canvasLookupTableGradeEffect.d.ts +0 -4
  88. package/dist/canvasLookupTableGradeEffect.d.ts.map +0 -1
  89. package/dist/canvasLookupTableGradeEffect.js +0 -10
  90. package/dist/canvasLookupTableGradeEffect.js.map +0 -1
  91. package/dist/canvasSepiaEffect.d.ts +0 -4
  92. package/dist/canvasSepiaEffect.d.ts.map +0 -1
  93. package/dist/canvasSepiaEffect.js +0 -10
  94. package/dist/canvasSepiaEffect.js.map +0 -1
  95. package/src/canvasBrightnessContrastEffect.test.ts +0 -16
  96. package/src/canvasChannelMixerEffect.test.ts +0 -13
  97. package/src/canvasColorGradeEffect.test.ts +0 -13
  98. package/src/canvasExposureEffect.test.ts +0 -13
  99. package/src/canvasGrayscaleEffect.test.ts +0 -13
  100. package/src/canvasHueSaturationEffect.test.ts +0 -13
  101. package/src/canvasInvertEffect.test.ts +0 -13
  102. package/src/canvasLiftGammaGainEffect.test.ts +0 -13
  103. package/src/canvasLookupTableGradeEffect.test.ts +0 -16
  104. package/src/canvasSepiaEffect.test.ts +0 -13
@@ -0,0 +1,4 @@
1
+ import type { BlurEffect, CanvasRenderEffectRunner, CanvasRenderTarget } from '@flighthq/types';
2
+ export declare function applyBlurEffectToCanvas(source: Readonly<CanvasRenderTarget>, dest: Readonly<CanvasRenderTarget>, effect: Readonly<BlurEffect>): void;
3
+ export declare const defaultCanvasBlurEffectRunner: CanvasRenderEffectRunner;
4
+ //# sourceMappingURL=canvasBlurEffect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvasBlurEffect.d.ts","sourceRoot":"","sources":["../src/canvasBlurEffect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAOhG,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EACpC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAClC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,GAC3B,IAAI,CAKN;AAED,eAAO,MAAM,6BAA6B,EAAE,wBAE3C,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { drawCanvasEffectPass } from './canvasEffectCompositing';
2
+ // Plain Gaussian blur via the Canvas 2D `blur()` CSS filter — the same primitive the canvas bloom
3
+ // branch uses. Canvas `blur()` is isotropic (a single radius), so the per-axis `blurX`/`blurY` sigmas
4
+ // are averaged into one radius; a non-positive radius passes the image through unchanged.
5
+ export function applyBlurEffectToCanvas(source, dest, effect) {
6
+ const blurX = effect.blurX ?? 4;
7
+ const blurY = effect.blurY ?? 4;
8
+ const radius = Math.max(0, (blurX + blurY) / 2);
9
+ drawCanvasEffectPass(dest, source, radius > 0 ? `blur(${radius}px)` : 'none');
10
+ }
11
+ export const defaultCanvasBlurEffectRunner = (ctx, effect) => {
12
+ applyBlurEffectToCanvas(ctx.source, ctx.dest, effect);
13
+ };
14
+ //# sourceMappingURL=canvasBlurEffect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvasBlurEffect.js","sourceRoot":"","sources":["../src/canvasBlurEffect.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEjE,kGAAkG;AAClG,sGAAsG;AACtG,0FAA0F;AAC1F,MAAM,UAAU,uBAAuB,CACrC,MAAoC,EACpC,IAAkC,EAClC,MAA4B;IAE5B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;IAChC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IAChD,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,MAAM,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AAChF,CAAC;AAED,MAAM,CAAC,MAAM,6BAA6B,GAA6B,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IACrF,uBAAuB,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAAoB,CAAC,CAAC;AACtE,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { CanvasRenderTarget, ColorLut } from '@flighthq/types';
2
+ export declare function applyColorLutPassToCanvas(source: Readonly<CanvasRenderTarget>, dest: Readonly<CanvasRenderTarget>, lut: Readonly<ColorLut>): void;
3
+ //# sourceMappingURL=canvasColorLutPass.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvasColorLutPass.d.ts","sourceRoot":"","sources":["../src/canvasColorLutPass.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AASpE,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EACpC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAClC,GAAG,EAAE,QAAQ,CAAC,QAAQ,CAAC,GACtB,IAAI,CAWN"}
@@ -0,0 +1,20 @@
1
+ import { sampleColorLut } from '@flighthq/adjustments';
2
+ import { drawCanvasImageDataPass } from './canvasEffectCompositing';
3
+ // Generic pointwise color-LUT pass — the single fold-in realization for the whole LUT-tier Adjustment
4
+ // family on Canvas 2D. A run of consecutive pointwise adjustments containing any nonlinear (LUT-tier)
5
+ // member bakes to ONE `ColorLut` (matrices folded in) and runs through this one per-pixel pass instead of
6
+ // one pass per op. Each pixel is normalized to [0,1], trilinearly sampled from the LUT (the CPU
7
+ // counterpart of the GPU's hardware-filtered 3D tap), and written back; alpha is preserved.
8
+ export function applyColorLutPassToCanvas(source, dest, lut) {
9
+ const rgb = [0, 0, 0];
10
+ drawCanvasImageDataPass(dest, source, (data, pixelCount) => {
11
+ for (let i = 0; i < pixelCount; i++) {
12
+ const p = i * 4;
13
+ sampleColorLut(lut, rgb, data[p] / 255, data[p + 1] / 255, data[p + 2] / 255);
14
+ data[p] = rgb[0] * 255;
15
+ data[p + 1] = rgb[1] * 255;
16
+ data[p + 2] = rgb[2] * 255;
17
+ }
18
+ });
19
+ }
20
+ //# sourceMappingURL=canvasColorLutPass.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvasColorLutPass.js","sourceRoot":"","sources":["../src/canvasColorLutPass.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,sGAAsG;AACtG,sGAAsG;AACtG,0GAA0G;AAC1G,gGAAgG;AAChG,4FAA4F;AAC5F,MAAM,UAAU,yBAAyB,CACvC,MAAoC,EACpC,IAAkC,EAClC,GAAuB;IAEvB,MAAM,GAAG,GAA6B,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAChD,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE;QACzD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAChB,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;YAC9E,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;YACvB,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;YAC3B,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;QAC7B,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { CanvasRenderTarget } from '@flighthq/types';
2
+ export declare function applyColorMatrixPassToCanvas(source: Readonly<CanvasRenderTarget>, dest: Readonly<CanvasRenderTarget>, matrix: ReadonlyArray<number>): void;
3
+ //# sourceMappingURL=canvasColorMatrixPass.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvasColorMatrixPass.d.ts","sourceRoot":"","sources":["../src/canvasColorMatrixPass.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAS1D,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EACpC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAClC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,GAC5B,IAAI,CAmCN"}
@@ -0,0 +1,43 @@
1
+ import { drawCanvasImageDataPass } from './canvasEffectCompositing';
2
+ // Generic pointwise color-matrix pass — the single fold-in realization for the whole matrix-tier
3
+ // Adjustment family on Canvas 2D. A run of consecutive matrix-tier adjustments fuses to ONE 4×5 matrix
4
+ // (in the adjustments colorMatrixMath convention: linear RGBA coefficients + a 0–255 offset column) and
5
+ // runs through this one per-pixel pass instead of one pass per op. ImageData is straight-alpha 0–255 —
6
+ // the same units the offset column is in — so the matrix applies directly, clamped per channel.
7
+ export function applyColorMatrixPassToCanvas(source, dest, matrix) {
8
+ const m0 = matrix[0] ?? 0;
9
+ const m1 = matrix[1] ?? 0;
10
+ const m2 = matrix[2] ?? 0;
11
+ const m3 = matrix[3] ?? 0;
12
+ const m4 = matrix[4] ?? 0;
13
+ const m5 = matrix[5] ?? 0;
14
+ const m6 = matrix[6] ?? 0;
15
+ const m7 = matrix[7] ?? 0;
16
+ const m8 = matrix[8] ?? 0;
17
+ const m9 = matrix[9] ?? 0;
18
+ const m10 = matrix[10] ?? 0;
19
+ const m11 = matrix[11] ?? 0;
20
+ const m12 = matrix[12] ?? 0;
21
+ const m13 = matrix[13] ?? 0;
22
+ const m14 = matrix[14] ?? 0;
23
+ const m15 = matrix[15] ?? 0;
24
+ const m16 = matrix[16] ?? 0;
25
+ const m17 = matrix[17] ?? 0;
26
+ const m18 = matrix[18] ?? 0;
27
+ const m19 = matrix[19] ?? 0;
28
+ drawCanvasImageDataPass(dest, source, (data, pixelCount) => {
29
+ for (let i = 0; i < pixelCount; i++) {
30
+ const p = i * 4;
31
+ const r = data[p];
32
+ const g = data[p + 1];
33
+ const b = data[p + 2];
34
+ const a = data[p + 3];
35
+ // Uint8ClampedArray clamps stores to 0–255, so an explicit clamp is unnecessary.
36
+ data[p] = m0 * r + m1 * g + m2 * b + m3 * a + m4;
37
+ data[p + 1] = m5 * r + m6 * g + m7 * b + m8 * a + m9;
38
+ data[p + 2] = m10 * r + m11 * g + m12 * b + m13 * a + m14;
39
+ data[p + 3] = m15 * r + m16 * g + m17 * b + m18 * a + m19;
40
+ }
41
+ });
42
+ }
43
+ //# sourceMappingURL=canvasColorMatrixPass.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvasColorMatrixPass.js","sourceRoot":"","sources":["../src/canvasColorMatrixPass.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { CanvasRenderEffectRunner, CanvasRenderTarget, ConvolutionEffect } from '@flighthq/types';
2
+ export declare function applyConvolutionEffectToCanvas(source: Readonly<CanvasRenderTarget>, dest: Readonly<CanvasRenderTarget>, _effect: Readonly<ConvolutionEffect>): void;
3
+ export declare const defaultCanvasConvolutionEffectRunner: CanvasRenderEffectRunner;
4
+ //# sourceMappingURL=canvasConvolutionEffect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvasConvolutionEffect.d.ts","sourceRoot":"","sources":["../src/canvasConvolutionEffect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAOvG,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EACpC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAClC,OAAO,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GACnC,IAAI,CAEN;AAED,eAAO,MAAM,oCAAoC,EAAE,wBAElD,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { passthroughCanvasEffectPass } from './canvasEffectCompositing';
2
+ // Convolution (PASSTHROUGH): a generic matrix-kernel gather is per-pixel neighbor math. No CSS filter
3
+ // equivalent, but expressible per-pixel via getImageData/putImageData; not yet implemented — passthrough
4
+ // for now.
5
+ export function applyConvolutionEffectToCanvas(source, dest, _effect) {
6
+ passthroughCanvasEffectPass(dest, source);
7
+ }
8
+ export const defaultCanvasConvolutionEffectRunner = (ctx, effect) => {
9
+ applyConvolutionEffectToCanvas(ctx.source, ctx.dest, effect);
10
+ };
11
+ //# sourceMappingURL=canvasConvolutionEffect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvasConvolutionEffect.js","sourceRoot":"","sources":["../src/canvasConvolutionEffect.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AAExE,sGAAsG;AACtG,yGAAyG;AACzG,WAAW;AACX,MAAM,UAAU,8BAA8B,CAC5C,MAAoC,EACpC,IAAkC,EAClC,OAAoC;IAEpC,2BAA2B,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,MAAM,oCAAoC,GAA6B,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IAC5F,8BAA8B,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAA2B,CAAC,CAAC;AACpF,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { CanvasRenderEffectRunner, CanvasRenderTarget, DropShadowEffect } from '@flighthq/types';
2
+ export declare function applyDropShadowEffectToCanvas(source: Readonly<CanvasRenderTarget>, dest: Readonly<CanvasRenderTarget>, effect: Readonly<DropShadowEffect>): void;
3
+ export declare const defaultCanvasDropShadowEffectRunner: CanvasRenderEffectRunner;
4
+ //# sourceMappingURL=canvasDropShadowEffect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvasDropShadowEffect.d.ts","sourceRoot":"","sources":["../src/canvasDropShadowEffect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAStG,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EACpC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAClC,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GACjC,IAAI,CAGN;AAED,eAAO,MAAM,mCAAmC,EAAE,wBAEjD,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { drawCanvasEffectPass } from './canvasEffectCompositing';
2
+ import { computeDropShadowEffectCss } from './canvasEffectDropShadowCss';
3
+ // Drop-shadow composite effect: tint the scene silhouette, blur it, offset it by angle/distance, then composite the source over the shadow.
4
+ // Canvas 2D realizes the shadow/glow as a CSS `drop-shadow()` filter chain (the same string the DOM
5
+ // backend emits). Knockout and anisotropic-blur variants have no CSS equivalent; those pass the scene
6
+ // through unchanged rather than faking an approximation.
7
+ export function applyDropShadowEffectToCanvas(source, dest, effect) {
8
+ const css = computeDropShadowEffectCss(effect);
9
+ drawCanvasEffectPass(dest, source, css ?? 'none');
10
+ }
11
+ export const defaultCanvasDropShadowEffectRunner = (ctx, effect) => {
12
+ applyDropShadowEffectToCanvas(ctx.source, ctx.dest, effect);
13
+ };
14
+ //# sourceMappingURL=canvasDropShadowEffect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvasDropShadowEffect.js","sourceRoot":"","sources":["../src/canvasDropShadowEffect.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AAEzE,4IAA4I;AAC5I,oGAAoG;AACpG,sGAAsG;AACtG,yDAAyD;AACzD,MAAM,UAAU,6BAA6B,CAC3C,MAAoC,EACpC,IAAkC,EAClC,MAAkC;IAElC,MAAM,GAAG,GAAG,0BAA0B,CAAC,MAAM,CAAC,CAAC;IAC/C,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,CAAC,MAAM,mCAAmC,GAA6B,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IAC3F,6BAA6B,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAA0B,CAAC,CAAC;AAClF,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { DropShadowEffect, OuterGlowEffect } from '@flighthq/types';
2
+ export declare function computeDropShadowEffectCss(effect: Readonly<DropShadowEffect>): string | null;
3
+ export declare function computeOuterGlowEffectCss(effect: Readonly<OuterGlowEffect>): string | null;
4
+ //# sourceMappingURL=canvasEffectDropShadowCss.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvasEffectDropShadowCss.d.ts","sourceRoot":"","sources":["../src/canvasEffectDropShadowCss.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAKzE,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GAAG,MAAM,GAAG,IAAI,CAW5F;AAID,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,QAAQ,CAAC,eAAe,CAAC,GAAG,MAAM,GAAG,IAAI,CAM1F"}
@@ -0,0 +1,36 @@
1
+ // Drop-shadow composite effect as a CSS `drop-shadow()` string (the same string the DOM backend emits).
2
+ // Knockout and anisotropic-blur (blurX !== blurY) variants have no CSS equivalent and return null.
3
+ // Offset is derived from angle (degrees, default 45) and distance (default 4), rounded to whole pixels.
4
+ export function computeDropShadowEffectCss(effect) {
5
+ if (effect.knockout)
6
+ return null;
7
+ const blurX = effect.blurX ?? 4;
8
+ const blurY = effect.blurY ?? 4;
9
+ if (blurX !== blurY)
10
+ return null;
11
+ const angle = effect.angle ?? 45;
12
+ const distance = effect.distance ?? 4;
13
+ const radians = (angle * Math.PI) / 180;
14
+ const dx = Math.round(Math.cos(radians) * distance);
15
+ const dy = Math.round(Math.sin(radians) * distance);
16
+ return `drop-shadow(${dx}px ${dy}px ${blurX}px ${cssRgbaFromColor(effect.color ?? 0, effect.alpha ?? 1)})`;
17
+ }
18
+ // Outer-glow composite effect as a centered (no offset) CSS `drop-shadow()` string.
19
+ // Knockout and anisotropic-blur (blurX !== blurY) variants have no CSS equivalent and return null.
20
+ export function computeOuterGlowEffectCss(effect) {
21
+ if (effect.knockout)
22
+ return null;
23
+ const blurX = effect.blurX ?? 6;
24
+ const blurY = effect.blurY ?? 6;
25
+ if (blurX !== blurY)
26
+ return null;
27
+ return `drop-shadow(0px 0px ${blurX}px ${cssRgbaFromColor(effect.color ?? 0xff0000, effect.alpha ?? 1)})`;
28
+ }
29
+ // Packed 0xRRGGBB integer + separate alpha to a CSS `rgba()` string (alpha fixed to 3 decimals).
30
+ function cssRgbaFromColor(color, alpha) {
31
+ const r = (color >> 16) & 0xff;
32
+ const g = (color >> 8) & 0xff;
33
+ const b = color & 0xff;
34
+ return `rgba(${r},${g},${b},${alpha.toFixed(3)})`;
35
+ }
36
+ //# sourceMappingURL=canvasEffectDropShadowCss.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvasEffectDropShadowCss.js","sourceRoot":"","sources":["../src/canvasEffectDropShadowCss.ts"],"names":[],"mappings":"AAEA,wGAAwG;AACxG,mGAAmG;AACnG,wGAAwG;AACxG,MAAM,UAAU,0BAA0B,CAAC,MAAkC;IAC3E,IAAI,MAAM,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IACjC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;IAChC,IAAI,KAAK,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IACjC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;IACjC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC;IACxC,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC;IACpD,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC;IACpD,OAAO,eAAe,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,gBAAgB,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC;AAC7G,CAAC;AAED,oFAAoF;AACpF,mGAAmG;AACnG,MAAM,UAAU,yBAAyB,CAAC,MAAiC;IACzE,IAAI,MAAM,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IACjC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;IAChC,IAAI,KAAK,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IACjC,OAAO,uBAAuB,KAAK,MAAM,gBAAgB,CAAC,MAAM,CAAC,KAAK,IAAI,QAAQ,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC;AAC5G,CAAC;AAED,iGAAiG;AACjG,SAAS,gBAAgB,CAAC,KAAa,EAAE,KAAa;IACpD,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IAC/B,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;IAC9B,MAAM,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC;IACvB,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;AACpD,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { CanvasRenderEffectRunner, CanvasRenderTarget, MedianEffect } from '@flighthq/types';
2
+ export declare function applyMedianEffectToCanvas(source: Readonly<CanvasRenderTarget>, dest: Readonly<CanvasRenderTarget>, _effect: Readonly<MedianEffect>): void;
3
+ export declare const defaultCanvasMedianEffectRunner: CanvasRenderEffectRunner;
4
+ //# sourceMappingURL=canvasMedianEffect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvasMedianEffect.d.ts","sourceRoot":"","sources":["../src/canvasMedianEffect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAOlG,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EACpC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAClC,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,GAC9B,IAAI,CAEN;AAED,eAAO,MAAM,+BAA+B,EAAE,wBAE7C,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { passthroughCanvasEffectPass } from './canvasEffectCompositing';
2
+ // Median (PASSTHROUGH): per-channel median over a neighborhood is per-pixel neighbor math. No CSS filter
3
+ // equivalent, but expressible per-pixel via getImageData/putImageData; not yet implemented — passthrough
4
+ // for now.
5
+ export function applyMedianEffectToCanvas(source, dest, _effect) {
6
+ passthroughCanvasEffectPass(dest, source);
7
+ }
8
+ export const defaultCanvasMedianEffectRunner = (ctx, effect) => {
9
+ applyMedianEffectToCanvas(ctx.source, ctx.dest, effect);
10
+ };
11
+ //# sourceMappingURL=canvasMedianEffect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvasMedianEffect.js","sourceRoot":"","sources":["../src/canvasMedianEffect.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AAExE,yGAAyG;AACzG,yGAAyG;AACzG,WAAW;AACX,MAAM,UAAU,yBAAyB,CACvC,MAAoC,EACpC,IAAkC,EAClC,OAA+B;IAE/B,2BAA2B,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,MAAM,+BAA+B,GAA6B,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IACvF,yBAAyB,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAAsB,CAAC,CAAC;AAC1E,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { CanvasRenderEffectRunner, CanvasRenderTarget, OuterGlowEffect } from '@flighthq/types';
2
+ export declare function applyOuterGlowEffectToCanvas(source: Readonly<CanvasRenderTarget>, dest: Readonly<CanvasRenderTarget>, effect: Readonly<OuterGlowEffect>): void;
3
+ export declare const defaultCanvasOuterGlowEffectRunner: CanvasRenderEffectRunner;
4
+ //# sourceMappingURL=canvasOuterGlowEffect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvasOuterGlowEffect.d.ts","sourceRoot":"","sources":["../src/canvasOuterGlowEffect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AASrG,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EACpC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAClC,MAAM,EAAE,QAAQ,CAAC,eAAe,CAAC,GAChC,IAAI,CAGN;AAED,eAAO,MAAM,kCAAkC,EAAE,wBAEhD,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { drawCanvasEffectPass } from './canvasEffectCompositing';
2
+ import { computeOuterGlowEffectCss } from './canvasEffectDropShadowCss';
3
+ // Outer-glow composite effect: tint the scene silhouette, blur it centered (no offset), then composite the source over the glow.
4
+ // Canvas 2D realizes the shadow/glow as a CSS `drop-shadow()` filter chain (the same string the DOM
5
+ // backend emits). Knockout and anisotropic-blur variants have no CSS equivalent; those pass the scene
6
+ // through unchanged rather than faking an approximation.
7
+ export function applyOuterGlowEffectToCanvas(source, dest, effect) {
8
+ const css = computeOuterGlowEffectCss(effect);
9
+ drawCanvasEffectPass(dest, source, css ?? 'none');
10
+ }
11
+ export const defaultCanvasOuterGlowEffectRunner = (ctx, effect) => {
12
+ applyOuterGlowEffectToCanvas(ctx.source, ctx.dest, effect);
13
+ };
14
+ //# sourceMappingURL=canvasOuterGlowEffect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvasOuterGlowEffect.js","sourceRoot":"","sources":["../src/canvasOuterGlowEffect.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAExE,iIAAiI;AACjI,oGAAoG;AACpG,sGAAsG;AACtG,yDAAyD;AACzD,MAAM,UAAU,4BAA4B,CAC1C,MAAoC,EACpC,IAAkC,EAClC,MAAiC;IAEjC,MAAM,GAAG,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC;IAC9C,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,CAAC,MAAM,kCAAkC,GAA6B,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IAC1F,4BAA4B,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAAyB,CAAC,CAAC;AAChF,CAAC,CAAC"}
@@ -1,9 +1,9 @@
1
- import type { CanvasRenderEffectPipeline, CanvasRenderState, CanvasRenderTarget, CanvasRenderTargetPool, RenderEffect, RenderEffectPipelineOptions } from '@flighthq/types';
1
+ import type { Adjustment, CanvasRenderEffectPipeline, CanvasRenderState, CanvasRenderTarget, CanvasRenderTargetPool, RenderEffect, RenderEffectPipelineOptions } from '@flighthq/types';
2
2
  export declare function acquireCanvasRenderTarget(pool: CanvasRenderTargetPool, width: number, height: number): CanvasRenderTarget;
3
3
  export declare function beginCanvasRenderEffectPipeline(state: CanvasRenderState, pipeline: CanvasRenderEffectPipeline): void;
4
4
  export declare function createCanvasRenderEffectPipeline(_state: CanvasRenderState, options?: Readonly<RenderEffectPipelineOptions>): CanvasRenderEffectPipeline;
5
5
  export declare function createCanvasRenderTargetPool(): CanvasRenderTargetPool;
6
6
  export declare function destroyCanvasRenderEffectPipeline(_state: CanvasRenderState, pipeline: CanvasRenderEffectPipeline): void;
7
- export declare function endCanvasRenderEffectPipeline(state: CanvasRenderState, pipeline: CanvasRenderEffectPipeline, effects: ReadonlyArray<RenderEffect>): void;
7
+ export declare function endCanvasRenderEffectPipeline(state: CanvasRenderState, pipeline: CanvasRenderEffectPipeline, operations: ReadonlyArray<RenderEffect | Adjustment>): void;
8
8
  export declare function releaseCanvasRenderTarget(pool: CanvasRenderTargetPool, target: CanvasRenderTarget): void;
9
9
  //# sourceMappingURL=canvasRenderEffectPipeline.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"canvasRenderEffectPipeline.d.ts","sourceRoot":"","sources":["../src/canvasRenderEffectPipeline.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,0BAA0B,EAC1B,iBAAiB,EACjB,kBAAkB,EAClB,sBAAsB,EACtB,YAAY,EACZ,2BAA2B,EAC5B,MAAM,iBAAiB,CAAC;AAczB,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,sBAAsB,EAC5B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,kBAAkB,CAOpB;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,0BAA0B,GAAG,IAAI,CAapH;AAED,wBAAgB,gCAAgC,CAC9C,MAAM,EAAE,iBAAiB,EACzB,OAAO,GAAE,QAAQ,CAAC,2BAA2B,CAAM,GAClD,0BAA0B,CAE5B;AAED,wBAAgB,4BAA4B,IAAI,sBAAsB,CAErE;AAED,wBAAgB,iCAAiC,CAC/C,MAAM,EAAE,iBAAiB,EACzB,QAAQ,EAAE,0BAA0B,GACnC,IAAI,CAMN;AAED,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,iBAAiB,EACxB,QAAQ,EAAE,0BAA0B,EACpC,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,GACnC,IAAI,CAyBN;AAID,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,sBAAsB,EAAE,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAIxG"}
1
+ {"version":3,"file":"canvasRenderEffectPipeline.d.ts","sourceRoot":"","sources":["../src/canvasRenderEffectPipeline.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACV,UAAU,EACV,0BAA0B,EAC1B,iBAAiB,EACjB,kBAAkB,EAClB,sBAAsB,EACtB,YAAY,EACZ,2BAA2B,EAC5B,MAAM,iBAAiB,CAAC;AAgBzB,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,sBAAsB,EAC5B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,kBAAkB,CAOpB;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,0BAA0B,GAAG,IAAI,CAapH;AAED,wBAAgB,gCAAgC,CAC9C,MAAM,EAAE,iBAAiB,EACzB,OAAO,GAAE,QAAQ,CAAC,2BAA2B,CAAM,GAClD,0BAA0B,CAO5B;AAED,wBAAgB,4BAA4B,IAAI,sBAAsB,CAErE;AAED,wBAAgB,iCAAiC,CAC/C,MAAM,EAAE,iBAAiB,EACzB,QAAQ,EAAE,0BAA0B,GACnC,IAAI,CAQN;AAED,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,iBAAiB,EACxB,QAAQ,EAAE,0BAA0B,EACpC,UAAU,EAAE,aAAa,CAAC,YAAY,GAAG,UAAU,CAAC,GACnD,IAAI,CAyDN;AAID,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,sBAAsB,EAAE,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAIxG"}
@@ -1,5 +1,8 @@
1
+ import { bakeColorLutForRun, createColorLutCache, fuseColorMatrices, getAdjustmentColorMatrix, isColorLutAdjustment, } from '@flighthq/adjustments';
1
2
  import { beginCanvasRenderTarget, createCanvasRenderTarget, endCanvasRenderTarget, resizeCanvasRenderTarget, } from '@flighthq/displayobject-canvas';
2
3
  import { createMatrix } from '@flighthq/geometry';
4
+ import { applyColorLutPassToCanvas } from './canvasColorLutPass';
5
+ import { applyColorMatrixPassToCanvas } from './canvasColorMatrixPass';
3
6
  import { getCanvasRenderEffectRunner } from './canvasRenderEffectRegistry';
4
7
  // Opt-in Canvas 2D post-process pipeline — the parallel of the Gl effect pipeline. The scene renders
5
8
  // into the pipeline's offscreen canvas between begin/end; end runs the agnostic effect list through the
@@ -34,7 +37,12 @@ export function beginCanvasRenderEffectPipeline(state, pipeline) {
34
37
  beginCanvasRenderTarget(state, pipeline.sceneTarget, state.renderTransform2D ?? createMatrix());
35
38
  }
36
39
  export function createCanvasRenderEffectPipeline(_state, options = {}) {
37
- return { options: { ...options }, sceneTarget: null, pool: createCanvasRenderTargetPool() };
40
+ return {
41
+ options: { ...options },
42
+ sceneTarget: null,
43
+ pool: createCanvasRenderTargetPool(),
44
+ lutCache: createColorLutCache(),
45
+ };
38
46
  }
39
47
  export function createCanvasRenderTargetPool() {
40
48
  return { free: [], inUse: [] };
@@ -45,8 +53,10 @@ export function destroyCanvasRenderEffectPipeline(_state, pipeline) {
45
53
  pipeline.sceneTarget = null;
46
54
  pipeline.pool.free.length = 0;
47
55
  pipeline.pool.inUse.length = 0;
56
+ pipeline.lutCache.signature = null;
57
+ pipeline.lutCache.lut = null;
48
58
  }
49
- export function endCanvasRenderEffectPipeline(state, pipeline, effects) {
59
+ export function endCanvasRenderEffectPipeline(state, pipeline, operations) {
50
60
  const scene = pipeline.sceneTarget;
51
61
  if (scene === null)
52
62
  return;
@@ -55,18 +65,52 @@ export function endCanvasRenderEffectPipeline(state, pipeline, effects) {
55
65
  let source = scene;
56
66
  let scratchA = null;
57
67
  let scratchB = null;
58
- for (const effect of effects) {
59
- const runner = getCanvasRenderEffectRunner(state, effect.kind);
60
- if (runner === null)
61
- continue;
68
+ // A maximal run of consecutive pointwise adjustments fuses into ONE pass: all matrix-tier → one 4×5
69
+ // matrix (cheaper applyColorMatrixPass); any LUT-tier member → the whole run (matrices folded in) bakes
70
+ // into one ColorLut (applyColorLutPass). An effect (or the end of the stack) breaks the run and flushes
71
+ // it first, preserving stack order.
72
+ let pending = [];
73
+ const ensureScratch = () => {
62
74
  if (scratchA === null)
63
75
  scratchA = acquireCanvasRenderTarget(pool, scene.width, scene.height);
64
76
  if (scratchB === null)
65
77
  scratchB = acquireCanvasRenderTarget(pool, scene.width, scene.height);
78
+ };
79
+ const flushAdjustments = () => {
80
+ if (pending.length === 0)
81
+ return;
82
+ ensureScratch();
83
+ const dest = source === scratchA ? scratchB : scratchA;
84
+ if (pending.some(isColorLutAdjustment)) {
85
+ applyColorLutPassToCanvas(source, dest, bakeColorLutForRun(pipeline.lutCache, pending));
86
+ }
87
+ else {
88
+ const matrices = [];
89
+ for (const op of pending) {
90
+ const matrix = getAdjustmentColorMatrix(op);
91
+ if (matrix !== null)
92
+ matrices.push(matrix);
93
+ }
94
+ applyColorMatrixPassToCanvas(source, dest, fuseColorMatrices(matrices));
95
+ }
96
+ source = dest;
97
+ pending = [];
98
+ };
99
+ for (const operation of operations) {
100
+ if (getAdjustmentColorMatrix(operation) !== null || isColorLutAdjustment(operation)) {
101
+ pending.push(operation);
102
+ continue;
103
+ }
104
+ const runner = getCanvasRenderEffectRunner(state, operation.kind);
105
+ if (runner === null)
106
+ continue;
107
+ flushAdjustments();
108
+ ensureScratch();
66
109
  const dest = source === scratchA ? scratchB : scratchA;
67
- runner({ state, source, dest, pool }, effect);
110
+ runner({ state, source, dest, pool }, operation);
68
111
  source = dest;
69
112
  }
113
+ flushAdjustments();
70
114
  presentCanvasRenderEffectResult(state, source);
71
115
  if (scratchA !== null)
72
116
  releaseCanvasRenderTarget(pool, scratchA);
@@ -1 +1 @@
1
- {"version":3,"file":"canvasRenderEffectPipeline.js","sourceRoot":"","sources":["../src/canvasRenderEffectPipeline.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"canvasRenderEffectPipeline.js","sourceRoot":"","sources":["../src/canvasRenderEffectPipeline.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,wBAAwB,EACxB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,uBAAuB,EACvB,wBAAwB,EACxB,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAWlD,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,2BAA2B,EAAE,MAAM,8BAA8B,CAAC;AAE3E,qGAAqG;AACrG,wGAAwG;AACxG,wGAAwG;AACxG,wGAAwG;AACxG,yGAAyG;AACzG,kGAAkG;AAElG,uGAAuG;AACvG,qGAAqG;AACrG,yEAAyE;AACzE,MAAM,UAAU,yBAAyB,CACvC,IAA4B,EAC5B,KAAa,EACb,MAAc;IAEd,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACxC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACjE,IAAI,MAAM,CAAC,KAAK,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,wBAAwB,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACtF,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACxB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,+BAA+B,CAAC,KAAwB,EAAE,QAAoC;IAC5G,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC;IAC7B,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;IAE9B,IAAI,QAAQ,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;QAClC,QAAQ,CAAC,WAAW,GAAG,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACxD,CAAC;SAAM,CAAC;QACN,wBAAwB,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACvD,CAAC;IACD,mGAAmG;IACnG,wEAAwE;IACxE,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACtG,uBAAuB,CAAC,KAAK,EAAE,QAAQ,CAAC,WAAW,EAAE,KAAK,CAAC,iBAAiB,IAAI,YAAY,EAAE,CAAC,CAAC;AAClG,CAAC;AAED,MAAM,UAAU,gCAAgC,CAC9C,MAAyB,EACzB,UAAiD,EAAE;IAEnD,OAAO;QACL,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE;QACvB,WAAW,EAAE,IAAI;QACjB,IAAI,EAAE,4BAA4B,EAAE;QACpC,QAAQ,EAAE,mBAAmB,EAAE;KAChC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,4BAA4B;IAC1C,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,iCAAiC,CAC/C,MAAyB,EACzB,QAAoC;IAEpC,kGAAkG;IAClG,wDAAwD;IACxD,QAAQ,CAAC,WAAW,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IAC9B,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,QAAQ,CAAC,GAAG,GAAG,IAAI,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,6BAA6B,CAC3C,KAAwB,EACxB,QAAoC,EACpC,UAAoD;IAEpD,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,CAAC;IACnC,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO;IAE3B,qBAAqB,CAAC,KAAK,CAAC,CAAC;IAE7B,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;IAC3B,IAAI,MAAM,GAAuB,KAAK,CAAC;IACvC,IAAI,QAAQ,GAA8B,IAAI,CAAC;IAC/C,IAAI,QAAQ,GAA8B,IAAI,CAAC;IAC/C,oGAAoG;IACpG,wGAAwG;IACxG,wGAAwG;IACxG,oCAAoC;IACpC,IAAI,OAAO,GAAiB,EAAE,CAAC;IAE/B,MAAM,aAAa,GAAG,GAAS,EAAE;QAC/B,IAAI,QAAQ,KAAK,IAAI;YAAE,QAAQ,GAAG,yBAAyB,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAC7F,IAAI,QAAQ,KAAK,IAAI;YAAE,QAAQ,GAAG,yBAAyB,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC/F,CAAC,CAAC;IACF,MAAM,gBAAgB,GAAG,GAAS,EAAE;QAClC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACjC,aAAa,EAAE,CAAC;QAChB,MAAM,IAAI,GAAG,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAS,CAAC,CAAC,CAAC,QAAS,CAAC;QACzD,IAAI,OAAO,CAAC,IAAI,CAAC,oBAAoB,CAAC,EAAE,CAAC;YACvC,yBAAyB,CAAC,MAAM,EAAE,IAAI,EAAE,kBAAkB,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;QAC1F,CAAC;aAAM,CAAC;YACN,MAAM,QAAQ,GAA0B,EAAE,CAAC;YAC3C,KAAK,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;gBACzB,MAAM,MAAM,GAAG,wBAAwB,CAAC,EAAE,CAAC,CAAC;gBAC5C,IAAI,MAAM,KAAK,IAAI;oBAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC7C,CAAC;YACD,4BAA4B,CAAC,MAAM,EAAE,IAAI,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC1E,CAAC;QACD,MAAM,GAAG,IAAI,CAAC;QACd,OAAO,GAAG,EAAE,CAAC;IACf,CAAC,CAAC;IAEF,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,wBAAwB,CAAC,SAAS,CAAC,KAAK,IAAI,IAAI,oBAAoB,CAAC,SAAS,CAAC,EAAE,CAAC;YACpF,OAAO,CAAC,IAAI,CAAC,SAAuB,CAAC,CAAC;YACtC,SAAS;QACX,CAAC;QACD,MAAM,MAAM,GAAG,2BAA2B,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;QAClE,IAAI,MAAM,KAAK,IAAI;YAAE,SAAS;QAC9B,gBAAgB,EAAE,CAAC;QACnB,aAAa,EAAE,CAAC;QAChB,MAAM,IAAI,GAAG,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAS,CAAC,CAAC,CAAC,QAAS,CAAC;QACzD,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,SAAS,CAAC,CAAC;QACjD,MAAM,GAAG,IAAI,CAAC;IAChB,CAAC;IACD,gBAAgB,EAAE,CAAC;IAEnB,+BAA+B,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAE/C,IAAI,QAAQ,KAAK,IAAI;QAAE,yBAAyB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACjE,IAAI,QAAQ,KAAK,IAAI;QAAE,yBAAyB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AACnE,CAAC;AAED,mFAAmF;AACnF,4CAA4C;AAC5C,MAAM,UAAU,yBAAyB,CAAC,IAA4B,EAAE,MAA0B;IAChG,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,IAAI,KAAK,KAAK,CAAC,CAAC;QAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC9C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACzB,CAAC;AAED,mGAAmG;AACnG,kDAAkD;AAClD,SAAS,+BAA+B,CAAC,KAAwB,EAAE,MAAoC;IACrG,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC9B,OAAO,CAAC,IAAI,EAAE,CAAC;IACf,OAAO,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACvC,OAAO,CAAC,wBAAwB,GAAG,aAAa,CAAC;IACjD,OAAO,CAAC,WAAW,GAAG,CAAC,CAAC;IACxB,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC;IACxB,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACjE,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACvC,OAAO,CAAC,OAAO,EAAE,CAAC;AACpB,CAAC"}
@@ -2,6 +2,7 @@ import type { CanvasRenderState } from '@flighthq/types';
2
2
  export declare function registerAllCanvasRenderEffects(state: CanvasRenderState): void;
3
3
  export declare function registerBlurCanvasRenderEffects(state: CanvasRenderState): void;
4
4
  export declare function registerColorGradeCanvasRenderEffects(state: CanvasRenderState): void;
5
+ export declare function registerCompositeCanvasRenderEffects(state: CanvasRenderState): void;
5
6
  export declare function registerScreenSpaceCanvasRenderEffects(state: CanvasRenderState): void;
6
7
  export declare function registerStylizeCanvasRenderEffects(state: CanvasRenderState): void;
7
8
  //# sourceMappingURL=canvasRenderEffectRegistration.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"canvasRenderEffectRegistration.d.ts","sourceRoot":"","sources":["../src/canvasRenderEffectRegistration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA4B,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAiDnF,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAK7E;AAOD,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAI9E;AAQD,wBAAgB,qCAAqC,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAIpF;AAOD,wBAAgB,sCAAsC,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAIrF;AAOD,wBAAgB,kCAAkC,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAIjF"}
1
+ {"version":3,"file":"canvasRenderEffectRegistration.d.ts","sourceRoot":"","sources":["../src/canvasRenderEffectRegistration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA4B,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AA4CnF,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAM7E;AAOD,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAI9E;AASD,wBAAgB,qCAAqC,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAIpF;AAOD,wBAAgB,oCAAoC,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAInF;AAOD,wBAAgB,sCAAsC,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAIrF;AAOD,wBAAgB,kCAAkC,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAIjF"}
@@ -1,33 +1,28 @@
1
1
  import { defaultCanvasBloomEffectRunner } from './canvasBloomEffect';
2
- import { defaultCanvasBrightnessContrastEffectRunner } from './canvasBrightnessContrastEffect';
3
- import { defaultCanvasChannelMixerEffectRunner } from './canvasChannelMixerEffect';
2
+ import { defaultCanvasBlurEffectRunner } from './canvasBlurEffect';
4
3
  import { defaultCanvasChromaticAberrationEffectRunner } from './canvasChromaticAberrationEffect';
5
- import { defaultCanvasColorGradeEffectRunner } from './canvasColorGradeEffect';
4
+ import { defaultCanvasConvolutionEffectRunner } from './canvasConvolutionEffect';
6
5
  import { defaultCanvasCrtEffectRunner } from './canvasCrtEffect';
7
6
  import { defaultCanvasDirectionalBlurEffectRunner } from './canvasDirectionalBlurEffect';
8
7
  import { defaultCanvasDisplacementEffectRunner } from './canvasDisplacementEffect';
9
8
  import { defaultCanvasDitherEffectRunner } from './canvasDitherEffect';
10
- import { defaultCanvasExposureEffectRunner } from './canvasExposureEffect';
9
+ import { defaultCanvasDropShadowEffectRunner } from './canvasDropShadowEffect';
11
10
  import { defaultCanvasFilmGrainEffectRunner } from './canvasFilmGrainEffect';
12
11
  import { defaultCanvasGlitchEffectRunner } from './canvasGlitchEffect';
13
12
  import { defaultCanvasGodRaysEffectRunner } from './canvasGodRaysEffect';
14
- import { defaultCanvasGrayscaleEffectRunner } from './canvasGrayscaleEffect';
15
13
  import { defaultCanvasHalftoneEffectRunner } from './canvasHalftoneEffect';
16
- import { defaultCanvasHueSaturationEffectRunner } from './canvasHueSaturationEffect';
17
- import { defaultCanvasInvertEffectRunner } from './canvasInvertEffect';
18
14
  import { defaultCanvasKuwaharaEffectRunner } from './canvasKuwaharaEffect';
19
15
  import { defaultCanvasLensDirtEffectRunner } from './canvasLensDirtEffect';
20
16
  import { defaultCanvasLensDistortionEffectRunner } from './canvasLensDistortionEffect';
21
17
  import { defaultCanvasLensFlareEffectRunner } from './canvasLensFlareEffect';
22
- import { defaultCanvasLiftGammaGainEffectRunner } from './canvasLiftGammaGainEffect';
18
+ import { defaultCanvasMedianEffectRunner } from './canvasMedianEffect';
19
+ import { defaultCanvasOuterGlowEffectRunner } from './canvasOuterGlowEffect';
23
20
  import { defaultCanvasOutlineEffectRunner } from './canvasOutlineEffect';
24
21
  import { defaultCanvasPixelateEffectRunner } from './canvasPixelateEffect';
25
- import { defaultCanvasPosterizeEffectRunner } from './canvasPosterizeEffect';
26
22
  import { defaultCanvasRadialBlurEffectRunner } from './canvasRadialBlurEffect';
27
23
  import { registerCanvasRenderEffect } from './canvasRenderEffectRegistry';
28
24
  import { defaultCanvasScanlinesEffectRunner } from './canvasScanlinesEffect';
29
25
  import { defaultCanvasScreenSpaceFogEffectRunner } from './canvasScreenSpaceFogEffect';
30
- import { defaultCanvasSepiaEffectRunner } from './canvasSepiaEffect';
31
26
  import { defaultCanvasSharpenEffectRunner } from './canvasSharpenEffect';
32
27
  import { defaultCanvasSketchEffectRunner } from './canvasSketchEffect';
33
28
  import { defaultCanvasTiltShiftEffectRunner } from './canvasTiltShiftEffect';
@@ -47,6 +42,7 @@ import { defaultCanvasWhiteBalanceEffectRunner } from './canvasWhiteBalanceEffec
47
42
  export function registerAllCanvasRenderEffects(state) {
48
43
  registerBlurCanvasRenderEffects(state);
49
44
  registerColorGradeCanvasRenderEffects(state);
45
+ registerCompositeCanvasRenderEffects(state);
50
46
  registerScreenSpaceCanvasRenderEffects(state);
51
47
  registerStylizeCanvasRenderEffects(state);
52
48
  }
@@ -60,10 +56,11 @@ export function registerBlurCanvasRenderEffects(state) {
60
56
  registerCanvasRenderEffect(state, kind, runner);
61
57
  }
62
58
  }
63
- // Registers all color-grade default runners into a CanvasRenderState: brightness-contrast,
64
- // channel-mixer, color-grade, dither, exposure (approximate), grayscale, hue-saturation, invert,
65
- // lift-gamma-gain, posterize, sepia, tone-map (approximate), and white-balance.
66
- // LookupTableGradeEffect is excluded (passthrough descriptor carries no cube data array).
59
+ // Registers the remaining color-tone default runners into a CanvasRenderState: dither, tone-map
60
+ // (approximate), and white-balance. The pointwise color ops (grayscale/invert/sepia/brightness-contrast/
61
+ // channel-mixer/exposure as matrix-tier, and hue-saturation/lift-gamma-gain/color-grade/posterize/
62
+ // lookup-table-grade as LUT-tier) moved to @flighthq/adjustments and fold through the pipeline's generic
63
+ // color-matrix / color-LUT pass — see effect-adjustment-architecture.
67
64
  // Importing only this function pulls those runners into the bundle — use
68
65
  // `registerCanvasRenderEffect` per-runner for full tree-shaking.
69
66
  export function registerColorGradeCanvasRenderEffects(state) {
@@ -71,6 +68,16 @@ export function registerColorGradeCanvasRenderEffects(state) {
71
68
  registerCanvasRenderEffect(state, kind, runner);
72
69
  }
73
70
  }
71
+ // Registers the composite-family default runners realizable on Canvas 2D: DropShadowEffect and
72
+ // OuterGlowEffect, both drawn via a CSS `drop-shadow()` filter chain. The other former-filter
73
+ // composites (bevel, inner glow/shadow, gradient glow/bevel) have no Canvas 2D realization — they
74
+ // require the multi-target tint/blur/offset GPU recipe — so they are intentionally omitted here (the
75
+ // pipeline skips unregistered kinds). Symmetric with registerCompositeGlRenderEffects.
76
+ export function registerCompositeCanvasRenderEffects(state) {
77
+ for (const [kind, runner] of COMPOSITE_CANVAS_EFFECT_KINDS) {
78
+ registerCanvasRenderEffect(state, kind, runner);
79
+ }
80
+ }
74
81
  // Registers all screen-space and anti-aliasing default runners into a CanvasRenderState. On
75
82
  // Canvas 2D all screen-space effects (FxaaEffect, SmaaEffect, SsaoEffect, SsrEffect, TaaEffect,
76
83
  // ScreenSpaceShadowsEffect) are passthrough — they require GPU AA samples, depth, or velocity
@@ -93,30 +100,27 @@ export function registerStylizeCanvasRenderEffects(state) {
93
100
  }
94
101
  // The kind strings for the four category groups. Kept as local constants so the individual
95
102
  // register* functions above have a single source of truth for the loop.
103
+ // Composite effects realizable on Canvas 2D via a CSS drop-shadow() chain. Only the two centered/
104
+ // offset shadow-and-glow ops have a CSS equivalent; the rest are GPU-only and omitted.
105
+ const COMPOSITE_CANVAS_EFFECT_KINDS = [
106
+ ['DropShadowEffect', defaultCanvasDropShadowEffectRunner],
107
+ ['OuterGlowEffect', defaultCanvasOuterGlowEffectRunner],
108
+ ];
96
109
  // Blur effects: multi-pass or directional blurs operating on the color buffer.
97
110
  // BokehDepthOfFieldEffect, CameraMotionBlurEffect, and MotionBlurEffect are passthrough on Canvas
98
111
  // (require a depth or velocity buffer that Canvas 2D does not produce) and are omitted here.
99
112
  const BLUR_CANVAS_EFFECT_KINDS = [
100
113
  ['BloomEffect', defaultCanvasBloomEffectRunner],
114
+ ['BlurEffect', defaultCanvasBlurEffectRunner],
101
115
  ['DirectionalBlurEffect', defaultCanvasDirectionalBlurEffectRunner],
102
116
  ['RadialBlurEffect', defaultCanvasRadialBlurEffectRunner],
103
117
  ['TiltShiftEffect', defaultCanvasTiltShiftEffectRunner],
104
118
  ];
105
- // Color-grade effects: per-pixel color transforms with no multi-pass or geometry dependency.
106
- // LookupTableGradeEffect is passthrough on Canvas (descriptor carries no cube data array) and is
107
- // omitted here. ExposureEffect and ToneMapEffect are included as approximate LDR implementations.
119
+ // Color-tone effects still realized as Canvas passes: dither, tone-map (approximate LDR), and
120
+ // white-balance. The pointwise color ops moved to @flighthq/adjustments and fold through the pipeline's
121
+ // generic color-matrix / color-LUT pass (see effect-adjustment-architecture).
108
122
  const COLOR_GRADE_CANVAS_EFFECT_KINDS = [
109
- ['BrightnessContrastEffect', defaultCanvasBrightnessContrastEffectRunner],
110
- ['ChannelMixerEffect', defaultCanvasChannelMixerEffectRunner],
111
- ['ColorGradeEffect', defaultCanvasColorGradeEffectRunner],
112
123
  ['DitherEffect', defaultCanvasDitherEffectRunner],
113
- ['ExposureEffect', defaultCanvasExposureEffectRunner],
114
- ['GrayscaleEffect', defaultCanvasGrayscaleEffectRunner],
115
- ['HueSaturationEffect', defaultCanvasHueSaturationEffectRunner],
116
- ['InvertEffect', defaultCanvasInvertEffectRunner],
117
- ['LiftGammaGainEffect', defaultCanvasLiftGammaGainEffectRunner],
118
- ['PosterizeEffect', defaultCanvasPosterizeEffectRunner],
119
- ['SepiaEffect', defaultCanvasSepiaEffectRunner],
120
124
  ['ToneMapEffect', defaultCanvasToneMapEffectRunner],
121
125
  ['WhiteBalanceEffect', defaultCanvasWhiteBalanceEffectRunner],
122
126
  ];
@@ -129,6 +133,7 @@ const SCREENSPACE_CANVAS_EFFECT_KINDS = [];
129
133
  // Stylize effects: artistic transforms, screen-space overlays, and film emulation.
130
134
  const STYLIZE_CANVAS_EFFECT_KINDS = [
131
135
  ['ChromaticAberrationEffect', defaultCanvasChromaticAberrationEffectRunner],
136
+ ['ConvolutionEffect', defaultCanvasConvolutionEffectRunner],
132
137
  ['CrtEffect', defaultCanvasCrtEffectRunner],
133
138
  ['DisplacementEffect', defaultCanvasDisplacementEffectRunner],
134
139
  ['FilmGrainEffect', defaultCanvasFilmGrainEffectRunner],
@@ -139,6 +144,7 @@ const STYLIZE_CANVAS_EFFECT_KINDS = [
139
144
  ['LensDirtEffect', defaultCanvasLensDirtEffectRunner],
140
145
  ['LensDistortionEffect', defaultCanvasLensDistortionEffectRunner],
141
146
  ['LensFlareEffect', defaultCanvasLensFlareEffectRunner],
147
+ ['MedianEffect', defaultCanvasMedianEffectRunner],
142
148
  ['OutlineEffect', defaultCanvasOutlineEffectRunner],
143
149
  ['PixelateEffect', defaultCanvasPixelateEffectRunner],
144
150
  ['ScanlinesEffect', defaultCanvasScanlinesEffectRunner],