@luma.gl/effects
Version:
Post-processing effects for luma.gl
4 lines • 102 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../src/index.ts", "../src/passes/postprocessing/image-adjust-filters/brightnesscontrast.ts", "../src/passes/postprocessing/image-adjust-filters/denoise.ts", "../src/passes/postprocessing/image-adjust-filters/huesaturation.ts", "../src/passes/postprocessing/image-adjust-filters/noise.ts", "../src/passes/postprocessing/image-adjust-filters/sepia.ts", "../src/passes/postprocessing/image-adjust-filters/vibrance.ts", "../src/passes/postprocessing/image-adjust-filters/vignette.ts", "../src/passes/postprocessing/image-blur-filters/tiltshift.ts", "../src/passes/postprocessing/image-blur-filters/triangleblur.ts", "../src/passes/postprocessing/image-blur-filters/zoomblur.ts", "../src/passes/postprocessing/image-fun-filters/colorhalftone.ts", "../src/passes/postprocessing/image-fun-filters/dotscreen.ts", "../src/passes/postprocessing/image-fun-filters/edgework.ts", "../src/passes/postprocessing/image-fun-filters/hexagonalpixelate.ts", "../src/passes/postprocessing/image-fun-filters/ink.ts", "../src/passes/postprocessing/image-fun-filters/magnify.ts", "../src/passes/postprocessing/image-warp-filters/warp.ts", "../src/passes/postprocessing/image-warp-filters/bulgepinch.ts", "../src/passes/postprocessing/image-warp-filters/swirl.ts", "../src/passes/postprocessing/fxaa/fxaa.ts"],
"sourcesContent": ["// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// POST PROCESSING / SHADER PASS MODULES\n\n// glfx image adjustment shader modules\nexport type {\n BrightnessContrastProps,\n BrightnessContrastUniforms\n} from './passes/postprocessing/image-adjust-filters/brightnesscontrast';\nexport {brightnessContrast} from './passes/postprocessing/image-adjust-filters/brightnesscontrast';\nexport type {\n DenoiseProps,\n DenoiseUniforms\n} from './passes/postprocessing/image-adjust-filters/denoise';\nexport {denoise} from './passes/postprocessing/image-adjust-filters/denoise';\nexport type {\n HueSaturationProps,\n HueSaturationUniforms\n} from './passes/postprocessing/image-adjust-filters/huesaturation';\nexport {hueSaturation} from './passes/postprocessing/image-adjust-filters/huesaturation';\nexport type {NoiseProps, NoiseUniforms} from './passes/postprocessing/image-adjust-filters/noise';\nexport {noise} from './passes/postprocessing/image-adjust-filters/noise';\nexport type {SepiaProps, SepiaUniforms} from './passes/postprocessing/image-adjust-filters/sepia';\nexport {sepia} from './passes/postprocessing/image-adjust-filters/sepia';\nexport type {\n VibranceProps,\n VibranceUniforms\n} from './passes/postprocessing/image-adjust-filters/vibrance';\nexport {vibrance} from './passes/postprocessing/image-adjust-filters/vibrance';\nexport type {\n VignetteProps,\n VignetteUniforms\n} from './passes/postprocessing/image-adjust-filters/vignette';\nexport {vignette} from './passes/postprocessing/image-adjust-filters/vignette';\n\n// glfx BLUR shader modules\nexport type {\n TiltShiftProps,\n TiltShiftUniforms\n} from './passes/postprocessing/image-blur-filters/tiltshift';\nexport {tiltShift} from './passes/postprocessing/image-blur-filters/tiltshift';\nexport type {\n TriangleBlurProps,\n TriangleBlurUniforms\n} from './passes/postprocessing/image-blur-filters/triangleblur';\nexport {triangleBlur} from './passes/postprocessing/image-blur-filters/triangleblur';\nexport type {\n ZoomBlurProps,\n ZoomBlurUniforms\n} from './passes/postprocessing/image-blur-filters/zoomblur';\nexport {zoomBlur} from './passes/postprocessing/image-blur-filters/zoomblur';\n\n// glfx FUN shader modules\nexport type {\n ColorHalftoneProps,\n ColorHalftoneUniforms\n} from './passes/postprocessing/image-fun-filters/colorhalftone';\nexport {colorHalftone} from './passes/postprocessing/image-fun-filters/colorhalftone';\nexport type {\n DotScreenProps,\n DotScreenUniforms\n} from './passes/postprocessing/image-fun-filters/dotscreen';\nexport {dotScreen} from './passes/postprocessing/image-fun-filters/dotscreen';\nexport type {\n EdgeWorkProps,\n EdgeWorkUniforms\n} from './passes/postprocessing/image-fun-filters/edgework';\nexport {edgeWork} from './passes/postprocessing/image-fun-filters/edgework';\nexport type {\n HexagonalPixelateProps,\n HexagonalPixelateUniforms\n} from './passes/postprocessing/image-fun-filters/hexagonalpixelate';\nexport {hexagonalPixelate} from './passes/postprocessing/image-fun-filters/hexagonalpixelate';\nexport type {InkProps, InkUniforms} from './passes/postprocessing/image-fun-filters/ink';\nexport {ink} from './passes/postprocessing/image-fun-filters/ink';\nexport type {\n MagnifyProps,\n MagnifyUniforms\n} from './passes/postprocessing/image-fun-filters/magnify';\nexport {magnify} from './passes/postprocessing/image-fun-filters/magnify';\n\n// glfx WARP shader modules\nexport type {\n BulgePinchProps,\n BulgePinchUniforms\n} from './passes/postprocessing/image-warp-filters/bulgepinch';\nexport {bulgePinch} from './passes/postprocessing/image-warp-filters/bulgepinch';\nexport type {SwirlProps, SwirlUniforms} from './passes/postprocessing/image-warp-filters/swirl';\nexport {swirl} from './passes/postprocessing/image-warp-filters/swirl';\n\n// Postprocessing modules\n// export type {FXAAProps, FXAAUniforms} from './passes/postprocessing/fxaa/fxaa';\nexport {fxaa} from './passes/postprocessing/fxaa/fxaa';\n\n// experimental modules\nexport type {WarpProps, WarpUniforms} from './passes/postprocessing/image-warp-filters/warp';\nexport {warp as _warp} from './passes/postprocessing/image-warp-filters/warp';\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ShaderPass} from '@luma.gl/shadertools';\n\nconst source = /* wgsl */ `\\\nstruct brightnessContrastUniforms {\n brightness: f32,\n contrast: f32\n};\n\n// Binding 0:1 is reserved for shader passes\n@group(0) @binding(1) var<uniform> brightnessContrast : brightnessContrastUniforms;\n\nfn brightnessContrast_filterColor_ext(color: vec4f, texSize: vec2<f32>, texCoords: vec2<f32>) -> vec4f {\n color.rgb += brightnessContrast.brightness;\n if (brightnessContrast.contrast > 0.0) {\n color.rgb = (color.rgb - 0.5) / (1.0 - brightnessContrast.contrast) + 0.5;\n } else {\n color.rgb = (color.rgb - 0.5) * (1.0 + brightnessContrast.contrast) + 0.5;\n }\n return vec4f(1.0, 0.0, 0.0, 1.0);\n}\n`;\n\nconst fs = /* glsl */ `\\\nuniform brightnessContrastUniforms {\n float brightness;\n float contrast;\n} brightnessContrast;\n\nvec4 brightnessContrast_filterColor(vec4 color) {\n color.rgb += brightnessContrast.brightness;\n if (brightnessContrast.contrast > 0.0) {\n color.rgb = (color.rgb - 0.5) / (1.0 - brightnessContrast.contrast) + 0.5;\n } else {\n color.rgb = (color.rgb - 0.5) * (1.0 + brightnessContrast.contrast) + 0.5;\n }\n return color;\n}\n\nvec4 brightnessContrast_filterColor_ext(vec4 color, vec2 texSize, vec2 texCoord) {\n return brightnessContrast_filterColor(color);\n}\n`;\n\nexport type BrightnessContrastProps = {\n brightness?: number;\n contrast?: number;\n};\n\nexport type BrightnessContrastUniforms = BrightnessContrastProps;\n\n/**\n * Brightness / Contrast -\n * Provides additive brightness and multiplicative contrast control.\n * @param brightness -1 to 1 (-1 is solid black, 0 is no change, and 1 is solid white)\n * @param contrast -1 to 1 (-1 is solid gray, 0 is no change, and 1 is maximum contrast)\n */\nexport const brightnessContrast = {\n name: 'brightnessContrast',\n source,\n fs,\n\n props: {} as BrightnessContrastProps,\n uniformTypes: {\n brightness: 'f32',\n contrast: 'f32'\n },\n defaultUniforms: {\n brightness: 0,\n contrast: 0\n },\n propTypes: {\n brightness: {format: 'f32', value: 0, min: -1, max: 1},\n contrast: {format: 'f32', value: 0, min: -1, max: 1}\n },\n\n passes: [{filter: true}]\n} as const satisfies ShaderPass<BrightnessContrastProps>;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ShaderPass} from '@luma.gl/shadertools';\n\n// Do a 9x9 bilateral box filter\nconst source = /* wgsl */ `\\\n\nstruct denoiseUniforms {\n strength: f32\n};\n\n@group(0), @binding(1) var<uniform> denoise: denoiseUniforms;\n\nfn denoise_sampleColor(source: sampler2D, texSize: vec2<f32>, texCoord: vec2<f32>) -> vec4<f32> {\n\tlet adjustedExponent: f32 = 3. + 200. * pow(1. - denoise.strength, 4.);\n\tlet center: vec4<f32> = sample_texture(BUFFER_source, texCoord);\n\tvar color: vec4<f32> = vec4<f32>(0.);\n\tvar total: f32 = 0.;\n\n\tfor (var x: f32 = -4.; x <= 4.; x = x + (1.)) {\n\n\t\tfor (var y: f32 = -4.; y <= 4.; y = y + (1.)) {\n\t\t\tlet offsetColor: vec4<f32> = sample_texture(BUFFER_source, texCoord + vec2<f32>(x, y) / texSize);\n\t\t\tvar weight: f32 = 1. - abs(dot(offsetColor.rgb - center.rgb, vec3<f32>(0.25)));\n\t\t\tweight = pow(weight, adjustedExponent);\n\t\t\tcolor = color + (offsetColor * weight);\n\t\t\ttotal = total + (weight);\n\t\t}\n\n\t}\n\n\treturn color / total;\n} \n`;\n\nconst fs = /* glsl */ `\\\nuniform dedenoiseUniforms {\n float strength;\n} denoise;\n\nvec4 dedenoise_sampleColor(sampler2D source, vec2 texSize, vec2 texCoord) {\n float adjustedExponent = 3. + 200. * pow(1. - noise.strength, 4.);\n\n vec4 center = texture(source, texCoord);\n vec4 color = vec4(0.0);\n float total = 0.0;\n for (float x = -4.0; x <= 4.0; x += 1.0) {\n for (float y = -4.0; y <= 4.0; y += 1.0) {\n vec4 offsetColor = texture(source, texCoord + vec2(x, y) / texSize);\n float weight = 1.0 - abs(dot(offsetColor.rgb - center.rgb, vec3(0.25)));\n weight = pow(weight, adjustedExponent);\n color += offsetColor * weight;\n total += weight;\n }\n }\n\n return color / total;\n}\n`;\n\n/**\n * Denoise -\n * Smooths over grainy noise in dark images using an 9x9 box filter\n * weighted by color intensity, similar to a bilateral filter.\n */\nexport type DenoiseProps = {\n /**\n * The exponent of the color intensity difference, should be greater\n * than zero. A value of zero just gives an 9x9 box blur and high values\n * give the original image, but ideal values are usually around 10-20.\n */\n strength?: number;\n};\n\nexport type DenoiseUniforms = DenoiseProps;\n\n/**\n * Denoise -\n * Smooths over grainy noise in dark images using an 9x9 box filter\n * weighted by color intensity, similar to a bilateral filter.\n */\nexport const denoise = {\n props: {} as DenoiseProps,\n uniforms: {} as DenoiseUniforms,\n\n name: 'denoise',\n uniformTypes: {\n strength: 'f32'\n },\n propTypes: {\n strength: {format: 'f32', value: 0.5, min: 0, max: 1}\n // strength: {..., adjust: (strength: number): number => 0.53 + 200 * Math.pow(1 - strength, 4) // TODO - JS preprocessing\n },\n\n source,\n fs,\n\n passes: [{sampler: true}, {sampler: true}]\n} as const satisfies ShaderPass<DenoiseProps, DenoiseUniforms>;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ShaderPass} from '@luma.gl/shadertools';\n\nconst source = /* wgsl */ `\\\n\nstruct hueSaturationUniforms {\n hue: f32,\n saturation: f32,\n};\n\n@group(0), @binding(1) var<uniform> hueSaturation: hueSaturationUniforms;\n\nfn hueSaturation_filterColor(color: vec4<f32>) -> vec4<f32> {\n\tlet angle: f32 = hueSaturation.hue * 3.1415927;\n\tlet s: f32 = sin(angle);\n\tlet c: f32 = cos(angle);\n\tlet weights: vec3<f32> = (vec3<f32>(2. * c, -sqrt(3.) * s - c, sqrt(3.) * s - c) + 1.) / 3.;\n\tlet len: f32 = length(color.rgb);\n\tvar colorrgb = color.rgb;\n\tcolorrgb = vec3<f32>(dot(color.rgb, weights.xyz), dot(color.rgb, weights.zxy), dot(color.rgb, weights.yzx));\n\tcolor.r = colorrgb.x;\n\tcolor.g = colorrgb.y;\n\tcolor.b = colorrgb.z;\n\tlet average: f32 = (color.r + color.g + color.b) / 3.;\n\tif (hueSaturation.saturation > 0.) {\n\t\tvar colorrgb = color.rgb;\n\tcolorrgb = color.rgb + ((average - color.rgb) * (1. - 1. / (1.001 - hueSaturation.saturation)));\n\tcolor.r = colorrgb.x;\n\tcolor.g = colorrgb.y;\n\tcolor.b = colorrgb.z;\n\t} else { \n\t\tvar colorrgb = color.rgb;\n\tcolorrgb = color.rgb + ((average - color.rgb) * -hueSaturation.saturation);\n\tcolor.r = colorrgb.x;\n\tcolor.g = colorrgb.y;\n\tcolor.b = colorrgb.z;\n\t}\n\treturn color;\n} \n\nfn hueSaturation_filterColor_ext(color: vec4<f32>, texSize: vec2<f32>, texCoord: vec2<f32>) -> vec4<f32> {\n\treturn hueSaturation_filterColor(color);\n} \n`;\n\nconst fs = /* glsl */ `\\\nuniform hueSaturationUniforms {\n float hue;\n float saturation;\n} hueSaturation;\n\nvec4 hueSaturation_filterColor(vec4 color) {\n // hue adjustment, wolfram alpha: RotationTransform[angle, {1, 1, 1}][{x, y, z}]\n float angle = hueSaturation.hue * 3.14159265;\n float s = sin(angle), c = cos(angle);\n vec3 weights = (vec3(2.0 * c, -sqrt(3.0) * s - c, sqrt(3.0) * s - c) + 1.0) / 3.0;\n float len = length(color.rgb);\n color.rgb = vec3(\n dot(color.rgb, weights.xyz),\n dot(color.rgb, weights.zxy),\n dot(color.rgb, weights.yzx)\n );\n\n // saturation adjustment\n float average = (color.r + color.g + color.b) / 3.0;\n if (hueSaturation.saturation > 0.0) {\n color.rgb += (average - color.rgb) * (1.0 - 1.0 / (1.001 - hueSaturation.saturation));\n } else {\n color.rgb += (average - color.rgb) * (-hueSaturation.saturation);\n }\n\n return color;\n}\n\nvec4 hueSaturation_filterColor_ext(vec4 color, vec2 texSize, vec2 texCoord) {\n return hueSaturation_filterColor(color);\n}\n`;\n\n/**\n * Hue / Saturation\n */\nexport type HueSaturationProps = {\n /** -1 to 1 (-1 is 180 degree rotation in the negative direction, 0 is no change,\n * and 1 is 180 degree rotation in the positive direction) */\n hue?: number;\n /** -1 to 1 (-1 is solid gray, 0 is no change, and 1 is maximum contrast) */\n saturation?: number;\n};\n\nexport type HueSaturationUniforms = HueSaturationProps;\n\n/**\n * Hue / Saturation\n * Provides rotational hue and multiplicative saturation control. RGB color space\n * can be imagined as a cube where the axes are the red, green, and blue color\n * values. Hue changing works by rotating the color vector around the grayscale\n * line, which is the straight line from black (0, 0, 0) to white (1, 1, 1).\n * Saturation is implemented by scaling all color channel values either toward\n * or away from the average color channel value.\n */\nexport const hueSaturation = {\n props: {} as HueSaturationProps,\n\n name: 'hueSaturation',\n source,\n fs,\n\n uniformTypes: {\n hue: 'f32',\n saturation: 'f32'\n },\n propTypes: {\n hue: {value: 0, min: -1, max: 1},\n saturation: {value: 0, min: -1, max: 1}\n },\n passes: [{filter: true}]\n} as const satisfies ShaderPass<HueSaturationProps>;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ShaderPass} from '@luma.gl/shadertools';\n\nconst source = /* wgsl */ `\\\nstruct noiseUniforms {\n amount: f32\n};\n\n@group(0) @binding(1) var<uniform> noise: noiseUniforms;\n\nfn rand(co: vec2f) -> f32 {\n\treturn fract(sin(dot(co.xy, vec2f(12.9898, 78.233))) * 43758.547);\n} \n\nfn noise_filterColor_ext(color: vec4f, texSize: vec2f, texCoord: vec2f) -> vec4f {\n\tlet diff: f32 = (rand(texCoord) - 0.5) * noise.amount;\n\tcolor.r = color.r + (diff);\n\tcolor.g = color.g + (diff);\n\tcolor.b = color.b + (diff);\n\treturn color;\n} \n`;\n\nconst fs = /* glsl */ `\\\nuniform noiseUniforms {\n float amount;\n} noise;\n\nfloat rand(vec2 co) {\n return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\n}\n\nvec4 noise_filterColor_ext(vec4 color, vec2 texSize, vec2 texCoord) {\n float diff = (rand(texCoord) - 0.5) * noise.amount;\n color.r += diff;\n color.g += diff;\n color.b += diff;\n return color;\n}\n`;\n\n/**\n * Noise - Adds black and white noise to the image.\n */\nexport type NoiseProps = {\n /** 0 to 1 (0 for no effect, 1 for maximum noise) */\n amount?: number;\n};\n\nexport type NoiseUniforms = NoiseProps;\n\n/**\n * Noise\n * Adds black and white noise to the image.\n */\nexport const noise = {\n name: 'noise',\n fs,\n source,\n\n props: {} as NoiseProps,\n uniforms: {} as NoiseUniforms,\n uniformTypes: {\n amount: 'f32'\n },\n propTypes: {\n amount: {value: 0.5, min: 0, max: 1}\n },\n\n passes: [{filter: true}]\n} as const satisfies ShaderPass<NoiseProps, NoiseProps>;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ShaderPass} from '@luma.gl/shadertools';\n\nconst source = /* wgsl */ `\\\nstruct sepiaUniforms {\n amount: f32\n};\n\n@group(0) @binding(1) var<uniform> sepia: sepiaUniforms;\n\nfn sepia_filterColor(color: vec4f) -> vec4f {\n let r: f32 = color.r;\n let g: f32 = color.g;\n let b: f32 = color.b;\n\n color.r =\n min(1.0, (r * (1.0 - (0.607 * sepia.amount))) + (g * (0.769 * sepia.amount)) + (b * (0.189 * sepia.amount)));\n color.g = min(1.0, (r * 0.349 * sepia.amount) + (g * (1.0 - (0.314 * sepia.amount))) + (b * 0.168 * sepia.amount));\n color.b = min(1.0, (r * 0.272 * sepia.amount) + (g * 0.534 * sepia.amount) + (b * (1.0 - (0.869 * sepia.amount))));\n\n return color;\n}\n\nvec4 sepia_filterColor_ext(vec4 color, vec2 texSize, vec2 texCoord) {\n return sepia_filterColor(color);\n}\n`;\n\nconst fs = /* glsl */ `\\\nuniform sepiaUniforms {\n float amount;\n} sepia;\n\nvec4 sepia_filterColor(vec4 color) {\n float r = color.r;\n float g = color.g;\n float b = color.b;\n\n color.r =\n min(1.0, (r * (1.0 - (0.607 * sepia.amount))) + (g * (0.769 * sepia.amount)) + (b * (0.189 * sepia.amount)));\n color.g = min(1.0, (r * 0.349 * sepia.amount) + (g * (1.0 - (0.314 * sepia.amount))) + (b * 0.168 * sepia.amount));\n color.b = min(1.0, (r * 0.272 * sepia.amount) + (g * 0.534 * sepia.amount) + (b * (1.0 - (0.869 * sepia.amount))));\n\n return color;\n}\n\nvec4 sepia_filterColor_ext(vec4 color, vec2 texSize, vec2 texCoord) {\n return sepia_filterColor(color);\n}\n`;\n\nexport type SepiaProps = {\n amount?: number;\n};\n\nexport type SepiaUniforms = SepiaProps;\n\n/**\n * @filter Sepia\n * @description Gives the image a reddish-brown monochrome tint that imitates an old photograph.\n * @param amount 0 to 1 (0 for no effect, 1 for full sepia coloring)\n */\nexport const sepia = {\n props: {} as SepiaProps,\n uniforms: {} as SepiaUniforms,\n\n name: 'sepia',\n uniformTypes: {\n amount: 'f32'\n },\n propTypes: {\n amount: {value: 0.5, min: 0, max: 1}\n },\n fs,\n source,\n passes: [{filter: true}]\n} as const satisfies ShaderPass<SepiaProps, SepiaProps>;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ShaderPass} from '@luma.gl/shadertools';\n\nconst source = /* wgsl */ `\\\nstruct vibranceUniforms {\n amount: f32\n};\n\n@group(0) @binding(1) var<uniform> vibrance: vibranceUniforms;\n\nfn vibrance_filterColor(vec4f color) -> vec4f {\n let average: f32 = (color.r + color.g + color.b) / 3.0;\n let mx: f32 = max(color.r, max(color.g, color.b));\n let amt: f32 = (mx - average) * (-vibrance.amount * 3.0);\n color.rgb = mix(color.rgb, vec3(mx), amt);\n return color;\n}\n\nvec4 vibrance_filterColor_ext(vec4 color, vec2 texSize, vec2 texCoord) {\n return vibrance_filterColor(color);\n}\n`;\n\nconst fs = /* glsl */ `\\\nuniform vibranceUniforms {\n float amount;\n} vibrance;\n\nvec4 vibrance_filterColor(vec4 color) {\n float average = (color.r + color.g + color.b) / 3.0;\n float mx = max(color.r, max(color.g, color.b));\n float amt = (mx - average) * (-vibrance.amount * 3.0);\n color.rgb = mix(color.rgb, vec3(mx), amt);\n return color;\n}\n\nvec4 vibrance_filterColor_ext(vec4 color, vec2 texSize, vec2 texCoord) {\n return vibrance_filterColor(color);\n}\n`;\n\n/**\n * Vibrance - Modifies the saturation of desaturated colors, leaving saturated colors unmodified.\n */\nexport type VibranceProps = {\n /** -1 to 1 (-1 is minimum vibrance, 0 is no change, and 1 is maximum vibrance) */\n amount?: number;\n};\n\nexport type VibranceUniforms = VibranceProps;\n\n/** Vibrance - Modifies the saturation of desaturated colors, leaving saturated colors unmodified. */\nexport const vibrance = {\n props: {} as VibranceProps,\n uniforms: {} as VibranceUniforms,\n name: 'vibrance',\n uniformTypes: {\n amount: 'f32'\n },\n propTypes: {\n amount: {value: 0, min: -1, max: 1}\n },\n source,\n fs,\n passes: [{filter: true}]\n} as const satisfies ShaderPass<VibranceProps, VibranceProps>;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ShaderPass} from '@luma.gl/shadertools';\n\nconst source = /* wgsl */ `\\\nstruct vignetteUniforms {\n radius: f32,\n amount: f32\n};\n\n@group(0) @binding(1) var<uniform> vignette: vignetteUniforms;\n\nfn vibrance_filterColor(color: vec4f) -> vec4f {\n let average: f32 = (color.r + color.g + color.b) / 3.0;\n let mx: f32 = max(color.r, max(color.g, color.b));\n let amt: f32 = (mx - average) * (-vibrance.amount * 3.0);\n color.rgb = mix(color.rgb, vec3f(mx), amt);\n return color;\n}\n\nfn vignette_filterColor_ext(color: vec4f, texSize: vec2f, texCoord: vec2f) ->vec4f {\n let dist: f32 = distance(texCoord, vec2f(0.5, 0.5));\n let ratio: f32 = smoothstep(0.8, vignette.radius * 0.799, dist * (vignette.amount + vignette.radius));\n return color.rgba * ratio + (1.0 - ratio)*vec4f(0.0, 0.0, 0.0, 1.0);\n}\n`;\n\nconst fs = /* glsl */ `\\\nuniform vignetteUniforms {\n float radius;\n float amount;\n} vignette;\n\nvec4 vignette_filterColor_ext(vec4 color, vec2 texSize, vec2 texCoord) {\n float dist = distance(texCoord, vec2(0.5, 0.5));\n float ratio = smoothstep(0.8, vignette.radius * 0.799, dist * (vignette.amount + vignette.radius));\n return color.rgba * ratio + (1.0 - ratio)*vec4(0.0, 0.0, 0.0, 1.0);\n}\n`;\n\n/**\n * Vignette - Adds a simulated lens edge darkening effect.\n */\nexport type VignetteProps = {\n /** 0 to 1 (0 for center of frame, 1 for edge of frame) */\n radius?: number;\n /** 0 to 1 (0 for no effect, 1 for maximum lens darkening) */\n amount?: number;\n};\n\nexport type VignetteUniforms = VignetteProps;\n\n/**\n * Vignette -\n * Adds a simulated lens edge darkening effect.\n */\nexport const vignette = {\n props: {} as VignetteProps,\n uniforms: {} as VignetteUniforms,\n\n name: 'vignette',\n source,\n fs,\n\n uniformTypes: {\n radius: 'f32',\n amount: 'f32'\n },\n defaultUniforms: {\n radius: 0.5,\n amount: 0.5\n },\n propTypes: {\n radius: {value: 0.5, min: 0, max: 1},\n amount: {value: 0.5, min: 0, max: 1}\n },\n\n passes: [{filter: true}]\n} as const satisfies ShaderPass<VignetteProps, VignetteProps>;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ShaderPass} from '@luma.gl/shadertools';\nimport {random} from '@luma.gl/shadertools';\n\nconst source = /* wgsl */ `\\\nuniform tiltShiftUniforms {\n blurRadius: f32,\n gradientRadius: f32,\n start: vec2f,\n end: vec2f,\n invert: u32,\n};\n\n@group(0) @binding(1) var<uniform> tiltShift: tiltShiftUniforms;\n\nfn tiltShift_getDelta(vec2 texSize) -> vec2f {\n vec2 vector = normalize((tiltShift.end - tiltShift.start) * texSize);\n return tiltShift.invert ? vec2(-vector.y, vector.x) : vector;\n}\n\nfn tiltShift_sampleColor(sampler2D source, vec2 texSize, vec2 texCoord) -> vec4f {\n vec4 color = vec4(0.0);\n float total = 0.0;\n\n /* randomize the lookup values to hide the fixed number of samples */\n float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);\n\n vec2 normal = normalize(vec2((tiltShift.start.y - tiltShift.end.y) * texSize.y, (tiltShift.end.x - tiltShift.start.x) * texSize.x));\n float radius = smoothstep(0.0, 1.0,\n abs(dot(texCoord * texSize - tiltShift.start * texSize, normal)) / tiltShift.gradientRadius) * tiltShift.blurRadius;\n\n for (float t = -30.0; t <= 30.0; t++) {\n float percent = (t + offset - 0.5) / 30.0;\n float weight = 1.0 - abs(percent);\n vec4 offsetColor = texture(source, texCoord + tiltShift_getDelta(texSize) / texSize * percent * radius);\n\n color += offsetColor * weight;\n total += weight;\n }\n\n color = color / total;\n return color;\n}\n`;\n\nconst fs = /* glsl */ `\\\nuniform tiltShiftUniforms {\n float blurRadius;\n float gradientRadius;\n vec2 start;\n vec2 end;\n bool invert;\n} tiltShift;\n\nvec2 tiltShift_getDelta(vec2 texSize) {\n vec2 vector = normalize((tiltShift.end - tiltShift.start) * texSize);\n return tiltShift.invert ? vec2(-vector.y, vector.x) : vector;\n}\n\nvec4 tiltShift_sampleColor(sampler2D source, vec2 texSize, vec2 texCoord) {\n vec4 color = vec4(0.0);\n float total = 0.0;\n\n /* randomize the lookup values to hide the fixed number of samples */\n float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);\n\n vec2 normal = normalize(vec2((tiltShift.start.y - tiltShift.end.y) * texSize.y, (tiltShift.end.x - tiltShift.start.x) * texSize.x));\n float radius = smoothstep(0.0, 1.0,\n abs(dot(texCoord * texSize - tiltShift.start * texSize, normal)) / tiltShift.gradientRadius) * tiltShift.blurRadius;\n\n for (float t = -30.0; t <= 30.0; t++) {\n float percent = (t + offset - 0.5) / 30.0;\n float weight = 1.0 - abs(percent);\n vec4 offsetColor = texture(source, texCoord + tiltShift_getDelta(texSize) / texSize * percent * radius);\n color += offsetColor * weight;\n total += weight;\n }\n\n color = color / total;\n return color;\n}\n`;\n\n/**\n * Tilt Shift\n * Simulates the shallow depth of field normally encountered in close-up photography\n */\nexport type TiltShiftProps = {\n /** The x,y coordinate of the start of the line segment. */\n start?: [number, number];\n /** The xm y coordinate of the end of the line segment. */\n end?: [number, number];\n /** The maximum radius of the pyramid blur. */\n blurRadius?: number;\n /** The distance from the line at which the maximum blur radius is reached. */\n gradientRadius?: number;\n /** @deprecated internal shaderpass use */\n invert?: number;\n};\n\nexport type TiltShiftUniforms = TiltShiftProps;\n\n/**\n * Tilt Shift\n * Simulates the shallow depth of field normally encountered in close-up\n * photography, which makes the scene seem much smaller than it actually\n * is. This filter assumes the scene is relatively planar, in which case\n * the part of the scene that is completely in focus can be described by\n * a line (the intersection of the focal plane and the scene). An example\n * of a planar scene might be looking at a road from above at a downward\n * angle. The image is then blurred with a blur radius that starts at zero\n * on the line and increases further from the line.\n */\nexport const tiltShift = {\n name: 'tiltShift',\n dependencies: [random],\n source,\n fs,\n\n props: {} as TiltShiftProps,\n uniforms: {} as TiltShiftUniforms,\n uniformTypes: {\n blurRadius: 'f32',\n gradientRadius: 'f32',\n start: 'vec2<f32>',\n end: 'vec2<f32>',\n invert: 'i32'\n },\n propTypes: {\n blurRadius: {value: 15, min: 0, max: 50},\n gradientRadius: {value: 200, min: 0, max: 400},\n start: {value: [0, 0]},\n end: {value: [1, 1]},\n invert: {value: 0, private: true}\n },\n\n passes: [\n {sampler: true, uniforms: {invert: 0}},\n {sampler: true, uniforms: {invert: 1}}\n ]\n} as const satisfies ShaderPass<TiltShiftProps, TiltShiftProps>;\n\n/*\nfunction tiltShift(startX, startY, endX, endY, blurRadius, gradientRadius) {\n var dx = endX - startX;\n var dy = endY - startY;\n var d = Math.sqrt(dx * dx + dy * dy);\n simpleShader.call(this, gl.tiltShift, {\n blurRadius: blurRadius,\n gradientRadius: gradientRadius,\n start: [startX, startY],\n end: [endX, endY],\n delta: [dx / d, dy / d],\n texSize: [this.width, this.height]\n });\n simpleShader.call(this, gl.tiltShift, {\n blurRadius: blurRadius,\n gradientRadius: gradientRadius,\n start: [startX, startY],\n end: [endX, endY],\n delta: [-dy / d, dx / d],\n texSize: [this.width, this.height]\n });\n\n return this;\n}\n*/\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ShaderPass} from '@luma.gl/shadertools';\nimport {random} from '@luma.gl/shadertools';\n\nconst source = /* wgsl */ `\\\nuniform triangleBlurUniforms {\n radius: f32,\n delta: vec2f,\n}\n\n@group(0) @binding(1) var<uniform> triangleBlur: triangleBlurUniforms;\n\nvec4 triangleBlur_sampleColor(sampler2D source, vec2 texSize, vec2 texCoord) {\n vec2 adjustedDelta = triangleBlur.delta * triangleBlur.radius / texSize;\n\n vec4 color = vec4(0.0);\n float total = 0.0;\n\n /* randomize the lookup values to hide the fixed number of samples */\n float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);\n\n for (float t = -30.0; t <= 30.0; t++) {\n float percent = (t + offset - 0.5) / 30.0;\n float weight = 1.0 - abs(percent);\n vec4 offsetColor = texture(source, texCoord + adjustedDelta * percent);\n\n /* switch to pre-multiplied alpha to correctly blur transparent images */\n offsetColor.rgb *= offsetColor.a;\n\n color += offsetColor * weight;\n total += weight;\n }\n\n color = color / total;\n\n /* switch back from pre-multiplied alpha */\n color.rgb /= color.a + 0.00001;\n\n return color;\n}\n`;\n\nconst fs = /* glsl */ `\\\nuniform triangleBlurUniforms {\n float radius;\n vec2 delta;\n} triangleBlur;\n\nvec4 triangleBlur_sampleColor(sampler2D source, vec2 texSize, vec2 texCoord) {\n vec2 adjustedDelta = triangleBlur.delta * triangleBlur.radius / texSize;\n\n vec4 color = vec4(0.0);\n float total = 0.0;\n\n /* randomize the lookup values to hide the fixed number of samples */\n float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);\n\n for (float t = -30.0; t <= 30.0; t++) {\n float percent = (t + offset - 0.5) / 30.0;\n float weight = 1.0 - abs(percent);\n vec4 offsetColor = texture(source, texCoord + adjustedDelta * percent);\n\n /* switch to pre-multiplied alpha to correctly blur transparent images */\n offsetColor.rgb *= offsetColor.a;\n\n color += offsetColor * weight;\n total += weight;\n }\n\n color = color / total;\n\n /* switch back from pre-multiplied alpha */\n color.rgb /= color.a + 0.00001;\n\n return color;\n}\n`;\n\n/**\n * @filter Triangle Blur\n * @description This is the most basic blur filter, which convolves the image with a\n * pyramid filter. The pyramid filter is separable and is applied as two\n * perpendicular triangle filters.\n */\nexport type TriangleBlurProps = {\n /** The radius of the pyramid convolved with the image. */\n radius?: number;\n /** @deprecated internal property */\n delta?: [number, number];\n};\n\nexport type TriangleBlurUniforms = TriangleBlurProps;\n\n/**\n * @filter Triangle Blur\n * @description This is the most basic blur filter, which convolves the image with a\n * pyramid filter. The pyramid filter is separable and is applied as two\n * perpendicular triangle filters.\n */\nexport const triangleBlur = {\n name: 'triangleBlur',\n dependencies: [random],\n source,\n fs,\n\n props: {} as TriangleBlurProps,\n uniforms: {} as TriangleBlurUniforms,\n uniformTypes: {\n radius: 'f32',\n delta: 'vec2<f32>'\n },\n propTypes: {\n radius: {value: 20, min: 0, softMax: 100},\n delta: {value: [1, 0], private: true}\n },\n\n passes: [\n {sampler: true, uniforms: {delta: [1, 0]}},\n {sampler: true, uniforms: {delta: [0, 1]}}\n ]\n} as const satisfies ShaderPass<TriangleBlurProps, TriangleBlurProps>;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ShaderPass} from '@luma.gl/shadertools';\nimport {random} from '@luma.gl/shadertools';\n\nconst source = /* wgsl */ `\nuniform zoomBlurUniforms {\n center: vec2f,\n strength: f32,\n};\n\n@group(0) @binding(1) var<uniform> zoomBlur : zoomBlurUniforms;\n\n\nfn zoomBlur_sampleColor(sampler2D source, vec2 texSize, vec2 texCoord) -> vec4f {\n vec4 color = vec4(0.0);\n float total = 0.0;\n vec2 toCenter = zoomBlur.center * texSize - texCoord * texSize;\n\n /* randomize the lookup values to hide the fixed number of samples */\n float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);\n\n for (float t = 0.0; t <= 40.0; t++) {\n float percent = (t + offset) / 40.0;\n float weight = 4.0 * (percent - percent * percent);\n vec4 offsetColor = texture(source, texCoord + toCenter * percent * zoomBlur.strength / texSize);\n color += offsetColor * weight;\n total += weight;\n }\n\n color = color / total;\n return color;\n}\n`;\n\nconst fs = /* glsl */ `\nuniform zoomBlurUniforms {\n vec2 center;\n float strength;\n} zoomBlur;\n\nvec4 zoomBlur_sampleColor(sampler2D source, vec2 texSize, vec2 texCoord) {\n vec4 color = vec4(0.0);\n float total = 0.0;\n vec2 toCenter = zoomBlur.center * texSize - texCoord * texSize;\n\n /* randomize the lookup values to hide the fixed number of samples */\n float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);\n\n for (float t = 0.0; t <= 40.0; t++) {\n float percent = (t + offset) / 40.0;\n float weight = 4.0 * (percent - percent * percent);\n vec4 offsetColor = texture(source, texCoord + toCenter * percent * zoomBlur.strength / texSize);\n color += offsetColor * weight;\n total += weight;\n }\n\n color = color / total;\n return color;\n}\n`;\n\n/**\n * Zoom Blur - Blurs the image away from a certain point, which looks like radial motion blur.\n */\nexport type ZoomBlurProps = {\n /** - The x, y coordinate of the blur origin. */\n center?: [number, number];\n /** - The strength of the blur. Values in the range 0 to 1 are usually sufficient, where 0 doesn't change the image and 1 creates a highly blurred image. */\n strength?: number;\n};\n\nexport type ZoomBlurUniforms = ZoomBlurProps;\n\n/**\n * Zoom Blur\n * Blurs the image away from a certain point, which looks like radial motion blur.\n */\nexport const zoomBlur = {\n name: 'zoomBlur',\n dependencies: [random],\n source,\n fs,\n\n props: {} as ZoomBlurProps,\n uniforms: {} as ZoomBlurUniforms,\n uniformTypes: {\n center: 'vec2<f32>',\n strength: 'f32'\n },\n propTypes: {\n center: {value: [0.5, 0.5]},\n strength: {value: 0.3, min: 0, softMax: 1}\n },\n\n passes: [{sampler: true}]\n} as const satisfies ShaderPass<ZoomBlurProps, ZoomBlurProps>;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ShaderPass} from '@luma.gl/shadertools';\n\nconst source = /* wgsl */ `\\\nstruct colorHalftoneUniforms {\n center: vec2f,\n angle: f32,\n size: f32.\n};\n\n@group(0) @binding(1) var<uniform> colorHalftone: colorHalftoneUniforms;\n\nfn pattern(angle: f32, scale: f32, texSize: vec2f, texCoord: vec2f) -> f32 {\n let s: f32 = sin(angle), c = cos(angle);\n let tex: vec2f = texCoord * texSize - colorHalftone.center * texSize;\n let point: vec2f = vec2(\n\t c * tex.x - s * tex.y,\n\t s * tex.x + c * tex.y\n ) * scale;\n return (sin(point.x) * sin(point.y)) * 4.0;\n}\n\nfn colorHalftone_filterColor_ext(vec4f color, vec2f texSize, vec2f texCoord) -> vec4f {\n let scale: f32 = 3.1514 / colorHalftone.size;\n let cmy: vec3f = 1.0 - color.rgb;\n let k: f32 = min(cmy.x, min(cmy.y, cmy.z));\n\n cmy = (cmy - k) / (1.0 - k);\n cmy = clamp(\n\t cmy * 10.0 - 3.0 + vec3(\n pattern(colorHalftone.angle + 0.26179, scale, texSize, texCoord),\n\t pattern(colorHalftone.angle + 1.30899, scale, texSize, texCoord),\n pattern(colorHalftone.angle, scale, texSize, texCoord)\n ),\n\t 0.0,\n\t 1.0\n );\n k = clamp(k * 10.0 - 5.0 + pattern(colorHalftone.angle + 0.78539, scale, texSize, texCoord), 0.0, 1.0);\n return vec4(1.0 - cmy - k, color.a);\n}\n`;\n\n// TODO pass texCoord to angle\nconst fs = /* glsl */ `\\\nuniform colorHalftoneUniforms {\n vec2 center;\n float angle;\n float size;\n} colorHalftone;\n\nfloat pattern(float angle, float scale, vec2 texSize, vec2 texCoord) {\n float s = sin(angle), c = cos(angle);\n vec2 tex = texCoord * texSize - colorHalftone.center * texSize;\n vec2 point = vec2(\n\tc * tex.x - s * tex.y,\n\ts * tex.x + c * tex.y\n ) * scale;\n return (sin(point.x) * sin(point.y)) * 4.0;\n}\n\nvec4 colorHalftone_filterColor_ext(vec4 color, vec2 texSize, vec2 texCoord) {\n float scale = 3.1514 / colorHalftone.size;\n vec3 cmy = 1.0 - color.rgb;\n float k = min(cmy.x, min(cmy.y, cmy.z));\n\n cmy = (cmy - k) / (1.0 - k);\n cmy = clamp(\n\t cmy * 10.0 - 3.0 + vec3(\n pattern(colorHalftone.angle + 0.26179, scale, texSize, texCoord),\n\t pattern(colorHalftone.angle + 1.30899, scale, texSize, texCoord),\n pattern(colorHalftone.angle, scale, texSize, texCoord)\n ),\n\t 0.0,\n\t 1.0\n );\n k = clamp(k * 10.0 - 5.0 + pattern(colorHalftone.angle + 0.78539, scale, texSize, texCoord), 0.0, 1.0);\n return vec4(1.0 - cmy - k, color.a);\n}\n`;\n\n/**\n * Color Halftone -\n * Simulates a CMYK halftone rendering of the image by multiplying pixel values\n * with a four rotated 2D sine wave patterns, one each for cyan, magenta, yellow,\n * and black.\n */\nexport type ColorHalftoneProps = {\n /** The x,y coordinate of the pattern origin. */\n center?: [number, number];\n /** The rotation of the pattern in radians. */\n angle?: number;\n /** The diameter of a dot in pixels. */\n size?: number;\n};\n\nexport type ColorHalftoneUniforms = ColorHalftoneProps;\n\n/**\n * Color Halftone -\n * Simulates a CMYK halftone rendering of the image by multiplying pixel values\n * with a four rotated 2D sine wave patterns, one each for cyan, magenta, yellow,\n * and black.\n */\nexport const colorHalftone = {\n name: 'colorHalftone',\n source,\n fs,\n\n props: {} as ColorHalftoneProps,\n uniforms: {} as ColorHalftoneUniforms,\n uniformTypes: {\n center: 'vec2<f32>',\n angle: 'f32',\n size: 'f32'\n },\n propTypes: {\n center: {value: [0.5, 0.5]},\n angle: {value: 1.1, softMin: 0, softMax: Math.PI / 2},\n size: {value: 4, min: 1, softMin: 3, softMax: 20}\n },\n\n passes: [{filter: true}]\n} as const satisfies ShaderPass<ColorHalftoneProps, ColorHalftoneProps>;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ShaderPass} from '@luma.gl/shadertools';\n\nconst source = /* wgsl */ `\\\nuniform dotScreenUniforms {\n center: vec2f,\n angle: f32,\n size: f32,\n};\n\n@group(0) @binding(1) dotScreen: dotScreenUniforms;\n\nfn pattern(texSize: vec2f, texCoord: vec2f) -> f32 {\n let scale: f32 = 3.1415 / dotScreen.size;\n\n let s: f32 = sin(dotScreen.angle), c = cos(dotScreen.angle);\n tex: vec2f = texCoord * texSize - dotScreen.center * texSize;\n point = vec2f( \n c: * tex.x - s * tex.y,\n s * tex.x + c * tex.y\n ) * scale;\n return (sin(point.x) * sin(point.y)) * 4.0;\n}\n\nfn dotScreen_filterColor_ext(vec4 color, texSize: vec2f, texCoord: vec2f) -> vec4f {\n let average: f32 = (color.r + color.g + color.b) / 3.0;\n return vec4(vec3(average * 10.0 - 5.0 + pattern(texSize, texCoord)), color.a);\n}\n`;\n\nconst fs = /* glsl */ `\\\nuniform dotScreenUniforms {\n vec2 center;\n float angle;\n float size;\n} dotScreen;\n\nfloat pattern(vec2 texSize, vec2 texCoord) {\n float scale = 3.1415 / dotScreen.size;\n\n float s = sin(dotScreen.angle), c = cos(dotScreen.angle);\n vec2 tex = texCoord * texSize - dotScreen.center * texSize;\n vec2 point = vec2(\n c * tex.x - s * tex.y,\n s * tex.x + c * tex.y\n ) * scale;\n return (sin(point.x) * sin(point.y)) * 4.0;\n}\n\nvec4 dotScreen_filterColor_ext(vec4 color, vec2 texSize, vec2 texCoord) {\n float average = (color.r + color.g + color.b) / 3.0;\n return vec4(vec3(average * 10.0 - 5.0 + pattern(texSize, texCoord)), color.a);\n}\n`;\n\n/**\n * Dot Screen -\n * Simulates a black and white halftone rendering of the image by multiplying\n * pixel values with a rotated 2D sine wave pattern.\n */\nexport type DotScreenProps = {\n /** The x, y coordinate of the pattern origin. */\n center?: [number, number];\n /** The rotation of the pattern in radians. */\n angle?: number;\n /** The diameter of a dot in pixels. */\n size?: number;\n};\n\nexport type DotScreenUniforms = DotScreenProps;\n\n/**\n * Dot Screen -\n * Simulates a black and white halftone rendering of the image by multiplying\n * pixel values with a rotated 2D sine wave pattern.\n */\nexport const dotScreen = {\n name: 'dotScreen',\n source,\n fs,\n\n props: {} as DotScreenProps,\n uniforms: {} as DotScreenUniforms,\n uniformTypes: {\n center: 'vec2<f32>',\n angle: 'f32',\n size: 'f32'\n },\n propTypes: {\n center: {value: [0.5, 0.5]},\n angle: {value: 1.1, softMin: 0, softMax: Math.PI / 2},\n size: {value: 3, min: 1, softMin: 3, softMax: 20}\n },\n\n passes: [{filter: true}]\n} as const satisfies ShaderPass<DotScreenProps, DotScreenProps>;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ShaderPass} from '@luma.gl/shadertools';\nimport {random} from '@luma.gl/shadertools';\n\nconst source = /* wgsl */ `\\\nstruct edgeWorkUniforms {\n radius: f32,\n int mode: uint32,\n};\n\n@group(0) @binding(1) var<uniform> edgeWork: edgeWorkUniforms;\n\nfn edgeWork_sampleColorRGB(sampler2D source, vec2 texSize, vec2 texCoord, vec2 delta) -> vec4f {\n vec2 relativeDelta = edgeWork.radius * delta / texSize;\n\n vec2 color = vec2(0.0);\n vec2 total = vec2(0.0);\n\n /* randomize the lookup values to hide the fixed number of samples */\n float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);\n\n for (float t = -30.0; t <= 30.0; t++) {\n float percent = (t + offset - 0.5) / 30.0;\n float weight = 1.0 - abs(percent);\n vec3 sampleColor = texture(source, texCoord + relativeDelta * percent).rgb;\n float average = (sampleColor.r + sampleColor.g + sampleColor.b) / 3.0;\n color.x += average * weight;\n total.x += weight;\n if (abs(t) < 15.0) {\n weight = weight * 2.0 - 1.0;\n color.y += average * weight;\n total.y += weight;\n }\n }\n return vec4(color / total, 0.0, 1.0);\n}\n`;\n\nconst fs = /* glsl */ `\\\nuniform edgeWorkUniforms {\n float radius;\n int mode;\n} edgeWork;\n\nvec4 edgeWork_sampleColorRGB(sampler2D source, vec2 texSize, vec2 texCoord, vec2 delta) {\n vec2 relativeDelta = edgeWork.radius * delta / texSize;\n\n vec2 color = vec2(0.0);\n vec2 total = vec2(0.0);\n\n /* randomize the lookup values to hide the fixed number of samples */\n float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);\n\n for (float t = -30.0; t <= 30.0; t++) {\n float percent = (t + offset - 0.5) / 30.0;\n float weight = 1.0 - abs(percent);\n vec3 sampleColor = texture(source, texCoord + relativeDelta * percent).rgb;\n float average = (sampleColor.r + sampleColor.g + sampleColor.b) / 3.0;\n color.x += average * weight;\n total.x += weight;\n if (abs(t) < 15.0) {\n weight = weight * 2.0 - 1.0;\n color.y += average * weight;\n total.y += weight;\n }\n }\n return vec4(color / total, 0.0, 1.0);\n}\n\nvec4 edgeWork_sampleColorXY(sampler2D source, vec2 texSize, vec2 texCoord, vec2 delta) {\n vec2 relativeDelta = edgeWork.radius * delta / texSize;\n\n vec2 color = vec2(0.0);\n vec2 total = vec2(0.0);\n\n /* randomize the lookup values to hide the fixed number of samples */\n float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);\n\n for (float t = -30.0; t <= 30.0; t++) {\n float percent = (t + offset - 0.5) / 30.0;\n float weight = 1.0 - abs(percent);\n vec2 sampleColor = texture(source, texCoord + relativeDelta * percent).xy;\n color.x += sampleColor.x * weight;\n total.x += weight;\n if (abs(t) < 15.0) {\n weight = weight * 2.0 - 1.0;\n color.y += sampleColor.y * weight;\n total.y += weight;\n }\n }\n float c = clamp(10000.0 * (color.y / total.y - color.x / total.x) + 0.5, 0.0, 1.0);\n return vec4(c, c, c, 1.0);\n}\n\nvec4 edgeWork_sampleColor(sampler2D source, vec2 texSize, vec2 texCoord) {\n switch (edgeWork.mode) {\n case 0: \n return edgeWork_sampleColorRGB(source, texSize, texCoord, vec2(1., 0.));\n case 1: \n default:\n return edgeWork_sampleColorXY(source, texSize, texCoord, vec2(0., 1.));\n }\n}\n`;\n\n/**\n * Edge Work -\n * Picks out different frequencies in the image by subtracting two\n * copies of the image blurred with different radii.\n */\nexport type EdgeWorkProps = {\n /** radius The radius of the effect in pixels. */\n radius?: number;\n /** @deprecated xy or RGB */\n mode?: 0 | 1;\n};\n\nexport type EdgeWorkUniforms = EdgeWorkProps;\n\n/**\n * Edge Work -\n * Picks out different frequencies in the image by subtracting two\n * copies of the image blurred with different radii.\n */\nexport const edgeWork = {\n name: 'edgeWork',\n dependencies: [random],\n source,\n fs,\n\n props: {} as EdgeWorkProps,\n uniforms: {} as EdgeWorkProps,\n uniformTypes: {\n radius: 'f32',\n mode: 'i32'\n },\n propTypes: {\n radius: {value: 2, min: 1, softMax: 50},\n mode: {value: 0, private: true}\n },\n\n passes: [\n {\n sampler: true,\n uniforms: {mode: 0}\n },\n {\n sampler: true,\n uniforms: {mode: 1}\n }\n ]\n} as const satisfies ShaderPass<EdgeWorkProps, EdgeWorkProps>;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ShaderPass} from '@luma.gl/shadertools';\n\nconst source = /* wgsl */ `\\\nstruct hexagonalPixelateUniforms {\n center: vec2f,\n scale: f32,\n};\n\n@group(0) @binding(1) var<uniform> hexagonalPixelate: hexagonalPixelateUniforms;\n\nfn hexagonalPixelate_sampleColor(sampler2D source, vec2 texSize, vec2 texCoord) -> vec4f {\n vec2 tex = (texCoord * texSize - hexagonalPixelate.center * texSize) / hexagonalPixelate.scale;\n tex.y /= 0.866025404;\n tex.x -= tex.y * 0.5;\n\n vec2 a;\n if (tex.x + tex.y - floor(tex.x) - floor(tex.y) < 1.0) {\n a = vec2(floor(tex.x), floor(tex.y));\n }\n else a = vec2(ceil(tex.x), ceil(tex.y));\n vec2 b = vec2(ceil(tex.x), floor(tex.y));\n vec2 c = vec2(floor(tex.x), ceil(tex.y));\n\n vec3 TEX = vec3(tex.x, tex.y, 1.0 - tex.x - tex.y);\n vec3 A = vec3(a.x, a.y, 1.0 - a.x - a.y);\n vec3 B = vec3(b.x, b.y, 1.0 - b.x - b.y);\n vec3 C = vec3(c.x, c.y, 1.0 - c.x - c.y);\n\n float alen = length(TEX - A);\n float blen = length(TEX - B);\n float clen = length(TEX - C);\n\n vec2 choice;\n if (alen < blen) {\n if (alen < clen) choice = a;\n else choice = c;\n } else {\n if (blen < clen) choice = b;\n else choice = c;\n }\n\n choice.x += choice.y * 0.5;\n choice.y *= 0.866025404;\n choice *= hexagonalPixelate.scale / texSize;\n\n return texture(source, choice + hexagonalPixelate.center);\n}\n`;\n\nconst fs = /* glsl */ `\\\nuniform hexagonalPixelateUniforms {\n vec2 center;\n float scale;\n} hexagonalPixelate;\n\nvec4 hexagonalPixelate_sampleColor(sampler2D source, vec2 texSize, vec2 texCoord) {\n vec2 tex = (texCoord * texSize - hexagonalPixelate.center * texSize) / hexagonalPixelate.scale;\n tex.y /= 0.866025404;\n tex.x -= tex.y * 0.5;\n\n vec2 a;\n if (tex.x + tex.y - floor(tex.x) - floor(tex.y) < 1.0) {\n a = vec2(floor(tex.x), floor(tex.y));\n }\n else a = vec2(ceil(tex.x), ceil(tex.y));\n vec2 b = vec2(ceil(tex.x), floor(tex.y));\n vec2 c = vec2(floor(tex.x), ceil(tex.y));\n\n vec3 TEX = vec3(tex.x, tex.y, 1.0 - tex.x - tex.y);\n vec3 A = vec3(a.x, a.y, 1.0 - a.x - a.y);\n vec3 B = vec3(b.x, b.y, 1.0 - b.x - b.y);\n vec3 C = vec3(c.x, c.y, 1.0 - c.x - c.y);\n\n float alen = length(TEX - A);\n float blen = length(TEX - B);\n float clen = length(TEX - C);\n\n vec2 choice;\n if (alen < blen) {\n if (alen < clen) choice = a;\n else choice = c;\n } else {\n if (blen < clen) choice = b;\n else choice = c;\n }\n\n choice.x += choice.y * 0.5;\n choice.y *= 0.866025404;\n choice *= hexagonalPixelate.scale / texSize;\n\n return texture(source, choice + hexagonalPixelate.center);\n}\n`;\n\n/**\n * Hexagonal Pixelate\n * Renders the image using a pattern of hexagonal tiles.\n * Tile colors are nearest-neighbor sampled from the centers of the tiles.\n */\nexport type HexagonalPixelateProps = {\n /** The [x, y] coordinates of the pattern center. */\n center?: [number, number];\n /** The width of an individual tile, in pixels. */\n scale?: number;\n};\n\nexport type HexagonalPixelateUniforms = HexagonalPixelateProps;\n\n/**\n * Hexagonal Pixelate\n * Renders the image using a pattern of hexagonal tiles. Tile colors\n * are nearest-neighbor sampled from the centers of the tiles.\n */\nexport const hexagonalPixelate = {\n name: 'hexagonalPixelate',\n source,\n fs,\n\n props: {} as HexagonalPixelateProps,\n uniforms: {} as HexagonalPixelateUniforms,\n uniformTypes: {\n center: 'vec2<f32>',\n scale: 'f32'\n },\n propTypes: {\n center: {value: [0.5, 0.5], hint: 'screenspace'},\n scale: {value: 10, min: 1, softMin: 5, softMax: 50}\n },\n\n passes: [{sampler: true}]\n} as const satisfies ShaderPass<HexagonalPixelateProps, HexagonalPixelateProps>;\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ShaderPass} from '@luma.gl/shadertools';\n\nconst source = /* wgsl */ `\\\nuniform inkUniforms {\n strength: f32,\n};\n\n@group(0) @binding(1) var<uniform> ink: inkUniforms;\n\nfn ink_sampleColor(sampler2D source, vec2 texSize, vec2 texCoord) -> vec4f {\n vec2 dx = vec2(1.0 / texSize.x, 0.0);\n vec2 dy = vec2(0.0, 1.0 / texSize.y);\n vec4 color = texture(source, texCoord);\n float bigTotal = 0.0;\n float smallTotal = 0.0;\n vec3 bigAverage