@flighthq/effects-wgpu 0.2.1-next.652.c550eaa → 0.2.1-next.701.409c279

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/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  export * from './wgpuColorMatrixPass';
2
+ export * from './wgpuCompositeEffect';
3
+ export * from './wgpuBlendEffect';
2
4
  export * from './wgpuBevelEffect';
3
5
  export * from './wgpuBloomEffect';
4
6
  export * from './wgpuBlurEffect';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,iCAAiC,CAAC;AAChD,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,iCAAiC,CAAC;AAChD,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,6 @@
1
1
  export * from './wgpuColorMatrixPass';
2
+ export * from './wgpuCompositeEffect';
3
+ export * from './wgpuBlendEffect';
2
4
  export * from './wgpuBevelEffect';
3
5
  export * from './wgpuBloomEffect';
4
6
  export * from './wgpuBlurEffect';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,iCAAiC,CAAC;AAChD,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,iCAAiC,CAAC;AAChD,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { AdvancedBlendMode, BlendEffect, WgpuRenderEffectRunner, WgpuRenderState, WgpuRenderTarget } from '@flighthq/types';
2
+ export declare function applyBlendEffectToWgpu(state: WgpuRenderState, source: Readonly<WgpuRenderTarget>, dest: Readonly<WgpuRenderTarget>, effect: Readonly<BlendEffect>): void;
3
+ export declare const defaultWgpuBlendEffectRunner: WgpuRenderEffectRunner;
4
+ export declare function getWgpuBlendEffectBackdrop(state: WgpuRenderState, backdropKey: string | null): WgpuRenderTarget | null;
5
+ export declare function getWgpuBlendEffectModeIndex(mode: AdvancedBlendMode): number;
6
+ export declare function registerWgpuBlendEffectBackdrop(state: WgpuRenderState, backdropKey: string, target: WgpuRenderTarget): void;
7
+ export declare function unregisterWgpuBlendEffectBackdrop(state: WgpuRenderState, backdropKey: string): boolean;
8
+ export declare const WGPU_BLEND_FRAGMENT_WGSL = "\nstruct Uniforms {\n mode : i32,\n opacity : f32,\n hasBackdrop : i32,\n _pad0 : f32,\n}\n@group(0) @binding(0) var<uniform> uni : Uniforms;\n@group(1) @binding(0) var layerTexture : texture_2d<f32>;\n@group(1) @binding(1) var layerSampler : sampler;\n@group(2) @binding(0) var backdropTexture : texture_2d<f32>;\n@group(2) @binding(1) var backdropSampler : sampler;\n\nfn lum(c : vec3f) -> f32 {\n return dot(c, vec3f(0.3, 0.59, 0.11));\n}\n\nfn sat(c : vec3f) -> f32 {\n return max(max(c.r, c.g), c.b) - min(min(c.r, c.g), c.b);\n}\n\nfn clipColor(inputColor : vec3f) -> vec3f {\n var c = inputColor;\n let l = lum(c);\n let mn = min(min(c.r, c.g), c.b);\n let mx = max(max(c.r, c.g), c.b);\n if (mn < 0.0) {\n c = vec3f(l) + (c - vec3f(l)) * l / (l - mn);\n }\n if (mx > 1.0) {\n c = vec3f(l) + (c - vec3f(l)) * (1.0 - l) / (mx - l);\n }\n return c;\n}\n\nfn setLum(c : vec3f, l : f32) -> vec3f {\n return clipColor(c + vec3f(l - lum(c)));\n}\n\nfn setSat(c : vec3f, s : f32) -> vec3f {\n let mn = min(min(c.r, c.g), c.b);\n let mx = max(max(c.r, c.g), c.b);\n let md = c.r + c.g + c.b - mn - mx;\n let rmid = select(0.0, (md - mn) * s / (mx - mn), mx > mn);\n let rmax = select(0.0, s, mx > mn);\n var out = vec3f(0.0);\n out.r = select(select(rmid, 0.0, c.r == mn), rmax, c.r == mx);\n out.g = select(select(rmid, 0.0, c.g == mn), rmax, c.g == mx);\n out.b = select(select(rmid, 0.0, c.b == mn), rmax, c.b == mx);\n return out;\n}\n\nfn sepChannel(mode : i32, cb : f32, cs : f32) -> f32 {\n if (mode == 0) {\n return select(1.0 - 2.0 * (1.0 - cb) * (1.0 - cs), 2.0 * cb * cs, cb <= 0.5);\n }\n if (mode == 1) {\n return select(1.0 - 2.0 * (1.0 - cb) * (1.0 - cs), 2.0 * cb * cs, cs <= 0.5);\n }\n if (mode == 2) {\n let d = select(sqrt(cb), ((16.0 * cb - 12.0) * cb + 4.0) * cb, cb <= 0.25);\n return select(cb + (2.0 * cs - 1.0) * (d - cb), cb - (1.0 - 2.0 * cs) * cb * (1.0 - cb), cs <= 0.5);\n }\n if (mode == 3) { return abs(cb - cs); }\n if (mode == 4) { return cb + cs - 2.0 * cb * cs; }\n if (mode == 5) {\n if (cb <= 0.0) { return 0.0; }\n return select(min(1.0, cb / (1.0 - cs)), 1.0, cs >= 1.0);\n }\n if (mode == 6) {\n if (cb >= 1.0) { return 1.0; }\n return select(1.0 - min(1.0, (1.0 - cb) / cs), 0.0, cs <= 0.0);\n }\n return cs;\n}\n\nfn blendRgb(mode : i32, cb : vec3f, cs : vec3f) -> vec3f {\n if (mode == 7) { return setLum(setSat(cs, sat(cb)), lum(cb)); }\n if (mode == 8) { return setLum(setSat(cb, sat(cs)), lum(cb)); }\n if (mode == 9) { return setLum(cs, lum(cb)); }\n if (mode == 10) { return setLum(cb, lum(cs)); }\n return vec3f(\n sepChannel(mode, cb.r, cs.r),\n sepChannel(mode, cb.g, cs.g),\n sepChannel(mode, cb.b, cs.b),\n );\n}\n\n@fragment\nfn fs_main(@location(0) uv : vec2f) -> @location(0) vec4f {\n let layer = textureSampleLevel(layerTexture, layerSampler, uv, 0.0);\n if (uni.hasBackdrop == 0) {\n return layer;\n }\n let back = textureSampleLevel(backdropTexture, backdropSampler, uv, 0.0);\n let cs = select(vec3f(0.0), layer.rgb / layer.a, layer.a > 0.0);\n let cb = select(vec3f(0.0), back.rgb / back.a, back.a > 0.0);\n let sourceAlpha = layer.a * uni.opacity;\n let backdropAlpha = back.a;\n let blended = blendRgb(uni.mode, cb, cs);\n let mixed = (1.0 - backdropAlpha) * cs + backdropAlpha * blended;\n let outAlpha = sourceAlpha + backdropAlpha * (1.0 - sourceAlpha);\n let outRgb = mixed * sourceAlpha + cb * backdropAlpha * (1.0 - sourceAlpha);\n return vec4f(outRgb, outAlpha);\n}\n";
9
+ //# sourceMappingURL=wgpuBlendEffect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuBlendEffect.d.ts","sourceRoot":"","sources":["../src/wgpuBlendEffect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,WAAW,EAEX,sBAAsB,EACtB,eAAe,EACf,gBAAgB,EACjB,MAAM,iBAAiB,CAAC;AASzB,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAClC,IAAI,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAChC,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,GAC5B,IAAI,CAiBN;AAED,eAAO,MAAM,4BAA4B,EAAE,sBAE1C,CAAC;AAGF,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,eAAe,EACtB,WAAW,EAAE,MAAM,GAAG,IAAI,GACzB,gBAAgB,GAAG,IAAI,CAGzB;AAID,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAE3E;AAID,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,eAAe,EACtB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,gBAAgB,GACvB,IAAI,CAON;AAGD,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAEtG;AA8BD,eAAO,MAAM,wBAAwB,w9GAyGpC,CAAC"}
@@ -0,0 +1,177 @@
1
+ import { AdvancedBlendMode as AdvancedBlendModeValues } from '@flighthq/types';
2
+ import { createWgpuDualSourceEffectPipeline, drawWgpuDualSourceEffectPass } from './wgpuEffectPass';
3
+ // Advanced-blend composite pass: reads the incoming layer and an explicitly registered backdrop,
4
+ // applies the same W3C straight-color blend math as glBlendEffect, then writes premultiplied
5
+ // source-over output. A missing backdrop uses the layer as a harmless second binding and the uniform
6
+ // gate reduces the operation to passthrough.
7
+ export function applyBlendEffectToWgpu(state, source, dest, effect) {
8
+ const backdrop = getWgpuBlendEffectBackdrop(state, effect.backdropKey ?? null);
9
+ const pipeline = getWgpuBlendEffectPipeline(state);
10
+ const modeIndex = getWgpuBlendEffectModeIndex(effect.mode);
11
+ const hasBackdrop = backdrop !== null;
12
+ drawWgpuDualSourceEffectPass(state, source, (backdrop ?? source), dest, pipeline, (f32, i32) => {
13
+ i32[0] = modeIndex;
14
+ f32[1] = effect.opacity ?? 1;
15
+ i32[2] = hasBackdrop ? 1 : 0;
16
+ });
17
+ }
18
+ export const defaultWgpuBlendEffectRunner = (context, effect) => {
19
+ applyBlendEffectToWgpu(context.state, context.source, context.dest, effect);
20
+ };
21
+ // Returns the borrowed backdrop target registered under a key on this state, or null when absent.
22
+ export function getWgpuBlendEffectBackdrop(state, backdropKey) {
23
+ if (backdropKey === null)
24
+ return null;
25
+ return backdrops.get(state)?.get(backdropKey) ?? null;
26
+ }
27
+ // Maps the open AdvancedBlendMode value to the shared shader branch order. Unknown vendor values map
28
+ // to -1, whose shader fallback is Normal source color.
29
+ export function getWgpuBlendEffectModeIndex(mode) {
30
+ return BLEND_MODE_INDEX[mode] ?? -1;
31
+ }
32
+ // Registers a borrowed render target as a named backdrop. Last write wins; the registry never owns or
33
+ // destroys the target, so its caller must keep it alive until the BlendEffect pass completes.
34
+ export function registerWgpuBlendEffectBackdrop(state, backdropKey, target) {
35
+ let registry = backdrops.get(state);
36
+ if (registry === undefined) {
37
+ registry = new Map();
38
+ backdrops.set(state, registry);
39
+ }
40
+ registry.set(backdropKey, target);
41
+ }
42
+ // Removes a borrowed backdrop reference without destroying the target.
43
+ export function unregisterWgpuBlendEffectBackdrop(state, backdropKey) {
44
+ return backdrops.get(state)?.delete(backdropKey) ?? false;
45
+ }
46
+ function getWgpuBlendEffectPipeline(state) {
47
+ let pipeline = pipelines.get(state);
48
+ if (pipeline === undefined) {
49
+ pipeline = createWgpuDualSourceEffectPipeline(state, WGPU_BLEND_FRAGMENT_WGSL, 'replace');
50
+ pipelines.set(state, pipeline);
51
+ }
52
+ return pipeline;
53
+ }
54
+ const BLEND_MODE_INDEX = {
55
+ [AdvancedBlendModeValues.Overlay]: 0,
56
+ [AdvancedBlendModeValues.HardLight]: 1,
57
+ [AdvancedBlendModeValues.SoftLight]: 2,
58
+ [AdvancedBlendModeValues.Difference]: 3,
59
+ [AdvancedBlendModeValues.Exclusion]: 4,
60
+ [AdvancedBlendModeValues.ColorDodge]: 5,
61
+ [AdvancedBlendModeValues.ColorBurn]: 6,
62
+ [AdvancedBlendModeValues.Hue]: 7,
63
+ [AdvancedBlendModeValues.Saturation]: 8,
64
+ [AdvancedBlendModeValues.Color]: 9,
65
+ [AdvancedBlendModeValues.Luminosity]: 10,
66
+ };
67
+ const backdrops = new WeakMap();
68
+ const pipelines = new WeakMap();
69
+ // Layer and backdrop are premultiplied textures. Blend math operates on straight RGB, follows the W3C
70
+ // compositing formulas used by effects/blendModeMath and glBlendEffect, then premultiplies the result.
71
+ export const WGPU_BLEND_FRAGMENT_WGSL = /* wgsl */ `
72
+ struct Uniforms {
73
+ mode : i32,
74
+ opacity : f32,
75
+ hasBackdrop : i32,
76
+ _pad0 : f32,
77
+ }
78
+ @group(0) @binding(0) var<uniform> uni : Uniforms;
79
+ @group(1) @binding(0) var layerTexture : texture_2d<f32>;
80
+ @group(1) @binding(1) var layerSampler : sampler;
81
+ @group(2) @binding(0) var backdropTexture : texture_2d<f32>;
82
+ @group(2) @binding(1) var backdropSampler : sampler;
83
+
84
+ fn lum(c : vec3f) -> f32 {
85
+ return dot(c, vec3f(0.3, 0.59, 0.11));
86
+ }
87
+
88
+ fn sat(c : vec3f) -> f32 {
89
+ return max(max(c.r, c.g), c.b) - min(min(c.r, c.g), c.b);
90
+ }
91
+
92
+ fn clipColor(inputColor : vec3f) -> vec3f {
93
+ var c = inputColor;
94
+ let l = lum(c);
95
+ let mn = min(min(c.r, c.g), c.b);
96
+ let mx = max(max(c.r, c.g), c.b);
97
+ if (mn < 0.0) {
98
+ c = vec3f(l) + (c - vec3f(l)) * l / (l - mn);
99
+ }
100
+ if (mx > 1.0) {
101
+ c = vec3f(l) + (c - vec3f(l)) * (1.0 - l) / (mx - l);
102
+ }
103
+ return c;
104
+ }
105
+
106
+ fn setLum(c : vec3f, l : f32) -> vec3f {
107
+ return clipColor(c + vec3f(l - lum(c)));
108
+ }
109
+
110
+ fn setSat(c : vec3f, s : f32) -> vec3f {
111
+ let mn = min(min(c.r, c.g), c.b);
112
+ let mx = max(max(c.r, c.g), c.b);
113
+ let md = c.r + c.g + c.b - mn - mx;
114
+ let rmid = select(0.0, (md - mn) * s / (mx - mn), mx > mn);
115
+ let rmax = select(0.0, s, mx > mn);
116
+ var out = vec3f(0.0);
117
+ out.r = select(select(rmid, 0.0, c.r == mn), rmax, c.r == mx);
118
+ out.g = select(select(rmid, 0.0, c.g == mn), rmax, c.g == mx);
119
+ out.b = select(select(rmid, 0.0, c.b == mn), rmax, c.b == mx);
120
+ return out;
121
+ }
122
+
123
+ fn sepChannel(mode : i32, cb : f32, cs : f32) -> f32 {
124
+ if (mode == 0) {
125
+ return select(1.0 - 2.0 * (1.0 - cb) * (1.0 - cs), 2.0 * cb * cs, cb <= 0.5);
126
+ }
127
+ if (mode == 1) {
128
+ return select(1.0 - 2.0 * (1.0 - cb) * (1.0 - cs), 2.0 * cb * cs, cs <= 0.5);
129
+ }
130
+ if (mode == 2) {
131
+ let d = select(sqrt(cb), ((16.0 * cb - 12.0) * cb + 4.0) * cb, cb <= 0.25);
132
+ return select(cb + (2.0 * cs - 1.0) * (d - cb), cb - (1.0 - 2.0 * cs) * cb * (1.0 - cb), cs <= 0.5);
133
+ }
134
+ if (mode == 3) { return abs(cb - cs); }
135
+ if (mode == 4) { return cb + cs - 2.0 * cb * cs; }
136
+ if (mode == 5) {
137
+ if (cb <= 0.0) { return 0.0; }
138
+ return select(min(1.0, cb / (1.0 - cs)), 1.0, cs >= 1.0);
139
+ }
140
+ if (mode == 6) {
141
+ if (cb >= 1.0) { return 1.0; }
142
+ return select(1.0 - min(1.0, (1.0 - cb) / cs), 0.0, cs <= 0.0);
143
+ }
144
+ return cs;
145
+ }
146
+
147
+ fn blendRgb(mode : i32, cb : vec3f, cs : vec3f) -> vec3f {
148
+ if (mode == 7) { return setLum(setSat(cs, sat(cb)), lum(cb)); }
149
+ if (mode == 8) { return setLum(setSat(cb, sat(cs)), lum(cb)); }
150
+ if (mode == 9) { return setLum(cs, lum(cb)); }
151
+ if (mode == 10) { return setLum(cb, lum(cs)); }
152
+ return vec3f(
153
+ sepChannel(mode, cb.r, cs.r),
154
+ sepChannel(mode, cb.g, cs.g),
155
+ sepChannel(mode, cb.b, cs.b),
156
+ );
157
+ }
158
+
159
+ @fragment
160
+ fn fs_main(@location(0) uv : vec2f) -> @location(0) vec4f {
161
+ let layer = textureSampleLevel(layerTexture, layerSampler, uv, 0.0);
162
+ if (uni.hasBackdrop == 0) {
163
+ return layer;
164
+ }
165
+ let back = textureSampleLevel(backdropTexture, backdropSampler, uv, 0.0);
166
+ let cs = select(vec3f(0.0), layer.rgb / layer.a, layer.a > 0.0);
167
+ let cb = select(vec3f(0.0), back.rgb / back.a, back.a > 0.0);
168
+ let sourceAlpha = layer.a * uni.opacity;
169
+ let backdropAlpha = back.a;
170
+ let blended = blendRgb(uni.mode, cb, cs);
171
+ let mixed = (1.0 - backdropAlpha) * cs + backdropAlpha * blended;
172
+ let outAlpha = sourceAlpha + backdropAlpha * (1.0 - sourceAlpha);
173
+ let outRgb = mixed * sourceAlpha + cb * backdropAlpha * (1.0 - sourceAlpha);
174
+ return vec4f(outRgb, outAlpha);
175
+ }
176
+ `;
177
+ //# sourceMappingURL=wgpuBlendEffect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuBlendEffect.js","sourceRoot":"","sources":["../src/wgpuBlendEffect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { CompositeEffect, CompositeOperator, WgpuRenderEffectRunner, WgpuRenderState, WgpuRenderTarget } from '@flighthq/types';
2
+ export declare function applyCompositeEffectToWgpu(state: WgpuRenderState, source: Readonly<WgpuRenderTarget>, dest: Readonly<WgpuRenderTarget>, effect: Readonly<CompositeEffect>): void;
3
+ export declare const defaultWgpuCompositeEffectRunner: WgpuRenderEffectRunner;
4
+ export declare function getWgpuCompositeEffectOperatorIndex(operator: CompositeOperator): number;
5
+ export declare const WGPU_COMPOSITE_FRAGMENT_WGSL = "\nstruct Uniforms {\n operatorIndex : i32,\n hasBackdrop : i32,\n _pad0 : vec2f,\n}\n@group(0) @binding(0) var<uniform> uni : Uniforms;\n@group(1) @binding(0) var layerTexture : texture_2d<f32>;\n@group(1) @binding(1) var layerSampler : sampler;\n@group(2) @binding(0) var backdropTexture : texture_2d<f32>;\n@group(2) @binding(1) var backdropSampler : sampler;\n\n@fragment\nfn fs_main(@location(0) uv : vec2f) -> @location(0) vec4f {\n let layer = textureSampleLevel(layerTexture, layerSampler, uv, 0.0);\n let back = select(vec4f(0.0), textureSampleLevel(backdropTexture, backdropSampler, uv, 0.0),\n uni.hasBackdrop == 1);\n let sourceAlpha = layer.a;\n let backdropAlpha = back.a;\n var sourceFactor = 1.0;\n var backdropFactor = 1.0 - sourceAlpha;\n if (uni.operatorIndex == 1) {\n sourceFactor = 1.0 - backdropAlpha; backdropFactor = 1.0;\n } else if (uni.operatorIndex == 2) {\n sourceFactor = backdropAlpha; backdropFactor = 0.0;\n } else if (uni.operatorIndex == 3) {\n sourceFactor = 0.0; backdropFactor = sourceAlpha;\n } else if (uni.operatorIndex == 4) {\n sourceFactor = 1.0 - backdropAlpha; backdropFactor = 0.0;\n } else if (uni.operatorIndex == 5) {\n sourceFactor = 0.0; backdropFactor = 1.0 - sourceAlpha;\n } else if (uni.operatorIndex == 6) {\n sourceFactor = backdropAlpha; backdropFactor = 1.0 - sourceAlpha;\n } else if (uni.operatorIndex == 7) {\n sourceFactor = 1.0 - backdropAlpha; backdropFactor = sourceAlpha;\n } else if (uni.operatorIndex == 8) {\n sourceFactor = 1.0 - backdropAlpha; backdropFactor = 1.0 - sourceAlpha;\n } else if (uni.operatorIndex == 9) {\n sourceFactor = 1.0; backdropFactor = 0.0;\n } else if (uni.operatorIndex == 10) {\n sourceFactor = 0.0; backdropFactor = 0.0;\n }\n return sourceFactor * layer + backdropFactor * back;\n}\n";
6
+ //# sourceMappingURL=wgpuCompositeEffect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuCompositeEffect.d.ts","sourceRoot":"","sources":["../src/wgpuCompositeEffect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EAEjB,sBAAsB,EACtB,eAAe,EACf,gBAAgB,EACjB,MAAM,iBAAiB,CAAC;AAQzB,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAClC,IAAI,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAChC,MAAM,EAAE,QAAQ,CAAC,eAAe,CAAC,GAChC,IAAI,CAcN;AAED,eAAO,MAAM,gCAAgC,EAAE,sBAE9C,CAAC;AAEF,wBAAgB,mCAAmC,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM,CAEvF;AA2BD,eAAO,MAAM,4BAA4B,k0DA4CxC,CAAC"}
@@ -0,0 +1,87 @@
1
+ import { CompositeOperator as CompositeOperatorValues } from '@flighthq/types';
2
+ import { getWgpuBlendEffectBackdrop } from './wgpuBlendEffect';
3
+ import { createWgpuDualSourceEffectPipeline, drawWgpuDualSourceEffectPass } from './wgpuEffectPass';
4
+ // Porter-Duff coverage composite over the same named backdrop registry as BlendEffect. Both inputs are
5
+ // premultiplied, so one Fa/Fb pair applies to RGB and alpha exactly as compositeOperatorMath specifies.
6
+ export function applyCompositeEffectToWgpu(state, source, dest, effect) {
7
+ const backdrop = getWgpuBlendEffectBackdrop(state, effect.backdropKey ?? null);
8
+ const hasBackdrop = backdrop !== null;
9
+ drawWgpuDualSourceEffectPass(state, source, (backdrop ?? source), dest, getWgpuCompositeEffectPipeline(state), (_f32, i32) => {
10
+ i32[0] = getWgpuCompositeEffectOperatorIndex(effect.operator);
11
+ i32[1] = hasBackdrop ? 1 : 0;
12
+ });
13
+ }
14
+ export const defaultWgpuCompositeEffectRunner = (context, effect) => {
15
+ applyCompositeEffectToWgpu(context.state, context.source, context.dest, effect);
16
+ };
17
+ export function getWgpuCompositeEffectOperatorIndex(operator) {
18
+ return COMPOSITE_OPERATOR_INDEX[operator] ?? 0;
19
+ }
20
+ function getWgpuCompositeEffectPipeline(state) {
21
+ let pipeline = pipelines.get(state);
22
+ if (pipeline === undefined) {
23
+ pipeline = createWgpuDualSourceEffectPipeline(state, WGPU_COMPOSITE_FRAGMENT_WGSL, 'replace');
24
+ pipelines.set(state, pipeline);
25
+ }
26
+ return pipeline;
27
+ }
28
+ const COMPOSITE_OPERATOR_INDEX = {
29
+ [CompositeOperatorValues.SourceOver]: 0,
30
+ [CompositeOperatorValues.DestinationOver]: 1,
31
+ [CompositeOperatorValues.SourceIn]: 2,
32
+ [CompositeOperatorValues.DestinationIn]: 3,
33
+ [CompositeOperatorValues.SourceOut]: 4,
34
+ [CompositeOperatorValues.DestinationOut]: 5,
35
+ [CompositeOperatorValues.SourceAtop]: 6,
36
+ [CompositeOperatorValues.DestinationAtop]: 7,
37
+ [CompositeOperatorValues.Xor]: 8,
38
+ [CompositeOperatorValues.Copy]: 9,
39
+ [CompositeOperatorValues.Clear]: 10,
40
+ };
41
+ const pipelines = new WeakMap();
42
+ export const WGPU_COMPOSITE_FRAGMENT_WGSL = /* wgsl */ `
43
+ struct Uniforms {
44
+ operatorIndex : i32,
45
+ hasBackdrop : i32,
46
+ _pad0 : vec2f,
47
+ }
48
+ @group(0) @binding(0) var<uniform> uni : Uniforms;
49
+ @group(1) @binding(0) var layerTexture : texture_2d<f32>;
50
+ @group(1) @binding(1) var layerSampler : sampler;
51
+ @group(2) @binding(0) var backdropTexture : texture_2d<f32>;
52
+ @group(2) @binding(1) var backdropSampler : sampler;
53
+
54
+ @fragment
55
+ fn fs_main(@location(0) uv : vec2f) -> @location(0) vec4f {
56
+ let layer = textureSampleLevel(layerTexture, layerSampler, uv, 0.0);
57
+ let back = select(vec4f(0.0), textureSampleLevel(backdropTexture, backdropSampler, uv, 0.0),
58
+ uni.hasBackdrop == 1);
59
+ let sourceAlpha = layer.a;
60
+ let backdropAlpha = back.a;
61
+ var sourceFactor = 1.0;
62
+ var backdropFactor = 1.0 - sourceAlpha;
63
+ if (uni.operatorIndex == 1) {
64
+ sourceFactor = 1.0 - backdropAlpha; backdropFactor = 1.0;
65
+ } else if (uni.operatorIndex == 2) {
66
+ sourceFactor = backdropAlpha; backdropFactor = 0.0;
67
+ } else if (uni.operatorIndex == 3) {
68
+ sourceFactor = 0.0; backdropFactor = sourceAlpha;
69
+ } else if (uni.operatorIndex == 4) {
70
+ sourceFactor = 1.0 - backdropAlpha; backdropFactor = 0.0;
71
+ } else if (uni.operatorIndex == 5) {
72
+ sourceFactor = 0.0; backdropFactor = 1.0 - sourceAlpha;
73
+ } else if (uni.operatorIndex == 6) {
74
+ sourceFactor = backdropAlpha; backdropFactor = 1.0 - sourceAlpha;
75
+ } else if (uni.operatorIndex == 7) {
76
+ sourceFactor = 1.0 - backdropAlpha; backdropFactor = sourceAlpha;
77
+ } else if (uni.operatorIndex == 8) {
78
+ sourceFactor = 1.0 - backdropAlpha; backdropFactor = 1.0 - sourceAlpha;
79
+ } else if (uni.operatorIndex == 9) {
80
+ sourceFactor = 1.0; backdropFactor = 0.0;
81
+ } else if (uni.operatorIndex == 10) {
82
+ sourceFactor = 0.0; backdropFactor = 0.0;
83
+ }
84
+ return sourceFactor * layer + backdropFactor * back;
85
+ }
86
+ `;
87
+ //# sourceMappingURL=wgpuCompositeEffect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuCompositeEffect.js","sourceRoot":"","sources":["../src/wgpuCompositeEffect.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,iBAAiB,IAAI,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAE/E,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,kCAAkC,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC;AAEpG,uGAAuG;AACvG,wGAAwG;AACxG,MAAM,UAAU,0BAA0B,CACxC,KAAsB,EACtB,MAAkC,EAClC,IAAgC,EAChC,MAAiC;IAEjC,MAAM,QAAQ,GAAG,0BAA0B,CAAC,KAAK,EAAE,MAAM,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC;IAC/E,MAAM,WAAW,GAAG,QAAQ,KAAK,IAAI,CAAC;IACtC,4BAA4B,CAC1B,KAAK,EACL,MAA0B,EAC1B,CAAC,QAAQ,IAAI,MAAM,CAAqB,EACxC,IAAwB,EACxB,8BAA8B,CAAC,KAAK,CAAC,EACrC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QACZ,GAAG,CAAC,CAAC,CAAC,GAAG,mCAAmC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC9D,GAAG,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC,CACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,gCAAgC,GAA2B,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;IAC1F,0BAA0B,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,EAAE,MAAyB,CAAC,CAAC;AACrG,CAAC,CAAC;AAEF,MAAM,UAAU,mCAAmC,CAAC,QAA2B;IAC7E,OAAO,wBAAwB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,8BAA8B,CAAC,KAAsB;IAC5D,IAAI,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,QAAQ,GAAG,kCAAkC,CAAC,KAAK,EAAE,4BAA4B,EAAE,SAAS,CAAC,CAAC;QAC9F,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,wBAAwB,GAAqC;IACjE,CAAC,uBAAuB,CAAC,UAAU,CAAC,EAAE,CAAC;IACvC,CAAC,uBAAuB,CAAC,eAAe,CAAC,EAAE,CAAC;IAC5C,CAAC,uBAAuB,CAAC,QAAQ,CAAC,EAAE,CAAC;IACrC,CAAC,uBAAuB,CAAC,aAAa,CAAC,EAAE,CAAC;IAC1C,CAAC,uBAAuB,CAAC,SAAS,CAAC,EAAE,CAAC;IACtC,CAAC,uBAAuB,CAAC,cAAc,CAAC,EAAE,CAAC;IAC3C,CAAC,uBAAuB,CAAC,UAAU,CAAC,EAAE,CAAC;IACvC,CAAC,uBAAuB,CAAC,eAAe,CAAC,EAAE,CAAC;IAC5C,CAAC,uBAAuB,CAAC,GAAG,CAAC,EAAE,CAAC;IAChC,CAAC,uBAAuB,CAAC,IAAI,CAAC,EAAE,CAAC;IACjC,CAAC,uBAAuB,CAAC,KAAK,CAAC,EAAE,EAAE;CACpC,CAAC;AAEF,MAAM,SAAS,GAAG,IAAI,OAAO,EAAiD,CAAC;AAE/E,MAAM,CAAC,MAAM,4BAA4B,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4CtD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"wgpuRenderEffectRegistrants.d.ts","sourceRoot":"","sources":["../src/wgpuRenderEffectRegistrants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAsDvD,wBAAgB,qCAAqC,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAIlF;AAID,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAQ3E;AAID,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAQ1E;AAOD,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAG3E;AASD,wBAAgB,kCAAkC,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAQ/E;AAID,wBAAgB,oCAAoC,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAMjF;AAED,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAQ9E;AAMD,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAc7E"}
1
+ {"version":3,"file":"wgpuRenderEffectRegistrants.d.ts","sourceRoot":"","sources":["../src/wgpuRenderEffectRegistrants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAwDvD,wBAAgB,qCAAqC,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAIlF;AAID,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAQ3E;AAID,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAQ1E;AAOD,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAG3E;AASD,wBAAgB,kCAAkC,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAU/E;AAID,wBAAgB,oCAAoC,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAMjF;AAED,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAQ9E;AAMD,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAc7E"}
@@ -1,9 +1,11 @@
1
1
  import { defaultWgpuBevelEffectRunner } from './wgpuBevelEffect';
2
+ import { defaultWgpuBlendEffectRunner } from './wgpuBlendEffect';
2
3
  import { defaultWgpuBloomEffectRunner } from './wgpuBloomEffect';
3
4
  import { defaultWgpuBlurEffectRunner } from './wgpuBlurEffect';
4
5
  import { defaultWgpuBokehDepthOfFieldEffectRunner } from './wgpuBokehDepthOfFieldEffect';
5
6
  import { defaultWgpuCameraMotionBlurEffectRunner } from './wgpuCameraMotionBlurEffect';
6
7
  import { defaultWgpuChromaticAberrationEffectRunner } from './wgpuChromaticAberrationEffect';
8
+ import { defaultWgpuCompositeEffectRunner } from './wgpuCompositeEffect';
7
9
  import { defaultWgpuConvolutionEffectRunner } from './wgpuConvolutionEffect';
8
10
  import { defaultWgpuCrtEffectRunner } from './wgpuCrtEffect';
9
11
  import { defaultWgpuDirectionalBlurEffectRunner } from './wgpuDirectionalBlurEffect';
@@ -84,15 +86,17 @@ export function registerColorWgpuRenderEffects(state) {
84
86
  registerWgpuRenderEffect(state, 'ToneMapEffect', defaultWgpuToneMapEffectRunner);
85
87
  registerWgpuRenderEffect(state, 'WhiteBalanceEffect', defaultWgpuWhiteBalanceEffectRunner);
86
88
  }
87
- // Full standard set — composes all taxonomy bands. Registers all 43 default runners under their
89
+ // Full standard set — composes all taxonomy bands. Registers all 46 default runners under their
88
90
  // canonical kind keys. Import this when the full effect palette is needed; import individual band
89
91
  // helpers when only a subset of effects is used.
90
- // Composite band: BevelEffect, DropShadowEffect, GradientBevelEffect, GradientGlowEffect,
91
- // InnerGlowEffect, InnerShadowEffect, OuterGlowEffect. The former filter-layer composite ops,
92
- // now full-frame composite effects chaining tint/blur/offset passes through pooled offscreen targets.
93
- // Symmetric with Gl's registerCompositeGlRenderEffects.
92
+ // Composite band: BevelEffect, BlendEffect, CompositeEffect, DropShadowEffect, GradientBevelEffect,
93
+ // GradientGlowEffect, InnerGlowEffect, InnerShadowEffect, OuterGlowEffect. The former filter-layer
94
+ // composite ops, now full-frame composite effects chaining tint/blur/offset passes through pooled
95
+ // offscreen targets. Symmetric with Gl's registerCompositeGlRenderEffects.
94
96
  export function registerCompositeWgpuRenderEffects(state) {
95
97
  registerWgpuRenderEffect(state, 'BevelEffect', defaultWgpuBevelEffectRunner);
98
+ registerWgpuRenderEffect(state, 'BlendEffect', defaultWgpuBlendEffectRunner);
99
+ registerWgpuRenderEffect(state, 'CompositeEffect', defaultWgpuCompositeEffectRunner);
96
100
  registerWgpuRenderEffect(state, 'DropShadowEffect', defaultWgpuDropShadowEffectRunner);
97
101
  registerWgpuRenderEffect(state, 'GradientBevelEffect', defaultWgpuGradientBevelEffectRunner);
98
102
  registerWgpuRenderEffect(state, 'GradientGlowEffect', defaultWgpuGradientGlowEffectRunner);
@@ -1 +1 @@
1
- {"version":3,"file":"wgpuRenderEffectRegistrants.js","sourceRoot":"","sources":["../src/wgpuRenderEffectRegistrants.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wgpuRenderEffectRegistrants.js","sourceRoot":"","sources":["../src/wgpuRenderEffectRegistrants.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flighthq/effects-wgpu",
3
- "version": "0.2.1-next.652.c550eaa",
3
+ "version": "0.2.1-next.701.409c279",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/flighthq/flight.git",
@@ -32,11 +32,11 @@
32
32
  "clean:dist": "tsx ../../scripts/clean-package-dist.ts"
33
33
  },
34
34
  "dependencies": {
35
- "@flighthq/adjustments": "0.2.1-next.652.c550eaa",
36
- "@flighthq/effects": "0.2.1-next.652.c550eaa",
37
- "@flighthq/geometry": "0.2.1-next.652.c550eaa",
38
- "@flighthq/render-wgpu": "0.2.1-next.652.c550eaa",
39
- "@flighthq/types": "0.2.1-next.652.c550eaa"
35
+ "@flighthq/adjustments": "0.2.1-next.701.409c279",
36
+ "@flighthq/effects": "0.2.1-next.701.409c279",
37
+ "@flighthq/geometry": "0.2.1-next.701.409c279",
38
+ "@flighthq/render-wgpu": "0.2.1-next.701.409c279",
39
+ "@flighthq/types": "0.2.1-next.701.409c279"
40
40
  },
41
41
  "devDependencies": {
42
42
  "typescript": "^5.3.0"
@@ -0,0 +1,114 @@
1
+ import type { WgpuRenderState, WgpuRenderTarget } from '@flighthq/types';
2
+ import { AdvancedBlendMode } from '@flighthq/types';
3
+
4
+ import {
5
+ applyBlendEffectToWgpu,
6
+ defaultWgpuBlendEffectRunner,
7
+ getWgpuBlendEffectBackdrop,
8
+ getWgpuBlendEffectModeIndex,
9
+ registerWgpuBlendEffectBackdrop,
10
+ unregisterWgpuBlendEffectBackdrop,
11
+ WGPU_BLEND_FRAGMENT_WGSL,
12
+ } from './wgpuBlendEffect';
13
+
14
+ function makeState(): WgpuRenderState {
15
+ return {} as WgpuRenderState;
16
+ }
17
+
18
+ function makeTarget(): WgpuRenderTarget {
19
+ return {} as WgpuRenderTarget;
20
+ }
21
+
22
+ describe('applyBlendEffectToWgpu', () => {
23
+ it('is a function', () => {
24
+ expect(typeof applyBlendEffectToWgpu).toBe('function');
25
+ });
26
+ });
27
+
28
+ describe('defaultWgpuBlendEffectRunner', () => {
29
+ it('is a function', () => {
30
+ expect(typeof defaultWgpuBlendEffectRunner).toBe('function');
31
+ });
32
+ });
33
+
34
+ describe('getWgpuBlendEffectBackdrop', () => {
35
+ it('returns null for null and missing keys', () => {
36
+ const state = makeState();
37
+ expect(getWgpuBlendEffectBackdrop(state, null)).toBeNull();
38
+ expect(getWgpuBlendEffectBackdrop(state, 'missing')).toBeNull();
39
+ });
40
+
41
+ it('isolates registered targets per state', () => {
42
+ const first = makeState();
43
+ const second = makeState();
44
+ const target = makeTarget();
45
+ registerWgpuBlendEffectBackdrop(first, 'scene', target);
46
+ expect(getWgpuBlendEffectBackdrop(first, 'scene')).toBe(target);
47
+ expect(getWgpuBlendEffectBackdrop(second, 'scene')).toBeNull();
48
+ });
49
+ });
50
+
51
+ describe('getWgpuBlendEffectModeIndex', () => {
52
+ it('assigns the seven separable modes indices 0 through 6', () => {
53
+ expect(getWgpuBlendEffectModeIndex(AdvancedBlendMode.Overlay)).toBe(0);
54
+ expect(getWgpuBlendEffectModeIndex(AdvancedBlendMode.HardLight)).toBe(1);
55
+ expect(getWgpuBlendEffectModeIndex(AdvancedBlendMode.SoftLight)).toBe(2);
56
+ expect(getWgpuBlendEffectModeIndex(AdvancedBlendMode.Difference)).toBe(3);
57
+ expect(getWgpuBlendEffectModeIndex(AdvancedBlendMode.Exclusion)).toBe(4);
58
+ expect(getWgpuBlendEffectModeIndex(AdvancedBlendMode.ColorDodge)).toBe(5);
59
+ expect(getWgpuBlendEffectModeIndex(AdvancedBlendMode.ColorBurn)).toBe(6);
60
+ });
61
+
62
+ it('assigns the HSL modes indices 7 through 10', () => {
63
+ expect(getWgpuBlendEffectModeIndex(AdvancedBlendMode.Hue)).toBe(7);
64
+ expect(getWgpuBlendEffectModeIndex(AdvancedBlendMode.Saturation)).toBe(8);
65
+ expect(getWgpuBlendEffectModeIndex(AdvancedBlendMode.Color)).toBe(9);
66
+ expect(getWgpuBlendEffectModeIndex(AdvancedBlendMode.Luminosity)).toBe(10);
67
+ });
68
+
69
+ it('maps every canonical mode uniquely and unknown values to passthrough', () => {
70
+ const indices = Object.values(AdvancedBlendMode).map(getWgpuBlendEffectModeIndex);
71
+ expect(new Set(indices).size).toBe(indices.length);
72
+ expect(indices).not.toContain(-1);
73
+ expect(getWgpuBlendEffectModeIndex('acme.Unknown')).toBe(-1);
74
+ });
75
+ });
76
+
77
+ describe('registerWgpuBlendEffectBackdrop', () => {
78
+ it('is last-write-wins', () => {
79
+ const state = makeState();
80
+ const first = makeTarget();
81
+ const second = makeTarget();
82
+ registerWgpuBlendEffectBackdrop(state, 'scene', first);
83
+ registerWgpuBlendEffectBackdrop(state, 'scene', second);
84
+ expect(getWgpuBlendEffectBackdrop(state, 'scene')).toBe(second);
85
+ });
86
+ });
87
+
88
+ describe('unregisterWgpuBlendEffectBackdrop', () => {
89
+ it('removes present targets and reports absent keys', () => {
90
+ const state = makeState();
91
+ registerWgpuBlendEffectBackdrop(state, 'scene', makeTarget());
92
+ expect(unregisterWgpuBlendEffectBackdrop(state, 'scene')).toBe(true);
93
+ expect(unregisterWgpuBlendEffectBackdrop(state, 'scene')).toBe(false);
94
+ expect(getWgpuBlendEffectBackdrop(state, 'scene')).toBeNull();
95
+ });
96
+ });
97
+
98
+ describe('WGPU_BLEND_FRAGMENT_WGSL', () => {
99
+ it('binds both layer and backdrop textures and emits the separable and HSL blend helpers', () => {
100
+ expect(WGPU_BLEND_FRAGMENT_WGSL).toContain('@group(1) @binding(0) var layerTexture');
101
+ expect(WGPU_BLEND_FRAGMENT_WGSL).toContain('@group(2) @binding(0) var backdropTexture');
102
+ expect(WGPU_BLEND_FRAGMENT_WGSL).toContain('fn sepChannel');
103
+ expect(WGPU_BLEND_FRAGMENT_WGSL).toContain('fn setLum');
104
+ expect(WGPU_BLEND_FRAGMENT_WGSL).toContain('fn setSat');
105
+ expect(WGPU_BLEND_FRAGMENT_WGSL).toContain('if (mode == 10)');
106
+ });
107
+
108
+ it('un-premultiplies inputs and writes premultiplied source-over output', () => {
109
+ expect(WGPU_BLEND_FRAGMENT_WGSL).toContain('layer.rgb / layer.a');
110
+ expect(WGPU_BLEND_FRAGMENT_WGSL).toContain('back.rgb / back.a');
111
+ expect(WGPU_BLEND_FRAGMENT_WGSL).toContain('sourceAlpha + backdropAlpha * (1.0 - sourceAlpha)');
112
+ expect(WGPU_BLEND_FRAGMENT_WGSL).toContain('mixed * sourceAlpha + cb * backdropAlpha * (1.0 - sourceAlpha)');
113
+ });
114
+ });
@@ -0,0 +1,40 @@
1
+ import { CompositeOperator } from '@flighthq/types';
2
+
3
+ import {
4
+ applyCompositeEffectToWgpu,
5
+ defaultWgpuCompositeEffectRunner,
6
+ getWgpuCompositeEffectOperatorIndex,
7
+ WGPU_COMPOSITE_FRAGMENT_WGSL,
8
+ } from './wgpuCompositeEffect';
9
+
10
+ describe('applyCompositeEffectToWgpu', () => {
11
+ it('is the public WebGPU composite entry point', () => {
12
+ expect(typeof applyCompositeEffectToWgpu).toBe('function');
13
+ });
14
+ });
15
+
16
+ describe('defaultWgpuCompositeEffectRunner', () => {
17
+ it('is a render-effect runner', () => {
18
+ expect(typeof defaultWgpuCompositeEffectRunner).toBe('function');
19
+ });
20
+ });
21
+
22
+ describe('getWgpuCompositeEffectOperatorIndex', () => {
23
+ it('assigns every canonical operator a unique branch and unknown values SourceOver', () => {
24
+ const indices = Object.values(CompositeOperator).map(getWgpuCompositeEffectOperatorIndex);
25
+ expect(new Set(indices).size).toBe(indices.length);
26
+ expect(getWgpuCompositeEffectOperatorIndex(CompositeOperator.SourceOver)).toBe(0);
27
+ expect(getWgpuCompositeEffectOperatorIndex(CompositeOperator.DestinationOut)).toBe(5);
28
+ expect(getWgpuCompositeEffectOperatorIndex(CompositeOperator.Clear)).toBe(10);
29
+ expect(getWgpuCompositeEffectOperatorIndex('acme.Custom')).toBe(0);
30
+ });
31
+ });
32
+
33
+ describe('WGPU_COMPOSITE_FRAGMENT_WGSL', () => {
34
+ it('binds both premultiplied inputs and implements all Porter-Duff branches', () => {
35
+ expect(WGPU_COMPOSITE_FRAGMENT_WGSL).toContain('@group(1) @binding(0) var layerTexture');
36
+ expect(WGPU_COMPOSITE_FRAGMENT_WGSL).toContain('@group(2) @binding(0) var backdropTexture');
37
+ expect(WGPU_COMPOSITE_FRAGMENT_WGSL).toContain('uni.operatorIndex == 10');
38
+ expect(WGPU_COMPOSITE_FRAGMENT_WGSL).toContain('sourceFactor * layer + backdropFactor * back');
39
+ });
40
+ });
@@ -67,11 +67,13 @@ describe('registerColorWgpuRenderEffects', () => {
67
67
  });
68
68
 
69
69
  describe('registerCompositeWgpuRenderEffects', () => {
70
- it('registers the seven former-filter composite effect runners', async () => {
70
+ it('registers all composite effect runners', async () => {
71
71
  const state = await createWgpuRenderStateForTest();
72
72
  registerCompositeWgpuRenderEffects(state);
73
73
  for (const kind of [
74
74
  'BevelEffect',
75
+ 'BlendEffect',
76
+ 'CompositeEffect',
75
77
  'DropShadowEffect',
76
78
  'GradientBevelEffect',
77
79
  'GradientGlowEffect',
@@ -97,13 +99,14 @@ describe('registerScreenSpaceWgpuRenderEffects', () => {
97
99
  });
98
100
 
99
101
  describe('registerStandardWgpuRenderEffects', () => {
100
- it('registers all 43 standard effect runners', async () => {
102
+ it('registers all 46 standard effect runners', async () => {
101
103
  const state = await createWgpuRenderStateForTest();
102
104
  registerStandardWgpuRenderEffects(state);
103
105
  // Spot-check one from each band.
104
106
  expect(getWgpuRenderEffectRunner(state, 'FxaaEffect')).not.toBe(null);
105
107
  expect(getWgpuRenderEffectRunner(state, 'BloomEffect')).not.toBe(null);
106
108
  expect(getWgpuRenderEffectRunner(state, 'DirectionalBlurEffect')).not.toBe(null);
109
+ expect(getWgpuRenderEffectRunner(state, 'BlendEffect')).not.toBe(null);
107
110
  expect(getWgpuRenderEffectRunner(state, 'SsaoEffect')).not.toBe(null);
108
111
  expect(getWgpuRenderEffectRunner(state, 'HalftoneEffect')).not.toBe(null);
109
112
  });