@flighthq/effects-gl 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/glBloomEffect.d.ts +4 -0
- package/dist/glBloomEffect.d.ts.map +1 -0
- package/dist/glBloomEffect.js +56 -0
- package/dist/glBloomEffect.js.map +1 -0
- package/dist/glBokehDepthOfFieldEffect.d.ts +4 -0
- package/dist/glBokehDepthOfFieldEffect.d.ts.map +1 -0
- package/dist/glBokehDepthOfFieldEffect.js +55 -0
- package/dist/glBokehDepthOfFieldEffect.js.map +1 -0
- package/dist/glBrightnessContrastEffect.d.ts +4 -0
- package/dist/glBrightnessContrastEffect.d.ts.map +1 -0
- package/dist/glBrightnessContrastEffect.js +28 -0
- package/dist/glBrightnessContrastEffect.js.map +1 -0
- package/dist/glCameraMotionBlurEffect.d.ts +4 -0
- package/dist/glCameraMotionBlurEffect.d.ts.map +1 -0
- package/dist/glCameraMotionBlurEffect.js +41 -0
- package/dist/glCameraMotionBlurEffect.js.map +1 -0
- package/dist/glChannelMixerEffect.d.ts +4 -0
- package/dist/glChannelMixerEffect.d.ts.map +1 -0
- package/dist/glChannelMixerEffect.js +30 -0
- package/dist/glChannelMixerEffect.js.map +1 -0
- package/dist/glChromaticAberrationEffect.d.ts +4 -0
- package/dist/glChromaticAberrationEffect.d.ts.map +1 -0
- package/dist/glChromaticAberrationEffect.js +36 -0
- package/dist/glChromaticAberrationEffect.js.map +1 -0
- package/dist/glColorGradeEffect.d.ts +4 -0
- package/dist/glColorGradeEffect.d.ts.map +1 -0
- package/dist/glColorGradeEffect.js +46 -0
- package/dist/glColorGradeEffect.js.map +1 -0
- package/dist/glCrtEffect.d.ts +4 -0
- package/dist/glCrtEffect.d.ts.map +1 -0
- package/dist/glCrtEffect.js +55 -0
- package/dist/glCrtEffect.js.map +1 -0
- package/dist/glCustomShaderEffect.d.ts +6 -0
- package/dist/glCustomShaderEffect.d.ts.map +1 -0
- package/dist/glCustomShaderEffect.js +87 -0
- package/dist/glCustomShaderEffect.js.map +1 -0
- package/dist/glDirectionalBlurEffect.d.ts +4 -0
- package/dist/glDirectionalBlurEffect.d.ts.map +1 -0
- package/dist/glDirectionalBlurEffect.js +44 -0
- package/dist/glDirectionalBlurEffect.js.map +1 -0
- package/dist/glDisplacementEffect.d.ts +4 -0
- package/dist/glDisplacementEffect.d.ts.map +1 -0
- package/dist/glDisplacementEffect.js +37 -0
- package/dist/glDisplacementEffect.js.map +1 -0
- package/dist/glDitherEffect.d.ts +4 -0
- package/dist/glDitherEffect.d.ts.map +1 -0
- package/dist/glDitherEffect.js +37 -0
- package/dist/glDitherEffect.js.map +1 -0
- package/dist/glEffectProgramCache.d.ts +4 -0
- package/dist/glEffectProgramCache.d.ts.map +1 -0
- package/dist/glEffectProgramCache.js +42 -0
- package/dist/glEffectProgramCache.js.map +1 -0
- package/dist/glExposureEffect.d.ts +4 -0
- package/dist/glExposureEffect.d.ts.map +1 -0
- package/dist/glExposureEffect.js +24 -0
- package/dist/glExposureEffect.js.map +1 -0
- package/dist/glFilmGrainEffect.d.ts +4 -0
- package/dist/glFilmGrainEffect.d.ts.map +1 -0
- package/dist/glFilmGrainEffect.js +36 -0
- package/dist/glFilmGrainEffect.js.map +1 -0
- package/dist/glFxaaEffect.d.ts +4 -0
- package/dist/glFxaaEffect.d.ts.map +1 -0
- package/dist/glFxaaEffect.js +61 -0
- package/dist/glFxaaEffect.js.map +1 -0
- package/dist/glGlitchEffect.d.ts +4 -0
- package/dist/glGlitchEffect.d.ts.map +1 -0
- package/dist/glGlitchEffect.js +50 -0
- package/dist/glGlitchEffect.js.map +1 -0
- package/dist/glGodRaysEffect.d.ts +4 -0
- package/dist/glGodRaysEffect.d.ts.map +1 -0
- package/dist/glGodRaysEffect.js +59 -0
- package/dist/glGodRaysEffect.js.map +1 -0
- package/dist/glGrayscaleEffect.d.ts +4 -0
- package/dist/glGrayscaleEffect.d.ts.map +1 -0
- package/dist/glGrayscaleEffect.js +25 -0
- package/dist/glGrayscaleEffect.js.map +1 -0
- package/dist/glHalftoneEffect.d.ts +4 -0
- package/dist/glHalftoneEffect.d.ts.map +1 -0
- package/dist/glHalftoneEffect.js +38 -0
- package/dist/glHalftoneEffect.js.map +1 -0
- package/dist/glHueSaturationEffect.d.ts +4 -0
- package/dist/glHueSaturationEffect.d.ts.map +1 -0
- package/dist/glHueSaturationEffect.js +67 -0
- package/dist/glHueSaturationEffect.js.map +1 -0
- package/dist/glInvertEffect.d.ts +4 -0
- package/dist/glInvertEffect.d.ts.map +1 -0
- package/dist/glInvertEffect.js +24 -0
- package/dist/glInvertEffect.js.map +1 -0
- package/dist/glKuwaharaEffect.d.ts +4 -0
- package/dist/glKuwaharaEffect.d.ts.map +1 -0
- package/dist/glKuwaharaEffect.js +61 -0
- package/dist/glKuwaharaEffect.js.map +1 -0
- package/dist/glLensDirtEffect.d.ts +4 -0
- package/dist/glLensDirtEffect.d.ts.map +1 -0
- package/dist/glLensDirtEffect.js +45 -0
- package/dist/glLensDirtEffect.js.map +1 -0
- package/dist/glLensDistortionEffect.d.ts +4 -0
- package/dist/glLensDistortionEffect.d.ts.map +1 -0
- package/dist/glLensDistortionEffect.js +34 -0
- package/dist/glLensDistortionEffect.js.map +1 -0
- package/dist/glLensFlareEffect.d.ts +4 -0
- package/dist/glLensFlareEffect.d.ts.map +1 -0
- package/dist/glLensFlareEffect.js +56 -0
- package/dist/glLensFlareEffect.js.map +1 -0
- package/dist/glLiftGammaGainEffect.d.ts +4 -0
- package/dist/glLiftGammaGainEffect.d.ts.map +1 -0
- package/dist/glLiftGammaGainEffect.js +44 -0
- package/dist/glLiftGammaGainEffect.js.map +1 -0
- package/dist/glLookupTableGradeEffect.d.ts +4 -0
- package/dist/glLookupTableGradeEffect.d.ts.map +1 -0
- package/dist/glLookupTableGradeEffect.js +28 -0
- package/dist/glLookupTableGradeEffect.js.map +1 -0
- package/dist/glMotionBlurEffect.d.ts +4 -0
- package/dist/glMotionBlurEffect.d.ts.map +1 -0
- package/dist/glMotionBlurEffect.js +61 -0
- package/dist/glMotionBlurEffect.js.map +1 -0
- package/dist/glOutlineEffect.d.ts +4 -0
- package/dist/glOutlineEffect.d.ts.map +1 -0
- package/dist/glOutlineEffect.js +49 -0
- package/dist/glOutlineEffect.js.map +1 -0
- package/dist/glPixelateEffect.d.ts +4 -0
- package/dist/glPixelateEffect.d.ts.map +1 -0
- package/dist/glPixelateEffect.js +27 -0
- package/dist/glPixelateEffect.js.map +1 -0
- package/dist/glPosterizeEffect.d.ts +4 -0
- package/dist/glPosterizeEffect.d.ts.map +1 -0
- package/dist/glPosterizeEffect.js +25 -0
- package/dist/glPosterizeEffect.js.map +1 -0
- package/dist/glRadialBlurEffect.d.ts +4 -0
- package/dist/glRadialBlurEffect.d.ts.map +1 -0
- package/dist/glRadialBlurEffect.js +43 -0
- package/dist/glRadialBlurEffect.js.map +1 -0
- package/dist/glRenderEffectPipeline.d.ts +7 -0
- package/dist/glRenderEffectPipeline.d.ts.map +1 -0
- package/dist/glRenderEffectPipeline.js +86 -0
- package/dist/glRenderEffectPipeline.js.map +1 -0
- package/dist/glRenderEffectRegistrar.d.ts +13 -0
- package/dist/glRenderEffectRegistrar.d.ts.map +1 -0
- package/dist/glRenderEffectRegistrar.js +222 -0
- package/dist/glRenderEffectRegistrar.js.map +1 -0
- package/dist/glRenderEffectRegistry.d.ts +5 -0
- package/dist/glRenderEffectRegistry.d.ts.map +1 -0
- package/dist/glRenderEffectRegistry.js +23 -0
- package/dist/glRenderEffectRegistry.js.map +1 -0
- package/dist/glScanlinesEffect.d.ts +4 -0
- package/dist/glScanlinesEffect.d.ts.map +1 -0
- package/dist/glScanlinesEffect.js +28 -0
- package/dist/glScanlinesEffect.js.map +1 -0
- package/dist/glScreenSpaceFogEffect.d.ts +4 -0
- package/dist/glScreenSpaceFogEffect.d.ts.map +1 -0
- package/dist/glScreenSpaceFogEffect.js +55 -0
- package/dist/glScreenSpaceFogEffect.js.map +1 -0
- package/dist/glSepiaEffect.d.ts +4 -0
- package/dist/glSepiaEffect.d.ts.map +1 -0
- package/dist/glSepiaEffect.js +29 -0
- package/dist/glSepiaEffect.js.map +1 -0
- package/dist/glSharpenEffect.d.ts +4 -0
- package/dist/glSharpenEffect.d.ts.map +1 -0
- package/dist/glSharpenEffect.js +33 -0
- package/dist/glSharpenEffect.js.map +1 -0
- package/dist/glSketchEffect.d.ts +4 -0
- package/dist/glSketchEffect.d.ts.map +1 -0
- package/dist/glSketchEffect.js +43 -0
- package/dist/glSketchEffect.js.map +1 -0
- package/dist/glSmaaEffect.d.ts +4 -0
- package/dist/glSmaaEffect.d.ts.map +1 -0
- package/dist/glSmaaEffect.js +48 -0
- package/dist/glSmaaEffect.js.map +1 -0
- package/dist/glSsaoEffect.d.ts +4 -0
- package/dist/glSsaoEffect.d.ts.map +1 -0
- package/dist/glSsaoEffect.js +45 -0
- package/dist/glSsaoEffect.js.map +1 -0
- package/dist/glSsrEffect.d.ts +4 -0
- package/dist/glSsrEffect.d.ts.map +1 -0
- package/dist/glSsrEffect.js +24 -0
- package/dist/glSsrEffect.js.map +1 -0
- package/dist/glTaaEffect.d.ts +4 -0
- package/dist/glTaaEffect.d.ts.map +1 -0
- package/dist/glTaaEffect.js +22 -0
- package/dist/glTaaEffect.js.map +1 -0
- package/dist/glTiltShiftEffect.d.ts +4 -0
- package/dist/glTiltShiftEffect.d.ts.map +1 -0
- package/dist/glTiltShiftEffect.js +45 -0
- package/dist/glTiltShiftEffect.js.map +1 -0
- package/dist/glToneMapEffect.d.ts +4 -0
- package/dist/glToneMapEffect.d.ts.map +1 -0
- package/dist/glToneMapEffect.js +51 -0
- package/dist/glToneMapEffect.js.map +1 -0
- package/dist/glVignetteEffect.d.ts +4 -0
- package/dist/glVignetteEffect.d.ts.map +1 -0
- package/dist/glVignetteEffect.js +42 -0
- package/dist/glVignetteEffect.js.map +1 -0
- package/dist/glWhiteBalanceEffect.d.ts +4 -0
- package/dist/glWhiteBalanceEffect.d.ts.map +1 -0
- package/dist/glWhiteBalanceEffect.js +31 -0
- package/dist/glWhiteBalanceEffect.js.map +1 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +50 -0
- package/dist/index.js.map +1 -0
- package/package.json +41 -0
- package/src/glBloomEffect.test.ts +13 -0
- package/src/glBokehDepthOfFieldEffect.test.ts +13 -0
- package/src/glBrightnessContrastEffect.test.ts +16 -0
- package/src/glCameraMotionBlurEffect.test.ts +13 -0
- package/src/glChannelMixerEffect.test.ts +13 -0
- package/src/glChromaticAberrationEffect.test.ts +16 -0
- package/src/glColorGradeEffect.test.ts +13 -0
- package/src/glCrtEffect.test.ts +13 -0
- package/src/glCustomShaderEffect.test.ts +68 -0
- package/src/glDirectionalBlurEffect.test.ts +13 -0
- package/src/glDisplacementEffect.test.ts +13 -0
- package/src/glDitherEffect.test.ts +13 -0
- package/src/glEffectProgramCache.test.ts +13 -0
- package/src/glExposureEffect.test.ts +13 -0
- package/src/glFilmGrainEffect.test.ts +13 -0
- package/src/glFxaaEffect.test.ts +13 -0
- package/src/glGlitchEffect.test.ts +13 -0
- package/src/glGodRaysEffect.test.ts +13 -0
- package/src/glGrayscaleEffect.test.ts +13 -0
- package/src/glHalftoneEffect.test.ts +13 -0
- package/src/glHueSaturationEffect.test.ts +13 -0
- package/src/glInvertEffect.test.ts +13 -0
- package/src/glKuwaharaEffect.test.ts +13 -0
- package/src/glLensDirtEffect.test.ts +13 -0
- package/src/glLensDistortionEffect.test.ts +13 -0
- package/src/glLensFlareEffect.test.ts +13 -0
- package/src/glLiftGammaGainEffect.test.ts +13 -0
- package/src/glLookupTableGradeEffect.test.ts +13 -0
- package/src/glMotionBlurEffect.test.ts +13 -0
- package/src/glOutlineEffect.test.ts +13 -0
- package/src/glPixelateEffect.test.ts +13 -0
- package/src/glPosterizeEffect.test.ts +13 -0
- package/src/glRadialBlurEffect.test.ts +13 -0
- package/src/glRenderEffectPipeline.test.ts +37 -0
- package/src/glRenderEffectRegistrar.test.ts +187 -0
- package/src/glRenderEffectRegistry.test.ts +52 -0
- package/src/glScanlinesEffect.test.ts +13 -0
- package/src/glScreenSpaceFogEffect.test.ts +13 -0
- package/src/glSepiaEffect.test.ts +13 -0
- package/src/glSharpenEffect.test.ts +13 -0
- package/src/glSketchEffect.test.ts +13 -0
- package/src/glSmaaEffect.test.ts +13 -0
- package/src/glSsaoEffect.test.ts +13 -0
- package/src/glSsrEffect.test.ts +13 -0
- package/src/glTaaEffect.test.ts +13 -0
- package/src/glTiltShiftEffect.test.ts +13 -0
- package/src/glToneMapEffect.test.ts +13 -0
- package/src/glVignetteEffect.test.ts +13 -0
- package/src/glWhiteBalanceEffect.test.ts +13 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { drawGlFullscreenPass } from '@flighthq/render-gl';
|
|
2
|
+
import { getGlEffectProgram } from './glEffectProgramCache';
|
|
3
|
+
// Directional blur: accumulate samples stepped along `angle` over `length` texels, normalized by the
|
|
4
|
+
// sample count. Single-pass reference recipe. u_resolution converts the texel length into UV space.
|
|
5
|
+
export function applyDirectionalBlurEffectToGl(state, source, dest, effect) {
|
|
6
|
+
const angle = effect.angle ?? 0;
|
|
7
|
+
const length = effect.length ?? 8;
|
|
8
|
+
const samples = effect.samples ?? 16;
|
|
9
|
+
const program = getGlEffectProgram(state, 'directionalBlur', DIRECTIONAL_BLUR_FRAGMENT_SRC);
|
|
10
|
+
drawGlFullscreenPass(state, program, [source.texture], dest, (gl, p) => {
|
|
11
|
+
gl.uniform1f(gl.getUniformLocation(p.program, 'u_angle'), angle);
|
|
12
|
+
gl.uniform1f(gl.getUniformLocation(p.program, 'u_length'), length);
|
|
13
|
+
gl.uniform1f(gl.getUniformLocation(p.program, 'u_samples'), samples);
|
|
14
|
+
gl.uniform2f(gl.getUniformLocation(p.program, 'u_resolution'), source.width, source.height);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
export const defaultGlDirectionalBlurEffectRunner = (ctx, effect) => {
|
|
18
|
+
applyDirectionalBlurEffectToGl(ctx.state, ctx.source, ctx.dest, effect);
|
|
19
|
+
};
|
|
20
|
+
const DIRECTIONAL_BLUR_FRAGMENT_SRC = `#version 300 es
|
|
21
|
+
precision highp float;
|
|
22
|
+
in vec2 v_texCoord;
|
|
23
|
+
uniform sampler2D u_texture0;
|
|
24
|
+
uniform float u_angle;
|
|
25
|
+
uniform float u_length;
|
|
26
|
+
uniform float u_samples;
|
|
27
|
+
uniform vec2 u_resolution;
|
|
28
|
+
out vec4 o_color;
|
|
29
|
+
const int SAMPLES = 16;
|
|
30
|
+
void main() {
|
|
31
|
+
vec2 dir = vec2(cos(u_angle), sin(u_angle)) * (u_length / u_resolution);
|
|
32
|
+
float count = min(u_samples, 16.0);
|
|
33
|
+
vec4 sum = vec4(0.0);
|
|
34
|
+
float taken = 0.0;
|
|
35
|
+
for (int i = 0; i < SAMPLES; i++) {
|
|
36
|
+
if (float(i) >= count) break;
|
|
37
|
+
float t = count > 1.0 ? (float(i) / (count - 1.0)) - 0.5 : 0.0;
|
|
38
|
+
vec2 uv = v_texCoord + dir * t;
|
|
39
|
+
sum += texture(u_texture0, uv);
|
|
40
|
+
taken += 1.0;
|
|
41
|
+
}
|
|
42
|
+
o_color = sum / max(taken, 1.0);
|
|
43
|
+
}`;
|
|
44
|
+
//# sourceMappingURL=glDirectionalBlurEffect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glDirectionalBlurEffect.js","sourceRoot":"","sources":["../src/glDirectionalBlurEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAG3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,qGAAqG;AACrG,oGAAoG;AACpG,MAAM,UAAU,8BAA8B,CAC5C,KAAoB,EACpB,MAAgC,EAChC,IAA8B,EAC9B,MAAuC;IAEvC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;IAChC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;IACrC,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,EAAE,6BAA6B,CAAC,CAAC;IAC5F,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE;QACrE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,KAAK,CAAC,CAAC;QACjE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,CAAC;QACnE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,OAAO,CAAC,CAAC;QACrE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC9F,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,oCAAoC,GAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IACxF,8BAA8B,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAA+B,CAAC,CAAC;AACnG,CAAC,CAAC;AAEF,MAAM,6BAA6B,GAAG;;;;;;;;;;;;;;;;;;;;;;;EAuBpC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { DisplacementEffect, GlRenderEffectRunner, GlRenderState, GlRenderTarget } from '@flighthq/types';
|
|
2
|
+
export declare function applyDisplacementEffectToGl(state: GlRenderState, source: Readonly<GlRenderTarget>, dest: Readonly<GlRenderTarget>, effect: Readonly<DisplacementEffect>): void;
|
|
3
|
+
export declare const defaultGlDisplacementEffectRunner: GlRenderEffectRunner;
|
|
4
|
+
//# sourceMappingURL=glDisplacementEffect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glDisplacementEffect.d.ts","sourceRoot":"","sources":["../src/glDisplacementEffect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAK/G,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,EAChC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC9B,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,GACnC,IAAI,CAWN;AAED,eAAO,MAAM,iCAAiC,EAAE,oBAE/C,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { drawGlFullscreenPass } from '@flighthq/render-gl';
|
|
2
|
+
import { getGlEffectProgram } from './glEffectProgramCache';
|
|
3
|
+
// Displacement / heat-haze: warp the sample uv by an animated sine field for a refractive wobble.
|
|
4
|
+
export function applyDisplacementEffectToGl(state, source, dest, effect) {
|
|
5
|
+
const intensity = effect.intensity ?? 8;
|
|
6
|
+
const frequency = effect.frequency ?? 12;
|
|
7
|
+
const seed = effect.seed ?? 0;
|
|
8
|
+
const program = getGlEffectProgram(state, 'lens.displacement', DISPLACEMENT_FRAGMENT_SRC);
|
|
9
|
+
drawGlFullscreenPass(state, program, [source.texture], dest, (gl, p) => {
|
|
10
|
+
gl.uniform1f(gl.getUniformLocation(p.program, 'u_intensity'), intensity);
|
|
11
|
+
gl.uniform1f(gl.getUniformLocation(p.program, 'u_frequency'), frequency);
|
|
12
|
+
gl.uniform1f(gl.getUniformLocation(p.program, 'u_seed'), seed);
|
|
13
|
+
gl.uniform2f(gl.getUniformLocation(p.program, 'u_resolution'), source.width, source.height);
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
export const defaultGlDisplacementEffectRunner = (ctx, effect) => {
|
|
17
|
+
applyDisplacementEffectToGl(ctx.state, ctx.source, ctx.dest, effect);
|
|
18
|
+
};
|
|
19
|
+
const DISPLACEMENT_FRAGMENT_SRC = `#version 300 es
|
|
20
|
+
precision highp float;
|
|
21
|
+
in vec2 v_texCoord;
|
|
22
|
+
uniform sampler2D u_texture0;
|
|
23
|
+
uniform float u_intensity;
|
|
24
|
+
uniform float u_frequency;
|
|
25
|
+
uniform float u_seed;
|
|
26
|
+
uniform vec2 u_resolution;
|
|
27
|
+
out vec4 o_color;
|
|
28
|
+
void main() {
|
|
29
|
+
float f = u_frequency;
|
|
30
|
+
vec2 warp = vec2(
|
|
31
|
+
sin(v_texCoord.y * f + u_seed) + sin(v_texCoord.y * f * 2.3 + u_seed * 1.7) * 0.5,
|
|
32
|
+
cos(v_texCoord.x * f * 0.8 + u_seed * 1.3)
|
|
33
|
+
);
|
|
34
|
+
vec2 displaced = v_texCoord + warp * (u_intensity / u_resolution);
|
|
35
|
+
o_color = texture(u_texture0, displaced);
|
|
36
|
+
}`;
|
|
37
|
+
//# sourceMappingURL=glDisplacementEffect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glDisplacementEffect.js","sourceRoot":"","sources":["../src/glDisplacementEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAG3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,kGAAkG;AAClG,MAAM,UAAU,2BAA2B,CACzC,KAAoB,EACpB,MAAgC,EAChC,IAA8B,EAC9B,MAAoC;IAEpC,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;IACxC,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC;IACzC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC;IAC9B,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,EAAE,mBAAmB,EAAE,yBAAyB,CAAC,CAAC;IAC1F,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE;QACrE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,aAAa,CAAC,EAAE,SAAS,CAAC,CAAC;QACzE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,aAAa,CAAC,EAAE,SAAS,CAAC,CAAC;QACzE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;QAC/D,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC9F,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,iCAAiC,GAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IACrF,2BAA2B,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAA4B,CAAC,CAAC;AAC7F,CAAC,CAAC;AAEF,MAAM,yBAAyB,GAAG;;;;;;;;;;;;;;;;;EAiBhC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { DitherEffect, GlRenderEffectRunner, GlRenderState, GlRenderTarget } from '@flighthq/types';
|
|
2
|
+
export declare function applyDitherEffectToGl(state: GlRenderState, source: Readonly<GlRenderTarget>, dest: Readonly<GlRenderTarget>, effect: Readonly<DitherEffect>): void;
|
|
3
|
+
export declare const defaultGlDitherEffectRunner: GlRenderEffectRunner;
|
|
4
|
+
//# sourceMappingURL=glDitherEffect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glDitherEffect.d.ts","sourceRoot":"","sources":["../src/glDitherEffect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAMzG,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,EAChC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC9B,MAAM,EAAE,QAAQ,CAAC,YAAY,CAAC,GAC7B,IAAI,CAON;AAED,eAAO,MAAM,2BAA2B,EAAE,oBAEzC,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { drawGlFullscreenPass } from '@flighthq/render-gl';
|
|
2
|
+
import { getGlEffectProgram } from './glEffectProgramCache';
|
|
3
|
+
// Dither: quantize each channel to `levels` steps with a 4x4 ordered Bayer threshold for a retro
|
|
4
|
+
// banded-but-textured look.
|
|
5
|
+
export function applyDitherEffectToGl(state, source, dest, effect) {
|
|
6
|
+
const levels = effect.levels ?? 4;
|
|
7
|
+
const program = getGlEffectProgram(state, 'stylization.dither', DITHER_FRAGMENT_SRC);
|
|
8
|
+
drawGlFullscreenPass(state, program, [source.texture], dest, (gl, p) => {
|
|
9
|
+
gl.uniform1f(gl.getUniformLocation(p.program, 'u_levels'), Math.max(2, levels));
|
|
10
|
+
gl.uniform2f(gl.getUniformLocation(p.program, 'u_resolution'), source.width, source.height);
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
export const defaultGlDitherEffectRunner = (ctx, effect) => {
|
|
14
|
+
applyDitherEffectToGl(ctx.state, ctx.source, ctx.dest, effect);
|
|
15
|
+
};
|
|
16
|
+
const DITHER_FRAGMENT_SRC = `#version 300 es
|
|
17
|
+
precision highp float;
|
|
18
|
+
in vec2 v_texCoord;
|
|
19
|
+
uniform sampler2D u_texture0;
|
|
20
|
+
uniform float u_levels;
|
|
21
|
+
uniform vec2 u_resolution;
|
|
22
|
+
out vec4 o_color;
|
|
23
|
+
float bayer(ivec2 p) {
|
|
24
|
+
int x = p.x & 3;
|
|
25
|
+
int y = p.y & 3;
|
|
26
|
+
int m[16] = int[16](0, 8, 2, 10, 12, 4, 14, 6, 3, 11, 1, 9, 15, 7, 13, 5);
|
|
27
|
+
return float(m[y * 4 + x]) / 16.0;
|
|
28
|
+
}
|
|
29
|
+
void main() {
|
|
30
|
+
vec4 c = texture(u_texture0, v_texCoord);
|
|
31
|
+
ivec2 px = ivec2(v_texCoord * u_resolution);
|
|
32
|
+
float t = bayer(px) - 0.5;
|
|
33
|
+
float steps = u_levels - 1.0;
|
|
34
|
+
vec3 q = floor(c.rgb * steps + 0.5 + t) / steps;
|
|
35
|
+
o_color = vec4(clamp(q, 0.0, 1.0), c.a);
|
|
36
|
+
}`;
|
|
37
|
+
//# sourceMappingURL=glDitherEffect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glDitherEffect.js","sourceRoot":"","sources":["../src/glDitherEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAG3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,iGAAiG;AACjG,4BAA4B;AAC5B,MAAM,UAAU,qBAAqB,CACnC,KAAoB,EACpB,MAAgC,EAChC,IAA8B,EAC9B,MAA8B;IAE9B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,CAAC,CAAC;IACrF,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE;QACrE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QAChF,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC9F,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,2BAA2B,GAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IAC/E,qBAAqB,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAAsB,CAAC,CAAC;AACjF,CAAC,CAAC;AAEF,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;EAoB1B,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { GlFullscreenProgram, GlRenderState } from '@flighthq/types';
|
|
2
|
+
export declare function getGlEffectProgram(state: GlRenderState, key: string, fragmentSource: string): GlFullscreenProgram;
|
|
3
|
+
export declare function getGlEffectUniformLocation(state: GlRenderState, program: Readonly<GlFullscreenProgram>, name: string): WebGLUniformLocation | null;
|
|
4
|
+
//# sourceMappingURL=glEffectProgramCache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glEffectProgramCache.d.ts","sourceRoot":"","sources":["../src/glEffectProgramCache.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAM1E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,mBAAmB,CAWjH;AAQD,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE,QAAQ,CAAC,mBAAmB,CAAC,EACtC,IAAI,EAAE,MAAM,GACX,oBAAoB,GAAG,IAAI,CAW7B"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { compileGlFullscreenProgram } from '@flighthq/render-gl';
|
|
2
|
+
// Per-state cache of compiled effect fragment programs, keyed by a stable string. Effect recipes call
|
|
3
|
+
// getGlEffectProgram with their own key + fragment source so each program compiles once per state
|
|
4
|
+
// and is reused every frame. Keeps compiled programs off the render-state runtime type.
|
|
5
|
+
export function getGlEffectProgram(state, key, fragmentSource) {
|
|
6
|
+
let cache = _programs.get(state);
|
|
7
|
+
if (cache === undefined) {
|
|
8
|
+
cache = new Map();
|
|
9
|
+
_programs.set(state, cache);
|
|
10
|
+
}
|
|
11
|
+
const existing = cache.get(key);
|
|
12
|
+
if (existing !== undefined)
|
|
13
|
+
return existing;
|
|
14
|
+
const compiled = compileGlFullscreenProgram(state.gl, fragmentSource);
|
|
15
|
+
cache.set(key, compiled);
|
|
16
|
+
return compiled;
|
|
17
|
+
}
|
|
18
|
+
// Returns a cached WebGLUniformLocation for the given program and uniform name. The texture-slot
|
|
19
|
+
// locations (u_texture0..N) are already resolved by compileGlFullscreenProgram and live on
|
|
20
|
+
// GlFullscreenProgram.textures. This cache covers the per-effect uniforms (u_threshold, u_intensity,
|
|
21
|
+
// u_matrix, etc.) that the render-gl layer does not pre-resolve. Because getUniformLocation is a
|
|
22
|
+
// GL driver call that involves string hashing on every draw, caching here removes O(N * uniforms)
|
|
23
|
+
// driver round-trips per frame for a 44-effect chain.
|
|
24
|
+
export function getGlEffectUniformLocation(state, program, name) {
|
|
25
|
+
let cache = _uniformLocations.get(program);
|
|
26
|
+
if (cache === undefined) {
|
|
27
|
+
cache = new Map();
|
|
28
|
+
_uniformLocations.set(program, cache);
|
|
29
|
+
}
|
|
30
|
+
const existing = cache.get(name);
|
|
31
|
+
if (existing !== undefined)
|
|
32
|
+
return existing;
|
|
33
|
+
const loc = state.gl.getUniformLocation(program.program, name);
|
|
34
|
+
cache.set(name, loc);
|
|
35
|
+
return loc;
|
|
36
|
+
}
|
|
37
|
+
const _programs = new WeakMap();
|
|
38
|
+
// Keyed by program object (not state) so the cache survives state-key rotation and is naturally
|
|
39
|
+
// freed when the program itself is garbage-collected (all GlFullscreenPrograms are stored in
|
|
40
|
+
// _programs above, which is already WeakMap-keyed by state).
|
|
41
|
+
const _uniformLocations = new WeakMap();
|
|
42
|
+
//# sourceMappingURL=glEffectProgramCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glEffectProgramCache.js","sourceRoot":"","sources":["../src/glEffectProgramCache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAGjE,sGAAsG;AACtG,kGAAkG;AAClG,wFAAwF;AAExF,MAAM,UAAU,kBAAkB,CAAC,KAAoB,EAAE,GAAW,EAAE,cAAsB;IAC1F,IAAI,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,KAAK,GAAG,IAAI,GAAG,EAAE,CAAC;QAClB,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC9B,CAAC;IACD,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IAC5C,MAAM,QAAQ,GAAG,0BAA0B,CAAC,KAAK,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;IACtE,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACzB,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,iGAAiG;AACjG,2FAA2F;AAC3F,qGAAqG;AACrG,iGAAiG;AACjG,kGAAkG;AAClG,sDAAsD;AACtD,MAAM,UAAU,0BAA0B,CACxC,KAAoB,EACpB,OAAsC,EACtC,IAAY;IAEZ,IAAI,KAAK,GAAG,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC3C,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,KAAK,GAAG,IAAI,GAAG,EAAE,CAAC;QAClB,iBAAiB,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACxC,CAAC;IACD,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IAC5C,MAAM,GAAG,GAAG,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC/D,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACrB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,SAAS,GAAG,IAAI,OAAO,EAAmD,CAAC;AAEjF,gGAAgG;AAChG,6FAA6F;AAC7F,6DAA6D;AAC7D,MAAM,iBAAiB,GAAG,IAAI,OAAO,EAA2E,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ExposureEffect, GlRenderEffectRunner, GlRenderState, GlRenderTarget } from '@flighthq/types';
|
|
2
|
+
export declare function applyExposureEffectToGl(state: GlRenderState, source: Readonly<GlRenderTarget>, dest: Readonly<GlRenderTarget>, effect: Readonly<ExposureEffect>): void;
|
|
3
|
+
export declare const defaultGlExposureEffectRunner: GlRenderEffectRunner;
|
|
4
|
+
//# sourceMappingURL=glExposureEffect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glExposureEffect.d.ts","sourceRoot":"","sources":["../src/glExposureEffect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAK3G,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,EAChC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC9B,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,GAC/B,IAAI,CAMN;AAED,eAAO,MAAM,6BAA6B,EAAE,oBAE3C,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { drawGlFullscreenPass } from '@flighthq/render-gl';
|
|
2
|
+
import { getGlEffectProgram } from './glEffectProgramCache';
|
|
3
|
+
// Exposure: scale linear color by 2^stops. Single-pass reference recipe.
|
|
4
|
+
export function applyExposureEffectToGl(state, source, dest, effect) {
|
|
5
|
+
const exposure = effect.exposure ?? 0;
|
|
6
|
+
const program = getGlEffectProgram(state, 'exposure', EXPOSURE_FRAGMENT_SRC);
|
|
7
|
+
drawGlFullscreenPass(state, program, [source.texture], dest, (gl, p) => {
|
|
8
|
+
gl.uniform1f(gl.getUniformLocation(p.program, 'u_exposure'), Math.pow(2, exposure));
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
export const defaultGlExposureEffectRunner = (ctx, effect) => {
|
|
12
|
+
applyExposureEffectToGl(ctx.state, ctx.source, ctx.dest, effect);
|
|
13
|
+
};
|
|
14
|
+
const EXPOSURE_FRAGMENT_SRC = `#version 300 es
|
|
15
|
+
precision highp float;
|
|
16
|
+
in vec2 v_texCoord;
|
|
17
|
+
uniform sampler2D u_texture0;
|
|
18
|
+
uniform float u_exposure;
|
|
19
|
+
out vec4 o_color;
|
|
20
|
+
void main() {
|
|
21
|
+
vec4 c = texture(u_texture0, v_texCoord);
|
|
22
|
+
o_color = vec4(c.rgb * u_exposure, c.a);
|
|
23
|
+
}`;
|
|
24
|
+
//# sourceMappingURL=glExposureEffect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glExposureEffect.js","sourceRoot":"","sources":["../src/glExposureEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAG3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,yEAAyE;AACzE,MAAM,UAAU,uBAAuB,CACrC,KAAoB,EACpB,MAAgC,EAChC,IAA8B,EAC9B,MAAgC;IAEhC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,EAAE,UAAU,EAAE,qBAAqB,CAAC,CAAC;IAC7E,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE;QACrE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,6BAA6B,GAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IACjF,uBAAuB,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAAwB,CAAC,CAAC;AACrF,CAAC,CAAC;AAEF,MAAM,qBAAqB,GAAG;;;;;;;;;EAS5B,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { FilmGrainEffect, GlRenderEffectRunner, GlRenderState, GlRenderTarget } from '@flighthq/types';
|
|
2
|
+
export declare function applyFilmGrainEffectToGl(state: GlRenderState, source: Readonly<GlRenderTarget>, dest: Readonly<GlRenderTarget>, effect: Readonly<FilmGrainEffect>): void;
|
|
3
|
+
export declare const defaultGlFilmGrainEffectRunner: GlRenderEffectRunner;
|
|
4
|
+
//# sourceMappingURL=glFilmGrainEffect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glFilmGrainEffect.d.ts","sourceRoot":"","sources":["../src/glFilmGrainEffect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAM5G,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,EAChC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC9B,MAAM,EAAE,QAAQ,CAAC,eAAe,CAAC,GAChC,IAAI,CAUN;AAED,eAAO,MAAM,8BAA8B,EAAE,oBAE5C,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { drawGlFullscreenPass } from '@flighthq/render-gl';
|
|
2
|
+
import { getGlEffectProgram } from './glEffectProgramCache';
|
|
3
|
+
// Film grain: add per-pixel hash noise scaled by intensity, with grain cell size and a seed so the
|
|
4
|
+
// noise can be animated frame to frame.
|
|
5
|
+
export function applyFilmGrainEffectToGl(state, source, dest, effect) {
|
|
6
|
+
const intensity = effect.intensity ?? 0.1;
|
|
7
|
+
const size = effect.size ?? 1;
|
|
8
|
+
const seed = effect.seed ?? 0;
|
|
9
|
+
const program = getGlEffectProgram(state, 'stylization.filmGrain', FILM_GRAIN_FRAGMENT_SRC);
|
|
10
|
+
drawGlFullscreenPass(state, program, [source.texture], dest, (gl, p) => {
|
|
11
|
+
gl.uniform1f(gl.getUniformLocation(p.program, 'u_intensity'), intensity);
|
|
12
|
+
gl.uniform1f(gl.getUniformLocation(p.program, 'u_size'), Math.max(0.0001, size));
|
|
13
|
+
gl.uniform1f(gl.getUniformLocation(p.program, 'u_seed'), seed);
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
export const defaultGlFilmGrainEffectRunner = (ctx, effect) => {
|
|
17
|
+
applyFilmGrainEffectToGl(ctx.state, ctx.source, ctx.dest, effect);
|
|
18
|
+
};
|
|
19
|
+
const FILM_GRAIN_FRAGMENT_SRC = `#version 300 es
|
|
20
|
+
precision highp float;
|
|
21
|
+
in vec2 v_texCoord;
|
|
22
|
+
uniform sampler2D u_texture0;
|
|
23
|
+
uniform float u_intensity;
|
|
24
|
+
uniform float u_size;
|
|
25
|
+
uniform float u_seed;
|
|
26
|
+
out vec4 o_color;
|
|
27
|
+
float hash(vec2 p) {
|
|
28
|
+
p = floor(p / u_size);
|
|
29
|
+
return fract(sin(dot(p, vec2(127.1, 311.7)) + u_seed) * 43758.5453123);
|
|
30
|
+
}
|
|
31
|
+
void main() {
|
|
32
|
+
vec4 c = texture(u_texture0, v_texCoord);
|
|
33
|
+
float n = hash(v_texCoord * 1024.0) - 0.5;
|
|
34
|
+
o_color = vec4(c.rgb + n * u_intensity, c.a);
|
|
35
|
+
}`;
|
|
36
|
+
//# sourceMappingURL=glFilmGrainEffect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glFilmGrainEffect.js","sourceRoot":"","sources":["../src/glFilmGrainEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAG3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,mGAAmG;AACnG,wCAAwC;AACxC,MAAM,UAAU,wBAAwB,CACtC,KAAoB,EACpB,MAAgC,EAChC,IAA8B,EAC9B,MAAiC;IAEjC,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,GAAG,CAAC;IAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC;IAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC;IAC9B,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,EAAE,uBAAuB,CAAC,CAAC;IAC5F,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE;QACrE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,aAAa,CAAC,EAAE,SAAS,CAAC,CAAC;QACzE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;QACjF,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,8BAA8B,GAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IAClF,wBAAwB,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAAyB,CAAC,CAAC;AACvF,CAAC,CAAC;AAEF,MAAM,uBAAuB,GAAG;;;;;;;;;;;;;;;;EAgB9B,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { FxaaEffect, GlRenderEffectRunner, GlRenderState, GlRenderTarget } from '@flighthq/types';
|
|
2
|
+
export declare function applyFxaaEffectToGl(state: GlRenderState, source: Readonly<GlRenderTarget>, dest: Readonly<GlRenderTarget>, effect: Readonly<FxaaEffect>): void;
|
|
3
|
+
export declare const defaultGlFxaaEffectRunner: GlRenderEffectRunner;
|
|
4
|
+
//# sourceMappingURL=glFxaaEffect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glFxaaEffect.d.ts","sourceRoot":"","sources":["../src/glFxaaEffect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAMvG,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,EAChC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC9B,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,GAC3B,IAAI,CAON;AAED,eAAO,MAAM,yBAAyB,EAAE,oBAEvC,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { drawGlFullscreenPass } from '@flighthq/render-gl';
|
|
2
|
+
import { getGlEffectProgram } from './glEffectProgramCache';
|
|
3
|
+
// FXAA: luminance edge detection + directional blend along the detected edge. Single-pass reference
|
|
4
|
+
// recipe. Reads u_texture0; u_resolution gives the texel size; u_edgeThreshold gates edge detection.
|
|
5
|
+
export function applyFxaaEffectToGl(state, source, dest, effect) {
|
|
6
|
+
const edgeThreshold = effect.edgeThreshold ?? 0.0312;
|
|
7
|
+
const program = getGlEffectProgram(state, 'antialiasing.fxaa', FXAA_FRAGMENT_SRC);
|
|
8
|
+
drawGlFullscreenPass(state, program, [source.texture], dest, (gl, p) => {
|
|
9
|
+
gl.uniform2f(gl.getUniformLocation(p.program, 'u_resolution'), source.width, source.height);
|
|
10
|
+
gl.uniform1f(gl.getUniformLocation(p.program, 'u_edgeThreshold'), edgeThreshold);
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
export const defaultGlFxaaEffectRunner = (ctx, effect) => {
|
|
14
|
+
applyFxaaEffectToGl(ctx.state, ctx.source, ctx.dest, effect);
|
|
15
|
+
};
|
|
16
|
+
const FXAA_FRAGMENT_SRC = `#version 300 es
|
|
17
|
+
precision highp float;
|
|
18
|
+
in vec2 v_texCoord;
|
|
19
|
+
uniform sampler2D u_texture0;
|
|
20
|
+
uniform vec2 u_resolution;
|
|
21
|
+
uniform float u_edgeThreshold;
|
|
22
|
+
out vec4 o_color;
|
|
23
|
+
float luma(vec3 c) {
|
|
24
|
+
return dot(c, vec3(0.299, 0.587, 0.114));
|
|
25
|
+
}
|
|
26
|
+
void main() {
|
|
27
|
+
vec2 texel = 1.0 / u_resolution;
|
|
28
|
+
vec3 rgbM = texture(u_texture0, v_texCoord).rgb;
|
|
29
|
+
vec3 rgbNW = texture(u_texture0, v_texCoord + vec2(-1.0, -1.0) * texel).rgb;
|
|
30
|
+
vec3 rgbNE = texture(u_texture0, v_texCoord + vec2(1.0, -1.0) * texel).rgb;
|
|
31
|
+
vec3 rgbSW = texture(u_texture0, v_texCoord + vec2(-1.0, 1.0) * texel).rgb;
|
|
32
|
+
vec3 rgbSE = texture(u_texture0, v_texCoord + vec2(1.0, 1.0) * texel).rgb;
|
|
33
|
+
float lumaM = luma(rgbM);
|
|
34
|
+
float lumaNW = luma(rgbNW);
|
|
35
|
+
float lumaNE = luma(rgbNE);
|
|
36
|
+
float lumaSW = luma(rgbSW);
|
|
37
|
+
float lumaSE = luma(rgbSE);
|
|
38
|
+
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
|
|
39
|
+
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
|
|
40
|
+
float range = lumaMax - lumaMin;
|
|
41
|
+
if (range < max(u_edgeThreshold, lumaMax * 0.125)) {
|
|
42
|
+
o_color = vec4(rgbM, texture(u_texture0, v_texCoord).a);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
vec2 dir;
|
|
46
|
+
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
|
|
47
|
+
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
|
|
48
|
+
float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * 0.03125, 0.0078125);
|
|
49
|
+
float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
|
|
50
|
+
dir = clamp(dir * rcpDirMin, vec2(-8.0), vec2(8.0)) * texel;
|
|
51
|
+
vec3 rgbA = 0.5 * (
|
|
52
|
+
texture(u_texture0, v_texCoord + dir * (1.0 / 3.0 - 0.5)).rgb +
|
|
53
|
+
texture(u_texture0, v_texCoord + dir * (2.0 / 3.0 - 0.5)).rgb);
|
|
54
|
+
vec3 rgbB = rgbA * 0.5 + 0.25 * (
|
|
55
|
+
texture(u_texture0, v_texCoord + dir * -0.5).rgb +
|
|
56
|
+
texture(u_texture0, v_texCoord + dir * 0.5).rgb);
|
|
57
|
+
float lumaB = luma(rgbB);
|
|
58
|
+
vec3 result = (lumaB < lumaMin || lumaB > lumaMax) ? rgbA : rgbB;
|
|
59
|
+
o_color = vec4(result, texture(u_texture0, v_texCoord).a);
|
|
60
|
+
}`;
|
|
61
|
+
//# sourceMappingURL=glFxaaEffect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glFxaaEffect.js","sourceRoot":"","sources":["../src/glFxaaEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAG3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,oGAAoG;AACpG,qGAAqG;AACrG,MAAM,UAAU,mBAAmB,CACjC,KAAoB,EACpB,MAAgC,EAChC,IAA8B,EAC9B,MAA4B;IAE5B,MAAM,aAAa,GAAG,MAAM,CAAC,aAAa,IAAI,MAAM,CAAC;IACrD,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,CAAC,CAAC;IAClF,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE;QACrE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAC5F,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,iBAAiB,CAAC,EAAE,aAAa,CAAC,CAAC;IACnF,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,yBAAyB,GAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IAC7E,mBAAmB,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAAoB,CAAC,CAAC;AAC7E,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4CxB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { GlitchEffect, GlRenderEffectRunner, GlRenderState, GlRenderTarget } from '@flighthq/types';
|
|
2
|
+
export declare function applyGlitchEffectToGl(state: GlRenderState, source: Readonly<GlRenderTarget>, dest: Readonly<GlRenderTarget>, effect: Readonly<GlitchEffect>): void;
|
|
3
|
+
export declare const defaultGlGlitchEffectRunner: GlRenderEffectRunner;
|
|
4
|
+
//# sourceMappingURL=glGlitchEffect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glGlitchEffect.d.ts","sourceRoot":"","sources":["../src/glGlitchEffect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAMzG,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,EAChC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC9B,MAAM,EAAE,QAAQ,CAAC,YAAY,CAAC,GAC7B,IAAI,CAaN;AAED,eAAO,MAAM,2BAA2B,EAAE,oBAEzC,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { drawGlFullscreenPass } from '@flighthq/render-gl';
|
|
2
|
+
import { getGlEffectProgram } from './glEffectProgramCache';
|
|
3
|
+
// Glitch: split the frame into horizontal blocks, displace each by a per-block hash (data-mosh tear),
|
|
4
|
+
// separate the RGB channels, and corrupt the occasional block to white. `seed` animates it.
|
|
5
|
+
export function applyGlitchEffectToGl(state, source, dest, effect) {
|
|
6
|
+
const intensity = effect.intensity ?? 0.5;
|
|
7
|
+
const blockSize = effect.blockSize ?? 24;
|
|
8
|
+
const colorShift = effect.colorShift ?? 8;
|
|
9
|
+
const seed = effect.seed ?? 0;
|
|
10
|
+
const program = getGlEffectProgram(state, 'stylization.glitch', GLITCH_FRAGMENT_SRC);
|
|
11
|
+
drawGlFullscreenPass(state, program, [source.texture], dest, (gl, p) => {
|
|
12
|
+
gl.uniform1f(gl.getUniformLocation(p.program, 'u_intensity'), intensity);
|
|
13
|
+
gl.uniform1f(gl.getUniformLocation(p.program, 'u_blockSize'), blockSize);
|
|
14
|
+
gl.uniform1f(gl.getUniformLocation(p.program, 'u_colorShift'), colorShift);
|
|
15
|
+
gl.uniform1f(gl.getUniformLocation(p.program, 'u_seed'), seed);
|
|
16
|
+
gl.uniform2f(gl.getUniformLocation(p.program, 'u_resolution'), source.width, source.height);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
export const defaultGlGlitchEffectRunner = (ctx, effect) => {
|
|
20
|
+
applyGlitchEffectToGl(ctx.state, ctx.source, ctx.dest, effect);
|
|
21
|
+
};
|
|
22
|
+
const GLITCH_FRAGMENT_SRC = `#version 300 es
|
|
23
|
+
precision highp float;
|
|
24
|
+
in vec2 v_texCoord;
|
|
25
|
+
uniform sampler2D u_texture0;
|
|
26
|
+
uniform float u_intensity;
|
|
27
|
+
uniform float u_blockSize;
|
|
28
|
+
uniform float u_colorShift;
|
|
29
|
+
uniform float u_seed;
|
|
30
|
+
uniform vec2 u_resolution;
|
|
31
|
+
out vec4 o_color;
|
|
32
|
+
float ghash(float n) { return fract(sin(n) * 43758.5453123); }
|
|
33
|
+
void main() {
|
|
34
|
+
float blockSize = max(2.0, u_blockSize);
|
|
35
|
+
float block = floor(v_texCoord.y * u_resolution.y / blockSize);
|
|
36
|
+
float r = ghash(block + u_seed * 7.0);
|
|
37
|
+
float tear = step(1.0 - u_intensity * 0.6, r);
|
|
38
|
+
float shiftPx = (ghash(block * 1.7 + u_seed) - 0.5) * 2.0 * tear * u_intensity * 40.0;
|
|
39
|
+
vec2 baseUv = vec2(v_texCoord.x + shiftPx / u_resolution.x, v_texCoord.y);
|
|
40
|
+
float cs = (u_colorShift * (0.4 + tear)) / u_resolution.x;
|
|
41
|
+
float rC = texture(u_texture0, vec2(baseUv.x + cs, baseUv.y)).r;
|
|
42
|
+
float gC = texture(u_texture0, baseUv).g;
|
|
43
|
+
float bC = texture(u_texture0, vec2(baseUv.x - cs, baseUv.y)).b;
|
|
44
|
+
float a = texture(u_texture0, baseUv).a;
|
|
45
|
+
vec3 col = vec3(rC, gC, bC);
|
|
46
|
+
float corrupt = step(0.985 - u_intensity * 0.04, ghash(block * 3.3 + u_seed * 2.0));
|
|
47
|
+
col = mix(col, vec3(1.0), corrupt * 0.6);
|
|
48
|
+
o_color = vec4(col, a);
|
|
49
|
+
}`;
|
|
50
|
+
//# sourceMappingURL=glGlitchEffect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glGlitchEffect.js","sourceRoot":"","sources":["../src/glGlitchEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAG3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,sGAAsG;AACtG,4FAA4F;AAC5F,MAAM,UAAU,qBAAqB,CACnC,KAAoB,EACpB,MAAgC,EAChC,IAA8B,EAC9B,MAA8B;IAE9B,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,GAAG,CAAC;IAC1C,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC;IACzC,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC;IAC9B,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,CAAC,CAAC;IACrF,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE;QACrE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,aAAa,CAAC,EAAE,SAAS,CAAC,CAAC;QACzE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,aAAa,CAAC,EAAE,SAAS,CAAC,CAAC;QACzE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE,UAAU,CAAC,CAAC;QAC3E,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;QAC/D,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC9F,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,2BAA2B,GAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IAC/E,qBAAqB,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAAsB,CAAC,CAAC;AACjF,CAAC,CAAC;AAEF,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2B1B,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { GlRenderEffectRunner, GlRenderState, GlRenderTarget, GodRaysEffect } from '@flighthq/types';
|
|
2
|
+
export declare function applyGodRaysEffectToGl(state: GlRenderState, source: Readonly<GlRenderTarget>, dest: Readonly<GlRenderTarget>, effect: Readonly<GodRaysEffect>): void;
|
|
3
|
+
export declare const defaultGlGodRaysEffectRunner: GlRenderEffectRunner;
|
|
4
|
+
//# sourceMappingURL=glGodRaysEffect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glGodRaysEffect.d.ts","sourceRoot":"","sources":["../src/glGodRaysEffect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAQ1G,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,EAChC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC9B,MAAM,EAAE,QAAQ,CAAC,aAAa,CAAC,GAC9B,IAAI,CAiBN;AAED,eAAO,MAAM,4BAA4B,EAAE,oBAE1C,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { drawGlFullscreenPass } from '@flighthq/render-gl';
|
|
2
|
+
import { getGlEffectProgram } from './glEffectProgramCache';
|
|
3
|
+
// God rays: radial light scattering from a screen-space light position (centerX, centerY). Marches
|
|
4
|
+
// SAMPLES steps along the ray from each fragment toward the light, accumulating color with per-step
|
|
5
|
+
// decay and weight, then scales by exposure. A true single-pass recipe — no depth needed. Reads
|
|
6
|
+
// u_texture0; u_resolution is set so the light direction is computed in a consistent space.
|
|
7
|
+
export function applyGodRaysEffectToGl(state, source, dest, effect) {
|
|
8
|
+
const centerX = effect.centerX ?? 0.5;
|
|
9
|
+
const centerY = effect.centerY ?? 0.5;
|
|
10
|
+
const density = effect.density ?? 0.96;
|
|
11
|
+
const decay = effect.decay ?? 0.93;
|
|
12
|
+
const weight = effect.weight ?? 0.4;
|
|
13
|
+
const exposure = effect.exposure ?? 0.6;
|
|
14
|
+
const samples = Math.max(1, Math.round(effect.samples ?? 64));
|
|
15
|
+
const program = getGlEffectProgram(state, `atmospheric.godRays.${samples}`, buildGodRaysFragment(samples));
|
|
16
|
+
drawGlFullscreenPass(state, program, [source.texture], dest, (gl, p) => {
|
|
17
|
+
gl.uniform2f(gl.getUniformLocation(p.program, 'u_resolution'), source.width, source.height);
|
|
18
|
+
gl.uniform2f(gl.getUniformLocation(p.program, 'u_lightPosition'), centerX, centerY);
|
|
19
|
+
gl.uniform1f(gl.getUniformLocation(p.program, 'u_density'), density);
|
|
20
|
+
gl.uniform1f(gl.getUniformLocation(p.program, 'u_decay'), decay);
|
|
21
|
+
gl.uniform1f(gl.getUniformLocation(p.program, 'u_weight'), weight);
|
|
22
|
+
gl.uniform1f(gl.getUniformLocation(p.program, 'u_exposure'), exposure);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
export const defaultGlGodRaysEffectRunner = (ctx, effect) => {
|
|
26
|
+
applyGodRaysEffectToGl(ctx.state, ctx.source, ctx.dest, effect);
|
|
27
|
+
};
|
|
28
|
+
function buildGodRaysFragment(samples) {
|
|
29
|
+
return GOD_RAYS_FRAGMENT_HEAD + samples.toFixed(1) + GOD_RAYS_FRAGMENT_TAIL;
|
|
30
|
+
}
|
|
31
|
+
const GOD_RAYS_FRAGMENT_HEAD = `#version 300 es
|
|
32
|
+
precision highp float;
|
|
33
|
+
in vec2 v_texCoord;
|
|
34
|
+
uniform sampler2D u_texture0;
|
|
35
|
+
uniform vec2 u_resolution;
|
|
36
|
+
uniform vec2 u_lightPosition;
|
|
37
|
+
uniform float u_density;
|
|
38
|
+
uniform float u_decay;
|
|
39
|
+
uniform float u_weight;
|
|
40
|
+
uniform float u_exposure;
|
|
41
|
+
out vec4 o_color;
|
|
42
|
+
const float SAMPLES = `;
|
|
43
|
+
const GOD_RAYS_FRAGMENT_TAIL = `;
|
|
44
|
+
void main() {
|
|
45
|
+
vec2 delta = (v_texCoord - u_lightPosition) * (u_density / SAMPLES);
|
|
46
|
+
vec2 coord = v_texCoord;
|
|
47
|
+
vec4 base = texture(u_texture0, v_texCoord);
|
|
48
|
+
vec3 accum = base.rgb;
|
|
49
|
+
float illumination = 1.0;
|
|
50
|
+
for (int i = 0; i < int(SAMPLES); i++) {
|
|
51
|
+
coord -= delta;
|
|
52
|
+
vec3 s = texture(u_texture0, coord).rgb;
|
|
53
|
+
s *= illumination * u_weight;
|
|
54
|
+
accum += s;
|
|
55
|
+
illumination *= u_decay;
|
|
56
|
+
}
|
|
57
|
+
o_color = vec4(base.rgb + accum * u_exposure, base.a);
|
|
58
|
+
}`;
|
|
59
|
+
//# sourceMappingURL=glGodRaysEffect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glGodRaysEffect.js","sourceRoot":"","sources":["../src/glGodRaysEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAG3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,mGAAmG;AACnG,oGAAoG;AACpG,gGAAgG;AAChG,4FAA4F;AAC5F,MAAM,UAAU,sBAAsB,CACpC,KAAoB,EACpB,MAAgC,EAChC,IAA8B,EAC9B,MAA+B;IAE/B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,GAAG,CAAC;IACtC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,GAAG,CAAC;IACtC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC;IACvC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,IAAI,CAAC;IACnC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC;IACpC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,GAAG,CAAC;IACxC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,OAAO,EAAE,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC;IAC3G,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE;QACrE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAC5F,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,iBAAiB,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QACpF,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,OAAO,CAAC,CAAC;QACrE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,KAAK,CAAC,CAAC;QACjE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,CAAC;QACnE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE,QAAQ,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,4BAA4B,GAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IAChF,sBAAsB,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAAuB,CAAC,CAAC;AACnF,CAAC,CAAC;AAEF,SAAS,oBAAoB,CAAC,OAAe;IAC3C,OAAO,sBAAsB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,sBAAsB,CAAC;AAC9E,CAAC;AAED,MAAM,sBAAsB,GAAG;;;;;;;;;;;uBAWR,CAAC;AAExB,MAAM,sBAAsB,GAAG;;;;;;;;;;;;;;;EAe7B,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { GlRenderEffectRunner, GlRenderState, GlRenderTarget, GrayscaleEffect } from '@flighthq/types';
|
|
2
|
+
export declare function applyGrayscaleEffectToGl(state: GlRenderState, source: Readonly<GlRenderTarget>, dest: Readonly<GlRenderTarget>, effect: Readonly<GrayscaleEffect>): void;
|
|
3
|
+
export declare const defaultGlGrayscaleEffectRunner: GlRenderEffectRunner;
|
|
4
|
+
//# sourceMappingURL=glGrayscaleEffect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glGrayscaleEffect.d.ts","sourceRoot":"","sources":["../src/glGrayscaleEffect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAK5G,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,EAChC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC9B,MAAM,EAAE,QAAQ,CAAC,eAAe,CAAC,GAChC,IAAI,CAMN;AAED,eAAO,MAAM,8BAA8B,EAAE,oBAE5C,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { drawGlFullscreenPass } from '@flighthq/render-gl';
|
|
2
|
+
import { getGlEffectProgram } from './glEffectProgramCache';
|
|
3
|
+
// Grayscale: mix toward luminance by intensity.
|
|
4
|
+
export function applyGrayscaleEffectToGl(state, source, dest, effect) {
|
|
5
|
+
const intensity = effect.intensity ?? 1;
|
|
6
|
+
const program = getGlEffectProgram(state, 'colorGrade.grayscale', GRAYSCALE_FRAGMENT_SRC);
|
|
7
|
+
drawGlFullscreenPass(state, program, [source.texture], dest, (gl, p) => {
|
|
8
|
+
gl.uniform1f(gl.getUniformLocation(p.program, 'u_intensity'), intensity);
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
export const defaultGlGrayscaleEffectRunner = (ctx, effect) => {
|
|
12
|
+
applyGrayscaleEffectToGl(ctx.state, ctx.source, ctx.dest, effect);
|
|
13
|
+
};
|
|
14
|
+
const GRAYSCALE_FRAGMENT_SRC = `#version 300 es
|
|
15
|
+
precision highp float;
|
|
16
|
+
in vec2 v_texCoord;
|
|
17
|
+
uniform sampler2D u_texture0;
|
|
18
|
+
uniform float u_intensity;
|
|
19
|
+
out vec4 o_color;
|
|
20
|
+
void main() {
|
|
21
|
+
vec4 c = texture(u_texture0, v_texCoord);
|
|
22
|
+
float l = dot(c.rgb, vec3(0.2126, 0.7152, 0.0722));
|
|
23
|
+
o_color = vec4(mix(c.rgb, vec3(l), u_intensity), c.a);
|
|
24
|
+
}`;
|
|
25
|
+
//# sourceMappingURL=glGrayscaleEffect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glGrayscaleEffect.js","sourceRoot":"","sources":["../src/glGrayscaleEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAG3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,gDAAgD;AAChD,MAAM,UAAU,wBAAwB,CACtC,KAAoB,EACpB,MAAgC,EAChC,IAA8B,EAC9B,MAAiC;IAEjC,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,EAAE,sBAAsB,EAAE,sBAAsB,CAAC,CAAC;IAC1F,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE;QACrE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,aAAa,CAAC,EAAE,SAAS,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,8BAA8B,GAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IAClF,wBAAwB,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAAyB,CAAC,CAAC;AACvF,CAAC,CAAC;AAEF,MAAM,sBAAsB,GAAG;;;;;;;;;;EAU7B,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { GlRenderEffectRunner, GlRenderState, GlRenderTarget, HalftoneEffect } from '@flighthq/types';
|
|
2
|
+
export declare function applyHalftoneEffectToGl(state: GlRenderState, source: Readonly<GlRenderTarget>, dest: Readonly<GlRenderTarget>, effect: Readonly<HalftoneEffect>): void;
|
|
3
|
+
export declare const defaultGlHalftoneEffectRunner: GlRenderEffectRunner;
|
|
4
|
+
//# sourceMappingURL=glHalftoneEffect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glHalftoneEffect.d.ts","sourceRoot":"","sources":["../src/glHalftoneEffect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAM3G,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,EAChC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC9B,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,GAC/B,IAAI,CASN;AAED,eAAO,MAAM,6BAA6B,EAAE,oBAE3C,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { drawGlFullscreenPass } from '@flighthq/render-gl';
|
|
2
|
+
import { getGlEffectProgram } from './glEffectProgramCache';
|
|
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 applyHalftoneEffectToGl(state, source, dest, effect) {
|
|
6
|
+
const scale = effect.scale ?? 6;
|
|
7
|
+
const angle = effect.angle ?? 0.4;
|
|
8
|
+
const program = getGlEffectProgram(state, 'stylization.halftone', HALFTONE_FRAGMENT_SRC);
|
|
9
|
+
drawGlFullscreenPass(state, program, [source.texture], dest, (gl, p) => {
|
|
10
|
+
gl.uniform1f(gl.getUniformLocation(p.program, 'u_scale'), Math.max(1, scale));
|
|
11
|
+
gl.uniform1f(gl.getUniformLocation(p.program, 'u_angle'), angle);
|
|
12
|
+
gl.uniform2f(gl.getUniformLocation(p.program, 'u_resolution'), source.width, source.height);
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
export const defaultGlHalftoneEffectRunner = (ctx, effect) => {
|
|
16
|
+
applyHalftoneEffectToGl(ctx.state, ctx.source, ctx.dest, effect);
|
|
17
|
+
};
|
|
18
|
+
const HALFTONE_FRAGMENT_SRC = `#version 300 es
|
|
19
|
+
precision highp float;
|
|
20
|
+
in vec2 v_texCoord;
|
|
21
|
+
uniform sampler2D u_texture0;
|
|
22
|
+
uniform float u_scale;
|
|
23
|
+
uniform float u_angle;
|
|
24
|
+
uniform vec2 u_resolution;
|
|
25
|
+
out vec4 o_color;
|
|
26
|
+
void main() {
|
|
27
|
+
vec4 c = texture(u_texture0, v_texCoord);
|
|
28
|
+
float lum = dot(c.rgb, vec3(0.2126, 0.7152, 0.0722));
|
|
29
|
+
vec2 p = v_texCoord * u_resolution;
|
|
30
|
+
float s = sin(u_angle), co = cos(u_angle);
|
|
31
|
+
vec2 rp = vec2(p.x * co - p.y * s, p.x * s + p.y * co);
|
|
32
|
+
vec2 cell = mod(rp, u_scale) - u_scale * 0.5;
|
|
33
|
+
float dist = length(cell) / (u_scale * 0.5);
|
|
34
|
+
float radius = sqrt(1.0 - lum);
|
|
35
|
+
float dot1 = step(dist, radius);
|
|
36
|
+
o_color = vec4(c.rgb * dot1, c.a);
|
|
37
|
+
}`;
|
|
38
|
+
//# sourceMappingURL=glHalftoneEffect.js.map
|