@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 +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/wgpuBlendEffect.d.ts +9 -0
- package/dist/wgpuBlendEffect.d.ts.map +1 -0
- package/dist/wgpuBlendEffect.js +177 -0
- package/dist/wgpuBlendEffect.js.map +1 -0
- package/dist/wgpuCompositeEffect.d.ts +6 -0
- package/dist/wgpuCompositeEffect.d.ts.map +1 -0
- package/dist/wgpuCompositeEffect.js +87 -0
- package/dist/wgpuCompositeEffect.js.map +1 -0
- package/dist/wgpuRenderEffectRegistrants.d.ts.map +1 -1
- package/dist/wgpuRenderEffectRegistrants.js +9 -5
- package/dist/wgpuRenderEffectRegistrants.js.map +1 -1
- package/package.json +6 -6
- package/src/wgpuBlendEffect.test.ts +114 -0
- package/src/wgpuCompositeEffect.test.ts +40 -0
- package/src/wgpuRenderEffectRegistrants.test.ts +5 -2
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -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
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;
|
|
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
|
|
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,
|
|
91
|
-
// InnerGlowEffect, InnerShadowEffect, OuterGlowEffect. The former filter-layer
|
|
92
|
-
// now full-frame composite effects chaining tint/blur/offset passes through pooled
|
|
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.
|
|
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.
|
|
36
|
-
"@flighthq/effects": "0.2.1-next.
|
|
37
|
-
"@flighthq/geometry": "0.2.1-next.
|
|
38
|
-
"@flighthq/render-wgpu": "0.2.1-next.
|
|
39
|
-
"@flighthq/types": "0.2.1-next.
|
|
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
|
|
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
|
|
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
|
});
|