@remotion/effects 4.0.539 → 4.0.540
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/THIRD_PARTY_LICENSES.md +15 -0
- package/dist/barrel-distortion/webgpu-shader.d.ts +1 -0
- package/dist/bevel-alpha/webgpu-shaders.d.ts +2 -0
- package/dist/burlap-webgpu-shader.d.ts +1 -0
- package/dist/checkerboard-webgpu-shader.d.ts +1 -0
- package/dist/chromatic-aberration/webgpu-shader.d.ts +1 -0
- package/dist/color-correction-webgpu-shader-utils.d.ts +4 -0
- package/dist/color-key-webgpu-shader.d.ts +1 -0
- package/dist/color-matrix-runtime.d.ts +4 -0
- package/dist/contour-lines-webgpu-shader.d.ts +1 -0
- package/dist/corner-pin/webgpu-shader.d.ts +1 -0
- package/dist/cylinder/webgl-shader.d.ts +1 -0
- package/dist/dot-grid-webgpu-shader.d.ts +1 -0
- package/dist/drop-shadow/webgpu-shaders.d.ts +2 -0
- package/dist/emboss-webgpu-shader.d.ts +1 -0
- package/dist/esm/barrel-distortion.mjs +67 -118
- package/dist/esm/bevel-alpha.mjs +247 -196
- package/dist/esm/blur.mjs +101 -115
- package/dist/esm/brightness.mjs +65 -132
- package/dist/esm/burlap.mjs +178 -151
- package/dist/esm/checkerboard.mjs +6 -514
- package/dist/esm/chromatic-aberration.mjs +72 -119
- package/dist/esm/color-correction.mjs +186 -224
- package/dist/esm/color-key.mjs +149 -136
- package/dist/esm/contour-lines.mjs +201 -160
- package/dist/esm/contrast.mjs +65 -132
- package/dist/esm/corner-pin.mjs +4 -390
- package/dist/esm/curves.mjs +195 -211
- package/dist/esm/cylinder.mjs +108 -225
- package/dist/esm/dot-grid.mjs +184 -213
- package/dist/esm/drop-shadow.mjs +162 -180
- package/dist/esm/duotone.mjs +110 -143
- package/dist/esm/emboss.mjs +153 -151
- package/dist/esm/evolve.mjs +228 -154
- package/dist/esm/exposure.mjs +93 -201
- package/dist/esm/film-burn.mjs +298 -0
- package/dist/esm/fisheye.mjs +97 -126
- package/dist/esm/flannel.mjs +158 -156
- package/dist/esm/fractal-noise.mjs +186 -232
- package/dist/esm/glow.mjs +164 -179
- package/dist/esm/grayscale.mjs +56 -122
- package/dist/esm/gridlines.mjs +6 -575
- package/dist/esm/halftone-linear-gradient.mjs +246 -245
- package/dist/esm/halftone.mjs +267 -243
- package/dist/esm/hue.mjs +55 -122
- package/dist/esm/index-00v3hr66.mjs +299 -0
- package/dist/esm/index-0w4eqht8.mjs +351 -0
- package/dist/esm/index-18y0zcy2.mjs +440 -0
- package/dist/esm/index-1m1b1ad7.mjs +520 -0
- package/dist/esm/index-34fxm3ax.mjs +518 -0
- package/dist/esm/index-4fvp93ps.mjs +32 -0
- package/dist/esm/index-4scpn12x.mjs +224 -0
- package/dist/esm/index-4z6pt3ka.mjs +104 -0
- package/dist/esm/index-618ky75w.mjs +51 -0
- package/dist/esm/index-6agxdrvr.mjs +411 -0
- package/dist/esm/index-6jkps947.mjs +120 -0
- package/dist/esm/index-8agtsbw4.mjs +617 -0
- package/dist/esm/index-8jx11jyn.mjs +29 -0
- package/dist/esm/index-8p04sssx.mjs +123 -0
- package/dist/esm/index-afdtmrh2.mjs +596 -0
- package/dist/esm/index-b86qstcs.mjs +18 -0
- package/dist/esm/index-cb77qg3g.mjs +587 -0
- package/dist/esm/index-cdp7tr8x.mjs +122 -0
- package/dist/esm/index-evy8hyah.mjs +55 -0
- package/dist/esm/index-gnsce796.mjs +6 -0
- package/dist/esm/index-kkvzt8b7.mjs +199 -0
- package/dist/esm/index-r0v18b2n.mjs +425 -0
- package/dist/esm/index-rswpzmm5.mjs +926 -0
- package/dist/esm/index-s9mrx750.mjs +97 -0
- package/dist/esm/index-tvfexb7s.mjs +164 -0
- package/dist/esm/index-vp56k1gj.mjs +215 -0
- package/dist/esm/index-wxhvgv2s.mjs +79 -0
- package/dist/esm/index-wy95a41r.mjs +407 -0
- package/dist/esm/index-ysnwfc4t.mjs +306 -0
- package/dist/esm/index.mjs +49 -4053
- package/dist/esm/invert.mjs +54 -122
- package/dist/esm/iris-wipe.mjs +315 -0
- package/dist/esm/lens-blur.mjs +169 -156
- package/dist/esm/levels.mjs +134 -151
- package/dist/esm/light-leak.mjs +6 -416
- package/dist/esm/light-trail.mjs +124 -128
- package/dist/esm/linear-gradient-tint.mjs +4 -424
- package/dist/esm/linear-gradient.mjs +4 -370
- package/dist/esm/linear-progressive-blur.mjs +92 -118
- package/dist/esm/linear-progressive-pixelate.mjs +83 -378
- package/dist/esm/lines.mjs +167 -162
- package/dist/esm/liquid-contours.mjs +192 -153
- package/dist/esm/long-shadows.mjs +278 -251
- package/dist/esm/lut.mjs +123 -23
- package/dist/esm/mirror.mjs +78 -120
- package/dist/esm/noise-displacement.mjs +156 -151
- package/dist/esm/noise.mjs +107 -143
- package/dist/esm/outline.mjs +192 -170
- package/dist/esm/page-turn.mjs +141 -244
- package/dist/esm/paper.mjs +522 -194
- package/dist/esm/pattern.mjs +4 -568
- package/dist/esm/pixel-dissolve.mjs +158 -186
- package/dist/esm/pixelate.mjs +92 -149
- package/dist/esm/radial-progressive-blur.mjs +96 -118
- package/dist/esm/radial-progressive-pixelate.mjs +91 -384
- package/dist/esm/radial-wipe.mjs +224 -0
- package/dist/esm/rain-fall.mjs +114 -0
- package/dist/esm/region-blur.mjs +138 -192
- package/dist/esm/rings.mjs +6 -512
- package/dist/esm/roughen-edges.mjs +180 -156
- package/dist/esm/saturation.mjs +56 -122
- package/dist/esm/scale.mjs +50 -60
- package/dist/esm/scanlines.mjs +115 -149
- package/dist/esm/shadows-highlights.mjs +103 -205
- package/dist/esm/shatter.mjs +133 -153
- package/dist/esm/shine.mjs +192 -227
- package/dist/esm/shrinkwrap.mjs +388 -225
- package/dist/esm/skew.mjs +100 -145
- package/dist/esm/snow-fall.mjs +170 -0
- package/dist/esm/speckle.mjs +192 -210
- package/dist/esm/sphere.mjs +101 -225
- package/dist/esm/starburst.mjs +6 -345
- package/dist/esm/tear.mjs +138 -155
- package/dist/esm/thermal-vision.mjs +135 -152
- package/dist/esm/tile.mjs +5 -184
- package/dist/esm/tint.mjs +80 -132
- package/dist/esm/translate.mjs +55 -137
- package/dist/esm/turbulent-displace.mjs +182 -221
- package/dist/esm/tv-signal-off.mjs +140 -149
- package/dist/esm/venetian-blinds.mjs +91 -140
- package/dist/esm/vibrance.mjs +95 -204
- package/dist/esm/vignette.mjs +136 -155
- package/dist/esm/wave.mjs +88 -47
- package/dist/esm/waves.mjs +181 -169
- package/dist/esm/white-balance.mjs +100 -204
- package/dist/esm/white-noise.mjs +98 -146
- package/dist/esm/zigzag.mjs +6 -575
- package/dist/esm/zoom-blur.mjs +90 -121
- package/dist/evolve.d.ts +46 -10
- package/dist/film-burn-webgpu-shader.d.ts +1 -0
- package/dist/film-burn.d.ts +40 -0
- package/dist/fisheye/webgpu-shader.d.ts +1 -0
- package/dist/flannel-webgpu-shader.d.ts +1 -0
- package/dist/fractal-noise/shader.d.ts +1 -1
- package/dist/fractal-noise/webgpu-shader.d.ts +1 -0
- package/dist/gaussian-blur-webgpu-shader.d.ts +1 -0
- package/dist/glow/webgpu-shaders.d.ts +2 -0
- package/dist/gridlines-webgpu-shader.d.ts +1 -0
- package/dist/halftone-linear-gradient-webgpu-shader.d.ts +1 -0
- package/dist/halftone-webgpu-shader.d.ts +1 -0
- package/dist/iris-wipe.d.ts +78 -0
- package/dist/lens-blur/webgpu-shader.d.ts +1 -0
- package/dist/light-leak-webgpu-shader.d.ts +1 -0
- package/dist/light-trail/webgpu-shader.d.ts +1 -0
- package/dist/linear-gradient-tint-webgpu-shader.d.ts +1 -0
- package/dist/linear-gradient-webgpu-shader.d.ts +1 -0
- package/dist/lines-webgpu-shader.d.ts +1 -0
- package/dist/liquid-contours-webgpu-shader.d.ts +1 -0
- package/dist/long-shadows-webgpu-shaders.d.ts +2 -0
- package/dist/lut/webgpu-shader.d.ts +1 -0
- package/dist/mirror/webgpu-shader.d.ts +1 -0
- package/dist/noise-displacement-webgpu-shader.d.ts +1 -0
- package/dist/noise-webgpu-shader.d.ts +1 -0
- package/dist/outline/webgpu-shader.d.ts +1 -0
- package/dist/page-turn/webgl-shader.d.ts +1 -0
- package/dist/paper-webgpu-shader.d.ts +2 -0
- package/dist/pattern-webgpu-shader.d.ts +1 -0
- package/dist/pixel-dissolve-webgpu-shader.d.ts +1 -0
- package/dist/progressive-pixelate-runtime.d.ts +1 -0
- package/dist/radial-wipe.d.ts +19 -0
- package/dist/rain-fall.d.ts +143 -0
- package/dist/rect-transform-runtime.d.ts +11 -0
- package/dist/region-blur/webgpu-shader.d.ts +1 -0
- package/dist/rings-webgpu-shader.d.ts +1 -0
- package/dist/roughen-edges-webgpu-shader.d.ts +1 -0
- package/dist/shatter/webgpu-shader.d.ts +1 -0
- package/dist/shine-webgpu-shader.d.ts +1 -0
- package/dist/shrinkwrap-webgpu-shader.d.ts +1 -0
- package/dist/single-pass-runtime.d.ts +18 -0
- package/dist/skew-webgpu-shader.d.ts +1 -0
- package/dist/snow-fall.d.ts +208 -0
- package/dist/speckle-webgpu-shader.d.ts +1 -0
- package/dist/sphere/webgl-shader.d.ts +1 -0
- package/dist/starburst-webgpu-shader.d.ts +1 -0
- package/dist/tear-webgpu-shader.d.ts +1 -0
- package/dist/thermal-vision-webgpu-shader.d.ts +1 -0
- package/dist/tile-gpu-runtime.d.ts +24 -0
- package/dist/turbulent-displace/webgpu-shader.d.ts +1 -0
- package/dist/value-noise-webgpu-shader.d.ts +1 -0
- package/dist/vignette-webgpu-shader.d.ts +1 -0
- package/dist/wave/wave-runtime.d.ts +2 -1
- package/dist/wave/webgpu-shader.d.ts +1 -0
- package/dist/waves-webgpu-shader.d.ts +1 -0
- package/dist/weather/params.d.ts +149 -0
- package/dist/weather/runtime.d.ts +52 -0
- package/dist/weather/shaders.d.ts +4 -0
- package/dist/weather/webgpu-runtime.d.ts +36 -0
- package/dist/weather/webgpu-shader.d.ts +1 -0
- package/dist/webgl-projection-runtime.d.ts +18 -0
- package/dist/webgpu-color-state.d.ts +10 -0
- package/dist/webgpu-mesh-runtime.d.ts +46 -0
- package/dist/webgpu-multipass-runtime.d.ts +50 -0
- package/dist/webgpu-projection-runtime.d.ts +9 -5
- package/dist/webgpu-single-pass-runtime.d.ts +47 -0
- package/dist/white-noise-webgpu-shader.d.ts +1 -0
- package/dist/zigzag-webgpu-shader.d.ts +1 -0
- package/dist/zoom-blur/webgpu-shader.d.ts +1 -0
- package/package.json +43 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const VALUE_NOISE_WEBGPU_SHADER = "\nfn lattice(point: vec3i, seed: u32) -> f32 {\n let p = bitcast<vec3u>(point) & vec3u(65535u);\n var h = (p.x*0x27d4eb2du) ^ (p.y*0x165667b1u) ^ (p.z*0x9e3779b9u) ^ (seed*0x85ebca6bu);\n h ^= h >> 15u; h *= 0x2c1b3c6du; h ^= h >> 12u; h *= 0x297a2d39u; h ^= h >> 15u;\n return f32(h & 65535u)/65535.0;\n}\nfn catmull(p: vec4f, t: f32) -> f32 {\n return 0.5*(2.0*p.y+(p.z-p.x)*t+(2.0*p.x-5.0*p.y+4.0*p.z-p.w)*t*t+(3.0*p.y-p.x-3.0*p.z+p.w)*t*t*t);\n}\nfn bspline(t: f32) -> vec3f { return vec3f(0.5*(1.0-t)*(1.0-t),0.5+t*(1.0-t),0.5*t*t); }\nfn sliceNoise(p: vec3i,t: vec2f,seed: u32) -> f32 {\n if(noiseType()==0) { return lattice(p,seed); }\n if(noiseType()==1) { return mix(mix(lattice(p,seed),lattice(p+vec3i(1,0,0),seed),t.x),mix(lattice(p+vec3i(0,1,0),seed),lattice(p+vec3i(1,1,0),seed),t.x),t.y); }\n if(noiseType()==2) {\n let wx=bspline(t.x); let wy=bspline(t.y); var result=0.0;\n for(var y=0;y<3;y++) { for(var x=0;x<3;x++) { result += wx[x]*wy[y]*lattice(p+vec3i(x-1,y-1,0),seed); } }\n return result;\n }\n var rows: vec4f;\n for(var y=0;y<4;y++) {\n var row: vec4f;\n for(var x=0;x<4;x++) { row[x]=lattice(p+vec3i(x-1,y-1,0),seed); }\n rows[y]=catmull(row,t.x);\n }\n return catmull(rows,t.y);\n}\nfn valueNoise(point: vec3f,seed: u32) -> f32 {\n let offset=select(0.0,0.5,noiseType()==2);\n let shifted=point+vec3f(offset,offset,0.0);\n let p=shifted-floor(shifted/65536.0)*65536.0;\n let cell=vec3i(floor(p)); let t=fract(p);\n let fz=t.z*t.z*t.z*(t.z*(t.z*6.0-15.0)+10.0);\n let n=mix(sliceNoise(cell,t.xy,seed),sliceNoise(cell+vec3i(0,0,1),t.xy,seed),fz);\n return select(n,0.5+(n-0.5)*(181.0/231.0)/0.55,noiseType()==2);\n}\n";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const VIGNETTE_WEBGPU_SHADER = "\n\nstruct VertexOutput {\n\t@builtin(position) position: vec4f,\n\t@location(0) uv: vec2f,\n}\n\n@vertex fn vertex(@builtin(vertex_index) index: u32) -> VertexOutput {\n\tlet positions = array<vec2f, 3>(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));\n\tlet position = positions[index];\n\tvar output: VertexOutput;\n\toutput.position = vec4f(position, 0, 1);\n\toutput.uv = vec2f(position.x * 0.5 + 0.5, 0.5 - position.y * 0.5);\n\treturn output;\n}\n\nstruct Params { shape: vec4f, color: vec4f, center: vec2f, mode: f32, padding: f32 }\n@group(0) @binding(0) var source: texture_2d<f32>;\n@group(0) @binding(1) var sourceSampler: sampler;\n@group(0) @binding(2) var<uniform> params: Params;\n\n@fragment fn fragment(input: VertexOutput) -> @location(0) vec4f {\n let color = textureSampleLevel(source, sourceSampler, input.uv, 0.0);\n let centered = abs(input.uv - params.center) * 2.0;\n let distanceFromCenter = mix(max(centered.x, centered.y), length(centered), params.shape.w);\n var mask: f32;\n if (params.shape.z <= 0.0001) {\n mask = select(0.0, params.shape.x, distanceFromCenter >= params.shape.y);\n } else {\n mask = smoothstep(params.shape.y, params.shape.y + params.shape.z, distanceFromCenter) * params.shape.x;\n }\n if (params.mode == 1.0) { return color * (1.0 - mask); }\n let overlayAlpha = mask * params.color.a;\n return vec4f(params.color.rgb * overlayAlpha + color.rgb * (1.0 - overlayAlpha), overlayAlpha + color.a * (1.0 - overlayAlpha));\n}\n";
|
|
@@ -20,10 +20,11 @@ type ApplyWaveParams = {
|
|
|
20
20
|
readonly source: CanvasImageSource;
|
|
21
21
|
readonly width: number;
|
|
22
22
|
readonly height: number;
|
|
23
|
+
readonly flipSourceY: boolean;
|
|
23
24
|
readonly amplitude: number;
|
|
24
25
|
readonly wavelength: number;
|
|
25
26
|
readonly phase: number;
|
|
26
27
|
readonly direction: 'horizontal' | 'vertical';
|
|
27
28
|
};
|
|
28
|
-
export declare const applyWave: ({ state, source, width, height, amplitude, wavelength, phase, direction, }: ApplyWaveParams) => void;
|
|
29
|
+
export declare const applyWave: ({ state, source, width, height, flipSourceY, amplitude, wavelength, phase, direction, }: ApplyWaveParams) => void;
|
|
29
30
|
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const WAVE_WEBGPU_SHADER = "\n\nstruct VertexOutput {\n\t@builtin(position) position: vec4f,\n\t@location(0) uv: vec2f,\n}\n\n@vertex fn vertex(@builtin(vertex_index) index: u32) -> VertexOutput {\n\tlet positions = array<vec2f, 3>(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));\n\tlet position = positions[index];\n\tvar output: VertexOutput;\n\toutput.position = vec4f(position, 0, 1);\n\toutput.uv = vec2f(position.x * 0.5 + 0.5, 0.5 - position.y * 0.5);\n\treturn output;\n}\n\n@group(0) @binding(0) var source: texture_2d<f32>;\n@group(0) @binding(1) var sourceSampler: sampler;\n@group(0) @binding(2) var<uniform> params: Params;\nstruct Params { resolutionAndWave: vec4f, phaseAndDirection: vec4f, }\n@fragment fn fragment(input: VertexOutput) -> @location(0) vec4f {\n let resolution = params.resolutionAndWave.xy;\n let amplitude = params.resolutionAndWave.z;\n let wavelength = max(params.resolutionAndWave.w, 0.001);\n let phase = params.phaseAndDirection.x;\n var uv = input.uv;\n if (params.phaseAndDirection.y == 0.0) {\n let coord = input.uv.x * resolution.x;\n let offset = sin((coord / wavelength) * 6.28318530718 + phase) * amplitude;\n uv.y += offset / resolution.y;\n } else {\n let coord = (1.0 - input.uv.y) * resolution.y;\n let offset = sin((coord / wavelength) * 6.28318530718 + phase) * amplitude;\n uv.x -= offset / resolution.x;\n }\n return textureSampleLevel(source, sourceSampler, uv, 0);\n}\n";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const WAVES_WEBGPU_SHADER = "\n\nstruct VertexOutput {\n\t@builtin(position) position: vec4f,\n\t@location(0) uv: vec2f,\n}\n\n@vertex fn vertex(@builtin(vertex_index) index: u32) -> VertexOutput {\n\tlet positions = array<vec2f, 3>(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));\n\tlet position = positions[index];\n\tvar output: VertexOutput;\n\toutput.position = vec4f(position, 0, 1);\n\toutput.uv = vec2f(position.x * 0.5 + 0.5, 0.5 - position.y * 0.5);\n\treturn output;\n}\n\n@group(0) @binding(0) var sourceTexture: texture_2d<f32>;\n@group(0) @binding(1) var sourceSampler: sampler;\n@group(0) @binding(2) var<uniform> params: Params;\n@group(0) @binding(3) var palette: texture_2d<f32>;\nstruct Params {\n geometry: vec4f,\n stripe: vec4f,\n flags: vec4f,\n wave: vec4f,\n}\nfn sampleSource(uv: vec2f) -> vec4f {\n return textureSampleLevel(sourceTexture, sourceSampler, vec2f(uv.x, 1.0 - uv.y), 0);\n}\nfn glslModulo(value: f32, divisor: f32) -> f32 { return value - divisor * floor(value / divisor); }\nfn paletteColor(index: f32) -> vec4f { return textureLoad(palette, vec2i(i32(index), 0), 0); }\n\n@fragment fn fragment(input: VertexOutput) -> @location(0) vec4f {\n let vUv = vec2f(input.uv.x, 1.0 - input.uv.y);\n\n let texColor = sampleSource(vUv);\n let thickness = max(params.stripe.x, 0.001);\n let spacing = max(params.stripe.y, 0.001);\n let cycle = spacing * params.geometry.z;\n let centered = vec2f(input.position.x, params.geometry.y - input.position.y) - params.geometry.xy * 0.5;\n let s = sin(params.stripe.z);\n let c = cos(params.stripe.z);\n let rotated = vec2f(centered.x * c - centered.y * s, centered.x * s + centered.y * c);\n var axis = select(rotated.x, rotated.y, params.geometry.w == 0.0);\n let waveAxis = select(rotated.y, rotated.x, params.geometry.w == 0.0);\naxis += sin((waveAxis / max(params.wave.y, 0.001)) * 6.283185307179586 + params.wave.z) * params.wave.x;\n\n var position = glslModulo(axis + params.stripe.w, cycle);\n if (position < 0.0) { position += cycle; }\n let colorIndex = floor(position / spacing);\n let inStripe = glslModulo(position, spacing);\n if (inStripe > thickness) { return texColor; }\n\n let overlay = paletteColor(colorIndex);\n let premultiplied = overlay.rgb * overlay.a;\n if (params.flags.x != 0.0) {\n return vec4f(premultiplied * texColor.a + texColor.rgb * (1.0 - overlay.a), texColor.a);\n }\n return vec4f(premultiplied + texColor.rgb * (1.0 - overlay.a), overlay.a + texColor.a * (1.0 - overlay.a));\n\n}\n";
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
export type WeatherCommonParams = {
|
|
2
|
+
/** Elapsed time in seconds. Must be nonnegative. Defaults to `0`. */
|
|
3
|
+
readonly time?: number;
|
|
4
|
+
/** Particle size, from `0` to `50`. Defaults to `1` for rain and `3` for snow. */
|
|
5
|
+
readonly size?: number;
|
|
6
|
+
/** Depth of the particle field, from `0` to `20000`. Defaults to `5000`. */
|
|
7
|
+
readonly sceneDepth?: number;
|
|
8
|
+
/** Fall speed. Defaults to `4000` for rain and `100` for snow. */
|
|
9
|
+
readonly speed?: number;
|
|
10
|
+
/** Horizontal wind strength. Positive values move right. Defaults to `0` for rain and `25` for snow. */
|
|
11
|
+
readonly wind?: number;
|
|
12
|
+
/** Per-particle wind variation, from `0` to `1`. Defaults to `0` for rain and `0.5` for snow. */
|
|
13
|
+
readonly windVariation?: number;
|
|
14
|
+
/** Random horizontal velocity spread, from `0` to `1000`. Defaults to `0`. */
|
|
15
|
+
readonly spread?: number;
|
|
16
|
+
/** Particle color. Its alpha multiplies opacity. Defaults to `#cccccc` for rain and `#ffffff` for snow. */
|
|
17
|
+
readonly color?: string;
|
|
18
|
+
/** Particle opacity, from `0` to `1`. Defaults to `0.25` for rain and `1` for snow. */
|
|
19
|
+
readonly opacity?: number;
|
|
20
|
+
/** Blend with the source. Defaults to `lighten` for rain and `composite` for snow. */
|
|
21
|
+
readonly transferMode?: 'composite' | 'lighten';
|
|
22
|
+
/** Include the source behind the particles. Defaults to `true`. */
|
|
23
|
+
readonly compositeWithOriginal?: boolean;
|
|
24
|
+
/** Normalized pattern position. `[0.5, 0.5]` leaves it centered, the default. */
|
|
25
|
+
readonly offset?: readonly [number, number];
|
|
26
|
+
/** Unsigned 32-bit integer for a repeatable particle field. Defaults to `0`. */
|
|
27
|
+
readonly seed?: number;
|
|
28
|
+
};
|
|
29
|
+
export type WeatherCommonResolved = Required<WeatherCommonParams>;
|
|
30
|
+
export declare const COMMON_WEATHER_DEFAULTS: {
|
|
31
|
+
readonly time: 0;
|
|
32
|
+
readonly sceneDepth: 5000;
|
|
33
|
+
readonly spread: 0;
|
|
34
|
+
readonly compositeWithOriginal: true;
|
|
35
|
+
readonly offset: readonly [0.5, 0.5];
|
|
36
|
+
readonly seed: 0;
|
|
37
|
+
};
|
|
38
|
+
export declare const createWeatherSchema: (defaults: WeatherCommonResolved, maxSpeed: number, maxWind: number) => {
|
|
39
|
+
readonly time: {
|
|
40
|
+
readonly type: 'number';
|
|
41
|
+
readonly min: 0;
|
|
42
|
+
readonly max: 10;
|
|
43
|
+
readonly step: 0.01;
|
|
44
|
+
readonly default: number;
|
|
45
|
+
readonly description: 'Time';
|
|
46
|
+
readonly hiddenFromList: false;
|
|
47
|
+
};
|
|
48
|
+
readonly size: {
|
|
49
|
+
readonly type: 'number';
|
|
50
|
+
readonly min: 0;
|
|
51
|
+
readonly max: 50;
|
|
52
|
+
readonly step: 0.01;
|
|
53
|
+
readonly default: number;
|
|
54
|
+
readonly description: 'Size';
|
|
55
|
+
readonly hiddenFromList: false;
|
|
56
|
+
};
|
|
57
|
+
readonly sceneDepth: {
|
|
58
|
+
readonly type: 'number';
|
|
59
|
+
readonly min: 0;
|
|
60
|
+
readonly max: 20000;
|
|
61
|
+
readonly step: 1;
|
|
62
|
+
readonly default: number;
|
|
63
|
+
readonly description: 'Scene depth';
|
|
64
|
+
readonly hiddenFromList: false;
|
|
65
|
+
};
|
|
66
|
+
readonly speed: {
|
|
67
|
+
readonly type: 'number';
|
|
68
|
+
readonly min: 0;
|
|
69
|
+
readonly max: number;
|
|
70
|
+
readonly step: 1;
|
|
71
|
+
readonly default: number;
|
|
72
|
+
readonly description: 'Speed';
|
|
73
|
+
readonly hiddenFromList: false;
|
|
74
|
+
};
|
|
75
|
+
readonly wind: {
|
|
76
|
+
readonly type: 'number';
|
|
77
|
+
readonly min: number;
|
|
78
|
+
readonly max: number;
|
|
79
|
+
readonly step: 1;
|
|
80
|
+
readonly default: number;
|
|
81
|
+
readonly description: 'Wind';
|
|
82
|
+
readonly hiddenFromList: false;
|
|
83
|
+
};
|
|
84
|
+
readonly windVariation: {
|
|
85
|
+
readonly type: 'number';
|
|
86
|
+
readonly min: 0;
|
|
87
|
+
readonly max: 1;
|
|
88
|
+
readonly step: 0.01;
|
|
89
|
+
readonly default: number;
|
|
90
|
+
readonly description: 'Wind variation';
|
|
91
|
+
readonly hiddenFromList: false;
|
|
92
|
+
};
|
|
93
|
+
readonly spread: {
|
|
94
|
+
readonly type: 'number';
|
|
95
|
+
readonly min: 0;
|
|
96
|
+
readonly max: 1000;
|
|
97
|
+
readonly step: 1;
|
|
98
|
+
readonly default: number;
|
|
99
|
+
readonly description: 'Spread';
|
|
100
|
+
readonly hiddenFromList: false;
|
|
101
|
+
};
|
|
102
|
+
readonly opacity: {
|
|
103
|
+
readonly type: 'number';
|
|
104
|
+
readonly min: 0;
|
|
105
|
+
readonly max: 1;
|
|
106
|
+
readonly step: 0.01;
|
|
107
|
+
readonly default: number;
|
|
108
|
+
readonly description: 'Opacity';
|
|
109
|
+
readonly hiddenFromList: false;
|
|
110
|
+
};
|
|
111
|
+
readonly color: {
|
|
112
|
+
readonly type: 'color';
|
|
113
|
+
readonly default: string;
|
|
114
|
+
readonly description: 'Color';
|
|
115
|
+
};
|
|
116
|
+
readonly transferMode: {
|
|
117
|
+
readonly type: 'enum';
|
|
118
|
+
readonly variants: {
|
|
119
|
+
readonly composite: {};
|
|
120
|
+
readonly lighten: {};
|
|
121
|
+
};
|
|
122
|
+
readonly default: "composite" | "lighten";
|
|
123
|
+
readonly description: 'Transfer mode';
|
|
124
|
+
};
|
|
125
|
+
readonly compositeWithOriginal: {
|
|
126
|
+
readonly type: 'boolean';
|
|
127
|
+
readonly default: boolean;
|
|
128
|
+
readonly description: 'Composite with original';
|
|
129
|
+
};
|
|
130
|
+
readonly offset: {
|
|
131
|
+
readonly type: 'uv-coordinate';
|
|
132
|
+
readonly step: 0.01;
|
|
133
|
+
readonly default: readonly [number, number];
|
|
134
|
+
readonly description: 'Offset';
|
|
135
|
+
};
|
|
136
|
+
readonly seed: {
|
|
137
|
+
readonly type: 'number';
|
|
138
|
+
readonly min: 0;
|
|
139
|
+
readonly max: 4294967295;
|
|
140
|
+
readonly step: 1;
|
|
141
|
+
readonly integer: true;
|
|
142
|
+
readonly default: number;
|
|
143
|
+
readonly description: 'Seed';
|
|
144
|
+
readonly hiddenFromList: false;
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
export declare const resolveWeatherParams: (params: WeatherCommonParams, defaults: WeatherCommonResolved) => WeatherCommonResolved;
|
|
148
|
+
export declare const validateWeatherRange: (value: number | undefined, name: string, min: number, max: number | null) => void;
|
|
149
|
+
export declare const validateWeatherParams: (params: WeatherCommonParams, label: string, maxSpeed: number, maxWind: number) => void;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type ParsedColorRgba } from '../color-utils.js';
|
|
2
|
+
export type WeatherRenderParams = {
|
|
3
|
+
readonly time: number;
|
|
4
|
+
readonly count: number;
|
|
5
|
+
readonly size: number;
|
|
6
|
+
readonly sizeVariation: number;
|
|
7
|
+
readonly sceneDepth: number;
|
|
8
|
+
readonly speed: number;
|
|
9
|
+
readonly speedVariation: number;
|
|
10
|
+
readonly wind: number;
|
|
11
|
+
readonly windVariation: number;
|
|
12
|
+
readonly spread: number;
|
|
13
|
+
readonly wiggleAmount: number;
|
|
14
|
+
readonly wiggleAmountVariation: number;
|
|
15
|
+
readonly wiggleFrequency: number;
|
|
16
|
+
readonly wiggleFrequencyVariation: number;
|
|
17
|
+
readonly color: string;
|
|
18
|
+
readonly opacity: number;
|
|
19
|
+
readonly transferMode: 'composite' | 'lighten';
|
|
20
|
+
readonly compositeWithOriginal: boolean;
|
|
21
|
+
readonly appearance: 'refracting' | 'soft-solid';
|
|
22
|
+
readonly offset: readonly [number, number];
|
|
23
|
+
readonly seed: number;
|
|
24
|
+
};
|
|
25
|
+
export type WeatherState = {
|
|
26
|
+
readonly gl: WebGL2RenderingContext;
|
|
27
|
+
readonly program: WebGLProgram;
|
|
28
|
+
readonly compositeProgram: WebGLProgram;
|
|
29
|
+
readonly vao: WebGLVertexArrayObject;
|
|
30
|
+
readonly sourceTexture: WebGLTexture;
|
|
31
|
+
readonly weatherTexture: WebGLTexture;
|
|
32
|
+
readonly framebuffer: WebGLFramebuffer;
|
|
33
|
+
readonly uniforms: Record<string, WebGLUniformLocation | null>;
|
|
34
|
+
readonly compositeUniforms: Record<string, WebGLUniformLocation | null>;
|
|
35
|
+
readonly colorCtx: CanvasRenderingContext2D;
|
|
36
|
+
readonly floatingPoint: boolean;
|
|
37
|
+
cachedColor: string | null;
|
|
38
|
+
cachedColorRgba: ParsedColorRgba;
|
|
39
|
+
width: number;
|
|
40
|
+
height: number;
|
|
41
|
+
};
|
|
42
|
+
export declare const setupWeather: (target: HTMLCanvasElement, effectName: string) => WeatherState;
|
|
43
|
+
export declare const drawWeather: ({ state, source, width, height, flipSourceY, params, type, }: {
|
|
44
|
+
state: WeatherState;
|
|
45
|
+
source: TexImageSource;
|
|
46
|
+
width: number;
|
|
47
|
+
height: number;
|
|
48
|
+
flipSourceY: boolean;
|
|
49
|
+
params: WeatherRenderParams;
|
|
50
|
+
type: 'rain' | 'snow';
|
|
51
|
+
}) => void;
|
|
52
|
+
export declare const cleanupWeather: (state: WeatherState) => void;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const WEATHER_VERTEX_SHADER = "#version 300 es\nprecision highp float;\nprecision highp int;\n\nuniform sampler2D uSource;\nuniform vec2 uResolution;\nuniform int uSnow;\nuniform float uTime;\nuniform uint uSeed;\nuniform vec2 uOffset;\nuniform float uSize;\nuniform float uSizeVariation;\nuniform float uSceneDepth;\nuniform float uSpeed;\nuniform float uSpeedVariation;\nuniform float uWind;\nuniform float uWindVariation;\nuniform float uSpread;\nuniform float uWiggleAmount;\nuniform float uWiggleAmountVariation;\nuniform float uWiggleFrequency;\nuniform float uWiggleFrequencyVariation;\nuniform vec4 uColor;\nuniform float uOpacity;\nuniform int uRefract;\n\nflat out vec2 vPosition;\nflat out vec2 vLine;\nflat out float vRadius;\nflat out vec4 vColor;\n\nfloat noise(uint i, uint key) {\n\tuint h = i * 0x8da6b343u ^ key * 0xd8163841u ^ uSeed * 0xcb1ab31fu;\n\th ^= h >> 13;\n\th *= 0x5bd1e995u;\n\th ^= h >> 15;\n\treturn float(h & 0x00ffffffu) / 16777216.0;\n}\n\nfloat signedNoise(uint i, uint key) {\n\treturn noise(i, key) * 2.0 - 1.0;\n}\n\nfloat wrap(float value, float margin, float size) {\n\treturn -margin + mod(value + margin, size + 2.0 * margin);\n}\n\nvec4 sourcePixel(ivec2 p) {\n\tivec2 size = textureSize(uSource, 0);\n\tif (p.x < 0 || p.y < 0 || p.x >= size.x || p.y >= size.y) {\n\t\treturn vec4(0.0);\n\t}\n\treturn texelFetch(uSource, ivec2(p.x, size.y - 1 - p.y), 0);\n}\n\n// Bilinear sampling with transparent borders, at pixel centers of +0.5.\nvec4 sourceAt(vec2 position) {\n\tvec2 p = position - 0.5;\n\tivec2 base = ivec2(floor(p));\n\tvec2 f = fract(p);\n\treturn mix(\n\t\tmix(sourcePixel(base), sourcePixel(base + ivec2(1, 0)), f.x),\n\t\tmix(sourcePixel(base + ivec2(0, 1)), sourcePixel(base + ivec2(1, 1)), f.x),\n\t\tf.y\n\t);\n}\n\nvoid main() {\n\tuint i = uint(gl_InstanceID);\n\tfloat depth = 1.0 / (1.0 + noise(i, 1u) * uSceneDepth / 2500.0);\n\tvec2 offset = (uOffset - 0.5) * uResolution;\n\tvec2 position;\n\tvec2 line = vec2(0.0);\n\tfloat radius;\n\tfloat alpha;\n\tif (uSnow == 1) {\n\t\tradius = max(uSize * 0.5 * depth * (1.0 + uSizeVariation * signedNoise(i, 2u)), 0.05);\n\t\tfloat speed = uSpeed * (uResolution.y / 600.0) * depth * (1.0 + uSpeedVariation * signedNoise(i, 3u));\n\t\tfloat wind = uWind * (uResolution.y / 1200.0) * depth * (1.0 + uWindVariation * signedNoise(i, 4u))\n\t\t\t+ uSpread * signedNoise(i, 8u) * depth;\n\t\tfloat amplitude = uWiggleAmount * 2.0 * depth * (1.0 + uWiggleAmountVariation * signedNoise(i, 5u));\n\t\tfloat frequency = uWiggleFrequency * (1.0 + uWiggleFrequencyVariation * signedNoise(i, 6u));\n\t\tfloat phase = noise(i, 9u) * 6.283185307179586;\n\t\tfloat margin = radius + abs(amplitude) + 2.0;\n\t\tposition.y = wrap(noise(i, 10u) * (uResolution.y + 2.0 * margin) + speed * uTime + offset.y, margin, uResolution.y);\n\t\tposition.x = wrap(noise(i, 11u) * (uResolution.x + 2.0 * margin) + wind * uTime + offset.x, margin, uResolution.x)\n\t\t\t+ amplitude * sin(frequency * uTime * 6.283185307179586 + phase);\n\t\talpha = uOpacity * (0.4 + 0.6 * depth);\n\t} else {\n\t\tfloat speed = uSpeed / 4000.0 * uResolution.y * 2.2 * depth;\n\t\tfloat wind = uWind / 1000.0 * uResolution.y * (1.0 + uWindVariation * signedNoise(i, 2u)) * depth\n\t\t\t+ uSpread * signedNoise(i, 7u) * depth;\n\t\tfloat length = max(speed * 0.04 * max(uSize, 0.2), 1.0);\n\t\tfloat horizontalLength = wind * 0.04 * max(uSize, 0.2);\n\t\tfloat margin = length + abs(horizontalLength) + 4.0;\n\t\tposition.y = wrap(noise(i, 3u) * (uResolution.y + 2.0 * margin) + speed * uTime + offset.y, margin, uResolution.y);\n\t\tposition.x = wrap(noise(i, 4u) * (uResolution.x + 2.0 * margin) + wind * uTime + offset.x, margin, uResolution.x);\n\t\tline = vec2(-horizontalLength, -length);\n\t\tradius = max(uSize * 0.6 * depth, 0.25);\n\t\talpha = uOpacity * (0.35 + 0.65 * depth);\n\t}\n\n\tvec3 color = uColor.rgb;\n\tif (uSnow == 0 && uRefract == 1) {\n\t\tvec4 sampleColor = sourceAt(position + vec2(2.0, 0.0));\n\t\tif (sampleColor.a > 0.0) {\n\t\t\tvec3 straight = sampleColor.a > 0.000001 ? sampleColor.rgb / sampleColor.a : vec3(0.0);\n\t\t\tcolor *= straight * 0.6 + 0.5;\n\t\t}\n\t}\n\n\tvPosition = position;\n\tvLine = line;\n\tvRadius = radius;\n\tvColor = vec4(color, alpha * uColor.a);\n\tfloat padding = max(radius, 0.5) + 1.0;\n\tvec2 minimum = min(position, position + line) - padding;\n\tvec2 maximum = max(position, position + line) + padding;\n\tvec2 corner = vec2(float(gl_VertexID & 1), float(gl_VertexID >> 1));\n\tvec2 pixel = mix(minimum, maximum, corner);\n\tgl_Position = vec4(pixel.x / uResolution.x * 2.0 - 1.0, 1.0 - pixel.y / uResolution.y * 2.0, 0.0, 1.0);\n}\n";
|
|
2
|
+
export declare const WEATHER_FRAGMENT_SHADER = "#version 300 es\nprecision highp float;\nprecision highp int;\n\nuniform vec2 uResolution;\nuniform int uSnow;\n\nflat in vec2 vPosition;\nflat in vec2 vLine;\nflat in float vRadius;\nflat in vec4 vColor;\nout vec4 fragColor;\n\nvoid main() {\n\tif (vColor.a <= 0.00001) discard;\n\tvec2 delta = vec2(gl_FragCoord.x, uResolution.y - gl_FragCoord.y) - vPosition;\n\tfloat radius = max(vRadius, 0.5);\n\tfloat fade = min(vRadius / 0.5, 1.0);\n\tfloat coverage;\n\tif (uSnow == 1) {\n\t\tfloat distanceSquared = dot(delta, delta) / (radius * radius);\n\t\tif (distanceSquared >= 1.0) discard;\n\t\tfloat q = 1.0 - distanceSquared;\n\t\tcoverage = q * q;\n\t} else {\n\t\tfloat lengthSquared = dot(vLine, vLine);\n\t\tfloat along = lengthSquared > 0.0 ? clamp(dot(delta, vLine) / lengthSquared, 0.0, 1.0) : 0.0;\n\t\tcoverage = clamp(radius - length(delta - vLine * along) + 0.5, 0.0, 1.0);\n\t}\n\tfloat alpha = coverage * vColor.a * fade;\n\tif (alpha <= 0.000001) discard;\n\tfragColor = vec4(vColor.rgb * alpha, alpha);\n}\n";
|
|
3
|
+
export declare const WEATHER_COMPOSITE_VERTEX_SHADER = "#version 300 es\nout vec2 vUv;\n\nvoid main() {\n\tvUv = vec2(float(gl_VertexID & 1), float(gl_VertexID >> 1));\n\tgl_Position = vec4(vUv * 2.0 - 1.0, 0.0, 1.0);\n}\n";
|
|
4
|
+
export declare const WEATHER_COMPOSITE_FRAGMENT_SHADER = "#version 300 es\nprecision highp float;\n\nuniform sampler2D uSource;\nuniform sampler2D uWeather;\nuniform int uCompositeWithOriginal;\nuniform int uLighten;\n\nin vec2 vUv;\nout vec4 fragColor;\n\nvoid main() {\n\tvec4 weather = texture(uWeather, vUv);\n\tif (uCompositeWithOriginal == 0) {\n\t\tfragColor = weather;\n\t\treturn;\n\t}\n\tvec4 source = texture(uSource, vUv);\n\tif (uLighten == 1) {\n\t\tfragColor = vec4(max(source.rgb, weather.rgb), source.a + weather.a - source.a * weather.a);\n\t} else {\n\t\tfragColor = weather + source * (1.0 - weather.a);\n\t}\n}\n";
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type ParsedColorRgba } from '../color-utils.js';
|
|
2
|
+
import type { WeatherRenderParams } from './runtime.js';
|
|
3
|
+
export type WeatherWebGpuState = {
|
|
4
|
+
readonly context: GPUCanvasContext;
|
|
5
|
+
readonly colorCtx: CanvasRenderingContext2D;
|
|
6
|
+
cachedColor: string | null;
|
|
7
|
+
cachedColorRgba: ParsedColorRgba;
|
|
8
|
+
resources: {
|
|
9
|
+
readonly device: GPUDevice;
|
|
10
|
+
readonly particles: GPURenderPipeline;
|
|
11
|
+
readonly composite: GPURenderPipeline;
|
|
12
|
+
readonly uniforms: GPUBuffer;
|
|
13
|
+
readonly sampler: GPUSampler;
|
|
14
|
+
textures: {
|
|
15
|
+
readonly source: GPUTexture;
|
|
16
|
+
readonly weather: GPUTexture;
|
|
17
|
+
readonly particleGroup: GPUBindGroup;
|
|
18
|
+
readonly compositeGroup: GPUBindGroup;
|
|
19
|
+
readonly width: number;
|
|
20
|
+
readonly height: number;
|
|
21
|
+
readonly sourceWidth: number;
|
|
22
|
+
readonly sourceHeight: number;
|
|
23
|
+
} | null;
|
|
24
|
+
} | null;
|
|
25
|
+
};
|
|
26
|
+
export declare const setupWeatherWebGpu: (target: HTMLCanvasElement) => WeatherWebGpuState;
|
|
27
|
+
export declare const cleanupWeatherWebGpu: (state: WeatherWebGpuState) => void;
|
|
28
|
+
export declare const drawWeatherWebGpu: ({ state, source, width, height, device, params, type, }: {
|
|
29
|
+
state: WeatherWebGpuState;
|
|
30
|
+
source: CanvasImageSource;
|
|
31
|
+
width: number;
|
|
32
|
+
height: number;
|
|
33
|
+
device: GPUDevice;
|
|
34
|
+
params: WeatherRenderParams;
|
|
35
|
+
type: 'rain' | 'snow';
|
|
36
|
+
}) => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const WEATHER_WEBGPU_SHADER = "\n\nstruct VertexOutput {\n\t@builtin(position) position: vec4f,\n\t@location(0) uv: vec2f,\n}\n\n@vertex fn vertex(@builtin(vertex_index) index: u32) -> VertexOutput {\n\tlet positions = array<vec2f, 3>(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));\n\tlet position = positions[index];\n\tvar output: VertexOutput;\n\toutput.position = vec4f(position, 0, 1);\n\toutput.uv = vec2f(position.x * 0.5 + 0.5, 0.5 - position.y * 0.5);\n\treturn output;\n}\n\nstruct Params {\n resolution: vec2f, offset: vec2f, color: vec4f,\n snow: f32, time: f32, seed: u32, size: f32,\n sizeVariation: f32, sceneDepth: f32, speed: f32, speedVariation: f32,\n wind: f32, windVariation: f32, spread: f32, wiggleAmount: f32,\n wiggleAmountVariation: f32, wiggleFrequency: f32, wiggleFrequencyVariation: f32, opacity: f32,\n refract: f32, composite: f32, lighten: f32, padding: f32,\n}\nstruct ParticleOutput {\n @builtin(position) position: vec4f,\n @location(0) @interpolate(flat) particlePosition: vec2f,\n @location(1) @interpolate(flat) line: vec2f,\n @location(2) @interpolate(flat) radius: f32,\n @location(3) @interpolate(flat) color: vec4f,\n}\n@group(0) @binding(0) var source: texture_2d<f32>;\n@group(0) @binding(1) var sourceSampler: sampler;\n@group(0) @binding(2) var<uniform> params: Params;\n@group(0) @binding(3) var weather: texture_2d<f32>;\nfn noise(i: u32, key: u32) -> f32 {\n\tvar h: u32 = (i * 0x8da6b343u) ^ (key * 0xd8163841u) ^ (params.seed * 0xcb1ab31fu);\n\th ^= h >> 13u;\n\th *= 0x5bd1e995u;\n\th ^= h >> 15u;\n\treturn f32(h & 0x00ffffffu) / 16777216.0;\n}\n\nfn signedNoise(i: u32, key: u32) -> f32 {\n\treturn noise(i, key) * 2.0 - 1.0;\n}\n\nfn wrap(value: f32, margin: f32, size: f32) -> f32 {\n\treturn -margin + (value + margin - floor((value + margin)/(size + 2.0*margin))*(size+2.0*margin));\n}\n\nfn sourcePixel(p: vec2i) -> vec4f {\n\tvar size: vec2i = vec2i(textureDimensions(source));\n\tif (p.x < 0 || p.y < 0 || p.x >= size.x || p.y >= size.y) {\n\t\treturn vec4f(0.0);\n\t}\n\treturn textureLoad(source,p,0);\n}\n\n// Bilinear sampling with transparent borders, at pixel centers of +0.5.\nfn sourceAt(position: vec2f) -> vec4f {\n\tvar p: vec2f = position - vec2f(0.5);\n\tvar base: vec2i = vec2i(floor(p));\n\tvar f: vec2f = fract(p);\n\treturn mix(\n\t\tmix(sourcePixel(base), sourcePixel(base + vec2i(1, 0)), f.x),\n\t\tmix(sourcePixel(base + vec2i(0, 1)), sourcePixel(base + vec2i(1, 1)), f.x),\n\t\tf.y\n\t);\n}\n\n@vertex fn particleVertex(@builtin(vertex_index) vertexIndex: u32, @builtin(instance_index) instanceIndex: u32) -> ParticleOutput {\n var output: ParticleOutput;\n\tvar i: u32 = instanceIndex;\n\tvar depth: f32 = 1.0 / (1.0 + noise(i, 1u) * params.sceneDepth / 2500.0);\n\tvar offset: vec2f = (params.offset - vec2f(0.5)) * params.resolution;\n\tvar position: vec2f ;\n\tvar line: vec2f = vec2f(0.0);\n\tvar radius: f32 ;\n\tvar alpha: f32 ;\n\tif (params.snow == 1) {\n\t\tradius = max(params.size * 0.5 * depth * (1.0 + params.sizeVariation * signedNoise(i, 2u)), 0.05);\n\t\tvar speed: f32 = params.speed * (params.resolution.y / 600.0) * depth * (1.0 + params.speedVariation * signedNoise(i, 3u));\n\t\tvar wind: f32 = params.wind * (params.resolution.y / 1200.0) * depth * (1.0 + params.windVariation * signedNoise(i, 4u))\n\t\t\t+ params.spread * signedNoise(i, 8u) * depth;\n\t\tvar amplitude: f32 = params.wiggleAmount * 2.0 * depth * (1.0 + params.wiggleAmountVariation * signedNoise(i, 5u));\n\t\tvar frequency: f32 = params.wiggleFrequency * (1.0 + params.wiggleFrequencyVariation * signedNoise(i, 6u));\n\t\tvar phase: f32 = noise(i, 9u) * 6.283185307179586;\n\t\tvar margin: f32 = radius + abs(amplitude) + 2.0;\n\t\tposition.y = wrap(noise(i, 10u) * (params.resolution.y + 2.0 * margin) + speed * params.time + offset.y, margin, params.resolution.y);\n\t\tposition.x = wrap(noise(i, 11u) * (params.resolution.x + 2.0 * margin) + wind * params.time + offset.x, margin, params.resolution.x)\n\t\t\t+ amplitude * sin(frequency * params.time * 6.283185307179586 + phase);\n\t\talpha = params.opacity * (0.4 + 0.6 * depth);\n\t} else {\n\t\tvar speed: f32 = params.speed / 4000.0 * params.resolution.y * 2.2 * depth;\n\t\tvar wind: f32 = params.wind / 1000.0 * params.resolution.y * (1.0 + params.windVariation * signedNoise(i, 2u)) * depth\n\t\t\t+ params.spread * signedNoise(i, 7u) * depth;\n\t\tvar length: f32 = max(speed * 0.04 * max(params.size, 0.2), 1.0);\n\t\tvar horizontalLength: f32 = wind * 0.04 * max(params.size, 0.2);\n\t\tvar margin: f32 = length + abs(horizontalLength) + 4.0;\n\t\tposition.y = wrap(noise(i, 3u) * (params.resolution.y + 2.0 * margin) + speed * params.time + offset.y, margin, params.resolution.y);\n\t\tposition.x = wrap(noise(i, 4u) * (params.resolution.x + 2.0 * margin) + wind * params.time + offset.x, margin, params.resolution.x);\n\t\tline = vec2f(-horizontalLength, -length);\n\t\tradius = max(params.size * 0.6 * depth, 0.25);\n\t\talpha = params.opacity * (0.35 + 0.65 * depth);\n\t}\n\n\tvar color: vec3f = params.color.rgb;\n\tif (params.snow == 0 && params.refract == 1) {\n\t\tvar sampleColor: vec4f = sourceAt(position + vec2f(2.0, 0.0));\n\t\tif (sampleColor.a > 0.0) {\n\t\t\tvar straight: vec3f = select(vec3f(0),sampleColor.rgb/max(sampleColor.a,0.000001),sampleColor.a>0.000001);\n\t\t\tcolor *= straight * 0.6 + vec3f(0.5);\n\t\t}\n\t}\n\n\toutput.particlePosition = position;\n\toutput.line = line;\n\toutput.radius = radius;\n\toutput.color = vec4f(color, alpha * params.color.a);\n\tvar padding: f32 = max(radius, 0.5) + 1.0;\n\tvar minimum: vec2f = min(position, position + line) - vec2f(padding);\n\tvar maximum: vec2f = max(position, position + line) + vec2f(padding);\n\tvar corner: vec2f = vec2f(f32(vertexIndex & 1u), f32(vertexIndex >> 1u));\n\tvar pixel: vec2f = mix(minimum, maximum, corner);\n\toutput.position = vec4f(pixel.x / params.resolution.x * 2.0 - 1.0, 1.0 - pixel.y / params.resolution.y * 2.0, 0.0, 1.0);\nreturn output;\n}\n@fragment fn particleFragment(input: ParticleOutput) -> @location(0) vec4f {\n\tif (input.color.a <= 0.00001) { discard; }\n\tvar delta: vec2f = input.position.xy - input.particlePosition;\n\tvar radius: f32 = max(input.radius, 0.5);\n\tvar fade: f32 = min(input.radius / 0.5, 1.0);\n\tvar coverage: f32 ;\n\tif (params.snow == 1) {\n\t\tvar distanceSquared: f32 = dot(delta, delta) / (radius * radius);\n\t\tif (distanceSquared >= 1.0) { discard; }\n\t\tvar q: f32 = 1.0 - distanceSquared;\n\t\tcoverage = q * q;\n\t} else {\n\t\tvar lengthSquared: f32 = dot(input.line, input.line);\n\t\tvar along: f32 = select(0.0,clamp(dot(delta, input.line)/max(lengthSquared,0.00000001),0.0,1.0),lengthSquared>0.0);\n\t\tcoverage = clamp(radius - length(delta - input.line * along) + 0.5, 0.0, 1.0);\n\t}\n\tvar alpha: f32 = coverage * input.color.a * fade;\n\tif (alpha <= 0.000001) { discard; }\n\treturn vec4f(input.color.rgb * alpha, alpha);\n}\n\n@fragment fn fragment(input: VertexOutput) -> @location(0) vec4f {\n let result=textureSampleLevel(weather,sourceSampler,input.uv,0);\n if(params.composite==0.0) { return result; }\n let original=textureSampleLevel(source,sourceSampler,input.uv,0);\n if(params.lighten==1.0) { return vec4f(max(original.rgb,result.rgb),original.a+result.a-original.a*result.a); }\n return result+original*(1.0-result.a);\n}\n";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type WebGlProjectionState = {
|
|
2
|
+
gl: WebGL2RenderingContext;
|
|
3
|
+
program: WebGLProgram;
|
|
4
|
+
texture: WebGLTexture;
|
|
5
|
+
vao: WebGLVertexArrayObject;
|
|
6
|
+
uniforms: WebGLUniformLocation | null;
|
|
7
|
+
source: WebGLUniformLocation | null;
|
|
8
|
+
};
|
|
9
|
+
export declare const setupWebGlProjection: (target: HTMLCanvasElement, shader: string) => WebGlProjectionState;
|
|
10
|
+
export declare const applyWebGlProjection: ({ state, source, width, height, flipSourceY, uniformData, }: {
|
|
11
|
+
state: WebGlProjectionState;
|
|
12
|
+
source: CanvasImageSource;
|
|
13
|
+
width: number;
|
|
14
|
+
height: number;
|
|
15
|
+
flipSourceY: boolean;
|
|
16
|
+
uniformData: Float32Array<ArrayBuffer>;
|
|
17
|
+
}) => void;
|
|
18
|
+
export declare const cleanupWebGlProjection: ({ gl, program, texture, vao, }: WebGlProjectionState) => void;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type WebGpuSinglePassState } from './webgpu-single-pass-runtime.js';
|
|
2
|
+
export type WebGpuColorState = WebGpuSinglePassState & {
|
|
3
|
+
readonly colorContext: CanvasRenderingContext2D;
|
|
4
|
+
colors: {
|
|
5
|
+
key: string;
|
|
6
|
+
data: Uint8Array<ArrayBuffer>;
|
|
7
|
+
} | null;
|
|
8
|
+
};
|
|
9
|
+
export declare const setupWebGpuColors: (target: HTMLCanvasElement, label: string) => WebGpuColorState;
|
|
10
|
+
export declare const getWebGpuColors: (state: WebGpuColorState, colors: readonly string[]) => Uint8Array<ArrayBuffer>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export type WebGpuMeshState = {
|
|
2
|
+
readonly context: GPUCanvasContext;
|
|
3
|
+
readonly label: string;
|
|
4
|
+
resources: {
|
|
5
|
+
readonly device: GPUDevice;
|
|
6
|
+
readonly shader: string;
|
|
7
|
+
readonly uniformSize: number;
|
|
8
|
+
readonly topology: GPUPrimitiveTopology;
|
|
9
|
+
readonly blend: boolean;
|
|
10
|
+
readonly pipeline: GPURenderPipeline;
|
|
11
|
+
readonly flipPipeline: GPURenderPipeline;
|
|
12
|
+
readonly sampler: GPUSampler;
|
|
13
|
+
readonly uniforms: GPUBuffer;
|
|
14
|
+
multisample: {
|
|
15
|
+
readonly resolved: GPUTexture;
|
|
16
|
+
readonly texture: GPUTexture;
|
|
17
|
+
readonly width: number;
|
|
18
|
+
readonly height: number;
|
|
19
|
+
} | null;
|
|
20
|
+
vertices: {
|
|
21
|
+
readonly buffer: GPUBuffer;
|
|
22
|
+
readonly size: number;
|
|
23
|
+
} | null;
|
|
24
|
+
source: {
|
|
25
|
+
readonly texture: GPUTexture;
|
|
26
|
+
readonly width: number;
|
|
27
|
+
readonly height: number;
|
|
28
|
+
} | null;
|
|
29
|
+
} | null;
|
|
30
|
+
};
|
|
31
|
+
export declare const setupWebGpuMesh: (target: HTMLCanvasElement, label: string) => WebGpuMeshState;
|
|
32
|
+
export declare const cleanupWebGpuMesh: (state: WebGpuMeshState) => void;
|
|
33
|
+
export declare const applyWebGpuMesh: ({ state, source, width, height, vertices, device, shader, uniformData, topology, blend, vertexCount, instanceCount, }: {
|
|
34
|
+
state: WebGpuMeshState;
|
|
35
|
+
source: CanvasImageSource;
|
|
36
|
+
width: number;
|
|
37
|
+
height: number;
|
|
38
|
+
vertices: Float32Array | null;
|
|
39
|
+
shader: string;
|
|
40
|
+
uniformData: Float32Array<ArrayBuffer>;
|
|
41
|
+
topology: GPUPrimitiveTopology;
|
|
42
|
+
blend: boolean;
|
|
43
|
+
vertexCount: number;
|
|
44
|
+
instanceCount: number;
|
|
45
|
+
device: GPUDevice;
|
|
46
|
+
}) => void;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export declare const WEBGPU_MULTIPASS_BINDINGS = "\n\nstruct VertexOutput {\n\t@builtin(position) position: vec4f,\n\t@location(0) uv: vec2f,\n}\n\n@vertex fn vertex(@builtin(vertex_index) index: u32) -> VertexOutput {\n\tlet positions = array<vec2f, 3>(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));\n\tlet position = positions[index];\n\tvar output: VertexOutput;\n\toutput.position = vec4f(position, 0, 1);\n\toutput.uv = vec2f(position.x * 0.5 + 0.5, 0.5 - position.y * 0.5);\n\treturn output;\n}\n\n@group(0) @binding(0) var source: texture_2d<f32>;\n@group(0) @binding(1) var sourceSampler: sampler;\n@group(0) @binding(2) var<uniform> params: Params;\n@group(0) @binding(3) var secondary: texture_2d<f32>;\n";
|
|
2
|
+
export type WebGpuPass = {
|
|
3
|
+
readonly shader: string;
|
|
4
|
+
readonly uniforms: Float32Array<ArrayBuffer>;
|
|
5
|
+
readonly source: number;
|
|
6
|
+
readonly secondary: number;
|
|
7
|
+
};
|
|
8
|
+
type PassResources = {
|
|
9
|
+
readonly shader: string;
|
|
10
|
+
readonly size: number;
|
|
11
|
+
readonly format: GPUTextureFormat;
|
|
12
|
+
readonly pipeline: GPURenderPipeline;
|
|
13
|
+
readonly uniforms: GPUBuffer;
|
|
14
|
+
};
|
|
15
|
+
export type WebGpuMultipassState = {
|
|
16
|
+
readonly context: GPUCanvasContext;
|
|
17
|
+
readonly label: string;
|
|
18
|
+
resources: {
|
|
19
|
+
readonly device: GPUDevice;
|
|
20
|
+
readonly layout: GPUBindGroupLayout;
|
|
21
|
+
readonly sampler: GPUSampler;
|
|
22
|
+
readonly format: GPUTextureFormat;
|
|
23
|
+
readonly passes: PassResources[];
|
|
24
|
+
readonly textures: GPUTexture[];
|
|
25
|
+
auxiliary: {
|
|
26
|
+
readonly texture: GPUTexture;
|
|
27
|
+
readonly width: number;
|
|
28
|
+
readonly height: number;
|
|
29
|
+
} | null;
|
|
30
|
+
width: number;
|
|
31
|
+
height: number;
|
|
32
|
+
source: {
|
|
33
|
+
readonly texture: GPUTexture;
|
|
34
|
+
readonly width: number;
|
|
35
|
+
readonly height: number;
|
|
36
|
+
} | null;
|
|
37
|
+
} | null;
|
|
38
|
+
};
|
|
39
|
+
export declare const setupWebGpuMultipass: (target: HTMLCanvasElement, label: string) => WebGpuMultipassState;
|
|
40
|
+
export declare const cleanupWebGpuMultipass: (state: WebGpuMultipassState) => void;
|
|
41
|
+
export declare const applyWebGpuMultipass: ({ state, source, width, height, device, passes, auxiliarySource, }: {
|
|
42
|
+
state: WebGpuMultipassState;
|
|
43
|
+
source: CanvasImageSource;
|
|
44
|
+
width: number;
|
|
45
|
+
height: number;
|
|
46
|
+
device: GPUDevice;
|
|
47
|
+
passes: readonly WebGpuPass[];
|
|
48
|
+
auxiliarySource: HTMLCanvasElement | null;
|
|
49
|
+
}) => void;
|
|
50
|
+
export {};
|
|
@@ -2,18 +2,22 @@ export type WebGpuProjectionState = {
|
|
|
2
2
|
context: GPUCanvasContext;
|
|
3
3
|
resources: {
|
|
4
4
|
device: GPUDevice;
|
|
5
|
+
shader: string;
|
|
6
|
+
format: GPUTextureFormat;
|
|
5
7
|
pipeline: GPURenderPipeline;
|
|
6
8
|
uniforms: GPUBuffer;
|
|
7
9
|
sampler: GPUSampler;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
source: {
|
|
11
|
+
texture: GPUTexture;
|
|
12
|
+
bindGroup: GPUBindGroup;
|
|
13
|
+
width: number;
|
|
14
|
+
height: number;
|
|
15
|
+
} | null;
|
|
12
16
|
} | null;
|
|
13
17
|
};
|
|
14
18
|
export declare const cleanupWebGpuProjection: (state: WebGpuProjectionState) => void;
|
|
15
19
|
export declare const setupWebGpuProjection: (target: HTMLCanvasElement, label: string) => WebGpuProjectionState;
|
|
16
|
-
export declare const applyWebGpuProjection: ({ state, source,
|
|
20
|
+
export declare const applyWebGpuProjection: ({ state, source, device, shader, uniformData, }: {
|
|
17
21
|
state: WebGpuProjectionState;
|
|
18
22
|
source: CanvasImageSource;
|
|
19
23
|
width: number;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export type WebGpuSinglePassState = {
|
|
2
|
+
readonly context: GPUCanvasContext;
|
|
3
|
+
readonly label: string;
|
|
4
|
+
resources: {
|
|
5
|
+
readonly device: GPUDevice;
|
|
6
|
+
readonly shader: string;
|
|
7
|
+
readonly uniformBufferSize: number;
|
|
8
|
+
readonly sourceFilter: GPUFilterMode;
|
|
9
|
+
readonly auxiliary: {
|
|
10
|
+
readonly texture: GPUTexture;
|
|
11
|
+
readonly width: number;
|
|
12
|
+
readonly height: number;
|
|
13
|
+
readonly format: 'rgba8unorm' | 'rgba32float';
|
|
14
|
+
uploadedData: Uint8Array<ArrayBuffer> | Float32Array<ArrayBuffer> | null;
|
|
15
|
+
} | null;
|
|
16
|
+
readonly pipeline: GPURenderPipeline;
|
|
17
|
+
readonly uniforms: GPUBuffer;
|
|
18
|
+
readonly sampler: GPUSampler;
|
|
19
|
+
readonly bindGroupLayout: GPUBindGroupLayout;
|
|
20
|
+
source: {
|
|
21
|
+
readonly texture: GPUTexture;
|
|
22
|
+
readonly bindGroup: GPUBindGroup;
|
|
23
|
+
readonly width: number;
|
|
24
|
+
readonly height: number;
|
|
25
|
+
} | null;
|
|
26
|
+
} | null;
|
|
27
|
+
};
|
|
28
|
+
export declare const WEBGPU_SINGLE_PASS_VERTEX = "\nstruct VertexOutput {\n\t@builtin(position) position: vec4f,\n\t@location(0) uv: vec2f,\n}\n\n@vertex fn vertex(@builtin(vertex_index) index: u32) -> VertexOutput {\n\tlet positions = array<vec2f, 3>(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));\n\tlet position = positions[index];\n\tvar output: VertexOutput;\n\toutput.position = vec4f(position, 0, 1);\n\toutput.uv = vec2f(position.x * 0.5 + 0.5, 0.5 - position.y * 0.5);\n\treturn output;\n}\n";
|
|
29
|
+
export declare const setupWebGpuSinglePass: (target: HTMLCanvasElement, label: string) => WebGpuSinglePassState;
|
|
30
|
+
export declare const cleanupWebGpuSinglePass: (state: WebGpuSinglePassState) => void;
|
|
31
|
+
export declare const applyWebGpuSinglePass: ({ state, source, device, shader, uniformData, }: {
|
|
32
|
+
state: WebGpuSinglePassState;
|
|
33
|
+
source: CanvasImageSource;
|
|
34
|
+
width: number;
|
|
35
|
+
height: number;
|
|
36
|
+
device: GPUDevice;
|
|
37
|
+
shader: string;
|
|
38
|
+
uniformData: Float32Array<ArrayBuffer>;
|
|
39
|
+
}, options?: {
|
|
40
|
+
sourceFilter: GPUFilterMode | null;
|
|
41
|
+
auxiliaryTexture: {
|
|
42
|
+
data: Uint8Array<ArrayBuffer> | Float32Array<ArrayBuffer>;
|
|
43
|
+
width: number;
|
|
44
|
+
height: number;
|
|
45
|
+
format: 'rgba8unorm' | 'rgba32float';
|
|
46
|
+
} | null;
|
|
47
|
+
} | null) => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const WHITE_NOISE_WEBGPU_SHADER = "\n\nstruct VertexOutput {\n\t@builtin(position) position: vec4f,\n\t@location(0) uv: vec2f,\n}\n\n@vertex fn vertex(@builtin(vertex_index) index: u32) -> VertexOutput {\n\tlet positions = array<vec2f, 3>(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));\n\tlet position = positions[index];\n\tvar output: VertexOutput;\n\toutput.position = vec4f(position, 0, 1);\n\toutput.uv = vec2f(position.x * 0.5 + 0.5, 0.5 - position.y * 0.5);\n\treturn output;\n}\n\n@group(0) @binding(0) var source: texture_2d<f32>;\n@group(0) @binding(1) var sourceSampler: sampler;\n@group(0) @binding(2) var<uniform> params: Params;\n\nstruct Params { size: vec2f, amount: f32, seed: f32, }\nfn random(co: vec2f) -> f32 {\n return fract(sin(dot(co, vec2f(12.9898, 78.233)) + params.seed * 37.719) * 43758.5453);\n}\n@fragment fn fragment(input: VertexOutput) -> @location(0) vec4f {\n let color = textureSampleLevel(source, sourceSampler, input.uv, 0);\n let noise = random(vec2f(input.position.x, params.size.y - input.position.y));\n var rgb = vec3f(0);\n if (color.a != 0.0) { rgb = color.rgb / color.a; }\n return vec4f(mix(rgb, vec3f(noise), params.amount) * color.a, color.a);\n}\n\n";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const ZIGZAG_WEBGPU_SHADER = "\n\nstruct VertexOutput {\n\t@builtin(position) position: vec4f,\n\t@location(0) uv: vec2f,\n}\n\n@vertex fn vertex(@builtin(vertex_index) index: u32) -> VertexOutput {\n\tlet positions = array<vec2f, 3>(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));\n\tlet position = positions[index];\n\tvar output: VertexOutput;\n\toutput.position = vec4f(position, 0, 1);\n\toutput.uv = vec2f(position.x * 0.5 + 0.5, 0.5 - position.y * 0.5);\n\treturn output;\n}\n\n@group(0) @binding(0) var sourceTexture: texture_2d<f32>;\n@group(0) @binding(1) var sourceSampler: sampler;\n@group(0) @binding(2) var<uniform> params: Params;\n@group(0) @binding(3) var palette: texture_2d<f32>;\nstruct Params {\n geometry: vec4f,\n stripe: vec4f,\n flags: vec4f,\n wave: vec4f,\n}\nfn sampleSource(uv: vec2f) -> vec4f {\n return textureSampleLevel(sourceTexture, sourceSampler, vec2f(uv.x, 1.0 - uv.y), 0);\n}\nfn glslModulo(value: f32, divisor: f32) -> f32 { return value - divisor * floor(value / divisor); }\nfn paletteColor(index: f32) -> vec4f { return textureLoad(palette, vec2i(i32(index), 0), 0); }\n\n@fragment fn fragment(input: VertexOutput) -> @location(0) vec4f {\n let vUv = vec2f(input.uv.x, 1.0 - input.uv.y);\n\n let texColor = sampleSource(vUv);\n let thickness = max(params.stripe.x, 0.001);\n let spacing = max(params.stripe.y, 0.001);\n let cycle = spacing * params.geometry.z;\n let centered = vec2f(input.position.x, params.geometry.y - input.position.y) - params.geometry.xy * 0.5;\n let s = sin(params.stripe.z);\n let c = cos(params.stripe.z);\n let rotated = vec2f(centered.x * c - centered.y * s, centered.x * s + centered.y * c);\n var axis = select(rotated.x, rotated.y, params.geometry.w == 0.0);\n let waveAxis = select(rotated.y, rotated.x, params.geometry.w == 0.0);\nlet phase = fract(waveAxis / max(params.wave.y, 0.001));\n axis += (1.0 - abs(phase * 2.0 - 1.0) * 2.0) * params.wave.x;\n\n var position = glslModulo(axis + params.stripe.w, cycle);\n if (position < 0.0) { position += cycle; }\n // Snap rounding noise at exact band boundaries before choosing the palette entry.\n var stripeIndex = position / spacing;\n let nearestIndex = floor(stripeIndex + 0.5);\n if (abs(stripeIndex - nearestIndex) < 0.00001) { stripeIndex = nearestIndex; }\n let colorIndex = glslModulo(floor(stripeIndex), params.geometry.z);\n let inStripe = glslModulo(position, spacing);\n if (inStripe > thickness) { return texColor; }\n\n let overlay = paletteColor(colorIndex);\n let premultiplied = overlay.rgb * overlay.a;\n if (params.flags.x != 0.0) {\n return vec4f(premultiplied * texColor.a + texColor.rgb * (1.0 - overlay.a), texColor.a);\n }\n return vec4f(premultiplied + texColor.rgb * (1.0 - overlay.a), overlay.a + texColor.a * (1.0 - overlay.a));\n\n}\n";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const ZOOM_BLUR_WEBGPU_SHADER = "\n\nstruct VertexOutput {\n\t@builtin(position) position: vec4f,\n\t@location(0) uv: vec2f,\n}\n\n@vertex fn vertex(@builtin(vertex_index) index: u32) -> VertexOutput {\n\tlet positions = array<vec2f, 3>(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));\n\tlet position = positions[index];\n\tvar output: VertexOutput;\n\toutput.position = vec4f(position, 0, 1);\n\toutput.uv = vec2f(position.x * 0.5 + 0.5, 0.5 - position.y * 0.5);\n\treturn output;\n}\n\n@group(0) @binding(0) var source: texture_2d<f32>;\n@group(0) @binding(1) var sourceSampler: sampler;\n@group(0) @binding(2) var<uniform> params: Params;\nstruct Params { resolutionAndCenter: vec4f, amountAndSamples: vec4f, }\n@fragment fn fragment(input: VertexOutput) -> @location(0) vec4f {\n let resolution = params.resolutionAndCenter.xy;\n let center = vec2f(params.resolutionAndCenter.z, 1.0 - params.resolutionAndCenter.w);\n let direction = input.uv - center;\n let amount = params.amountAndSamples.x / min(resolution.x, resolution.y);\n let samples = i32(params.amountAndSamples.y);\n var color = vec4f(0);\n var total = 0.0;\n for (var i = 0; i < 64; i++) {\n if (i >= samples) { break; }\n let denominator = max(f32(samples - 1), 1.0);\n let progress = f32(i) / denominator;\n let uv = clamp(input.uv - direction * amount * progress, vec2f(0), vec2f(1));\n color += textureSampleLevel(source, sourceSampler, uv, 0);\n total += 1.0;\n }\n return color / total;\n}\n";
|