@flighthq/effects-gl 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/glBevelEffect.d.ts +4 -0
- package/dist/glBevelEffect.d.ts.map +1 -0
- package/dist/glBevelEffect.js +132 -0
- package/dist/glBevelEffect.js.map +1 -0
- package/dist/glBloomEffect.d.ts.map +1 -1
- package/dist/glBloomEffect.js +5 -5
- package/dist/glBloomEffect.js.map +1 -1
- package/dist/glBlurEffect.d.ts +8 -0
- package/dist/glBlurEffect.d.ts.map +1 -0
- package/dist/glBlurEffect.js +65 -0
- package/dist/glBlurEffect.js.map +1 -0
- package/dist/glColorLutPass.d.ts +3 -0
- package/dist/glColorLutPass.d.ts.map +1 -0
- package/dist/glColorLutPass.js +75 -0
- package/dist/glColorLutPass.js.map +1 -0
- package/dist/glColorMatrixPass.d.ts +3 -0
- package/dist/glColorMatrixPass.d.ts.map +1 -0
- package/dist/glColorMatrixPass.js +33 -0
- package/dist/glColorMatrixPass.js.map +1 -0
- package/dist/glConvolutionEffect.d.ts +5 -0
- package/dist/glConvolutionEffect.d.ts.map +1 -0
- package/dist/glConvolutionEffect.js +94 -0
- package/dist/glConvolutionEffect.js.map +1 -0
- package/dist/glDropShadowEffect.d.ts +4 -0
- package/dist/glDropShadowEffect.d.ts.map +1 -0
- package/dist/glDropShadowEffect.js +51 -0
- package/dist/glDropShadowEffect.js.map +1 -0
- package/dist/glEffectBlitShader.d.ts +10 -0
- package/dist/glEffectBlitShader.d.ts.map +1 -0
- package/dist/glEffectBlitShader.js +62 -0
- package/dist/glEffectBlitShader.js.map +1 -0
- package/dist/glEffectBoxBlur.d.ts +15 -0
- package/dist/glEffectBoxBlur.d.ts.map +1 -0
- package/dist/glEffectBoxBlur.js +89 -0
- package/dist/glEffectBoxBlur.js.map +1 -0
- package/dist/glEffectGradientRamp.d.ts +9 -0
- package/dist/glEffectGradientRamp.d.ts.map +1 -0
- package/dist/glEffectGradientRamp.js +64 -0
- package/dist/glEffectGradientRamp.js.map +1 -0
- package/dist/glEffectTintShader.d.ts +7 -0
- package/dist/glEffectTintShader.d.ts.map +1 -0
- package/dist/glEffectTintShader.js +80 -0
- package/dist/glEffectTintShader.js.map +1 -0
- package/dist/glGradientBevelEffect.d.ts +4 -0
- package/dist/glGradientBevelEffect.d.ts.map +1 -0
- package/dist/glGradientBevelEffect.js +121 -0
- package/dist/glGradientBevelEffect.js.map +1 -0
- package/dist/glGradientGlowEffect.d.ts +4 -0
- package/dist/glGradientGlowEffect.d.ts.map +1 -0
- package/dist/glGradientGlowEffect.js +71 -0
- package/dist/glGradientGlowEffect.js.map +1 -0
- package/dist/glInnerGlowEffect.d.ts +4 -0
- package/dist/glInnerGlowEffect.d.ts.map +1 -0
- package/dist/glInnerGlowEffect.js +77 -0
- package/dist/glInnerGlowEffect.js.map +1 -0
- package/dist/glInnerShadowEffect.d.ts +4 -0
- package/dist/glInnerShadowEffect.d.ts.map +1 -0
- package/dist/glInnerShadowEffect.js +84 -0
- package/dist/glInnerShadowEffect.js.map +1 -0
- package/dist/glMedianEffect.d.ts +5 -0
- package/dist/glMedianEffect.d.ts.map +1 -0
- package/dist/glMedianEffect.js +73 -0
- package/dist/glMedianEffect.js.map +1 -0
- package/dist/glOuterGlowEffect.d.ts +4 -0
- package/dist/glOuterGlowEffect.d.ts.map +1 -0
- package/dist/glOuterGlowEffect.js +45 -0
- package/dist/glOuterGlowEffect.js.map +1 -0
- package/dist/glRenderEffectPipeline.d.ts +2 -2
- package/dist/glRenderEffectPipeline.d.ts.map +1 -1
- package/dist/glRenderEffectPipeline.js +64 -8
- package/dist/glRenderEffectPipeline.js.map +1 -1
- package/dist/glRenderEffectRegistrar.d.ts +1 -0
- package/dist/glRenderEffectRegistrar.d.ts.map +1 -1
- package/dist/glRenderEffectRegistrar.js +52 -38
- package/dist/glRenderEffectRegistrar.js.map +1 -1
- package/dist/index.d.ts +16 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -10
- package/dist/index.js.map +1 -1
- package/package.json +11 -6
- package/src/glBevelEffect.test.ts +13 -0
- package/src/glBlurEffect.test.ts +19 -0
- package/src/glColorLutPass.test.ts +7 -0
- package/src/glColorMatrixPass.test.ts +7 -0
- package/src/glConvolutionEffect.test.ts +13 -0
- package/src/glDropShadowEffect.test.ts +13 -0
- package/src/glEffectBlitShader.test.ts +13 -0
- package/src/glEffectBoxBlur.test.ts +7 -0
- package/src/glEffectGradientRamp.test.ts +7 -0
- package/src/glEffectTintShader.test.ts +13 -0
- package/src/glGradientBevelEffect.test.ts +13 -0
- package/src/glGradientGlowEffect.test.ts +13 -0
- package/src/glInnerGlowEffect.test.ts +13 -0
- package/src/glInnerShadowEffect.test.ts +13 -0
- package/src/glMedianEffect.test.ts +13 -0
- package/src/glOuterGlowEffect.test.ts +13 -0
- package/src/glRenderEffectRegistrar.test.ts +36 -6
- package/dist/glBrightnessContrastEffect.d.ts +0 -4
- package/dist/glBrightnessContrastEffect.d.ts.map +0 -1
- package/dist/glBrightnessContrastEffect.js +0 -28
- package/dist/glBrightnessContrastEffect.js.map +0 -1
- package/dist/glChannelMixerEffect.d.ts +0 -4
- package/dist/glChannelMixerEffect.d.ts.map +0 -1
- package/dist/glChannelMixerEffect.js +0 -30
- package/dist/glChannelMixerEffect.js.map +0 -1
- package/dist/glColorGradeEffect.d.ts +0 -4
- package/dist/glColorGradeEffect.d.ts.map +0 -1
- package/dist/glColorGradeEffect.js +0 -46
- package/dist/glColorGradeEffect.js.map +0 -1
- package/dist/glExposureEffect.d.ts +0 -4
- package/dist/glExposureEffect.d.ts.map +0 -1
- package/dist/glExposureEffect.js +0 -24
- package/dist/glExposureEffect.js.map +0 -1
- package/dist/glGrayscaleEffect.d.ts +0 -4
- package/dist/glGrayscaleEffect.d.ts.map +0 -1
- package/dist/glGrayscaleEffect.js +0 -25
- package/dist/glGrayscaleEffect.js.map +0 -1
- package/dist/glHueSaturationEffect.d.ts +0 -4
- package/dist/glHueSaturationEffect.d.ts.map +0 -1
- package/dist/glHueSaturationEffect.js +0 -67
- package/dist/glHueSaturationEffect.js.map +0 -1
- package/dist/glInvertEffect.d.ts +0 -4
- package/dist/glInvertEffect.d.ts.map +0 -1
- package/dist/glInvertEffect.js +0 -24
- package/dist/glInvertEffect.js.map +0 -1
- package/dist/glLiftGammaGainEffect.d.ts +0 -4
- package/dist/glLiftGammaGainEffect.d.ts.map +0 -1
- package/dist/glLiftGammaGainEffect.js +0 -44
- package/dist/glLiftGammaGainEffect.js.map +0 -1
- package/dist/glLookupTableGradeEffect.d.ts +0 -4
- package/dist/glLookupTableGradeEffect.d.ts.map +0 -1
- package/dist/glLookupTableGradeEffect.js +0 -28
- package/dist/glLookupTableGradeEffect.js.map +0 -1
- package/dist/glSepiaEffect.d.ts +0 -4
- package/dist/glSepiaEffect.d.ts.map +0 -1
- package/dist/glSepiaEffect.js +0 -29
- package/dist/glSepiaEffect.js.map +0 -1
- package/src/glBrightnessContrastEffect.test.ts +0 -16
- package/src/glChannelMixerEffect.test.ts +0 -13
- package/src/glColorGradeEffect.test.ts +0 -13
- package/src/glExposureEffect.test.ts +0 -13
- package/src/glGrayscaleEffect.test.ts +0 -13
- package/src/glHueSaturationEffect.test.ts +0 -13
- package/src/glInvertEffect.test.ts +0 -13
- package/src/glLiftGammaGainEffect.test.ts +0 -13
- package/src/glLookupTableGradeEffect.test.ts +0 -13
- package/src/glSepiaEffect.test.ts +0 -13
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { BevelEffect, GlRenderEffectRunner, GlRenderState, GlRenderTarget, GlRenderTargetPool } from '@flighthq/types';
|
|
2
|
+
export declare function applyBevelEffectToGl(state: GlRenderState, source: Readonly<GlRenderTarget>, dest: Readonly<GlRenderTarget>, pool: GlRenderTargetPool, effect: Readonly<BevelEffect>): void;
|
|
3
|
+
export declare const defaultGlBevelEffectRunner: GlRenderEffectRunner;
|
|
4
|
+
//# sourceMappingURL=glBevelEffect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glBevelEffect.d.ts","sourceRoot":"","sources":["../src/glBevelEffect.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,WAAW,EAEX,oBAAoB,EACpB,aAAa,EACb,cAAc,EACd,kBAAkB,EACnB,MAAM,iBAAiB,CAAC;AAqBzB,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,EAChC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC9B,IAAI,EAAE,kBAAkB,EACxB,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,GAC5B,IAAI,CAoDN;AAED,eAAO,MAAM,0BAA0B,EAAE,oBAExC,CAAC"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { acquireGlRenderTarget, clearGlRenderTarget, compileGlFullscreenProgram, drawGlFullscreenPass, releaseGlRenderTarget, } from '@flighthq/render-gl';
|
|
2
|
+
import { applyGlEffectBlitPass } from './glEffectBlitShader';
|
|
3
|
+
import { applyGlEffectBoxBlur } from './glEffectBoxBlur';
|
|
4
|
+
import { applyGlEffectTintPass } from './glEffectTintShader';
|
|
5
|
+
// Bevel composite effect: the directional gradient of the blurred silhouette drives a highlight/shadow edge band, clipped by bevelType and composited over the source.
|
|
6
|
+
// Full-frame realization: acquires the recipe's three scratch targets from the effect pool, runs the
|
|
7
|
+
// inlined multi-pass recipe, then releases them.
|
|
8
|
+
//
|
|
9
|
+
// The bevel is the directional gradient of the source's blurred alpha:
|
|
10
|
+
// `gradient = m(p − L) − m(p + L)` where `m` is the blurred alpha and
|
|
11
|
+
// `L = (cos angle, sin angle) · distance`. A positive gradient (the edge facing
|
|
12
|
+
// the light) draws the highlight color; a negative gradient draws the shadow
|
|
13
|
+
// color; `|gradient| · strength` is the band's alpha. The resulting tinted mask
|
|
14
|
+
// is composited over the source — matching `bevelSurface` (the CPU reference).
|
|
15
|
+
//
|
|
16
|
+
// `bevelType` clips the mask:
|
|
17
|
+
// - `'inner'` (default): keep the band inside the shape (× source alpha)
|
|
18
|
+
// - `'outer'`: keep it outside the shape (× 1 − source alpha)
|
|
19
|
+
// - `'full'`: no clip
|
|
20
|
+
export function applyBevelEffectToGl(state, source, dest, pool, effect) {
|
|
21
|
+
const descriptor = { width: source.width, height: source.height, format: source.format };
|
|
22
|
+
const s0 = acquireGlRenderTarget(state, pool, descriptor);
|
|
23
|
+
const s1 = acquireGlRenderTarget(state, pool, descriptor);
|
|
24
|
+
const s2 = acquireGlRenderTarget(state, pool, descriptor);
|
|
25
|
+
const src = source;
|
|
26
|
+
const dst = dest;
|
|
27
|
+
const angle = ((effect.angle ?? 45) * Math.PI) / 180;
|
|
28
|
+
const distance = effect.distance ?? 4;
|
|
29
|
+
// Match the surface reference, which snaps the light offset to whole pixels.
|
|
30
|
+
const offsetX = Math.round(Math.cos(angle) * distance);
|
|
31
|
+
const offsetY = Math.round(Math.sin(angle) * distance);
|
|
32
|
+
const shadowColor = effect.shadowColor ?? 0x000000;
|
|
33
|
+
const shadowAlpha = effect.shadowAlpha ?? 1;
|
|
34
|
+
const highlightColor = effect.highlightColor ?? 0xffffff;
|
|
35
|
+
const highlightAlpha = effect.highlightAlpha ?? 1;
|
|
36
|
+
const strength = effect.strength ?? 1;
|
|
37
|
+
const quality = Math.max(1, Math.round(effect.quality ?? 1));
|
|
38
|
+
const knockout = effect.knockout ?? false;
|
|
39
|
+
const bevelType = effect.bevelType ?? 'inner';
|
|
40
|
+
const [tinted, blurred, blurTemp] = [s0, s1, s2];
|
|
41
|
+
// Blurred alpha field (neutral white tint, strength 1 — strength is the gradient
|
|
42
|
+
// intensity applied per-pixel in the composite, not baked into the field).
|
|
43
|
+
applyGlEffectTintPass(state, src, tinted, 0xffffff, 1, 1);
|
|
44
|
+
applyGlEffectBoxBlur(state, tinted, blurred, blurTemp, {
|
|
45
|
+
blurX: effect.blurX ?? 4,
|
|
46
|
+
blurY: effect.blurY ?? 4,
|
|
47
|
+
passes: quality,
|
|
48
|
+
});
|
|
49
|
+
clearGlRenderTarget(state, dst);
|
|
50
|
+
if (!knockout)
|
|
51
|
+
applyGlEffectBlitPass(state, src, dst);
|
|
52
|
+
applyGlBevelCompositePass(state, blurred, src, dst, {
|
|
53
|
+
offsetX: offsetX / src.width,
|
|
54
|
+
// Negate Y to match the screen-space-Y-down offset convention used by applyGlEffectBlitOffsetPass.
|
|
55
|
+
offsetY: -offsetY / src.height,
|
|
56
|
+
highlightColor,
|
|
57
|
+
highlightAlpha,
|
|
58
|
+
shadowColor,
|
|
59
|
+
shadowAlpha,
|
|
60
|
+
intensity: strength,
|
|
61
|
+
clipMode: bevelType === 'inner' ? 1 : bevelType === 'outer' ? 2 : 0,
|
|
62
|
+
});
|
|
63
|
+
releaseGlRenderTarget(pool, s0);
|
|
64
|
+
releaseGlRenderTarget(pool, s1);
|
|
65
|
+
releaseGlRenderTarget(pool, s2);
|
|
66
|
+
}
|
|
67
|
+
export const defaultGlBevelEffectRunner = (ctx, effect) => {
|
|
68
|
+
applyBevelEffectToGl(ctx.state, ctx.source, ctx.dest, ctx.pool, effect);
|
|
69
|
+
};
|
|
70
|
+
// Reads the blurred alpha field (unit 0) and source (unit 1); writes the tinted, clipped bevel mask,
|
|
71
|
+
// premultiplied, blended over `dest` (which already holds the source unless knockout).
|
|
72
|
+
const BEVEL_COMPOSITE_FRAGMENT_SRC = `#version 300 es
|
|
73
|
+
precision mediump float;
|
|
74
|
+
in vec2 v_texCoord;
|
|
75
|
+
uniform sampler2D u_texture0;
|
|
76
|
+
uniform sampler2D u_texture1;
|
|
77
|
+
uniform vec4 u_highlight;
|
|
78
|
+
uniform vec4 u_shadow;
|
|
79
|
+
uniform vec2 u_offset;
|
|
80
|
+
uniform float u_intensity;
|
|
81
|
+
uniform float u_clipMode;
|
|
82
|
+
out vec4 fragColor;
|
|
83
|
+
|
|
84
|
+
float sampleField(vec2 uv) {
|
|
85
|
+
if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) return 0.0;
|
|
86
|
+
return texture(u_texture0, uv).a;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
void main() {
|
|
90
|
+
float lit = sampleField(v_texCoord - u_offset);
|
|
91
|
+
float shade = sampleField(v_texCoord + u_offset);
|
|
92
|
+
float gradient = lit - shade;
|
|
93
|
+
float srcA = texture(u_texture1, v_texCoord).a;
|
|
94
|
+
bool isHighlight = gradient >= 0.0;
|
|
95
|
+
vec3 color = isHighlight ? u_highlight.rgb : u_shadow.rgb;
|
|
96
|
+
float colorAlpha = isHighlight ? u_highlight.a : u_shadow.a;
|
|
97
|
+
float clip = 1.0;
|
|
98
|
+
if (u_clipMode == 1.0) { clip = srcA; }
|
|
99
|
+
else if (u_clipMode == 2.0) { clip = 1.0 - srcA; }
|
|
100
|
+
float edge = min(1.0, abs(gradient) * u_intensity);
|
|
101
|
+
float a = edge * colorAlpha * clip;
|
|
102
|
+
fragColor = vec4(color * a, a);
|
|
103
|
+
}`;
|
|
104
|
+
const bevelCompositeShaders = new WeakMap();
|
|
105
|
+
function applyGlBevelCompositePass(state, field, source, dest, params) {
|
|
106
|
+
const loc = getGlBevelCompositeShader(state);
|
|
107
|
+
drawGlFullscreenPass(state, loc, [field.texture, source.texture], dest, (gl) => {
|
|
108
|
+
gl.uniform4f(loc.locHighlight, ((params.highlightColor >> 16) & 0xff) / 255, ((params.highlightColor >> 8) & 0xff) / 255, (params.highlightColor & 0xff) / 255, params.highlightAlpha);
|
|
109
|
+
gl.uniform4f(loc.locShadow, ((params.shadowColor >> 16) & 0xff) / 255, ((params.shadowColor >> 8) & 0xff) / 255, (params.shadowColor & 0xff) / 255, params.shadowAlpha);
|
|
110
|
+
gl.uniform2f(loc.locOffset, params.offsetX, params.offsetY);
|
|
111
|
+
gl.uniform1f(loc.locIntensity, params.intensity);
|
|
112
|
+
gl.uniform1f(loc.locClipMode, params.clipMode);
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
function getGlBevelCompositeShader(state) {
|
|
116
|
+
let loc = bevelCompositeShaders.get(state);
|
|
117
|
+
if (loc === undefined) {
|
|
118
|
+
const gl = state.gl;
|
|
119
|
+
const base = compileGlFullscreenProgram(gl, BEVEL_COMPOSITE_FRAGMENT_SRC);
|
|
120
|
+
loc = {
|
|
121
|
+
...base,
|
|
122
|
+
locHighlight: gl.getUniformLocation(base.program, 'u_highlight'),
|
|
123
|
+
locShadow: gl.getUniformLocation(base.program, 'u_shadow'),
|
|
124
|
+
locOffset: gl.getUniformLocation(base.program, 'u_offset'),
|
|
125
|
+
locIntensity: gl.getUniformLocation(base.program, 'u_intensity'),
|
|
126
|
+
locClipMode: gl.getUniformLocation(base.program, 'u_clipMode'),
|
|
127
|
+
};
|
|
128
|
+
bevelCompositeShaders.set(state, loc);
|
|
129
|
+
}
|
|
130
|
+
return loc;
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=glBevelEffect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glBevelEffect.js","sourceRoot":"","sources":["../src/glBevelEffect.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"glBloomEffect.d.ts","sourceRoot":"","sources":["../src/glBloomEffect.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"glBloomEffect.d.ts","sourceRoot":"","sources":["../src/glBloomEffect.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,WAAW,EACX,oBAAoB,EACpB,aAAa,EACb,cAAc,EACd,kBAAkB,EACnB,MAAM,iBAAiB,CAAC;AAQzB,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,EAChC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC9B,IAAI,EAAE,kBAAkB,EACxB,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,GAC5B,IAAI,CAyBN;AAED,eAAO,MAAM,0BAA0B,EAAE,oBAExC,CAAC"}
|
package/dist/glBloomEffect.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { computeBloomBlurRadius, computeBloomIntensity, computeBloomThreshold } from '@flighthq/effects';
|
|
2
|
-
import { applyGaussianBlurFilterToGl } from '@flighthq/filters-gl';
|
|
3
2
|
import { acquireGlRenderTarget, drawGlFullscreenPass, releaseGlRenderTarget } from '@flighthq/render-gl';
|
|
3
|
+
import { applyGaussianBlurToGl } from './glBlurEffect';
|
|
4
4
|
import { getGlEffectProgram } from './glEffectProgramCache';
|
|
5
|
-
// Bloom: bright-pass → blur the bright branch (
|
|
6
|
-
// composite back. The multi-pass reference recipe — it acquires intermediate targets from
|
|
7
|
-
// and releases them, branches, and reuses
|
|
5
|
+
// Bloom: bright-pass → blur the bright branch (via the effects-owned separable gaussian blur) →
|
|
6
|
+
// additively composite back. The multi-pass reference recipe — it acquires intermediate targets from
|
|
7
|
+
// the pool and releases them, branches, and reuses the blur primitive, which is what makes it an effect.
|
|
8
8
|
export function applyBloomEffectToGl(state, source, dest, pool, effect) {
|
|
9
9
|
const threshold = computeBloomThreshold(effect);
|
|
10
10
|
const intensity = computeBloomIntensity(effect);
|
|
@@ -17,7 +17,7 @@ export function applyBloomEffectToGl(state, source, dest, pool, effect) {
|
|
|
17
17
|
drawGlFullscreenPass(state, brightProgram, [source.texture], bright, (gl, program) => {
|
|
18
18
|
gl.uniform1f(gl.getUniformLocation(program.program, 'u_threshold'), threshold);
|
|
19
19
|
});
|
|
20
|
-
|
|
20
|
+
applyGaussianBlurToGl(state, bright, blurred, temp, { blurX: radius, blurY: radius });
|
|
21
21
|
const compositeProgram = getGlEffectProgram(state, 'bloom.composite', BLOOM_COMPOSITE_FRAGMENT_SRC);
|
|
22
22
|
drawGlFullscreenPass(state, compositeProgram, [source.texture, blurred.texture], dest, (gl, program) => {
|
|
23
23
|
gl.uniform1f(gl.getUniformLocation(program.program, 'u_intensity'), intensity);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"glBloomEffect.js","sourceRoot":"","sources":["../src/glBloomEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AACzG,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"glBloomEffect.js","sourceRoot":"","sources":["../src/glBloomEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AACzG,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AASzG,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,gGAAgG;AAChG,qGAAqG;AACrG,yGAAyG;AACzG,MAAM,UAAU,oBAAoB,CAClC,KAAoB,EACpB,MAAgC,EAChC,IAA8B,EAC9B,IAAwB,EACxB,MAA6B;IAE7B,MAAM,SAAS,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,SAAS,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,UAAU,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;IAEzF,MAAM,MAAM,GAAG,qBAAqB,CAAC,KAAK,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAG,qBAAqB,CAAC,KAAK,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;IAC/D,MAAM,IAAI,GAAG,qBAAqB,CAAC,KAAK,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;IAE5D,MAAM,aAAa,GAAG,kBAAkB,CAAC,KAAK,EAAE,cAAc,EAAE,yBAAyB,CAAC,CAAC;IAC3F,oBAAoB,CAAC,KAAK,EAAE,aAAa,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE;QACnF,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,OAAO,CAAC,OAAO,EAAE,aAAa,CAAC,EAAE,SAAS,CAAC,CAAC;IACjF,CAAC,CAAC,CAAC;IAEH,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAEtF,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,EAAE,4BAA4B,CAAC,CAAC;IACpG,oBAAoB,CAAC,KAAK,EAAE,gBAAgB,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE;QACrG,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,OAAO,CAAC,OAAO,EAAE,aAAa,CAAC,EAAE,SAAS,CAAC,CAAC;IACjF,CAAC,CAAC,CAAC;IAEH,qBAAqB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACpC,qBAAqB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACrC,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,CAAC,MAAM,0BAA0B,GAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IAC9E,oBAAoB,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,MAAqB,CAAC,CAAC;AACzF,CAAC,CAAC;AAEF,MAAM,yBAAyB,GAAG;;;;;;;;;;;EAWhC,CAAC;AAEH,MAAM,4BAA4B,GAAG;;;;;;;;;;;EAWnC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { BlurEffect, GlRenderEffectRunner, GlRenderState, GlRenderTarget } from '@flighthq/types';
|
|
2
|
+
export declare function applyBlurEffectToGl(state: GlRenderState, source: Readonly<GlRenderTarget>, dest: Readonly<GlRenderTarget>, temp: Readonly<GlRenderTarget>, effect: Readonly<BlurEffect>): void;
|
|
3
|
+
export declare function applyGaussianBlurToGl(state: GlRenderState, source: Readonly<GlRenderTarget>, dest: Readonly<GlRenderTarget>, temp: Readonly<GlRenderTarget>, options: Readonly<{
|
|
4
|
+
blurX?: number;
|
|
5
|
+
blurY?: number;
|
|
6
|
+
}>): void;
|
|
7
|
+
export declare const defaultGlBlurEffectRunner: GlRenderEffectRunner;
|
|
8
|
+
//# sourceMappingURL=glBlurEffect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glBlurEffect.d.ts","sourceRoot":"","sources":["../src/glBlurEffect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAYvG,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,EAChC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC9B,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC9B,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,GAC3B,IAAI,CAEN;AAMD,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,EAChC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC9B,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC9B,OAAO,EAAE,QAAQ,CAAC;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GACpD,IAAI,CAON;AAED,eAAO,MAAM,yBAAyB,EAAE,oBAKvC,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { acquireGlRenderTarget, drawGlFullscreenPass, releaseGlRenderTarget } from '@flighthq/render-gl';
|
|
2
|
+
import { getGlEffectProgram, getGlEffectUniformLocation } from './glEffectProgramCache';
|
|
3
|
+
// Plain separable Gaussian blur: two axis passes (source → temp horizontally, temp → dest vertically),
|
|
4
|
+
// each a single weighted fullscreen pass with radius ⌈3σ⌉. `blurX`/`blurY` are the Gaussian standard
|
|
5
|
+
// deviations (CSS `blur(Xpx)` uses sigma = X), so this matches the CSS and surface Gaussian references.
|
|
6
|
+
// The effects-owned blur primitive — the shared gaussian pass BloomEffect and the plain BlurEffect both
|
|
7
|
+
// use, so the effects backend owns its blur outright rather than delegating to a filters backend.
|
|
8
|
+
// Applies a `BlurEffect` descriptor to `source`, writing to `dest`. `temp` is a ping-pong scratch
|
|
9
|
+
// target distinct from both `source` and `dest`.
|
|
10
|
+
export function applyBlurEffectToGl(state, source, dest, temp, effect) {
|
|
11
|
+
applyGaussianBlurToGl(state, source, dest, temp, { blurX: effect.blurX, blurY: effect.blurY });
|
|
12
|
+
}
|
|
13
|
+
// Applies a faithful separable Gaussian blur to `source`, writing to `dest`. `blurX`/`blurY` are the
|
|
14
|
+
// Gaussian standard deviations in pixels (default 4). Runs two unconditional separable passes,
|
|
15
|
+
// source → temp (X) then temp → dest (Y); a zero-radius axis copies through unchanged, so the result
|
|
16
|
+
// always lands in `dest` without a separate blit. `temp` is a ping-pong scratch distinct from both.
|
|
17
|
+
export function applyGaussianBlurToGl(state, source, dest, temp, options) {
|
|
18
|
+
const sigmaX = options.blurX ?? 4;
|
|
19
|
+
const sigmaY = options.blurY ?? 4;
|
|
20
|
+
const radiusX = sigmaX > 0 ? Math.ceil(sigmaX * 3) : 0;
|
|
21
|
+
const radiusY = sigmaY > 0 ? Math.ceil(sigmaY * 3) : 0;
|
|
22
|
+
applyGlGaussianBlurPass(state, source, temp, sigmaX, radiusX, 1, 0);
|
|
23
|
+
applyGlGaussianBlurPass(state, temp, dest, sigmaY, radiusY, 0, 1);
|
|
24
|
+
}
|
|
25
|
+
export const defaultGlBlurEffectRunner = (ctx, effect) => {
|
|
26
|
+
const descriptor = { width: ctx.source.width, height: ctx.source.height, format: ctx.source.format };
|
|
27
|
+
const temp = acquireGlRenderTarget(ctx.state, ctx.pool, descriptor);
|
|
28
|
+
applyBlurEffectToGl(ctx.state, ctx.source, ctx.dest, temp, effect);
|
|
29
|
+
releaseGlRenderTarget(ctx.pool, temp);
|
|
30
|
+
};
|
|
31
|
+
function applyGlGaussianBlurPass(state, source, dest, sigma, radius, dirX, dirY) {
|
|
32
|
+
const program = getGlEffectProgram(state, 'blur.gaussian', GAUSSIAN_BLUR_FRAGMENT_SRC);
|
|
33
|
+
drawGlFullscreenPass(state, program, [source.texture], dest, (gl, p) => {
|
|
34
|
+
gl.uniform2f(getGlEffectUniformLocation(state, p, 'u_texelSize'), 1 / source.width, 1 / source.height);
|
|
35
|
+
gl.uniform1f(getGlEffectUniformLocation(state, p, 'u_sigma'), sigma);
|
|
36
|
+
gl.uniform1f(getGlEffectUniformLocation(state, p, 'u_radius'), radius);
|
|
37
|
+
gl.uniform2f(getGlEffectUniformLocation(state, p, 'u_direction'), dirX, dirY);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
const GAUSSIAN_BLUR_FRAGMENT_SRC = `#version 300 es
|
|
41
|
+
precision mediump float;
|
|
42
|
+
in vec2 v_texCoord;
|
|
43
|
+
uniform sampler2D u_texture0;
|
|
44
|
+
uniform vec2 u_texelSize;
|
|
45
|
+
uniform float u_sigma;
|
|
46
|
+
uniform float u_radius;
|
|
47
|
+
uniform vec2 u_direction;
|
|
48
|
+
out vec4 o_color;
|
|
49
|
+
void main() {
|
|
50
|
+
int r = max(0, int(u_radius));
|
|
51
|
+
if (r == 0) {
|
|
52
|
+
o_color = texture(u_texture0, v_texCoord);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
float twoSigmaSq = 2.0 * u_sigma * u_sigma;
|
|
56
|
+
vec4 sum = vec4(0.0);
|
|
57
|
+
float weightSum = 0.0;
|
|
58
|
+
for (int i = -r; i <= r; i++) {
|
|
59
|
+
float w = exp(-float(i * i) / twoSigmaSq);
|
|
60
|
+
sum += w * texture(u_texture0, v_texCoord + float(i) * u_texelSize * u_direction);
|
|
61
|
+
weightSum += w;
|
|
62
|
+
}
|
|
63
|
+
o_color = sum / weightSum;
|
|
64
|
+
}`;
|
|
65
|
+
//# sourceMappingURL=glBlurEffect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glBlurEffect.js","sourceRoot":"","sources":["../src/glBlurEffect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { ColorLut, GlColorLutTextureCache, GlRenderState, GlRenderTarget } from '@flighthq/types';
|
|
2
|
+
export declare function applyColorLutPassToGl(state: GlRenderState, source: Readonly<GlRenderTarget>, dest: Readonly<GlRenderTarget>, lut: Readonly<ColorLut>, cache: GlColorLutTextureCache): void;
|
|
3
|
+
//# sourceMappingURL=glColorLutPass.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glColorLutPass.d.ts","sourceRoot":"","sources":["../src/glColorLutPass.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,sBAAsB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAavG,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,EAChC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC9B,GAAG,EAAE,QAAQ,CAAC,QAAQ,CAAC,EACvB,KAAK,EAAE,sBAAsB,GAC5B,IAAI,CAYN"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { drawGlFullscreenPass } from '@flighthq/render-gl';
|
|
2
|
+
import { getGlEffectProgram } from './glEffectProgramCache';
|
|
3
|
+
// Generic pointwise color-LUT pass — the single fold-in realization for the whole LUT-tier Adjustment
|
|
4
|
+
// family on WebGL 2. A run of consecutive pointwise adjustments containing any nonlinear (LUT-tier)
|
|
5
|
+
// member bakes to ONE 3D `ColorLut` (matrices folded in) and runs through this one trilinear pass instead
|
|
6
|
+
// of one pass per op. The LUT is uploaded as a `size³` RGBA8 3D texture; hardware LINEAR filtering does
|
|
7
|
+
// the trilinear interpolation. Sampled color is treated as premultiplied and passed straight into the
|
|
8
|
+
// LUT (matching the per-op color passes this replaces); alpha is preserved. `cache` owns the uploaded 3D
|
|
9
|
+
// texture across frames; the LUT is re-uploaded only when it differs by identity from the last one baked
|
|
10
|
+
// into `cache` (bakeColorLutForRun returns a stable reference for an unchanged run), so a static grade
|
|
11
|
+
// uploads once. The caller owns `cache.texture` and destroys it on teardown.
|
|
12
|
+
export function applyColorLutPassToGl(state, source, dest, lut, cache) {
|
|
13
|
+
const gl = state.gl;
|
|
14
|
+
const size = lut.size;
|
|
15
|
+
const texture = uploadLutTexture(gl, lut, cache);
|
|
16
|
+
const program = getGlEffectProgram(state, 'adjustment.colorLut', COLOR_LUT_FRAGMENT_SRC);
|
|
17
|
+
drawGlFullscreenPass(state, program, [source.texture], dest, (glc, p) => {
|
|
18
|
+
glc.uniform1f(glc.getUniformLocation(p.program, 'u_lutSize'), size);
|
|
19
|
+
glc.activeTexture(glc.TEXTURE1);
|
|
20
|
+
glc.bindTexture(glc.TEXTURE_3D, texture);
|
|
21
|
+
glc.uniform1i(glc.getUniformLocation(p.program, 'u_lut'), 1);
|
|
22
|
+
glc.activeTexture(glc.TEXTURE0);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
// Uploads `lut` into the cache's reusable 3D texture (RGBA8, LINEAR, clamp-to-edge) and returns it. The
|
|
26
|
+
// upload is skipped entirely when `lut` is the same reference already baked into the texture — the common
|
|
27
|
+
// static-grade case — so an unchanged grade costs one texImage3D total, not one per frame.
|
|
28
|
+
function uploadLutTexture(gl, lut, cache) {
|
|
29
|
+
if (cache.texture !== null && cache.lut === lut)
|
|
30
|
+
return cache.texture;
|
|
31
|
+
const n = lut.size;
|
|
32
|
+
const samples = lut.samples;
|
|
33
|
+
const data = new Uint8Array(n * n * n * 4);
|
|
34
|
+
for (let i = 0, j = 0, o = 0; i < n * n * n; i++) {
|
|
35
|
+
data[o++] = Math.round(clamp01(samples[j++]) * 255);
|
|
36
|
+
data[o++] = Math.round(clamp01(samples[j++]) * 255);
|
|
37
|
+
data[o++] = Math.round(clamp01(samples[j++]) * 255);
|
|
38
|
+
data[o++] = 255;
|
|
39
|
+
}
|
|
40
|
+
let texture = cache.texture;
|
|
41
|
+
if (texture === null) {
|
|
42
|
+
texture = gl.createTexture();
|
|
43
|
+
cache.texture = texture;
|
|
44
|
+
}
|
|
45
|
+
gl.bindTexture(gl.TEXTURE_3D, texture);
|
|
46
|
+
gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, n, n, n, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
|
|
47
|
+
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
48
|
+
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
49
|
+
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
50
|
+
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
51
|
+
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDGE);
|
|
52
|
+
gl.bindTexture(gl.TEXTURE_3D, null);
|
|
53
|
+
cache.lut = lut;
|
|
54
|
+
return texture;
|
|
55
|
+
}
|
|
56
|
+
function clamp01(v) {
|
|
57
|
+
return v < 0 ? 0 : v > 1 ? 1 : v;
|
|
58
|
+
}
|
|
59
|
+
// Half-texel scale/offset maps the [0,1] color to LUT cell centres, so v=0 hits cell 0 and v=1 the last.
|
|
60
|
+
const COLOR_LUT_FRAGMENT_SRC = `#version 300 es
|
|
61
|
+
precision highp float;
|
|
62
|
+
precision highp sampler3D;
|
|
63
|
+
in vec2 v_texCoord;
|
|
64
|
+
uniform sampler2D u_texture0;
|
|
65
|
+
uniform sampler3D u_lut;
|
|
66
|
+
uniform float u_lutSize;
|
|
67
|
+
out vec4 o_color;
|
|
68
|
+
void main() {
|
|
69
|
+
vec4 c = texture(u_texture0, v_texCoord);
|
|
70
|
+
float scale = (u_lutSize - 1.0) / u_lutSize;
|
|
71
|
+
float offset = 0.5 / u_lutSize;
|
|
72
|
+
vec3 lc = clamp(c.rgb, 0.0, 1.0) * scale + offset;
|
|
73
|
+
o_color = vec4(texture(u_lut, lc).rgb, c.a);
|
|
74
|
+
}`;
|
|
75
|
+
//# sourceMappingURL=glColorLutPass.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glColorLutPass.js","sourceRoot":"","sources":["../src/glColorLutPass.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { GlRenderState, GlRenderTarget } from '@flighthq/types';
|
|
2
|
+
export declare function applyColorMatrixPassToGl(state: GlRenderState, source: Readonly<GlRenderTarget>, dest: Readonly<GlRenderTarget>, matrix: ReadonlyArray<number>): void;
|
|
3
|
+
//# sourceMappingURL=glColorMatrixPass.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glColorMatrixPass.d.ts","sourceRoot":"","sources":["../src/glColorMatrixPass.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AASrE,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,EAChC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC9B,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,GAC5B,IAAI,CAON"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { drawGlFullscreenPass } from '@flighthq/render-gl';
|
|
2
|
+
import { getGlEffectProgram } from './glEffectProgramCache';
|
|
3
|
+
// Generic pointwise color-matrix pass — the single fold-in realization for the whole matrix-tier
|
|
4
|
+
// Adjustment family. A run of consecutive matrix-tier adjustments fuses to ONE 4×5 matrix (in the
|
|
5
|
+
// adjustments colorMatrixMath convention: linear RGBA coefficients + a 0–255 offset column) and runs
|
|
6
|
+
// through this one pass instead of one pass per op. Sampled color is treated as premultiplied and the
|
|
7
|
+
// RGB result is clamped, matching the per-op color passes this replaces.
|
|
8
|
+
export function applyColorMatrixPassToGl(state, source, dest, matrix) {
|
|
9
|
+
const m = new Float32Array(20);
|
|
10
|
+
for (let i = 0; i < 20; i++)
|
|
11
|
+
m[i] = matrix[i] ?? 0;
|
|
12
|
+
const program = getGlEffectProgram(state, 'adjustment.colorMatrix', COLOR_MATRIX_FRAGMENT_SRC);
|
|
13
|
+
drawGlFullscreenPass(state, program, [source.texture], dest, (gl, p) => {
|
|
14
|
+
gl.uniform1fv(gl.getUniformLocation(p.program, 'u_colorMatrix'), m);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
// The offset column (indices 4, 9, 14, 19) is 0–255; normalized color needs it divided by 255.
|
|
18
|
+
const COLOR_MATRIX_FRAGMENT_SRC = `#version 300 es
|
|
19
|
+
precision highp float;
|
|
20
|
+
in vec2 v_texCoord;
|
|
21
|
+
uniform sampler2D u_texture0;
|
|
22
|
+
uniform float u_colorMatrix[20];
|
|
23
|
+
out vec4 o_color;
|
|
24
|
+
void main() {
|
|
25
|
+
vec4 c = texture(u_texture0, v_texCoord);
|
|
26
|
+
float r = c.r, g = c.g, b = c.b, a = c.a;
|
|
27
|
+
float nr = u_colorMatrix[0] * r + u_colorMatrix[1] * g + u_colorMatrix[2] * b + u_colorMatrix[3] * a + u_colorMatrix[4] / 255.0;
|
|
28
|
+
float ng = u_colorMatrix[5] * r + u_colorMatrix[6] * g + u_colorMatrix[7] * b + u_colorMatrix[8] * a + u_colorMatrix[9] / 255.0;
|
|
29
|
+
float nb = u_colorMatrix[10] * r + u_colorMatrix[11] * g + u_colorMatrix[12] * b + u_colorMatrix[13] * a + u_colorMatrix[14] / 255.0;
|
|
30
|
+
float na = u_colorMatrix[15] * r + u_colorMatrix[16] * g + u_colorMatrix[17] * b + u_colorMatrix[18] * a + u_colorMatrix[19] / 255.0;
|
|
31
|
+
o_color = vec4(clamp(vec3(nr, ng, nb), 0.0, 1.0), na);
|
|
32
|
+
}`;
|
|
33
|
+
//# sourceMappingURL=glColorMatrixPass.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glColorMatrixPass.js","sourceRoot":"","sources":["../src/glColorMatrixPass.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAG3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,iGAAiG;AACjG,kGAAkG;AAClG,qGAAqG;AACrG,sGAAsG;AACtG,yEAAyE;AACzE,MAAM,UAAU,wBAAwB,CACtC,KAAoB,EACpB,MAAgC,EAChC,IAA8B,EAC9B,MAA6B;IAE7B,MAAM,CAAC,GAAG,IAAI,YAAY,CAAC,EAAE,CAAC,CAAC;IAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE;QAAE,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,EAAE,wBAAwB,EAAE,yBAAyB,CAAC,CAAC;IAC/F,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE;QACrE,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,eAAe,CAAC,EAAE,CAAC,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;AACL,CAAC;AAED,+FAA+F;AAC/F,MAAM,yBAAyB,GAAG;;;;;;;;;;;;;;EAchC,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ConvolutionEffect, GlRenderEffectRunner, GlRenderState, GlRenderTarget } from '@flighthq/types';
|
|
2
|
+
export declare const MAX_CONVOLUTION_EFFECT_GL_KERNEL_SIZE = 49;
|
|
3
|
+
export declare function applyConvolutionEffectToGl(state: GlRenderState, source: Readonly<GlRenderTarget>, dest: Readonly<GlRenderTarget>, effect: Readonly<ConvolutionEffect>): void;
|
|
4
|
+
export declare const defaultGlConvolutionEffectRunner: GlRenderEffectRunner;
|
|
5
|
+
//# sourceMappingURL=glConvolutionEffect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glConvolutionEffect.d.ts","sourceRoot":"","sources":["../src/glConvolutionEffect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAM9G,eAAO,MAAM,qCAAqC,KAAK,CAAC;AAIxD,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,EAChC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC9B,MAAM,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAClC,IAAI,CAkCN;AAED,eAAO,MAAM,gCAAgC,EAAE,oBAE9C,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { drawGlFullscreenPass } from '@flighthq/render-gl';
|
|
2
|
+
import { getGlEffectProgram } from './glEffectProgramCache';
|
|
3
|
+
// Largest kernel the WebGL path supports (a 7×7). The cap is the fixed uniform-array size in the
|
|
4
|
+
// fragment shader; larger kernels are unsupported on this backend.
|
|
5
|
+
export const MAX_CONVOLUTION_EFFECT_GL_KERNEL_SIZE = 49;
|
|
6
|
+
// Generic matrix-kernel convolution: each output pixel is the weighted sum of its matrixX×matrixY
|
|
7
|
+
// neighborhood, normalized by `divisor` (defaults to the matrix sum) and offset by `bias`.
|
|
8
|
+
export function applyConvolutionEffectToGl(state, source, dest, effect) {
|
|
9
|
+
const { matrix, matrixX, matrixY } = effect;
|
|
10
|
+
if (matrixX <= 0 || matrixY <= 0)
|
|
11
|
+
throw new Error('Convolution matrix dimensions must be positive');
|
|
12
|
+
if (matrixX * matrixY > MAX_CONVOLUTION_EFFECT_GL_KERNEL_SIZE)
|
|
13
|
+
throw new Error(`Convolution kernel exceeds the WebGL maximum of 7×7 (${matrixX}×${matrixY} given)`);
|
|
14
|
+
if (matrix.length < matrixX * matrixY)
|
|
15
|
+
throw new Error('Convolution matrix does not match its declared dimensions');
|
|
16
|
+
const bias = effect.bias ?? 0;
|
|
17
|
+
const clampEdge = effect.clamp ?? true;
|
|
18
|
+
const preserveAlpha = effect.preserveAlpha ?? true;
|
|
19
|
+
const edgeColor = effect.color ?? 0;
|
|
20
|
+
const divisor = effect.divisor ?? getAutoDivisor(matrix, matrixX * matrixY);
|
|
21
|
+
const matrixData = new Float32Array(MAX_CONVOLUTION_EFFECT_GL_KERNEL_SIZE);
|
|
22
|
+
for (let i = 0; i < matrixX * matrixY; i++)
|
|
23
|
+
matrixData[i] = matrix[i];
|
|
24
|
+
const program = getGlEffectProgram(state, 'stylization.convolution', CONVOLUTION_FRAGMENT_SRC);
|
|
25
|
+
drawGlFullscreenPass(state, program, [source.texture], dest, (gl, p) => {
|
|
26
|
+
gl.uniform2f(gl.getUniformLocation(p.program, 'u_texelSize'), 1 / source.width, 1 / source.height);
|
|
27
|
+
gl.uniform1fv(gl.getUniformLocation(p.program, 'u_matrix[0]'), matrixData);
|
|
28
|
+
gl.uniform1i(gl.getUniformLocation(p.program, 'u_matrixX'), matrixX);
|
|
29
|
+
gl.uniform1i(gl.getUniformLocation(p.program, 'u_matrixY'), matrixY);
|
|
30
|
+
gl.uniform1f(gl.getUniformLocation(p.program, 'u_divisor'), divisor);
|
|
31
|
+
gl.uniform1f(gl.getUniformLocation(p.program, 'u_bias'), bias);
|
|
32
|
+
gl.uniform1i(gl.getUniformLocation(p.program, 'u_clamp'), clampEdge ? 1 : 0);
|
|
33
|
+
gl.uniform1i(gl.getUniformLocation(p.program, 'u_preserveAlpha'), preserveAlpha ? 1 : 0);
|
|
34
|
+
gl.uniform4f(gl.getUniformLocation(p.program, 'u_edgeColor'), ((edgeColor >> 16) & 0xff) / 255, ((edgeColor >> 8) & 0xff) / 255, (edgeColor & 0xff) / 255, ((edgeColor >>> 24) & 0xff) / 255);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
export const defaultGlConvolutionEffectRunner = (ctx, effect) => {
|
|
38
|
+
applyConvolutionEffectToGl(ctx.state, ctx.source, ctx.dest, effect);
|
|
39
|
+
};
|
|
40
|
+
// Sums the kernel weights; returns 1 when the sum is 0 (e.g. an edge-detect kernel) so the divide is safe.
|
|
41
|
+
function getAutoDivisor(matrix, length) {
|
|
42
|
+
let sum = 0;
|
|
43
|
+
for (let i = 0; i < length; i++)
|
|
44
|
+
sum += matrix[i];
|
|
45
|
+
return sum === 0 ? 1 : sum;
|
|
46
|
+
}
|
|
47
|
+
const CONVOLUTION_FRAGMENT_SRC = `#version 300 es
|
|
48
|
+
precision mediump float;
|
|
49
|
+
in vec2 v_texCoord;
|
|
50
|
+
uniform sampler2D u_texture0;
|
|
51
|
+
uniform vec2 u_texelSize;
|
|
52
|
+
uniform float u_matrix[${MAX_CONVOLUTION_EFFECT_GL_KERNEL_SIZE}];
|
|
53
|
+
uniform int u_matrixX;
|
|
54
|
+
uniform int u_matrixY;
|
|
55
|
+
uniform float u_divisor;
|
|
56
|
+
uniform float u_bias;
|
|
57
|
+
uniform bool u_clamp;
|
|
58
|
+
uniform bool u_preserveAlpha;
|
|
59
|
+
uniform vec4 u_edgeColor;
|
|
60
|
+
out vec4 fragColor;
|
|
61
|
+
|
|
62
|
+
vec4 sampleAt(vec2 uv) {
|
|
63
|
+
if (u_clamp) {
|
|
64
|
+
return texture(u_texture0, clamp(uv, vec2(0.0), vec2(1.0)));
|
|
65
|
+
}
|
|
66
|
+
if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) {
|
|
67
|
+
return u_edgeColor;
|
|
68
|
+
}
|
|
69
|
+
return texture(u_texture0, uv);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
void main() {
|
|
73
|
+
int offsetX = u_matrixX / 2;
|
|
74
|
+
int offsetY = u_matrixY / 2;
|
|
75
|
+
vec4 sum = vec4(0.0);
|
|
76
|
+
for (int ky = 0; ky < u_matrixY; ky++) {
|
|
77
|
+
for (int kx = 0; kx < u_matrixX; kx++) {
|
|
78
|
+
float weight = u_matrix[ky * u_matrixX + kx];
|
|
79
|
+
vec2 off = vec2(float(kx - offsetX), float(ky - offsetY)) * u_texelSize;
|
|
80
|
+
sum += sampleAt(v_texCoord + off) * weight;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
sum /= u_divisor;
|
|
84
|
+
sum += u_bias / 255.0;
|
|
85
|
+
sum = clamp(sum, 0.0, 1.0);
|
|
86
|
+
if (u_preserveAlpha) {
|
|
87
|
+
// Keep the convolved color and restore the source alpha, matching the reference: a zero-sum
|
|
88
|
+
// kernel (e.g. edge-detect) drives the convolved alpha to 0, so overriding only .a leaves the
|
|
89
|
+
// color channels as the non-preserve branch produces them.
|
|
90
|
+
sum.a = texture(u_texture0, v_texCoord).a;
|
|
91
|
+
}
|
|
92
|
+
fragColor = sum;
|
|
93
|
+
}`;
|
|
94
|
+
//# sourceMappingURL=glConvolutionEffect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glConvolutionEffect.js","sourceRoot":"","sources":["../src/glConvolutionEffect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { DropShadowEffect, GlRenderEffectRunner, GlRenderState, GlRenderTarget, GlRenderTargetPool } from '@flighthq/types';
|
|
2
|
+
export declare function applyDropShadowEffectToGl(state: GlRenderState, source: Readonly<GlRenderTarget>, dest: Readonly<GlRenderTarget>, pool: GlRenderTargetPool, effect: Readonly<DropShadowEffect>): void;
|
|
3
|
+
export declare const defaultGlDropShadowEffectRunner: GlRenderEffectRunner;
|
|
4
|
+
//# sourceMappingURL=glDropShadowEffect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glDropShadowEffect.d.ts","sourceRoot":"","sources":["../src/glDropShadowEffect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,EACb,cAAc,EACd,kBAAkB,EACnB,MAAM,iBAAiB,CAAC;AAYzB,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,EAChC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC9B,IAAI,EAAE,kBAAkB,EACxB,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GACjC,IAAI,CA4CN;AAED,eAAO,MAAM,+BAA+B,EAAE,oBAE7C,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { acquireGlRenderTarget, clearGlRenderTarget, releaseGlRenderTarget } from '@flighthq/render-gl';
|
|
2
|
+
import { applyGlEffectBlitOffsetPass, applyGlEffectBlitPass } from './glEffectBlitShader';
|
|
3
|
+
import { applyGlEffectBoxBlur } from './glEffectBoxBlur';
|
|
4
|
+
import { applyGlEffectTintPass } from './glEffectTintShader';
|
|
5
|
+
// Drop-shadow composite effect: tint the scene silhouette, blur it, offset it by angle/distance, then composite the source over the shadow.
|
|
6
|
+
// Full-frame realization: acquires the recipe's three scratch targets from the effect pool, runs the
|
|
7
|
+
// inlined multi-pass recipe, then releases them.
|
|
8
|
+
//
|
|
9
|
+
// Compositing order: shadow at offset → source (unless `hideObject` is true).
|
|
10
|
+
// `knockout` and `hideObject` both composite the shadow alone, omitting the source object.
|
|
11
|
+
export function applyDropShadowEffectToGl(state, source, dest, pool, effect) {
|
|
12
|
+
const descriptor = { width: source.width, height: source.height, format: source.format };
|
|
13
|
+
const s0 = acquireGlRenderTarget(state, pool, descriptor);
|
|
14
|
+
const s1 = acquireGlRenderTarget(state, pool, descriptor);
|
|
15
|
+
const s2 = acquireGlRenderTarget(state, pool, descriptor);
|
|
16
|
+
const src = source;
|
|
17
|
+
const dst = dest;
|
|
18
|
+
const angle = ((effect.angle ?? 45) * Math.PI) / 180;
|
|
19
|
+
const distance = effect.distance ?? 4;
|
|
20
|
+
const dx = Math.cos(angle) * distance;
|
|
21
|
+
const dy = Math.sin(angle) * distance;
|
|
22
|
+
const color = effect.color ?? 0;
|
|
23
|
+
const alpha = effect.alpha ?? 1;
|
|
24
|
+
const strength = effect.strength ?? 1;
|
|
25
|
+
const quality = Math.max(1, Math.round(effect.quality ?? 1));
|
|
26
|
+
const hideObject = effect.hideObject ?? false;
|
|
27
|
+
const knockout = effect.knockout ?? false;
|
|
28
|
+
const tintStrength = Math.min(1, strength);
|
|
29
|
+
const shadowPasses = Math.max(1, Math.floor(strength));
|
|
30
|
+
const [mask, blurred, blurTemp] = [s0, s1, s2];
|
|
31
|
+
applyGlEffectTintPass(state, src, mask, color, alpha, tintStrength);
|
|
32
|
+
applyGlEffectBoxBlur(state, mask, blurred, blurTemp, {
|
|
33
|
+
blurX: effect.blurX ?? 4,
|
|
34
|
+
blurY: effect.blurY ?? 4,
|
|
35
|
+
passes: quality,
|
|
36
|
+
});
|
|
37
|
+
clearGlRenderTarget(state, dst);
|
|
38
|
+
for (let i = 0; i < shadowPasses; i++) {
|
|
39
|
+
applyGlEffectBlitOffsetPass(state, blurred, dst, dx, dy);
|
|
40
|
+
}
|
|
41
|
+
if (!hideObject && !knockout) {
|
|
42
|
+
applyGlEffectBlitPass(state, src, dst);
|
|
43
|
+
}
|
|
44
|
+
releaseGlRenderTarget(pool, s0);
|
|
45
|
+
releaseGlRenderTarget(pool, s1);
|
|
46
|
+
releaseGlRenderTarget(pool, s2);
|
|
47
|
+
}
|
|
48
|
+
export const defaultGlDropShadowEffectRunner = (ctx, effect) => {
|
|
49
|
+
applyDropShadowEffectToGl(ctx.state, ctx.source, ctx.dest, ctx.pool, effect);
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=glDropShadowEffect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glDropShadowEffect.js","sourceRoot":"","sources":["../src/glDropShadowEffect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { GlRenderTarget } from '@flighthq/render-gl';
|
|
2
|
+
import type { GlRenderState } from '@flighthq/types';
|
|
3
|
+
/**
|
|
4
|
+
* Blits source into dest at a pixel offset (dx, dy in screen-space Y-down).
|
|
5
|
+
* Pixels sampling outside the source bounds produce transparent output.
|
|
6
|
+
*/
|
|
7
|
+
export declare function applyGlEffectBlitOffsetPass(state: GlRenderState, source: GlRenderTarget, dest: GlRenderTarget, dx: number, dy: number): void;
|
|
8
|
+
/** Blits source directly into dest without modification. */
|
|
9
|
+
export declare function applyGlEffectBlitPass(state: GlRenderState, source: GlRenderTarget, dest: GlRenderTarget): void;
|
|
10
|
+
//# sourceMappingURL=glEffectBlitShader.d.ts.map
|