@flighthq/effects-wgpu 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +49 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +49 -0
- package/dist/index.js.map +1 -0
- package/dist/wgpuBloomEffect.d.ts +4 -0
- package/dist/wgpuBloomEffect.d.ts.map +1 -0
- package/dist/wgpuBloomEffect.js +72 -0
- package/dist/wgpuBloomEffect.js.map +1 -0
- package/dist/wgpuBokehDepthOfFieldEffect.d.ts +4 -0
- package/dist/wgpuBokehDepthOfFieldEffect.d.ts.map +1 -0
- package/dist/wgpuBokehDepthOfFieldEffect.js +51 -0
- package/dist/wgpuBokehDepthOfFieldEffect.js.map +1 -0
- package/dist/wgpuBrightnessContrastEffect.d.ts +4 -0
- package/dist/wgpuBrightnessContrastEffect.d.ts.map +1 -0
- package/dist/wgpuBrightnessContrastEffect.js +29 -0
- package/dist/wgpuBrightnessContrastEffect.js.map +1 -0
- package/dist/wgpuCameraMotionBlurEffect.d.ts +4 -0
- package/dist/wgpuCameraMotionBlurEffect.d.ts.map +1 -0
- package/dist/wgpuCameraMotionBlurEffect.js +49 -0
- package/dist/wgpuCameraMotionBlurEffect.js.map +1 -0
- package/dist/wgpuChannelMixerEffect.d.ts +4 -0
- package/dist/wgpuChannelMixerEffect.d.ts.map +1 -0
- package/dist/wgpuChannelMixerEffect.js +34 -0
- package/dist/wgpuChannelMixerEffect.js.map +1 -0
- package/dist/wgpuChromaticAberrationEffect.d.ts +4 -0
- package/dist/wgpuChromaticAberrationEffect.d.ts.map +1 -0
- package/dist/wgpuChromaticAberrationEffect.js +40 -0
- package/dist/wgpuChromaticAberrationEffect.js.map +1 -0
- package/dist/wgpuColorGradeEffect.d.ts +4 -0
- package/dist/wgpuColorGradeEffect.d.ts.map +1 -0
- package/dist/wgpuColorGradeEffect.js +52 -0
- package/dist/wgpuColorGradeEffect.js.map +1 -0
- package/dist/wgpuCrtEffect.d.ts +4 -0
- package/dist/wgpuCrtEffect.d.ts.map +1 -0
- package/dist/wgpuCrtEffect.js +60 -0
- package/dist/wgpuCrtEffect.js.map +1 -0
- package/dist/wgpuDirectionalBlurEffect.d.ts +4 -0
- package/dist/wgpuDirectionalBlurEffect.d.ts.map +1 -0
- package/dist/wgpuDirectionalBlurEffect.js +52 -0
- package/dist/wgpuDirectionalBlurEffect.js.map +1 -0
- package/dist/wgpuDisplacementEffect.d.ts +4 -0
- package/dist/wgpuDisplacementEffect.d.ts.map +1 -0
- package/dist/wgpuDisplacementEffect.js +44 -0
- package/dist/wgpuDisplacementEffect.js.map +1 -0
- package/dist/wgpuDitherEffect.d.ts +4 -0
- package/dist/wgpuDitherEffect.d.ts.map +1 -0
- package/dist/wgpuDitherEffect.js +45 -0
- package/dist/wgpuDitherEffect.js.map +1 -0
- package/dist/wgpuEffectProgramCache.d.ts +4 -0
- package/dist/wgpuEffectProgramCache.d.ts.map +1 -0
- package/dist/wgpuEffectProgramCache.js +26 -0
- package/dist/wgpuEffectProgramCache.js.map +1 -0
- package/dist/wgpuExposureEffect.d.ts +4 -0
- package/dist/wgpuExposureEffect.d.ts.map +1 -0
- package/dist/wgpuExposureEffect.js +28 -0
- package/dist/wgpuExposureEffect.js.map +1 -0
- package/dist/wgpuFilmGrainEffect.d.ts +4 -0
- package/dist/wgpuFilmGrainEffect.d.ts.map +1 -0
- package/dist/wgpuFilmGrainEffect.js +41 -0
- package/dist/wgpuFilmGrainEffect.js.map +1 -0
- package/dist/wgpuFxaaEffect.d.ts +4 -0
- package/dist/wgpuFxaaEffect.d.ts.map +1 -0
- package/dist/wgpuFxaaEffect.js +65 -0
- package/dist/wgpuFxaaEffect.js.map +1 -0
- package/dist/wgpuGlitchEffect.d.ts +4 -0
- package/dist/wgpuGlitchEffect.d.ts.map +1 -0
- package/dist/wgpuGlitchEffect.js +60 -0
- package/dist/wgpuGlitchEffect.js.map +1 -0
- package/dist/wgpuGodRaysEffect.d.ts +4 -0
- package/dist/wgpuGodRaysEffect.d.ts.map +1 -0
- package/dist/wgpuGodRaysEffect.js +67 -0
- package/dist/wgpuGodRaysEffect.js.map +1 -0
- package/dist/wgpuGrayscaleEffect.d.ts +4 -0
- package/dist/wgpuGrayscaleEffect.d.ts.map +1 -0
- package/dist/wgpuGrayscaleEffect.js +27 -0
- package/dist/wgpuGrayscaleEffect.js.map +1 -0
- package/dist/wgpuHalftoneEffect.d.ts +4 -0
- package/dist/wgpuHalftoneEffect.d.ts.map +1 -0
- package/dist/wgpuHalftoneEffect.js +45 -0
- package/dist/wgpuHalftoneEffect.js.map +1 -0
- package/dist/wgpuHueSaturationEffect.d.ts +4 -0
- package/dist/wgpuHueSaturationEffect.d.ts.map +1 -0
- package/dist/wgpuHueSaturationEffect.js +75 -0
- package/dist/wgpuHueSaturationEffect.js.map +1 -0
- package/dist/wgpuInvertEffect.d.ts +4 -0
- package/dist/wgpuInvertEffect.d.ts.map +1 -0
- package/dist/wgpuInvertEffect.js +26 -0
- package/dist/wgpuInvertEffect.js.map +1 -0
- package/dist/wgpuKuwaharaEffect.d.ts +4 -0
- package/dist/wgpuKuwaharaEffect.d.ts.map +1 -0
- package/dist/wgpuKuwaharaEffect.js +69 -0
- package/dist/wgpuKuwaharaEffect.js.map +1 -0
- package/dist/wgpuLensDirtEffect.d.ts +4 -0
- package/dist/wgpuLensDirtEffect.d.ts.map +1 -0
- package/dist/wgpuLensDirtEffect.js +51 -0
- package/dist/wgpuLensDirtEffect.js.map +1 -0
- package/dist/wgpuLensDistortionEffect.d.ts +4 -0
- package/dist/wgpuLensDistortionEffect.d.ts.map +1 -0
- package/dist/wgpuLensDistortionEffect.js +36 -0
- package/dist/wgpuLensDistortionEffect.js.map +1 -0
- package/dist/wgpuLensFlareEffect.d.ts +4 -0
- package/dist/wgpuLensFlareEffect.d.ts.map +1 -0
- package/dist/wgpuLensFlareEffect.js +61 -0
- package/dist/wgpuLensFlareEffect.js.map +1 -0
- package/dist/wgpuLiftGammaGainEffect.d.ts +4 -0
- package/dist/wgpuLiftGammaGainEffect.d.ts.map +1 -0
- package/dist/wgpuLiftGammaGainEffect.js +51 -0
- package/dist/wgpuLiftGammaGainEffect.js.map +1 -0
- package/dist/wgpuLookupTableGradeEffect.d.ts +4 -0
- package/dist/wgpuLookupTableGradeEffect.d.ts.map +1 -0
- package/dist/wgpuLookupTableGradeEffect.js +30 -0
- package/dist/wgpuLookupTableGradeEffect.js.map +1 -0
- package/dist/wgpuMotionBlurEffect.d.ts +4 -0
- package/dist/wgpuMotionBlurEffect.d.ts.map +1 -0
- package/dist/wgpuMotionBlurEffect.js +97 -0
- package/dist/wgpuMotionBlurEffect.js.map +1 -0
- package/dist/wgpuOutlineEffect.d.ts +4 -0
- package/dist/wgpuOutlineEffect.d.ts.map +1 -0
- package/dist/wgpuOutlineEffect.js +64 -0
- package/dist/wgpuOutlineEffect.js.map +1 -0
- package/dist/wgpuPixelateEffect.d.ts +4 -0
- package/dist/wgpuPixelateEffect.d.ts.map +1 -0
- package/dist/wgpuPixelateEffect.js +34 -0
- package/dist/wgpuPixelateEffect.js.map +1 -0
- package/dist/wgpuPosterizeEffect.d.ts +4 -0
- package/dist/wgpuPosterizeEffect.d.ts.map +1 -0
- package/dist/wgpuPosterizeEffect.js +27 -0
- package/dist/wgpuPosterizeEffect.js.map +1 -0
- package/dist/wgpuRadialBlurEffect.d.ts +4 -0
- package/dist/wgpuRadialBlurEffect.d.ts.map +1 -0
- package/dist/wgpuRadialBlurEffect.js +50 -0
- package/dist/wgpuRadialBlurEffect.js.map +1 -0
- package/dist/wgpuRenderEffectPipeline.d.ts +7 -0
- package/dist/wgpuRenderEffectPipeline.d.ts.map +1 -0
- package/dist/wgpuRenderEffectPipeline.js +106 -0
- package/dist/wgpuRenderEffectPipeline.js.map +1 -0
- package/dist/wgpuRenderEffectRegistrants.d.ts +9 -0
- package/dist/wgpuRenderEffectRegistrants.d.ts.map +1 -0
- package/dist/wgpuRenderEffectRegistrants.js +129 -0
- package/dist/wgpuRenderEffectRegistrants.js.map +1 -0
- package/dist/wgpuRenderEffectRegistry.d.ts +5 -0
- package/dist/wgpuRenderEffectRegistry.d.ts.map +1 -0
- package/dist/wgpuRenderEffectRegistry.js +25 -0
- package/dist/wgpuRenderEffectRegistry.js.map +1 -0
- package/dist/wgpuScanlinesEffect.d.ts +4 -0
- package/dist/wgpuScanlinesEffect.d.ts.map +1 -0
- package/dist/wgpuScanlinesEffect.js +32 -0
- package/dist/wgpuScanlinesEffect.js.map +1 -0
- package/dist/wgpuScreenSpaceFogEffect.d.ts +4 -0
- package/dist/wgpuScreenSpaceFogEffect.d.ts.map +1 -0
- package/dist/wgpuScreenSpaceFogEffect.js +47 -0
- package/dist/wgpuScreenSpaceFogEffect.js.map +1 -0
- package/dist/wgpuSepiaEffect.d.ts +4 -0
- package/dist/wgpuSepiaEffect.d.ts.map +1 -0
- package/dist/wgpuSepiaEffect.js +31 -0
- package/dist/wgpuSepiaEffect.js.map +1 -0
- package/dist/wgpuSharpenEffect.d.ts +4 -0
- package/dist/wgpuSharpenEffect.d.ts.map +1 -0
- package/dist/wgpuSharpenEffect.js +40 -0
- package/dist/wgpuSharpenEffect.js.map +1 -0
- package/dist/wgpuSketchEffect.d.ts +4 -0
- package/dist/wgpuSketchEffect.d.ts.map +1 -0
- package/dist/wgpuSketchEffect.js +51 -0
- package/dist/wgpuSketchEffect.js.map +1 -0
- package/dist/wgpuSmaaEffect.d.ts +4 -0
- package/dist/wgpuSmaaEffect.d.ts.map +1 -0
- package/dist/wgpuSmaaEffect.js +52 -0
- package/dist/wgpuSmaaEffect.js.map +1 -0
- package/dist/wgpuSsaoEffect.d.ts +4 -0
- package/dist/wgpuSsaoEffect.d.ts.map +1 -0
- package/dist/wgpuSsaoEffect.js +51 -0
- package/dist/wgpuSsaoEffect.js.map +1 -0
- package/dist/wgpuSsrEffect.d.ts +4 -0
- package/dist/wgpuSsrEffect.d.ts.map +1 -0
- package/dist/wgpuSsrEffect.js +28 -0
- package/dist/wgpuSsrEffect.js.map +1 -0
- package/dist/wgpuTaaEffect.d.ts +4 -0
- package/dist/wgpuTaaEffect.d.ts.map +1 -0
- package/dist/wgpuTaaEffect.js +27 -0
- package/dist/wgpuTaaEffect.js.map +1 -0
- package/dist/wgpuTiltShiftEffect.d.ts +4 -0
- package/dist/wgpuTiltShiftEffect.d.ts.map +1 -0
- package/dist/wgpuTiltShiftEffect.js +51 -0
- package/dist/wgpuTiltShiftEffect.js.map +1 -0
- package/dist/wgpuToneMapEffect.d.ts +4 -0
- package/dist/wgpuToneMapEffect.d.ts.map +1 -0
- package/dist/wgpuToneMapEffect.js +57 -0
- package/dist/wgpuToneMapEffect.js.map +1 -0
- package/dist/wgpuVignetteEffect.d.ts +4 -0
- package/dist/wgpuVignetteEffect.d.ts.map +1 -0
- package/dist/wgpuVignetteEffect.js +54 -0
- package/dist/wgpuVignetteEffect.js.map +1 -0
- package/dist/wgpuWhiteBalanceEffect.d.ts +4 -0
- package/dist/wgpuWhiteBalanceEffect.d.ts.map +1 -0
- package/dist/wgpuWhiteBalanceEffect.js +32 -0
- package/dist/wgpuWhiteBalanceEffect.js.map +1 -0
- package/package.json +42 -0
- package/src/wgpuBloomEffect.test.ts +13 -0
- package/src/wgpuBokehDepthOfFieldEffect.test.ts +16 -0
- package/src/wgpuBrightnessContrastEffect.test.ts +16 -0
- package/src/wgpuCameraMotionBlurEffect.test.ts +16 -0
- package/src/wgpuChannelMixerEffect.test.ts +13 -0
- package/src/wgpuChromaticAberrationEffect.test.ts +16 -0
- package/src/wgpuColorGradeEffect.test.ts +13 -0
- package/src/wgpuCrtEffect.test.ts +13 -0
- package/src/wgpuDirectionalBlurEffect.test.ts +13 -0
- package/src/wgpuDisplacementEffect.test.ts +13 -0
- package/src/wgpuDitherEffect.test.ts +13 -0
- package/src/wgpuEffectProgramCache.test.ts +7 -0
- package/src/wgpuExposureEffect.test.ts +13 -0
- package/src/wgpuFilmGrainEffect.test.ts +13 -0
- package/src/wgpuFxaaEffect.test.ts +13 -0
- package/src/wgpuGlitchEffect.test.ts +13 -0
- package/src/wgpuGodRaysEffect.test.ts +13 -0
- package/src/wgpuGrayscaleEffect.test.ts +13 -0
- package/src/wgpuHalftoneEffect.test.ts +13 -0
- package/src/wgpuHueSaturationEffect.test.ts +13 -0
- package/src/wgpuInvertEffect.test.ts +13 -0
- package/src/wgpuKuwaharaEffect.test.ts +13 -0
- package/src/wgpuLensDirtEffect.test.ts +13 -0
- package/src/wgpuLensDistortionEffect.test.ts +13 -0
- package/src/wgpuLensFlareEffect.test.ts +13 -0
- package/src/wgpuLiftGammaGainEffect.test.ts +13 -0
- package/src/wgpuLookupTableGradeEffect.test.ts +16 -0
- package/src/wgpuMotionBlurEffect.test.ts +13 -0
- package/src/wgpuOutlineEffect.test.ts +13 -0
- package/src/wgpuPixelateEffect.test.ts +13 -0
- package/src/wgpuPosterizeEffect.test.ts +13 -0
- package/src/wgpuRadialBlurEffect.test.ts +13 -0
- package/src/wgpuRenderEffectPipeline.test.ts +45 -0
- package/src/wgpuRenderEffectRegistrants.test.ts +122 -0
- package/src/wgpuRenderEffectRegistry.test.ts +40 -0
- package/src/wgpuScanlinesEffect.test.ts +13 -0
- package/src/wgpuScreenSpaceFogEffect.test.ts +13 -0
- package/src/wgpuSepiaEffect.test.ts +13 -0
- package/src/wgpuSharpenEffect.test.ts +13 -0
- package/src/wgpuSketchEffect.test.ts +13 -0
- package/src/wgpuSmaaEffect.test.ts +13 -0
- package/src/wgpuSsaoEffect.test.ts +13 -0
- package/src/wgpuSsrEffect.test.ts +13 -0
- package/src/wgpuTaaEffect.test.ts +13 -0
- package/src/wgpuTiltShiftEffect.test.ts +13 -0
- package/src/wgpuToneMapEffect.test.ts +13 -0
- package/src/wgpuVignetteEffect.test.ts +13 -0
- package/src/wgpuWhiteBalanceEffect.test.ts +13 -0
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { HalftoneEffect, WgpuRenderEffectRunner, WgpuRenderState, WgpuRenderTarget } from '@flighthq/types';
|
|
2
|
+
export declare function applyHalftoneEffectToWgpu(state: WgpuRenderState, source: Readonly<WgpuRenderTarget>, dest: Readonly<WgpuRenderTarget>, effect: Readonly<HalftoneEffect>): void;
|
|
3
|
+
export declare const defaultWgpuHalftoneEffectRunner: WgpuRenderEffectRunner;
|
|
4
|
+
//# sourceMappingURL=wgpuHalftoneEffect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wgpuHalftoneEffect.d.ts","sourceRoot":"","sources":["../src/wgpuHalftoneEffect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,sBAAsB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAMjH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAClC,IAAI,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAChC,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,GAC/B,IAAI,CAWN;AAED,eAAO,MAAM,+BAA+B,EAAE,sBAE7C,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { drawWgpuFilterPass } from '@flighthq/filters-wgpu';
|
|
2
|
+
import { getWgpuEffectPipeline } from './wgpuEffectProgramCache';
|
|
3
|
+
// Halftone: sample luminance, then carve a rotated dot grid whose dot radius tracks darkness — the
|
|
4
|
+
// classic print/comic screen. `scale` sets the cell size, `angle` rotates the grid.
|
|
5
|
+
export function applyHalftoneEffectToWgpu(state, source, dest, effect) {
|
|
6
|
+
const scale = effect.scale ?? 6;
|
|
7
|
+
const angle = effect.angle ?? 0.4;
|
|
8
|
+
const pipeline = getWgpuEffectPipeline(state, 'stylization.halftone', HALFTONE_FRAGMENT_WGSL, 'replace');
|
|
9
|
+
drawWgpuFilterPass(state, source, dest, pipeline, (f32) => {
|
|
10
|
+
f32[0] = Math.max(1, scale);
|
|
11
|
+
f32[1] = angle;
|
|
12
|
+
// u_resolution (vec2f) aligns to slot [2].
|
|
13
|
+
f32[2] = source.width;
|
|
14
|
+
f32[3] = source.height;
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
export const defaultWgpuHalftoneEffectRunner = (ctx, effect) => {
|
|
18
|
+
applyHalftoneEffectToWgpu(ctx.state, ctx.source, ctx.dest, effect);
|
|
19
|
+
};
|
|
20
|
+
// Slot layout: [0]=scale, [1]=angle, [2..3]=resolution.
|
|
21
|
+
const HALFTONE_FRAGMENT_WGSL = /* wgsl */ `
|
|
22
|
+
struct Uniforms {
|
|
23
|
+
u_scale : f32,
|
|
24
|
+
u_angle : f32,
|
|
25
|
+
u_resolution : vec2f,
|
|
26
|
+
}
|
|
27
|
+
@group(0) @binding(0) var<uniform> uni : Uniforms;
|
|
28
|
+
@group(1) @binding(0) var tex : texture_2d<f32>;
|
|
29
|
+
@group(1) @binding(1) var smp : sampler;
|
|
30
|
+
|
|
31
|
+
@fragment
|
|
32
|
+
fn fs_main(@location(0) uv : vec2f) -> @location(0) vec4f {
|
|
33
|
+
let c = textureSampleLevel(tex, smp, uv, 0.0);
|
|
34
|
+
let lum = dot(c.rgb, vec3f(0.2126, 0.7152, 0.0722));
|
|
35
|
+
let p = uv * uni.u_resolution;
|
|
36
|
+
let s = sin(uni.u_angle);
|
|
37
|
+
let co = cos(uni.u_angle);
|
|
38
|
+
let rp = vec2f(p.x * co - p.y * s, p.x * s + p.y * co);
|
|
39
|
+
let cell = (rp % vec2f(uni.u_scale)) - uni.u_scale * 0.5;
|
|
40
|
+
let dist = length(cell) / (uni.u_scale * 0.5);
|
|
41
|
+
let radius = sqrt(1.0 - lum);
|
|
42
|
+
let dot1 = step(dist, radius);
|
|
43
|
+
return vec4f(c.rgb * dot1, c.a);
|
|
44
|
+
}`;
|
|
45
|
+
//# sourceMappingURL=wgpuHalftoneEffect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wgpuHalftoneEffect.js","sourceRoot":"","sources":["../src/wgpuHalftoneEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAG5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,mGAAmG;AACnG,oFAAoF;AACpF,MAAM,UAAU,yBAAyB,CACvC,KAAsB,EACtB,MAAkC,EAClC,IAAgC,EAChC,MAAgC;IAEhC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,GAAG,CAAC;IAClC,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,SAAS,CAAC,CAAC;IACzG,kBAAkB,CAAC,KAAK,EAAE,MAA0B,EAAE,IAAwB,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE;QAChG,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QAC5B,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;QACf,2CAA2C;QAC3C,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC;QACtB,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;IACzB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,+BAA+B,GAA2B,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IACrF,yBAAyB,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAAwB,CAAC,CAAC;AACvF,CAAC,CAAC;AAEF,wDAAwD;AACxD,MAAM,sBAAsB,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;EAuBxC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { HueSaturationEffect, WgpuRenderEffectRunner, WgpuRenderState, WgpuRenderTarget } from '@flighthq/types';
|
|
2
|
+
export declare function applyHueSaturationEffectToWgpu(state: WgpuRenderState, source: Readonly<WgpuRenderTarget>, dest: Readonly<WgpuRenderTarget>, effect: Readonly<HueSaturationEffect>): void;
|
|
3
|
+
export declare const defaultWgpuHueSaturationEffectRunner: WgpuRenderEffectRunner;
|
|
4
|
+
//# sourceMappingURL=wgpuHueSaturationEffect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wgpuHueSaturationEffect.d.ts","sourceRoot":"","sources":["../src/wgpuHueSaturationEffect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAKtH,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAClC,IAAI,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAChC,MAAM,EAAE,QAAQ,CAAC,mBAAmB,CAAC,GACpC,IAAI,CAUN;AAED,eAAO,MAAM,oCAAoC,EAAE,sBAElD,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { drawWgpuFilterPass } from '@flighthq/filters-wgpu';
|
|
2
|
+
import { getWgpuEffectPipeline } from './wgpuEffectProgramCache';
|
|
3
|
+
// Hue/saturation/lightness: convert to HSL, adjust, convert back.
|
|
4
|
+
export function applyHueSaturationEffectToWgpu(state, source, dest, effect) {
|
|
5
|
+
const hue = (effect.hue ?? 0) / 360;
|
|
6
|
+
const saturation = effect.saturation ?? 1;
|
|
7
|
+
const lightness = effect.lightness ?? 0;
|
|
8
|
+
const pipeline = getWgpuEffectPipeline(state, 'colorGrade.hueSaturation', HUE_SATURATION_FRAGMENT_WGSL, 'replace');
|
|
9
|
+
drawWgpuFilterPass(state, source, dest, pipeline, (f32) => {
|
|
10
|
+
f32[0] = hue;
|
|
11
|
+
f32[1] = saturation;
|
|
12
|
+
f32[2] = lightness;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
export const defaultWgpuHueSaturationEffectRunner = (ctx, effect) => {
|
|
16
|
+
applyHueSaturationEffectToWgpu(ctx.state, ctx.source, ctx.dest, effect);
|
|
17
|
+
};
|
|
18
|
+
// Slot layout: [0]=hue (turns), [1]=saturation, [2]=lightness.
|
|
19
|
+
const HUE_SATURATION_FRAGMENT_WGSL = /* wgsl */ `
|
|
20
|
+
struct Uniforms { u_hue : f32, u_saturation : f32, u_lightness : f32, _pad0 : f32, }
|
|
21
|
+
@group(0) @binding(0) var<uniform> uni : Uniforms;
|
|
22
|
+
@group(1) @binding(0) var tex : texture_2d<f32>;
|
|
23
|
+
@group(1) @binding(1) var smp : sampler;
|
|
24
|
+
|
|
25
|
+
fn rgb2hsl(c : vec3f) -> vec3f {
|
|
26
|
+
let mx = max(c.r, max(c.g, c.b));
|
|
27
|
+
let mn = min(c.r, min(c.g, c.b));
|
|
28
|
+
let l = (mx + mn) * 0.5;
|
|
29
|
+
var h = 0.0;
|
|
30
|
+
var s = 0.0;
|
|
31
|
+
let d = mx - mn;
|
|
32
|
+
if (d > 0.0001) {
|
|
33
|
+
s = select(d / (2.0 - mx - mn), d / (mx + mn), l < 0.5);
|
|
34
|
+
if (mx == c.r) {
|
|
35
|
+
h = (c.g - c.b) / d + select(0.0, 6.0, c.g < c.b);
|
|
36
|
+
} else if (mx == c.g) {
|
|
37
|
+
h = (c.b - c.r) / d + 2.0;
|
|
38
|
+
} else {
|
|
39
|
+
h = (c.r - c.g) / d + 4.0;
|
|
40
|
+
}
|
|
41
|
+
h /= 6.0;
|
|
42
|
+
}
|
|
43
|
+
return vec3f(h, s, l);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
fn hue2rgb(p : f32, q : f32, t_in : f32) -> f32 {
|
|
47
|
+
var t = t_in;
|
|
48
|
+
if (t < 0.0) { t += 1.0; }
|
|
49
|
+
if (t > 1.0) { t -= 1.0; }
|
|
50
|
+
if (t < 1.0 / 6.0) { return p + (q - p) * 6.0 * t; }
|
|
51
|
+
if (t < 1.0 / 2.0) { return q; }
|
|
52
|
+
if (t < 2.0 / 3.0) { return p + (q - p) * (2.0 / 3.0 - t) * 6.0; }
|
|
53
|
+
return p;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
fn hsl2rgb(hsl : vec3f) -> vec3f {
|
|
57
|
+
let h = hsl.x;
|
|
58
|
+
let s = hsl.y;
|
|
59
|
+
let l = hsl.z;
|
|
60
|
+
if (s <= 0.0) { return vec3f(l); }
|
|
61
|
+
let q = select(l + s - l * s, l * (1.0 + s), l < 0.5);
|
|
62
|
+
let p = 2.0 * l - q;
|
|
63
|
+
return vec3f(hue2rgb(p, q, h + 1.0 / 3.0), hue2rgb(p, q, h), hue2rgb(p, q, h - 1.0 / 3.0));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@fragment
|
|
67
|
+
fn fs_main(@location(0) uv : vec2f) -> @location(0) vec4f {
|
|
68
|
+
let c = textureSampleLevel(tex, smp, uv, 0.0);
|
|
69
|
+
var hsl = rgb2hsl(c.rgb);
|
|
70
|
+
hsl.x = fract(hsl.x + uni.u_hue);
|
|
71
|
+
hsl.y = clamp(hsl.y * uni.u_saturation, 0.0, 1.0);
|
|
72
|
+
hsl.z = clamp(hsl.z + uni.u_lightness, 0.0, 1.0);
|
|
73
|
+
return vec4f(hsl2rgb(hsl), c.a);
|
|
74
|
+
}`;
|
|
75
|
+
//# sourceMappingURL=wgpuHueSaturationEffect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wgpuHueSaturationEffect.js","sourceRoot":"","sources":["../src/wgpuHueSaturationEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAG5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,kEAAkE;AAClE,MAAM,UAAU,8BAA8B,CAC5C,KAAsB,EACtB,MAAkC,EAClC,IAAgC,EAChC,MAAqC;IAErC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC;IACpC,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,EAAE,0BAA0B,EAAE,4BAA4B,EAAE,SAAS,CAAC,CAAC;IACnH,kBAAkB,CAAC,KAAK,EAAE,MAA0B,EAAE,IAAwB,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE;QAChG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;QACb,GAAG,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC;QACpB,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IACrB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,oCAAoC,GAA2B,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IAC1F,8BAA8B,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAA6B,CAAC,CAAC;AACjG,CAAC,CAAC;AAEF,+DAA+D;AAC/D,MAAM,4BAA4B,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuD9C,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { InvertEffect, WgpuRenderEffectRunner, WgpuRenderState, WgpuRenderTarget } from '@flighthq/types';
|
|
2
|
+
export declare function applyInvertEffectToWgpu(state: WgpuRenderState, source: Readonly<WgpuRenderTarget>, dest: Readonly<WgpuRenderTarget>, effect: Readonly<InvertEffect>): void;
|
|
3
|
+
export declare const defaultWgpuInvertEffectRunner: WgpuRenderEffectRunner;
|
|
4
|
+
//# sourceMappingURL=wgpuInvertEffect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wgpuInvertEffect.d.ts","sourceRoot":"","sources":["../src/wgpuInvertEffect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,sBAAsB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAK/G,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAClC,IAAI,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAChC,MAAM,EAAE,QAAQ,CAAC,YAAY,CAAC,GAC7B,IAAI,CAMN;AAED,eAAO,MAAM,6BAA6B,EAAE,sBAE3C,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { drawWgpuFilterPass } from '@flighthq/filters-wgpu';
|
|
2
|
+
import { getWgpuEffectPipeline } from './wgpuEffectProgramCache';
|
|
3
|
+
// Invert: mix toward 1 - rgb by intensity.
|
|
4
|
+
export function applyInvertEffectToWgpu(state, source, dest, effect) {
|
|
5
|
+
const intensity = effect.intensity ?? 1;
|
|
6
|
+
const pipeline = getWgpuEffectPipeline(state, 'colorGrade.invert', INVERT_FRAGMENT_WGSL, 'replace');
|
|
7
|
+
drawWgpuFilterPass(state, source, dest, pipeline, (f32) => {
|
|
8
|
+
f32[0] = intensity;
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
export const defaultWgpuInvertEffectRunner = (ctx, effect) => {
|
|
12
|
+
applyInvertEffectToWgpu(ctx.state, ctx.source, ctx.dest, effect);
|
|
13
|
+
};
|
|
14
|
+
// Slot layout: [0]=intensity.
|
|
15
|
+
const INVERT_FRAGMENT_WGSL = /* wgsl */ `
|
|
16
|
+
struct Uniforms { u_intensity : f32, _pad0 : f32, _pad1 : f32, _pad2 : f32, }
|
|
17
|
+
@group(0) @binding(0) var<uniform> uni : Uniforms;
|
|
18
|
+
@group(1) @binding(0) var tex : texture_2d<f32>;
|
|
19
|
+
@group(1) @binding(1) var smp : sampler;
|
|
20
|
+
|
|
21
|
+
@fragment
|
|
22
|
+
fn fs_main(@location(0) uv : vec2f) -> @location(0) vec4f {
|
|
23
|
+
let c = textureSampleLevel(tex, smp, uv, 0.0);
|
|
24
|
+
return vec4f(mix(c.rgb, vec3f(1.0) - c.rgb, uni.u_intensity), c.a);
|
|
25
|
+
}`;
|
|
26
|
+
//# sourceMappingURL=wgpuInvertEffect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wgpuInvertEffect.js","sourceRoot":"","sources":["../src/wgpuInvertEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAG5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,2CAA2C;AAC3C,MAAM,UAAU,uBAAuB,CACrC,KAAsB,EACtB,MAAkC,EAClC,IAAgC,EAChC,MAA8B;IAE9B,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,SAAS,CAAC,CAAC;IACpG,kBAAkB,CAAC,KAAK,EAAE,MAA0B,EAAE,IAAwB,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE;QAChG,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IACrB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,6BAA6B,GAA2B,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IACnF,uBAAuB,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAAsB,CAAC,CAAC;AACnF,CAAC,CAAC;AAEF,8BAA8B;AAC9B,MAAM,oBAAoB,GAAG,UAAU,CAAC;;;;;;;;;;EAUtC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { KuwaharaEffect, WgpuRenderEffectRunner, WgpuRenderState, WgpuRenderTarget } from '@flighthq/types';
|
|
2
|
+
export declare function applyKuwaharaEffectToWgpu(state: WgpuRenderState, source: Readonly<WgpuRenderTarget>, dest: Readonly<WgpuRenderTarget>, effect: Readonly<KuwaharaEffect>): void;
|
|
3
|
+
export declare const defaultWgpuKuwaharaEffectRunner: WgpuRenderEffectRunner;
|
|
4
|
+
//# sourceMappingURL=wgpuKuwaharaEffect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wgpuKuwaharaEffect.d.ts","sourceRoot":"","sources":["../src/wgpuKuwaharaEffect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,sBAAsB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAOjH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAClC,IAAI,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAChC,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,GAC/B,IAAI,CASN;AAED,eAAO,MAAM,+BAA+B,EAAE,sBAE7C,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { drawWgpuFilterPass } from '@flighthq/filters-wgpu';
|
|
2
|
+
import { getWgpuEffectPipeline } from './wgpuEffectProgramCache';
|
|
3
|
+
// Kuwahara: edge-preserving smoothing. Over a fixed small radius split the neighborhood into four
|
|
4
|
+
// overlapping quadrants, compute each mean and variance, and emit the lowest-variance mean — flattens
|
|
5
|
+
// regions while keeping edges crisp. `radius` gates the sampled extent.
|
|
6
|
+
export function applyKuwaharaEffectToWgpu(state, source, dest, effect) {
|
|
7
|
+
const radius = effect.radius ?? 3;
|
|
8
|
+
const pipeline = getWgpuEffectPipeline(state, 'stylization.kuwahara', KUWAHARA_FRAGMENT_WGSL, 'replace');
|
|
9
|
+
drawWgpuFilterPass(state, source, dest, pipeline, (f32) => {
|
|
10
|
+
f32[0] = Math.max(1, radius);
|
|
11
|
+
// u_resolution (vec2f) aligns to slot [2].
|
|
12
|
+
f32[2] = source.width;
|
|
13
|
+
f32[3] = source.height;
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
export const defaultWgpuKuwaharaEffectRunner = (ctx, effect) => {
|
|
17
|
+
applyKuwaharaEffectToWgpu(ctx.state, ctx.source, ctx.dest, effect);
|
|
18
|
+
};
|
|
19
|
+
// Slot layout: [0]=radius, [1]=pad, [2..3]=resolution.
|
|
20
|
+
const KUWAHARA_FRAGMENT_WGSL = /* wgsl */ `
|
|
21
|
+
struct Uniforms {
|
|
22
|
+
u_radius : f32,
|
|
23
|
+
_pad0 : f32,
|
|
24
|
+
u_resolution : vec2f,
|
|
25
|
+
}
|
|
26
|
+
@group(0) @binding(0) var<uniform> uni : Uniforms;
|
|
27
|
+
@group(1) @binding(0) var tex : texture_2d<f32>;
|
|
28
|
+
@group(1) @binding(1) var smp : sampler;
|
|
29
|
+
|
|
30
|
+
const R : i32 = 4;
|
|
31
|
+
|
|
32
|
+
@fragment
|
|
33
|
+
fn fs_main(@location(0) uv : vec2f) -> @location(0) vec4f {
|
|
34
|
+
let texel = 1.0 / uni.u_resolution;
|
|
35
|
+
let r = i32(min(f32(R), uni.u_radius));
|
|
36
|
+
var means : array<vec3f, 4>;
|
|
37
|
+
var vars : array<f32, 4>;
|
|
38
|
+
var lo = array<vec2i, 4>(vec2i(-1, -1), vec2i(0, -1), vec2i(-1, 0), vec2i(0, 0));
|
|
39
|
+
for (var q = 0; q < 4; q++) {
|
|
40
|
+
var sum = vec3f(0.0);
|
|
41
|
+
var sumSq = vec3f(0.0);
|
|
42
|
+
var n = 0.0;
|
|
43
|
+
for (var y = 0; y <= R; y++) {
|
|
44
|
+
for (var x = 0; x <= R; x++) {
|
|
45
|
+
if (x > r || y > r) { continue; }
|
|
46
|
+
let d = vec2i(x, y) * sign(lo[q] + vec2i(1)) + lo[q] * r;
|
|
47
|
+
let off = vec2f(f32(d.x), f32(d.y)) * texel;
|
|
48
|
+
let col = textureSampleLevel(tex, smp, uv + off, 0.0).rgb;
|
|
49
|
+
sum += col;
|
|
50
|
+
sumSq += col * col;
|
|
51
|
+
n += 1.0;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
let mean = sum / n;
|
|
55
|
+
means[q] = mean;
|
|
56
|
+
let v = sumSq / n - mean * mean;
|
|
57
|
+
vars[q] = v.r + v.g + v.b;
|
|
58
|
+
}
|
|
59
|
+
var minVar = vars[0];
|
|
60
|
+
var result = means[0];
|
|
61
|
+
for (var q = 1; q < 4; q++) {
|
|
62
|
+
if (vars[q] < minVar) {
|
|
63
|
+
minVar = vars[q];
|
|
64
|
+
result = means[q];
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return vec4f(result, textureSampleLevel(tex, smp, uv, 0.0).a);
|
|
68
|
+
}`;
|
|
69
|
+
//# sourceMappingURL=wgpuKuwaharaEffect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wgpuKuwaharaEffect.js","sourceRoot":"","sources":["../src/wgpuKuwaharaEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAG5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,kGAAkG;AAClG,sGAAsG;AACtG,wEAAwE;AACxE,MAAM,UAAU,yBAAyB,CACvC,KAAsB,EACtB,MAAkC,EAClC,IAAgC,EAChC,MAAgC;IAEhC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;IAClC,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,SAAS,CAAC,CAAC;IACzG,kBAAkB,CAAC,KAAK,EAAE,MAA0B,EAAE,IAAwB,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE;QAChG,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QAC7B,2CAA2C;QAC3C,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC;QACtB,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;IACzB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,+BAA+B,GAA2B,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IACrF,yBAAyB,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAAwB,CAAC,CAAC;AACvF,CAAC,CAAC;AAEF,uDAAuD;AACvD,MAAM,sBAAsB,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgDxC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { LensDirtEffect, WgpuRenderEffectRunner, WgpuRenderState, WgpuRenderTarget } from '@flighthq/types';
|
|
2
|
+
export declare function applyLensDirtEffectToWgpu(state: WgpuRenderState, source: Readonly<WgpuRenderTarget>, dest: Readonly<WgpuRenderTarget>, effect: Readonly<LensDirtEffect>): void;
|
|
3
|
+
export declare const defaultWgpuLensDirtEffectRunner: WgpuRenderEffectRunner;
|
|
4
|
+
//# sourceMappingURL=wgpuLensDirtEffect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wgpuLensDirtEffect.d.ts","sourceRoot":"","sources":["../src/wgpuLensDirtEffect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,sBAAsB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAKjH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAClC,IAAI,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAChC,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,GAC/B,IAAI,CAUN;AAED,eAAO,MAAM,+BAA+B,EAAE,sBAE7C,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { drawWgpuFilterPass } from '@flighthq/filters-wgpu';
|
|
2
|
+
import { getWgpuEffectPipeline } from './wgpuEffectProgramCache';
|
|
3
|
+
// Lens dirt: procedural soft smudges that brighten where the scene is bright — a cheap bloom-dirt overlay.
|
|
4
|
+
export function applyLensDirtEffectToWgpu(state, source, dest, effect) {
|
|
5
|
+
const intensity = effect.intensity ?? 1;
|
|
6
|
+
const threshold = effect.threshold ?? 0.55;
|
|
7
|
+
const seed = effect.seed ?? 0;
|
|
8
|
+
const pipeline = getWgpuEffectPipeline(state, 'lens.lensDirt', LENS_DIRT_FRAGMENT_WGSL, 'replace');
|
|
9
|
+
drawWgpuFilterPass(state, source, dest, pipeline, (f32) => {
|
|
10
|
+
f32[0] = intensity;
|
|
11
|
+
f32[1] = threshold;
|
|
12
|
+
f32[2] = seed;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
export const defaultWgpuLensDirtEffectRunner = (ctx, effect) => {
|
|
16
|
+
applyLensDirtEffectToWgpu(ctx.state, ctx.source, ctx.dest, effect);
|
|
17
|
+
};
|
|
18
|
+
// Slot layout: [0]=intensity, [1]=threshold, [2]=seed.
|
|
19
|
+
const LENS_DIRT_FRAGMENT_WGSL = /* wgsl */ `
|
|
20
|
+
struct Uniforms {
|
|
21
|
+
u_intensity : f32,
|
|
22
|
+
u_threshold : f32,
|
|
23
|
+
u_seed : f32,
|
|
24
|
+
}
|
|
25
|
+
@group(0) @binding(0) var<uniform> uni : Uniforms;
|
|
26
|
+
@group(1) @binding(0) var tex : texture_2d<f32>;
|
|
27
|
+
@group(1) @binding(1) var smp : sampler;
|
|
28
|
+
|
|
29
|
+
fn dirtHash(p : vec2f) -> f32 { return fract(sin(dot(p, vec2f(127.1, 311.7))) * 43758.5453123); }
|
|
30
|
+
|
|
31
|
+
fn dirtAmount(uv : vec2f, seed : f32) -> f32 {
|
|
32
|
+
var acc = 0.0;
|
|
33
|
+
for (var i = 0; i < 8; i = i + 1) {
|
|
34
|
+
let fi = f32(i);
|
|
35
|
+
let c = vec2f(dirtHash(vec2f(fi, seed)), dirtHash(vec2f(fi + 9.0, seed)));
|
|
36
|
+
let r = 0.06 + 0.16 * dirtHash(vec2f(fi + 3.0, seed));
|
|
37
|
+
let d = distance(uv, c) / r;
|
|
38
|
+
acc = acc + smoothstep(1.0, 0.0, d) * (0.3 + 0.7 * dirtHash(vec2f(fi + 5.0, seed)));
|
|
39
|
+
}
|
|
40
|
+
return clamp(acc, 0.0, 1.0);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@fragment
|
|
44
|
+
fn fs_main(@location(0) uv : vec2f) -> @location(0) vec4f {
|
|
45
|
+
let c = textureSampleLevel(tex, smp, uv, 0.0);
|
|
46
|
+
let lum = dot(c.rgb, vec3f(0.299, 0.587, 0.114));
|
|
47
|
+
let bright = max(0.0, lum - uni.u_threshold);
|
|
48
|
+
let dirt = dirtAmount(uv, uni.u_seed + 1.0);
|
|
49
|
+
return vec4f(c.rgb + bright * dirt * uni.u_intensity * 2.0, c.a);
|
|
50
|
+
}`;
|
|
51
|
+
//# sourceMappingURL=wgpuLensDirtEffect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wgpuLensDirtEffect.js","sourceRoot":"","sources":["../src/wgpuLensDirtEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAG5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,2GAA2G;AAC3G,MAAM,UAAU,yBAAyB,CACvC,KAAsB,EACtB,MAAkC,EAClC,IAAgC,EAChC,MAAgC;IAEhC,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;IACxC,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,IAAI,CAAC;IAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC;IAC9B,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,EAAE,eAAe,EAAE,uBAAuB,EAAE,SAAS,CAAC,CAAC;IACnG,kBAAkB,CAAC,KAAK,EAAE,MAA0B,EAAE,IAAwB,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE;QAChG,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;QACnB,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;QACnB,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,+BAA+B,GAA2B,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IACrF,yBAAyB,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAAwB,CAAC,CAAC;AACvF,CAAC,CAAC;AAEF,uDAAuD;AACvD,MAAM,uBAAuB,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+BzC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { LensDistortionEffect, WgpuRenderEffectRunner, WgpuRenderState, WgpuRenderTarget } from '@flighthq/types';
|
|
2
|
+
export declare function applyLensDistortionEffectToWgpu(state: WgpuRenderState, source: Readonly<WgpuRenderTarget>, dest: Readonly<WgpuRenderTarget>, effect: Readonly<LensDistortionEffect>): void;
|
|
3
|
+
export declare const defaultWgpuLensDistortionEffectRunner: WgpuRenderEffectRunner;
|
|
4
|
+
//# sourceMappingURL=wgpuLensDistortionEffect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wgpuLensDistortionEffect.d.ts","sourceRoot":"","sources":["../src/wgpuLensDistortionEffect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAMvH,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAClC,IAAI,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAChC,MAAM,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GACrC,IAAI,CAQN;AAED,eAAO,MAAM,qCAAqC,EAAE,sBAEnD,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { drawWgpuFilterPass } from '@flighthq/filters-wgpu';
|
|
2
|
+
import { getWgpuEffectPipeline } from './wgpuEffectProgramCache';
|
|
3
|
+
// Lens distortion: remap uv by a radial polynomial. Positive amount bulges outward (barrel), negative
|
|
4
|
+
// pinches inward (pincushion); scale re-frames the result so corners stay in view.
|
|
5
|
+
export function applyLensDistortionEffectToWgpu(state, source, dest, effect) {
|
|
6
|
+
const amount = effect.amount ?? 0.2;
|
|
7
|
+
const scale = effect.scale ?? 1;
|
|
8
|
+
const pipeline = getWgpuEffectPipeline(state, 'lens.lensDistortion', LENS_DISTORTION_FRAGMENT_WGSL, 'replace');
|
|
9
|
+
drawWgpuFilterPass(state, source, dest, pipeline, (f32) => {
|
|
10
|
+
f32[0] = amount;
|
|
11
|
+
f32[1] = scale;
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
export const defaultWgpuLensDistortionEffectRunner = (ctx, effect) => {
|
|
15
|
+
applyLensDistortionEffectToWgpu(ctx.state, ctx.source, ctx.dest, effect);
|
|
16
|
+
};
|
|
17
|
+
const LENS_DISTORTION_FRAGMENT_WGSL = /* wgsl */ `
|
|
18
|
+
struct Uniforms {
|
|
19
|
+
u_amount : f32,
|
|
20
|
+
u_scale : f32,
|
|
21
|
+
}
|
|
22
|
+
@group(0) @binding(0) var<uniform> uni : Uniforms;
|
|
23
|
+
@group(1) @binding(0) var tex : texture_2d<f32>;
|
|
24
|
+
@group(1) @binding(1) var smp : sampler;
|
|
25
|
+
|
|
26
|
+
@fragment
|
|
27
|
+
fn fs_main(@location(0) uv : vec2f) -> @location(0) vec4f {
|
|
28
|
+
let centered = (uv - vec2f(0.5)) / uni.u_scale;
|
|
29
|
+
let r2 = dot(centered, centered);
|
|
30
|
+
let distorted = centered * (1.0 + uni.u_amount * r2) + vec2f(0.5);
|
|
31
|
+
if (distorted.x < 0.0 || distorted.x > 1.0 || distorted.y < 0.0 || distorted.y > 1.0) {
|
|
32
|
+
return vec4f(0.0, 0.0, 0.0, 1.0);
|
|
33
|
+
}
|
|
34
|
+
return textureSampleLevel(tex, smp, distorted, 0.0);
|
|
35
|
+
}`;
|
|
36
|
+
//# sourceMappingURL=wgpuLensDistortionEffect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wgpuLensDistortionEffect.js","sourceRoot":"","sources":["../src/wgpuLensDistortionEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAG5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,sGAAsG;AACtG,mFAAmF;AACnF,MAAM,UAAU,+BAA+B,CAC7C,KAAsB,EACtB,MAAkC,EAClC,IAAgC,EAChC,MAAsC;IAEtC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC;IACpC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;IAChC,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,EAAE,qBAAqB,EAAE,6BAA6B,EAAE,SAAS,CAAC,CAAC;IAC/G,kBAAkB,CAAC,KAAK,EAAE,MAA0B,EAAE,IAAwB,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE;QAChG,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;QAChB,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;IACjB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,qCAAqC,GAA2B,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IAC3F,+BAA+B,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAA8B,CAAC,CAAC;AACnG,CAAC,CAAC;AAEF,MAAM,6BAA6B,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;EAkB/C,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { LensFlareEffect, WgpuRenderEffectRunner, WgpuRenderState, WgpuRenderTarget } from '@flighthq/types';
|
|
2
|
+
export declare function applyLensFlareEffectToWgpu(state: WgpuRenderState, source: Readonly<WgpuRenderTarget>, dest: Readonly<WgpuRenderTarget>, effect: Readonly<LensFlareEffect>): void;
|
|
3
|
+
export declare const defaultWgpuLensFlareEffectRunner: WgpuRenderEffectRunner;
|
|
4
|
+
//# sourceMappingURL=wgpuLensFlareEffect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wgpuLensFlareEffect.d.ts","sourceRoot":"","sources":["../src/wgpuLensFlareEffect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,sBAAsB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AASlH,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,CAYN;AAED,eAAO,MAAM,gCAAgC,EAAE,sBAE9C,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { drawWgpuFilterPass } from '@flighthq/filters-wgpu';
|
|
2
|
+
import { getWgpuEffectPipeline } from './wgpuEffectProgramCache';
|
|
3
|
+
// Lens flare: a single-pass approximation. A true flare is a multi-pass recipe (downsample a bright
|
|
4
|
+
// pass, then accumulate ghosts and a halo from it). Here, on each fragment, we sample the source's
|
|
5
|
+
// bright spots along the vector from the pixel toward the center, adding `ghosts` evenly spaced ghost
|
|
6
|
+
// samples plus a halo ring, scaled by threshold/intensity. It previews the look without the bright-pass
|
|
7
|
+
// buffer.
|
|
8
|
+
export function applyLensFlareEffectToWgpu(state, source, dest, effect) {
|
|
9
|
+
const threshold = effect.threshold ?? 0.8;
|
|
10
|
+
const intensity = effect.intensity ?? 1;
|
|
11
|
+
const ghosts = effect.ghosts ?? 4;
|
|
12
|
+
const halo = effect.halo ?? 0.5;
|
|
13
|
+
const pipeline = getWgpuEffectPipeline(state, 'lens.lensFlare', LENS_FLARE_FRAGMENT_WGSL, 'replace');
|
|
14
|
+
drawWgpuFilterPass(state, source, dest, pipeline, (f32) => {
|
|
15
|
+
f32[0] = threshold;
|
|
16
|
+
f32[1] = intensity;
|
|
17
|
+
f32[2] = ghosts;
|
|
18
|
+
f32[3] = halo;
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
export const defaultWgpuLensFlareEffectRunner = (ctx, effect) => {
|
|
22
|
+
applyLensFlareEffectToWgpu(ctx.state, ctx.source, ctx.dest, effect);
|
|
23
|
+
};
|
|
24
|
+
// Slot layout: [0]=threshold, [1]=intensity, [2]=ghosts, [3]=halo.
|
|
25
|
+
const LENS_FLARE_FRAGMENT_WGSL = /* wgsl */ `
|
|
26
|
+
struct Uniforms {
|
|
27
|
+
u_threshold : f32,
|
|
28
|
+
u_intensity : f32,
|
|
29
|
+
u_ghosts : f32,
|
|
30
|
+
u_halo : f32,
|
|
31
|
+
}
|
|
32
|
+
@group(0) @binding(0) var<uniform> uni : Uniforms;
|
|
33
|
+
@group(1) @binding(0) var tex : texture_2d<f32>;
|
|
34
|
+
@group(1) @binding(1) var smp : sampler;
|
|
35
|
+
|
|
36
|
+
fn brightPass(uv : vec2f) -> vec3f {
|
|
37
|
+
if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) { return vec3f(0.0); }
|
|
38
|
+
let c = textureSampleLevel(tex, smp, uv, 0.0).rgb;
|
|
39
|
+
let l = dot(c, vec3f(0.2126, 0.7152, 0.0722));
|
|
40
|
+
return c * max(0.0, l - uni.u_threshold);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@fragment
|
|
44
|
+
fn fs_main(@location(0) uv : vec2f) -> @location(0) vec4f {
|
|
45
|
+
let scene = textureSampleLevel(tex, smp, uv, 0.0);
|
|
46
|
+
// Single-pass approximation of a flare: walk ghost samples along the vector toward the optical
|
|
47
|
+
// center and add a halo ring, all from the bright pass of the scene itself (no separate buffer).
|
|
48
|
+
let toCenter = vec2f(0.5) - uv;
|
|
49
|
+
var flare = vec3f(0.0);
|
|
50
|
+
let count = i32(clamp(uni.u_ghosts, 0.0, 8.0));
|
|
51
|
+
for (var i = 0; i < 8; i = i + 1) {
|
|
52
|
+
if (i >= count) { break; }
|
|
53
|
+
let t = (f32(i) + 1.0) / (f32(count) + 1.0);
|
|
54
|
+
let ghostUv = uv + toCenter * (2.0 * t);
|
|
55
|
+
flare = flare + brightPass(ghostUv);
|
|
56
|
+
}
|
|
57
|
+
let haloDir = normalize(toCenter + vec2f(1e-5));
|
|
58
|
+
flare = flare + brightPass(uv + haloDir * uni.u_halo) * uni.u_halo;
|
|
59
|
+
return vec4f(scene.rgb + flare * uni.u_intensity, scene.a);
|
|
60
|
+
}`;
|
|
61
|
+
//# sourceMappingURL=wgpuLensFlareEffect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wgpuLensFlareEffect.js","sourceRoot":"","sources":["../src/wgpuLensFlareEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAG5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,oGAAoG;AACpG,mGAAmG;AACnG,sGAAsG;AACtG,wGAAwG;AACxG,UAAU;AACV,MAAM,UAAU,0BAA0B,CACxC,KAAsB,EACtB,MAAkC,EAClC,IAAgC,EAChC,MAAiC;IAEjC,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,GAAG,CAAC;IAC1C,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,GAAG,CAAC;IAChC,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,SAAS,CAAC,CAAC;IACrG,kBAAkB,CAAC,KAAK,EAAE,MAA0B,EAAE,IAAwB,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE;QAChG,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;QACnB,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;QACnB,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;QAChB,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,gCAAgC,GAA2B,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IACtF,0BAA0B,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAAyB,CAAC,CAAC;AACzF,CAAC,CAAC;AAEF,mEAAmE;AACnE,MAAM,wBAAwB,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmC1C,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { LiftGammaGainEffect, WgpuRenderEffectRunner, WgpuRenderState, WgpuRenderTarget } from '@flighthq/types';
|
|
2
|
+
export declare function applyLiftGammaGainEffectToWgpu(state: WgpuRenderState, source: Readonly<WgpuRenderTarget>, dest: Readonly<WgpuRenderTarget>, effect: Readonly<LiftGammaGainEffect>): void;
|
|
3
|
+
export declare const defaultWgpuLiftGammaGainEffectRunner: WgpuRenderEffectRunner;
|
|
4
|
+
//# sourceMappingURL=wgpuLiftGammaGainEffect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wgpuLiftGammaGainEffect.d.ts","sourceRoot":"","sources":["../src/wgpuLiftGammaGainEffect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAOtH,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAClC,IAAI,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAChC,MAAM,EAAE,QAAQ,CAAC,mBAAmB,CAAC,GACpC,IAAI,CAsBN;AAED,eAAO,MAAM,oCAAoC,EAAE,sBAElD,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { drawWgpuFilterPass } from '@flighthq/filters-wgpu';
|
|
2
|
+
import { getWgpuEffectPipeline } from './wgpuEffectProgramCache';
|
|
3
|
+
// Lift/gamma/gain: unpack packed-RGBA neutrals to per-channel offsets/exponents/multipliers in JS.
|
|
4
|
+
// Neutral packed values: lift 0x000000ff, gamma 0x808080ff, gain 0xffffffff. Each vec3 is uploaded
|
|
5
|
+
// into its own 16-byte-aligned slot so the std140 vec3 alignment is satisfied.
|
|
6
|
+
export function applyLiftGammaGainEffectToWgpu(state, source, dest, effect) {
|
|
7
|
+
const lift = unpackColor(effect.lift ?? 0x000000ff);
|
|
8
|
+
const gammaRaw = unpackColor(effect.gamma ?? 0x808080ff);
|
|
9
|
+
const gain = unpackColor(effect.gain ?? 0xffffffff);
|
|
10
|
+
// Map gamma's 0.5-neutral to a 1.0-neutral exponent so 0x808080 leaves the image unchanged.
|
|
11
|
+
const gamma = [
|
|
12
|
+
1 / Math.max(gammaRaw[0] * 2, 1e-3),
|
|
13
|
+
1 / Math.max(gammaRaw[1] * 2, 1e-3),
|
|
14
|
+
1 / Math.max(gammaRaw[2] * 2, 1e-3),
|
|
15
|
+
];
|
|
16
|
+
const pipeline = getWgpuEffectPipeline(state, 'colorGrade.liftGammaGain', LIFT_GAMMA_GAIN_FRAGMENT_WGSL, 'replace');
|
|
17
|
+
drawWgpuFilterPass(state, source, dest, pipeline, (f32) => {
|
|
18
|
+
f32[0] = lift[0];
|
|
19
|
+
f32[1] = lift[1];
|
|
20
|
+
f32[2] = lift[2];
|
|
21
|
+
f32[4] = gamma[0];
|
|
22
|
+
f32[5] = gamma[1];
|
|
23
|
+
f32[6] = gamma[2];
|
|
24
|
+
f32[8] = gain[0];
|
|
25
|
+
f32[9] = gain[1];
|
|
26
|
+
f32[10] = gain[2];
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
export const defaultWgpuLiftGammaGainEffectRunner = (ctx, effect) => {
|
|
30
|
+
applyLiftGammaGainEffectToWgpu(ctx.state, ctx.source, ctx.dest, effect);
|
|
31
|
+
};
|
|
32
|
+
// Unpack a packed RGBA integer (0xRRGGBBAA) into normalized [r, g, b] floats. Alpha is dropped — these
|
|
33
|
+
// grade values describe RGB channels only.
|
|
34
|
+
function unpackColor(c) {
|
|
35
|
+
return [((c >>> 24) & 255) / 255, ((c >>> 16) & 255) / 255, ((c >>> 8) & 255) / 255];
|
|
36
|
+
}
|
|
37
|
+
// Slot layout: three vec3 in 16-byte-aligned slots — [0..2]=lift, [4..6]=gamma, [8..10]=gain.
|
|
38
|
+
const LIFT_GAMMA_GAIN_FRAGMENT_WGSL = /* wgsl */ `
|
|
39
|
+
struct Uniforms { u_lift : vec3f, u_gamma : vec3f, u_gain : vec3f, }
|
|
40
|
+
@group(0) @binding(0) var<uniform> uni : Uniforms;
|
|
41
|
+
@group(1) @binding(0) var tex : texture_2d<f32>;
|
|
42
|
+
@group(1) @binding(1) var smp : sampler;
|
|
43
|
+
|
|
44
|
+
@fragment
|
|
45
|
+
fn fs_main(@location(0) uv : vec2f) -> @location(0) vec4f {
|
|
46
|
+
let c = textureSampleLevel(tex, smp, uv, 0.0);
|
|
47
|
+
var rgb = c.rgb * uni.u_gain + uni.u_lift * (vec3f(1.0) - c.rgb);
|
|
48
|
+
rgb = pow(max(rgb, vec3f(0.0)), uni.u_gamma);
|
|
49
|
+
return vec4f(clamp(rgb, vec3f(0.0), vec3f(1.0)), c.a);
|
|
50
|
+
}`;
|
|
51
|
+
//# sourceMappingURL=wgpuLiftGammaGainEffect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wgpuLiftGammaGainEffect.js","sourceRoot":"","sources":["../src/wgpuLiftGammaGainEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAG5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,mGAAmG;AACnG,mGAAmG;AACnG,+EAA+E;AAC/E,MAAM,UAAU,8BAA8B,CAC5C,KAAsB,EACtB,MAAkC,EAClC,IAAgC,EAChC,MAAqC;IAErC,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,IAAI,UAAU,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,KAAK,IAAI,UAAU,CAAC,CAAC;IACzD,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,IAAI,UAAU,CAAC,CAAC;IACpD,4FAA4F;IAC5F,MAAM,KAAK,GAAsC;QAC/C,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC;QACnC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC;QACnC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC;KACpC,CAAC;IACF,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,EAAE,0BAA0B,EAAE,6BAA6B,EAAE,SAAS,CAAC,CAAC;IACpH,kBAAkB,CAAC,KAAK,EAAE,MAA0B,EAAE,IAAwB,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE;QAChG,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAClB,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAClB,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAClB,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,oCAAoC,GAA2B,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IAC1F,8BAA8B,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAA6B,CAAC,CAAC;AACjG,CAAC,CAAC;AAEF,uGAAuG;AACvG,2CAA2C;AAC3C,SAAS,WAAW,CAAC,CAAS;IAC5B,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AACvF,CAAC;AAED,8FAA8F;AAC9F,MAAM,6BAA6B,GAAG,UAAU,CAAC;;;;;;;;;;;;EAY/C,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { LookupTableGradeEffect, WgpuRenderEffectRunner, WgpuRenderState, WgpuRenderTarget } from '@flighthq/types';
|
|
2
|
+
export declare function applyLookupTableGradeEffectToWgpu(state: WgpuRenderState, source: Readonly<WgpuRenderTarget>, dest: Readonly<WgpuRenderTarget>, effect: Readonly<LookupTableGradeEffect>): void;
|
|
3
|
+
export declare const defaultWgpuLookupTableGradeEffectRunner: WgpuRenderEffectRunner;
|
|
4
|
+
//# sourceMappingURL=wgpuLookupTableGradeEffect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wgpuLookupTableGradeEffect.d.ts","sourceRoot":"","sources":["../src/wgpuLookupTableGradeEffect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,sBAAsB,EACtB,sBAAsB,EACtB,eAAe,EACf,gBAAgB,EACjB,MAAM,iBAAiB,CAAC;AAOzB,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAClC,IAAI,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAChC,MAAM,EAAE,QAAQ,CAAC,sBAAsB,CAAC,GACvC,IAAI,CAMN;AAED,eAAO,MAAM,uCAAuC,EAAE,sBAErD,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { drawWgpuFilterPass } from '@flighthq/filters-wgpu';
|
|
2
|
+
import { getWgpuEffectPipeline } from './wgpuEffectProgramCache';
|
|
3
|
+
// LUT grade: passthrough with a strength mix. A real 3D LUT grade needs an uploaded LUT cube texture
|
|
4
|
+
// (size from effect.size) sampled per pixel as an extra bound texture; that texture path is not yet
|
|
5
|
+
// wired, so this keeps the pass compiling and color-neutral until the LUT upload is added.
|
|
6
|
+
export function applyLookupTableGradeEffectToWgpu(state, source, dest, effect) {
|
|
7
|
+
const strength = effect.strength ?? 1;
|
|
8
|
+
const pipeline = getWgpuEffectPipeline(state, 'colorGrade.lutGrade', LUT_GRADE_FRAGMENT_WGSL, 'replace');
|
|
9
|
+
drawWgpuFilterPass(state, source, dest, pipeline, (f32) => {
|
|
10
|
+
f32[0] = strength;
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
export const defaultWgpuLookupTableGradeEffectRunner = (ctx, effect) => {
|
|
14
|
+
applyLookupTableGradeEffectToWgpu(ctx.state, ctx.source, ctx.dest, effect);
|
|
15
|
+
};
|
|
16
|
+
// Slot layout: [0]=strength.
|
|
17
|
+
const LUT_GRADE_FRAGMENT_WGSL = /* wgsl */ `
|
|
18
|
+
struct Uniforms { u_strength : f32, _pad0 : f32, _pad1 : f32, _pad2 : f32, }
|
|
19
|
+
@group(0) @binding(0) var<uniform> uni : Uniforms;
|
|
20
|
+
@group(1) @binding(0) var tex : texture_2d<f32>;
|
|
21
|
+
@group(1) @binding(1) var smp : sampler;
|
|
22
|
+
|
|
23
|
+
@fragment
|
|
24
|
+
fn fs_main(@location(0) uv : vec2f) -> @location(0) vec4f {
|
|
25
|
+
let c = textureSampleLevel(tex, smp, uv, 0.0);
|
|
26
|
+
// Passthrough: a real 3D LUT samples an uploaded LUT cube texture here, then mixes by u_strength.
|
|
27
|
+
let graded = c.rgb;
|
|
28
|
+
return vec4f(mix(c.rgb, graded, uni.u_strength), c.a);
|
|
29
|
+
}`;
|
|
30
|
+
//# sourceMappingURL=wgpuLookupTableGradeEffect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wgpuLookupTableGradeEffect.js","sourceRoot":"","sources":["../src/wgpuLookupTableGradeEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAQ5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,qGAAqG;AACrG,oGAAoG;AACpG,2FAA2F;AAC3F,MAAM,UAAU,iCAAiC,CAC/C,KAAsB,EACtB,MAAkC,EAClC,IAAgC,EAChC,MAAwC;IAExC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;IACtC,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,SAAS,CAAC,CAAC;IACzG,kBAAkB,CAAC,KAAK,EAAE,MAA0B,EAAE,IAAwB,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE;QAChG,GAAG,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;IACpB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,uCAAuC,GAA2B,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IAC7F,iCAAiC,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAAgC,CAAC,CAAC;AACvG,CAAC,CAAC;AAEF,6BAA6B;AAC7B,MAAM,uBAAuB,GAAG,UAAU,CAAC;;;;;;;;;;;;EAYzC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { MotionBlurEffect, WgpuRenderEffectRunner, WgpuRenderState, WgpuRenderTarget } from '@flighthq/types';
|
|
2
|
+
export declare function applyMotionBlurEffectToWgpu(state: WgpuRenderState, source: Readonly<WgpuRenderTarget>, dest: Readonly<WgpuRenderTarget>, velocityTexture: GPUTexture | null, effect: Readonly<MotionBlurEffect>): void;
|
|
3
|
+
export declare const defaultWgpuMotionBlurEffectRunner: WgpuRenderEffectRunner;
|
|
4
|
+
//# sourceMappingURL=wgpuMotionBlurEffect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wgpuMotionBlurEffect.d.ts","sourceRoot":"","sources":["../src/wgpuMotionBlurEffect.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAWnH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAClC,IAAI,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAChC,eAAe,EAAE,UAAU,GAAG,IAAI,EAClC,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GACjC,IAAI,CAwCN;AAED,eAAO,MAAM,iCAAiC,EAAE,sBAE/C,CAAC"}
|