@wolsok/thanos 18.3.3 → 18.4.1
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/README.md +26 -1
- package/esm2022/index.js +1 -0
- package/esm2022/index.js.map +1 -1
- package/esm2022/lib/canvas-particle-renderer.js +31 -24
- package/esm2022/lib/canvas-particle-renderer.js.map +1 -1
- package/esm2022/lib/capture-scale.js +9 -6
- package/esm2022/lib/capture-scale.js.map +1 -1
- package/esm2022/lib/choose-particle-renderer.js +4 -3
- package/esm2022/lib/choose-particle-renderer.js.map +1 -1
- package/esm2022/lib/create-ws-thanos-options.js +2 -0
- package/esm2022/lib/create-ws-thanos-options.js.map +1 -1
- package/esm2022/lib/flow-field.js +58 -0
- package/esm2022/lib/flow-field.js.map +1 -0
- package/esm2022/lib/frame-rate.js +13 -0
- package/esm2022/lib/frame-rate.js.map +1 -0
- package/esm2022/lib/particle-renderer.js.map +1 -1
- package/esm2022/lib/particles.js +20 -10
- package/esm2022/lib/particles.js.map +1 -1
- package/esm2022/lib/simplex-noise.js +8 -4
- package/esm2022/lib/simplex-noise.js.map +1 -1
- package/esm2022/lib/vaporizing-front.js +32 -9
- package/esm2022/lib/vaporizing-front.js.map +1 -1
- package/esm2022/lib/webgl/webgl-particle-renderer.js +67 -9
- package/esm2022/lib/webgl/webgl-particle-renderer.js.map +1 -1
- package/esm2022/lib/webgl/webgl-shaders.js +50 -16
- package/esm2022/lib/webgl/webgl-shaders.js.map +1 -1
- package/esm2022/lib/wind.js +55 -0
- package/esm2022/lib/wind.js.map +1 -0
- package/esm2022/lib/ws-thanos.options.js.map +1 -1
- package/esm2022/lib/ws-thanos.service.js +47 -26
- package/esm2022/lib/ws-thanos.service.js.map +1 -1
- package/index.d.ts +1 -0
- package/lib/canvas-particle-renderer.d.ts +9 -7
- package/lib/capture-scale.d.ts +6 -5
- package/lib/choose-particle-renderer.d.ts +3 -2
- package/lib/flow-field.d.ts +24 -0
- package/lib/frame-rate.d.ts +10 -0
- package/lib/particle-renderer.d.ts +6 -0
- package/lib/particles.d.ts +14 -6
- package/lib/vaporizing-front.d.ts +26 -4
- package/lib/webgl/webgl-particle-renderer.d.ts +3 -2
- package/lib/webgl/webgl-shaders.d.ts +7 -0
- package/lib/wind.d.ts +40 -0
- package/lib/ws-thanos.options.d.ts +6 -0
- package/lib/ws-thanos.service.d.ts +2 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simplex-noise.js","sourceRoot":"","sources":["../../../../../../libs/public/ws-thanos/src/lib/simplex-noise.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SimplexNoiseOptions } from './simplex-noise-options';\n\nexport class SimplexNoise {\n constructor(options?: Partial<SimplexNoiseOptions>) {\n const { min, max, random, amplitude, frequency, octaves, persistence } =\n createOptionsWithDefaults(options);\n\n this.random = random;\n this.amplitude = amplitude;\n this.frequency = frequency;\n this.octaves = octaves;\n this.persistence = persistence;\n\n this.scale =\n min === -1 && max === 1\n ? (value) => value\n : (value) => min + ((value + 1) / 2) * (max - min);\n\n const p = new Uint8Array(256);\n for (let i = 0; i < 256; i++) {\n p[i] = i;\n }\n\n let n: number;\n let q: number;\n for (let i = 255; i > 0; i--) {\n n = Math.floor((i + 1) * this.random());\n q = p[i];\n p[i] = p[n];\n p[n] = q;\n }\n\n this.perm = new Uint8Array(512);\n this.permMod12 = new Uint8Array(512);\n for (let i = 0; i < 512; i++) {\n this.perm[i] = p[i & 255];\n this.permMod12[i] = this.perm[i] % 12;\n }\n }\n\n static G3 = 1.0 / 6.0;\n\n static GRAD3D = [\n [1, 1, 0],\n [-1, 1, 0],\n [1, -1, 0],\n [-1, -1, 0],\n [1, 0, 1],\n [-1, 0, 1],\n [1, 0, -1],\n [-1, 0, -1],\n [0, 1, 1],\n [0, -1, -1],\n [0, 1, -1],\n [0, -1, -1],\n ];\n\n readonly amplitude: number;\n readonly frequency: number;\n readonly octaves: number;\n readonly perm: Uint8Array;\n readonly permMod12: Uint8Array;\n readonly persistence: number;\n readonly random: () => number;\n readonly scale: (value: number) => number;\n private memScale3D: { [key: string]: number } = {};\n\n dot(gs: number[], coords: number[]): number {\n return gs\n .slice(0, Math.min(gs.length, coords.length))\n .reduce((total, g, i) => total + g * coords[i], 0);\n }\n\n raw3D(x: number, y: number, z: number): number {\n // Skew the input space to determine which simplex cell we're in\n const s = (x + y + z) / 3.0; // Very nice and simple skew factor for 3D\n const i = Math.floor(x + s);\n const j = Math.floor(y + s);\n const k = Math.floor(z + s);\n const t = (i + j + k) * SimplexNoise.G3;\n const X0 = i - t; // Unskew the cell origin back to (x,y,z) space\n const Y0 = j - t;\n const Z0 = k - t;\n const x0 = x - X0; // The x,y,z distances from the cell origin\n const y0 = y - Y0;\n const z0 = z - Z0;\n\n // Determine which simplex we are in\n let i1: number, j1: number, k1: number; // Offsets for second corner of simplex in (i,j,k) coords\n let i2: number, j2: number, k2: number; // Offsets for third corner of simplex in (i,j,k) coords\n if (x0 >= y0) {\n if (y0 >= z0) {\n i1 = i2 = j2 = 1;\n j1 = k1 = k2 = 0;\n } else if (x0 >= z0) {\n i1 = i2 = k2 = 1;\n j1 = k1 = j2 = 0;\n } else {\n k1 = i2 = k2 = 1;\n i1 = j1 = j2 = 0;\n }\n } else {\n if (y0 < z0) {\n k1 = j2 = k2 = 1;\n i1 = j1 = i2 = 0;\n } else if (x0 < z0) {\n j1 = j2 = k2 = 1;\n i1 = k1 = i2 = 0;\n } else {\n j1 = i2 = j2 = 1;\n i1 = k1 = k2 = 0;\n }\n }\n\n const x1 = x0 - i1 + SimplexNoise.G3; // Offsets for second corner in (x,y,z) coords\n const y1 = y0 - j1 + SimplexNoise.G3;\n const z1 = z0 - k1 + SimplexNoise.G3;\n const x2 = x0 - i2 + 2.0 * SimplexNoise.G3; // Offsets for third corner in (x,y,z) coords\n const y2 = y0 - j2 + 2.0 * SimplexNoise.G3;\n const z2 = z0 - k2 + 2.0 * SimplexNoise.G3;\n const x3 = x0 - 1.0 + 3.0 * SimplexNoise.G3; // Offsets for last corner in (x,y,z) coords\n const y3 = y0 - 1.0 + 3.0 * SimplexNoise.G3;\n const z3 = z0 - 1.0 + 3.0 * SimplexNoise.G3;\n\n // Work out the hashed gradient indices of the four simplex corners\n const ii = i & 255;\n const jj = j & 255;\n const kk = k & 255;\n const gi0 = this.permMod12[ii + this.perm[jj + this.perm[kk]]];\n const gi1 =\n this.permMod12[ii + i1 + this.perm[jj + j1 + this.perm[kk + k1]]];\n const gi2 =\n this.permMod12[ii + i2 + this.perm[jj + j2 + this.perm[kk + k2]]];\n const gi3 = this.permMod12[ii + 1 + this.perm[jj + 1 + this.perm[kk + 1]]];\n\n // Calculate the contribution from the four corners\n const t0 = 0.5 - x0 * x0 - y0 * y0 - z0 * z0;\n const n0 =\n t0 < 0\n ? 0.0\n : Math.pow(t0, 4) * this.dot(SimplexNoise.GRAD3D[gi0], [x0, y0, z0]);\n const t1 = 0.5 - x1 * x1 - y1 * y1 - z1 * z1;\n const n1 =\n t1 < 0\n ? 0.0\n : Math.pow(t1, 4) * this.dot(SimplexNoise.GRAD3D[gi1], [x1, y1, z1]);\n const t2 = 0.5 - x2 * x2 - y2 * y2 - z2 * z2;\n const n2 =\n t2 < 0\n ? 0.0\n : Math.pow(t2, 4) * this.dot(SimplexNoise.GRAD3D[gi2], [x2, y2, z2]);\n const t3 = 0.5 - x3 * x3 - y3 * y3 - z3 * z3;\n const n3 =\n t3 < 0\n ? 0.0\n : Math.pow(t3, 4) * this.dot(SimplexNoise.GRAD3D[gi3], [x3, y3, z3]);\n\n // Add contributions from each corner to get the final noise value.\n // The result is scaled to stay just inside [-1,1]\n return 94.68493150681972 * (n0 + n1 + n2 + n3);\n }\n\n scaled3D(x: number, y: number, z: number, resolution: number): number {\n const memIndex = `${Math.round(x * resolution)}${Math.round(\n y * resolution\n )}${Math.round(z * resolution)}`;\n const memElem = this.memScale3D[memIndex];\n if (memElem != null) {\n return memElem;\n }\n\n let amplitude = this.amplitude;\n let frequency = this.frequency;\n let maxAmplitude = 0;\n let noise = 0;\n\n for (let i = 0; i < this.octaves; i++) {\n noise +=\n this.raw3D(x * frequency, y * frequency, z * frequency) * amplitude;\n maxAmplitude += amplitude;\n amplitude *= this.persistence;\n frequency *= 2;\n }\n const result = this.scale(noise / maxAmplitude);\n this.memScale3D[memIndex] = result;\n return result;\n }\n}\n\nfunction createOptionsWithDefaults(options?: Partial<SimplexNoiseOptions>) {\n if (options != null) {\n if (options['amplitude'] && typeof options.amplitude !== 'number') {\n throw new Error('options.amplitude must be a number');\n }\n\n if (options['frequency'] && typeof options.frequency !== 'number') {\n throw new Error('options.frequency must be a number');\n }\n\n if (\n options['octaves'] &&\n (typeof options.octaves !== 'number' ||\n !isFinite(options.octaves) ||\n Math.floor(options.octaves) !== options.octaves)\n ) {\n throw new Error('options.octaves must be an integer');\n }\n\n if (options['persistence'] && typeof options.persistence !== 'number') {\n throw new Error('options.persistence must be a number');\n }\n\n if (options['random'] && typeof options.random !== 'function') {\n throw new Error('options.random must be a function');\n }\n\n if (options['min'] && typeof options.min !== 'number') {\n throw new Error('options.min must be a number');\n }\n\n if (options['max'] && typeof options.max !== 'number') {\n throw new Error('options.max must be a number');\n }\n }\n\n const optionsResult = {\n amplitude: 1.0,\n frequency: 1.0,\n max: 1.0,\n min: -1.0,\n octaves: 1,\n persistence: 0.5,\n random: Math.random,\n ...options,\n };\n if (optionsResult.min > optionsResult.max) {\n throw new Error('min must be smaller max');\n }\n return optionsResult;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"simplex-noise.js","sourceRoot":"","sources":["../../../../../../libs/public/ws-thanos/src/lib/simplex-noise.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SimplexNoiseOptions } from './simplex-noise-options';\n\nexport class SimplexNoise {\n constructor(options?: Partial<SimplexNoiseOptions>) {\n const { min, max, random, amplitude, frequency, octaves, persistence } =\n createOptionsWithDefaults(options);\n\n this.random = random;\n this.amplitude = amplitude;\n this.frequency = frequency;\n this.octaves = octaves;\n this.persistence = persistence;\n\n this.scale =\n min === -1 && max === 1\n ? (value) => value\n : (value) => min + ((value + 1) / 2) * (max - min);\n\n const p = new Uint8Array(256);\n for (let i = 0; i < 256; i++) {\n p[i] = i;\n }\n\n let n: number;\n let q: number;\n for (let i = 255; i > 0; i--) {\n n = Math.floor((i + 1) * this.random());\n q = p[i];\n p[i] = p[n];\n p[n] = q;\n }\n\n this.perm = new Uint8Array(512);\n this.permMod12 = new Uint8Array(512);\n for (let i = 0; i < 512; i++) {\n this.perm[i] = p[i & 255];\n this.permMod12[i] = this.perm[i] % 12;\n }\n }\n\n static G3 = 1.0 / 6.0;\n\n static GRAD3D = [\n [1, 1, 0],\n [-1, 1, 0],\n [1, -1, 0],\n [-1, -1, 0],\n [1, 0, 1],\n [-1, 0, 1],\n [1, 0, -1],\n [-1, 0, -1],\n [0, 1, 1],\n [0, -1, -1],\n [0, 1, -1],\n [0, -1, -1],\n ];\n\n readonly amplitude: number;\n readonly frequency: number;\n readonly octaves: number;\n readonly perm: Uint8Array;\n readonly permMod12: Uint8Array;\n readonly persistence: number;\n readonly random: () => number;\n readonly scale: (value: number) => number;\n private memScale3D: { [key: string]: number } = {};\n\n dot(gs: number[], coords: number[]): number {\n return gs\n .slice(0, Math.min(gs.length, coords.length))\n .reduce((total, g, i) => total + g * coords[i], 0);\n }\n\n raw3D(x: number, y: number, z: number): number {\n // Skew the input space to determine which simplex cell we're in\n const s = (x + y + z) / 3.0; // Very nice and simple skew factor for 3D\n const i = Math.floor(x + s);\n const j = Math.floor(y + s);\n const k = Math.floor(z + s);\n const t = (i + j + k) * SimplexNoise.G3;\n const X0 = i - t; // Unskew the cell origin back to (x,y,z) space\n const Y0 = j - t;\n const Z0 = k - t;\n const x0 = x - X0; // The x,y,z distances from the cell origin\n const y0 = y - Y0;\n const z0 = z - Z0;\n\n // Determine which simplex we are in\n let i1: number, j1: number, k1: number; // Offsets for second corner of simplex in (i,j,k) coords\n let i2: number, j2: number, k2: number; // Offsets for third corner of simplex in (i,j,k) coords\n if (x0 >= y0) {\n if (y0 >= z0) {\n i1 = i2 = j2 = 1;\n j1 = k1 = k2 = 0;\n } else if (x0 >= z0) {\n i1 = i2 = k2 = 1;\n j1 = k1 = j2 = 0;\n } else {\n k1 = i2 = k2 = 1;\n i1 = j1 = j2 = 0;\n }\n } else {\n if (y0 < z0) {\n k1 = j2 = k2 = 1;\n i1 = j1 = i2 = 0;\n } else if (x0 < z0) {\n j1 = j2 = k2 = 1;\n i1 = k1 = i2 = 0;\n } else {\n j1 = i2 = j2 = 1;\n i1 = k1 = k2 = 0;\n }\n }\n\n const x1 = x0 - i1 + SimplexNoise.G3; // Offsets for second corner in (x,y,z) coords\n const y1 = y0 - j1 + SimplexNoise.G3;\n const z1 = z0 - k1 + SimplexNoise.G3;\n const x2 = x0 - i2 + 2.0 * SimplexNoise.G3; // Offsets for third corner in (x,y,z) coords\n const y2 = y0 - j2 + 2.0 * SimplexNoise.G3;\n const z2 = z0 - k2 + 2.0 * SimplexNoise.G3;\n const x3 = x0 - 1.0 + 3.0 * SimplexNoise.G3; // Offsets for last corner in (x,y,z) coords\n const y3 = y0 - 1.0 + 3.0 * SimplexNoise.G3;\n const z3 = z0 - 1.0 + 3.0 * SimplexNoise.G3;\n\n // Work out the hashed gradient indices of the four simplex corners\n const ii = i & 255;\n const jj = j & 255;\n const kk = k & 255;\n const gi0 = this.permMod12[ii + this.perm[jj + this.perm[kk]]];\n const gi1 =\n this.permMod12[ii + i1 + this.perm[jj + j1 + this.perm[kk + k1]]];\n const gi2 =\n this.permMod12[ii + i2 + this.perm[jj + j2 + this.perm[kk + k2]]];\n const gi3 = this.permMod12[ii + 1 + this.perm[jj + 1 + this.perm[kk + 1]]];\n\n // Calculate the contribution from the four corners\n const t0 = 0.5 - x0 * x0 - y0 * y0 - z0 * z0;\n const n0 =\n t0 < 0\n ? 0.0\n : Math.pow(t0, 4) * dot3(SimplexNoise.GRAD3D[gi0], x0, y0, z0);\n const t1 = 0.5 - x1 * x1 - y1 * y1 - z1 * z1;\n const n1 =\n t1 < 0\n ? 0.0\n : Math.pow(t1, 4) * dot3(SimplexNoise.GRAD3D[gi1], x1, y1, z1);\n const t2 = 0.5 - x2 * x2 - y2 * y2 - z2 * z2;\n const n2 =\n t2 < 0\n ? 0.0\n : Math.pow(t2, 4) * dot3(SimplexNoise.GRAD3D[gi2], x2, y2, z2);\n const t3 = 0.5 - x3 * x3 - y3 * y3 - z3 * z3;\n const n3 =\n t3 < 0\n ? 0.0\n : Math.pow(t3, 4) * dot3(SimplexNoise.GRAD3D[gi3], x3, y3, z3);\n\n // Add contributions from each corner to get the final noise value.\n // The result is scaled to stay just inside [-1,1]\n return 94.68493150681972 * (n0 + n1 + n2 + n3);\n }\n\n scaled3D(x: number, y: number, z: number, resolution: number): number {\n const memIndex = `${Math.round(x * resolution)}${Math.round(\n y * resolution\n )}${Math.round(z * resolution)}`;\n const memElem = this.memScale3D[memIndex];\n if (memElem != null) {\n return memElem;\n }\n\n let amplitude = this.amplitude;\n let frequency = this.frequency;\n let maxAmplitude = 0;\n let noise = 0;\n\n for (let i = 0; i < this.octaves; i++) {\n noise +=\n this.raw3D(x * frequency, y * frequency, z * frequency) * amplitude;\n maxAmplitude += amplitude;\n amplitude *= this.persistence;\n frequency *= 2;\n }\n const result = this.scale(noise / maxAmplitude);\n this.memScale3D[memIndex] = result;\n return result;\n }\n}\n\n/** like dot() without allocating, raw3D runs many times in a row */\nfunction dot3(g: number[], x: number, y: number, z: number): number {\n return g[0] * x + g[1] * y + g[2] * z;\n}\n\nfunction createOptionsWithDefaults(options?: Partial<SimplexNoiseOptions>) {\n if (options != null) {\n if (options['amplitude'] && typeof options.amplitude !== 'number') {\n throw new Error('options.amplitude must be a number');\n }\n\n if (options['frequency'] && typeof options.frequency !== 'number') {\n throw new Error('options.frequency must be a number');\n }\n\n if (\n options['octaves'] &&\n (typeof options.octaves !== 'number' ||\n !isFinite(options.octaves) ||\n Math.floor(options.octaves) !== options.octaves)\n ) {\n throw new Error('options.octaves must be an integer');\n }\n\n if (options['persistence'] && typeof options.persistence !== 'number') {\n throw new Error('options.persistence must be a number');\n }\n\n if (options['random'] && typeof options.random !== 'function') {\n throw new Error('options.random must be a function');\n }\n\n if (options['min'] && typeof options.min !== 'number') {\n throw new Error('options.min must be a number');\n }\n\n if (options['max'] && typeof options.max !== 'number') {\n throw new Error('options.max must be a number');\n }\n }\n\n const optionsResult = {\n amplitude: 1.0,\n frequency: 1.0,\n max: 1.0,\n min: -1.0,\n octaves: 1,\n persistence: 0.5,\n random: Math.random,\n ...options,\n };\n if (optionsResult.min > optionsResult.max) {\n throw new Error('min must be smaller max');\n }\n return optionsResult;\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The vaporizing front sweeps
|
|
2
|
+
* The vaporizing front sweeps against the wind through the element.
|
|
3
3
|
* Shared by the CPU and the GPU simulation, the GPU gets the values below as uniforms
|
|
4
4
|
* and the constants interpolated into its shader.
|
|
5
5
|
*/
|
|
@@ -20,23 +20,46 @@ export const FLOW_FIELD = {
|
|
|
20
20
|
xSeedOffset: 33.23,
|
|
21
21
|
ySeedDivisor: 13.23,
|
|
22
22
|
};
|
|
23
|
+
/**
|
|
24
|
+
* The front starts at the downwind side and sweeps against the wind to the upwind point of the element,
|
|
25
|
+
* for the default wind from the top right to the bottom left corner.
|
|
26
|
+
* It starts out as far as the room above or below the element reaches,
|
|
27
|
+
* so the element cracks first and only later blows away.
|
|
28
|
+
*/
|
|
29
|
+
export function frontGeometry(bounds, wind, margins) {
|
|
30
|
+
const centerX = (bounds.left + bounds.right) / 2;
|
|
31
|
+
const centerY = (bounds.top + bounds.bottom) / 2;
|
|
32
|
+
// the point where a ray from the center against the wind leaves the box
|
|
33
|
+
const toEdge = Math.max(Math.abs(wind.x), Math.abs(wind.y)) || 1;
|
|
34
|
+
const originX = centerX - (wind.x / toEdge) * ((bounds.right - bounds.left) / 2);
|
|
35
|
+
const originY = centerY - (wind.y / toEdge) * ((bounds.bottom - bounds.top) / 2);
|
|
36
|
+
let reach = 0;
|
|
37
|
+
for (const x of [bounds.left, bounds.right]) {
|
|
38
|
+
for (const y of [bounds.top, bounds.bottom]) {
|
|
39
|
+
const dy = y - originY;
|
|
40
|
+
const room = dy < 0 ? margins.top : dy > 0 ? margins.bottom : 0;
|
|
41
|
+
reach = Math.max(reach, Math.hypot(x - originX, Math.abs(dy) + room));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return { originX, originY, reach };
|
|
45
|
+
}
|
|
23
46
|
/** where the front is at the given animation progress */
|
|
24
|
-
export function vaporizingFront(animationT,
|
|
47
|
+
export function vaporizingFront(animationT, { originX, originY, reach }) {
|
|
25
48
|
const time = Math.sin(animationT * (Math.PI / 2)) * 1.1;
|
|
26
|
-
const
|
|
27
|
-
const startAccelerateY = time * (height - minParticleY) + minParticleY;
|
|
28
|
-
const lengthY = height - startAccelerateY;
|
|
49
|
+
const radius = reach * (1 - time);
|
|
29
50
|
return {
|
|
30
51
|
time,
|
|
31
|
-
|
|
52
|
+
originX,
|
|
53
|
+
originY,
|
|
54
|
+
radiusPow: radius * radius,
|
|
32
55
|
fade: 1 - Math.pow(animationT, 15),
|
|
33
56
|
};
|
|
34
57
|
}
|
|
35
58
|
/** has the front passed the particle at x, y. No tan() waves: their poles break off whole rows */
|
|
36
|
-
export function isBehindFront(x, y,
|
|
59
|
+
export function isBehindFront(x, y, deltaTSec, seed, { time, originX, originY, radiusPow }) {
|
|
37
60
|
const f = FRONT_FRAY;
|
|
38
|
-
let pXLength = x + (x % deltaTSec) * 0.5;
|
|
39
|
-
let pYLength =
|
|
61
|
+
let pXLength = x - originX + (x % deltaTSec) * 0.5;
|
|
62
|
+
let pYLength = originY - y;
|
|
40
63
|
pXLength +=
|
|
41
64
|
Math.sin((pXLength / f.xWave + f.xPhase) * time + seed * f.xSeed) *
|
|
42
65
|
f.xAmplitude;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vaporizing-front.js","sourceRoot":"","sources":["../../../../../../libs/public/ws-thanos/src/lib/vaporizing-front.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vaporizing-front.js","sourceRoot":"","sources":["../../../../../../libs/public/ws-thanos/src/lib/vaporizing-front.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ParticleBounds } from './particles';\nimport type { Wind } from './wind';\n\n/**\n * The vaporizing front sweeps against the wind through the element.\n * Shared by the CPU and the GPU simulation, the GPU gets the values below as uniforms\n * and the constants interpolated into its shader.\n */\n\n/** some random looking waves give the front a frayed edge */\nexport const FRONT_FRAY = {\n xWave: 30,\n xPhase: 723.394,\n xSeed: 12.5,\n xAmplitude: 11,\n yWave: 100,\n yPhase: 2323.234,\n ySeed: 456.1,\n yAmplitude: 23,\n} as const;\n\n/** the noise field released particles flow along */\nexport const FLOW_FIELD = {\n frequency: 0.01,\n xSeedOffset: 33.23,\n ySeedDivisor: 13.23,\n} as const;\n\n/** where the front starts and how far it reaches, in effect canvas pixels */\nexport interface FrontGeometry {\n /** upwind point of the element, the front sweeps towards it */\n originX: number;\n originY: number;\n /** distance from the origin at which the front starts */\n reach: number;\n}\n\nexport interface VaporizingFront {\n /** drives the fray waves */\n time: number;\n originX: number;\n originY: number;\n /** particles further than this (squared) from the origin break off */\n radiusPow: number;\n /** alpha factor that fades the particles out very late */\n fade: number;\n}\n\n/**\n * The front starts at the downwind side and sweeps against the wind to the upwind point of the element,\n * for the default wind from the top right to the bottom left corner.\n * It starts out as far as the room above or below the element reaches,\n * so the element cracks first and only later blows away.\n */\nexport function frontGeometry(\n bounds: ParticleBounds,\n wind: Pick<Wind, 'x' | 'y'>,\n margins: { top: number; bottom: number }\n): FrontGeometry {\n const centerX = (bounds.left + bounds.right) / 2;\n const centerY = (bounds.top + bounds.bottom) / 2;\n // the point where a ray from the center against the wind leaves the box\n const toEdge = Math.max(Math.abs(wind.x), Math.abs(wind.y)) || 1;\n const originX =\n centerX - (wind.x / toEdge) * ((bounds.right - bounds.left) / 2);\n const originY =\n centerY - (wind.y / toEdge) * ((bounds.bottom - bounds.top) / 2);\n\n let reach = 0;\n for (const x of [bounds.left, bounds.right]) {\n for (const y of [bounds.top, bounds.bottom]) {\n const dy = y - originY;\n const room = dy < 0 ? margins.top : dy > 0 ? margins.bottom : 0;\n reach = Math.max(reach, Math.hypot(x - originX, Math.abs(dy) + room));\n }\n }\n return { originX, originY, reach };\n}\n\n/** where the front is at the given animation progress */\nexport function vaporizingFront(\n animationT: number,\n { originX, originY, reach }: FrontGeometry\n): VaporizingFront {\n const time = Math.sin(animationT * (Math.PI / 2)) * 1.1;\n const radius = reach * (1 - time);\n return {\n time,\n originX,\n originY,\n radiusPow: radius * radius,\n fade: 1 - Math.pow(animationT, 15),\n };\n}\n\n/** has the front passed the particle at x, y. No tan() waves: their poles break off whole rows */\nexport function isBehindFront(\n x: number,\n y: number,\n deltaTSec: number,\n seed: number,\n { time, originX, originY, radiusPow }: VaporizingFront\n): boolean {\n const f = FRONT_FRAY;\n let pXLength = x - originX + (x % deltaTSec) * 0.5;\n let pYLength = originY - y;\n pXLength +=\n Math.sin((pXLength / f.xWave + f.xPhase) * time + seed * f.xSeed) *\n f.xAmplitude;\n pYLength +=\n Math.cos((pYLength / f.yWave + f.yPhase) * time + seed * f.ySeed) *\n f.yAmplitude;\n return pXLength * pXLength + pYLength * pYLength > radiusPow;\n}\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { EFFECT_HEIGHT_SCALE, EFFECT_WIDTH_SCALE } from '../capture-scale';
|
|
2
1
|
import { crumbleShape } from '../crumble-shape';
|
|
2
|
+
import { frameFade } from '../frame-rate';
|
|
3
3
|
import { PARTICLE_STATE_LENGTH, ParticleStateIndex, } from '../particles';
|
|
4
4
|
import { vaporizingFront } from '../vaporizing-front';
|
|
5
|
-
import { AttributeLocation, CRACK_FEEDBACK_VARYINGS, CRACK_LENGTH, CRACK_VERTEX_SHADER, CRUMBLE_MODE, DRAW_FRAGMENT_SHADER, DRAW_VERTEX_SHADER, FEEDBACK_FRAGMENT_SHADER, UPDATE_FEEDBACK_VARYINGS, UPDATE_VERTEX_SHADER, } from './webgl-shaders';
|
|
5
|
+
import { AttributeLocation, CRACK_FEEDBACK_VARYINGS, CRACK_LENGTH, CRACK_VERTEX_SHADER, CRUMBLE_MODE, DRAW_FRAGMENT_SHADER, DRAW_VERTEX_SHADER, FEEDBACK_FRAGMENT_SHADER, FLOW_FIELD_FRAGMENT_SHADER, FULL_VIEWPORT_VERTEX_SHADER, UPDATE_FEEDBACK_VARYINGS, UPDATE_VERTEX_SHADER, } from './webgl-shaders';
|
|
6
6
|
const FLOAT_BYTES = Float32Array.BYTES_PER_ELEMENT;
|
|
7
7
|
const STATE_STRIDE = PARTICLE_STATE_LENGTH * FLOAT_BYTES;
|
|
8
8
|
const CRACK_STRIDE = CRACK_LENGTH * FLOAT_BYTES;
|
|
@@ -20,10 +20,18 @@ const UPDATE_UNIFORMS = [
|
|
|
20
20
|
'uCoarseCrack',
|
|
21
21
|
'uFineCrack',
|
|
22
22
|
'uShardGrow',
|
|
23
|
+
'uWind',
|
|
24
|
+
'uFrontOrigin',
|
|
25
|
+
'uFlowField',
|
|
23
26
|
];
|
|
24
27
|
const DRAW_UNIFORMS = ['uSize', 'uPixelScale', 'uShardGrow'];
|
|
25
28
|
/** smallest shard size in css pixels */
|
|
26
29
|
const MIN_CELL_SIZE = 28;
|
|
30
|
+
/**
|
|
31
|
+
* Device pixels per texel of the flow field. The noise changes over about a hundred pixels,
|
|
32
|
+
* so the linear filtered texture looks the same as computing the noise for every particle.
|
|
33
|
+
*/
|
|
34
|
+
const FLOW_TEXTURE_CELL = 4;
|
|
27
35
|
/**
|
|
28
36
|
* Simulates and draws the particles on the GPU.
|
|
29
37
|
* The particle state lives in two buffers: every frame the update program reads
|
|
@@ -62,8 +70,6 @@ export class WebGlParticleRenderer {
|
|
|
62
70
|
this.current = 0;
|
|
63
71
|
this.crumble = params.crumble;
|
|
64
72
|
this.count = particles.count;
|
|
65
|
-
this.maxParticleX = particles.maxParticleX;
|
|
66
|
-
this.minParticleY = particles.minParticleY;
|
|
67
73
|
canvas.width = params.width;
|
|
68
74
|
canvas.height = params.height;
|
|
69
75
|
this.updateProgram = this.createProgram(UPDATE_VERTEX_SHADER, FEEDBACK_FRAGMENT_SHADER, UPDATE_FEEDBACK_VARYINGS);
|
|
@@ -75,7 +81,8 @@ export class WebGlParticleRenderer {
|
|
|
75
81
|
];
|
|
76
82
|
const colorBuffer = this.createBuffer(particles.colors, gl.STATIC_DRAW);
|
|
77
83
|
// dust has no cracks, the shaders then read the default attribute values
|
|
78
|
-
const crackBuffer = params.crumble === 'dust' ? undefined : this.createCracks();
|
|
84
|
+
const crackBuffer = params.crumble === 'dust' ? undefined : this.createCracks(particles);
|
|
85
|
+
this.flowField = this.createFlowField();
|
|
79
86
|
const crackAttributes = crackBuffer
|
|
80
87
|
? [
|
|
81
88
|
{
|
|
@@ -130,6 +137,17 @@ export class WebGlParticleRenderer {
|
|
|
130
137
|
gl.uniform1f(this.updateUniforms.uSeed, params.seed);
|
|
131
138
|
gl.uniform1i(this.updateUniforms.uCrumble, CRUMBLE_MODE[params.crumble]);
|
|
132
139
|
gl.uniform1f(this.updateUniforms.uPixelScale, params.pixelScale);
|
|
140
|
+
const { cos, sin } = params.wind;
|
|
141
|
+
gl.uniformMatrix2fv(this.updateUniforms.uWind, false, [
|
|
142
|
+
cos,
|
|
143
|
+
sin,
|
|
144
|
+
-sin,
|
|
145
|
+
cos,
|
|
146
|
+
]);
|
|
147
|
+
gl.uniform2f(this.updateUniforms.uFrontOrigin, params.front.originX, params.front.originY);
|
|
148
|
+
gl.uniform1i(this.updateUniforms.uFlowField, 0);
|
|
149
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
150
|
+
gl.bindTexture(gl.TEXTURE_2D, this.flowField);
|
|
133
151
|
gl.useProgram(this.drawProgram);
|
|
134
152
|
gl.uniform2f(this.drawUniforms.uSize, params.width, params.height);
|
|
135
153
|
gl.uniform1f(this.drawUniforms.uPixelScale, params.pixelScale);
|
|
@@ -144,7 +162,7 @@ export class WebGlParticleRenderer {
|
|
|
144
162
|
return;
|
|
145
163
|
}
|
|
146
164
|
const next = 1 - this.current;
|
|
147
|
-
const front = vaporizingFront(animationT,
|
|
165
|
+
const front = vaporizingFront(animationT, params.front);
|
|
148
166
|
const shape = crumbleShape(params.crumble, animationT);
|
|
149
167
|
// simulate: read the current state, write the next one
|
|
150
168
|
const uniforms = this.updateUniforms;
|
|
@@ -153,7 +171,7 @@ export class WebGlParticleRenderer {
|
|
|
153
171
|
gl.uniform1f(uniforms.uAnimationT, animationT);
|
|
154
172
|
gl.uniform1f(uniforms.uFrontTime, front.time);
|
|
155
173
|
gl.uniform1f(uniforms.uFrontRadiusPow, front.radiusPow);
|
|
156
|
-
gl.uniform1f(uniforms.uFade, front.fade);
|
|
174
|
+
gl.uniform1f(uniforms.uFade, frameFade(front.fade, deltaTSec));
|
|
157
175
|
gl.uniform1f(uniforms.uCoarseCrack, shape.coarseCrack * params.pixelScale);
|
|
158
176
|
gl.uniform1f(uniforms.uFineCrack, shape.fineCrack * params.pixelScale);
|
|
159
177
|
gl.uniform1f(uniforms.uShardGrow, shape.shardGrow);
|
|
@@ -172,6 +190,7 @@ export class WebGlParticleRenderer {
|
|
|
172
190
|
const { gl } = this;
|
|
173
191
|
[...this.updateVaos, ...this.drawVaos].forEach((vao) => gl.deleteVertexArray(vao));
|
|
174
192
|
this.buffers.forEach((buffer) => gl.deleteBuffer(buffer));
|
|
193
|
+
gl.deleteTexture(this.flowField);
|
|
175
194
|
gl.deleteProgram(this.updateProgram);
|
|
176
195
|
gl.deleteProgram(this.drawProgram);
|
|
177
196
|
// browsers only allow a few live contexts, free this one right away
|
|
@@ -189,12 +208,51 @@ export class WebGlParticleRenderer {
|
|
|
189
208
|
gl.disable(gl.RASTERIZER_DISCARD);
|
|
190
209
|
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null);
|
|
191
210
|
}
|
|
211
|
+
/** render the flow field once into a texture, the update program samples it */
|
|
212
|
+
createFlowField() {
|
|
213
|
+
const { gl, params } = this;
|
|
214
|
+
const width = Math.ceil(params.width / FLOW_TEXTURE_CELL);
|
|
215
|
+
const height = Math.ceil(params.height / FLOW_TEXTURE_CELL);
|
|
216
|
+
const texture = gl.createTexture();
|
|
217
|
+
const framebuffer = gl.createFramebuffer();
|
|
218
|
+
const vao = gl.createVertexArray();
|
|
219
|
+
if (texture == null || framebuffer == null || vao == null) {
|
|
220
|
+
throw new Error('Could not create the WebGL flow field');
|
|
221
|
+
}
|
|
222
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
223
|
+
gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RG8, width, height);
|
|
224
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
225
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
226
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
227
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
228
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
229
|
+
const program = this.createProgram(FULL_VIEWPORT_VERTEX_SHADER, FLOW_FIELD_FRAGMENT_SHADER);
|
|
230
|
+
const uniforms = this.uniformLocations(program, [
|
|
231
|
+
'uSeed',
|
|
232
|
+
'uCell',
|
|
233
|
+
]);
|
|
234
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
|
|
235
|
+
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
|
|
236
|
+
gl.viewport(0, 0, width, height);
|
|
237
|
+
gl.useProgram(program);
|
|
238
|
+
gl.uniform1f(uniforms.uSeed, params.seed);
|
|
239
|
+
gl.uniform2f(uniforms.uCell, params.width / width, params.height / height);
|
|
240
|
+
// the vertex shader needs no attributes, the triangle comes from gl_VertexID
|
|
241
|
+
gl.bindVertexArray(vao);
|
|
242
|
+
gl.drawArrays(gl.TRIANGLES, 0, 3);
|
|
243
|
+
gl.bindVertexArray(null);
|
|
244
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
245
|
+
gl.deleteVertexArray(vao);
|
|
246
|
+
gl.deleteFramebuffer(framebuffer);
|
|
247
|
+
gl.deleteProgram(program);
|
|
248
|
+
return texture;
|
|
249
|
+
}
|
|
192
250
|
/** run the crack program once: shard center and crack distances per particle */
|
|
193
|
-
createCracks() {
|
|
251
|
+
createCracks({ bounds }) {
|
|
194
252
|
const { gl, params } = this;
|
|
195
253
|
const crackBuffer = this.createBuffer(this.count * CRACK_STRIDE, gl.STATIC_COPY);
|
|
196
254
|
const program = this.createProgram(CRACK_VERTEX_SHADER, FEEDBACK_FRAGMENT_SHADER, CRACK_FEEDBACK_VARYINGS);
|
|
197
|
-
const elementSize = Math.min(
|
|
255
|
+
const elementSize = Math.min(bounds.right - bounds.left + 1, bounds.bottom - bounds.top + 1);
|
|
198
256
|
const cellSize = Math.max(MIN_CELL_SIZE * params.pixelScale, elementSize / 2.2);
|
|
199
257
|
const uniforms = this.uniformLocations(program, [
|
|
200
258
|
'uCellSize',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webgl-particle-renderer.js","sourceRoot":"","sources":["../../../../../../../libs/public/ws-thanos/src/lib/webgl/webgl-particle-renderer.ts"],"names":[],"mappings":"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","sourcesContent":["import { AnimationState } from '../animation.state';\nimport { EFFECT_HEIGHT_SCALE, EFFECT_WIDTH_SCALE } from '../capture-scale';\nimport { crumbleShape } from '../crumble-shape';\nimport { ParticleRenderer, ParticleRendererParams } from '../particle-renderer';\nimport {\n PARTICLE_STATE_LENGTH,\n ParticleStateIndex,\n Particles,\n} from '../particles';\nimport { vaporizingFront } from '../vaporizing-front';\nimport { WsThanosCrumble } from '../ws-thanos.options';\nimport {\n AttributeLocation,\n CRACK_FEEDBACK_VARYINGS,\n CRACK_LENGTH,\n CRACK_VERTEX_SHADER,\n CRUMBLE_MODE,\n DRAW_FRAGMENT_SHADER,\n DRAW_VERTEX_SHADER,\n FEEDBACK_FRAGMENT_SHADER,\n UPDATE_FEEDBACK_VARYINGS,\n UPDATE_VERTEX_SHADER,\n} from './webgl-shaders';\n\nconst FLOAT_BYTES = Float32Array.BYTES_PER_ELEMENT;\nconst STATE_STRIDE = PARTICLE_STATE_LENGTH * FLOAT_BYTES;\nconst CRACK_STRIDE = CRACK_LENGTH * FLOAT_BYTES;\n\nconst UPDATE_UNIFORMS = [\n 'uSize',\n 'uDeltaTSec',\n 'uAnimationT',\n 'uParticleAcceleration',\n 'uSeed',\n 'uCrumble',\n 'uPixelScale',\n 'uFrontTime',\n 'uFrontRadiusPow',\n 'uFade',\n 'uCoarseCrack',\n 'uFineCrack',\n 'uShardGrow',\n] as const;\n\nconst DRAW_UNIFORMS = ['uSize', 'uPixelScale', 'uShardGrow'] as const;\n\ntype Uniforms<T extends readonly string[]> = Record<\n T[number],\n WebGLUniformLocation | null\n>;\n\n/** one vertex attribute read from a buffer */\ninterface AttributeBinding {\n buffer: WebGLBuffer;\n location: number;\n size: number;\n type?: GLenum;\n normalized?: boolean;\n stride: number;\n offset: number;\n}\n\n/** smallest shard size in css pixels */\nconst MIN_CELL_SIZE = 28;\n\n/**\n * Simulates and draws the particles on the GPU.\n * The particle state lives in two buffers: every frame the update program reads\n * one and writes the other via transform feedback, then the draw program renders it.\n * Once at the start the crack program computes the shard and crack distances of every particle.\n */\nexport class WebGlParticleRenderer implements ParticleRenderer {\n public readonly kind = 'webgl';\n public readonly crumble: WsThanosCrumble;\n private readonly count: number;\n private readonly maxParticleX: number;\n private readonly minParticleY: number;\n private readonly updateProgram: WebGLProgram;\n private readonly drawProgram: WebGLProgram;\n private readonly buffers: WebGLBuffer[] = [];\n private readonly stateBuffers: WebGLBuffer[];\n private readonly updateVaos: WebGLVertexArrayObject[];\n private readonly drawVaos: WebGLVertexArrayObject[];\n private readonly updateUniforms: Uniforms<typeof UPDATE_UNIFORMS>;\n private readonly drawUniforms: Uniforms<typeof DRAW_UNIFORMS>;\n private current = 0;\n\n /** get a WebGL2 context for the canvas or null if the browser can't */\n public static createContext(\n canvas: HTMLCanvasElement\n ): WebGL2RenderingContext | null {\n try {\n return canvas.getContext('webgl2', {\n alpha: true,\n premultipliedAlpha: true,\n antialias: false,\n depth: false,\n stencil: false,\n });\n } catch {\n return null;\n }\n }\n\n /** the largest canvas size the GPU can render into */\n public static maxCanvasSize(gl: WebGL2RenderingContext): number {\n const viewport: ArrayLike<number> =\n gl.getParameter(gl.MAX_VIEWPORT_DIMS) ?? [];\n return Math.min(\n gl.getParameter(gl.MAX_RENDERBUFFER_SIZE),\n viewport[0] ?? Infinity,\n viewport[1] ?? Infinity\n );\n }\n\n public constructor(\n public readonly canvas: HTMLCanvasElement,\n private readonly gl: WebGL2RenderingContext,\n // only the scalars are kept, the particle arrays live on the GPU\n particles: Particles,\n private readonly params: ParticleRendererParams\n ) {\n this.crumble = params.crumble;\n this.count = particles.count;\n this.maxParticleX = particles.maxParticleX;\n this.minParticleY = particles.minParticleY;\n canvas.width = params.width;\n canvas.height = params.height;\n\n this.updateProgram = this.createProgram(\n UPDATE_VERTEX_SHADER,\n FEEDBACK_FRAGMENT_SHADER,\n UPDATE_FEEDBACK_VARYINGS\n );\n this.drawProgram = this.createProgram(\n DRAW_VERTEX_SHADER,\n DRAW_FRAGMENT_SHADER\n );\n\n // the second state buffer is written by the first frame, it needs no data\n this.stateBuffers = [\n this.createBuffer(particles.state, gl.DYNAMIC_COPY),\n this.createBuffer(particles.state.byteLength, gl.DYNAMIC_COPY),\n ];\n const colorBuffer = this.createBuffer(particles.colors, gl.STATIC_DRAW);\n // dust has no cracks, the shaders then read the default attribute values\n const crackBuffer =\n params.crumble === 'dust' ? undefined : this.createCracks();\n\n const crackAttributes: AttributeBinding[] = crackBuffer\n ? [\n {\n buffer: crackBuffer,\n location: AttributeLocation.CRACK,\n size: 4,\n stride: CRACK_STRIDE,\n offset: 0,\n },\n {\n buffer: crackBuffer,\n location: AttributeLocation.CELL_RANDOM,\n size: 1,\n stride: CRACK_STRIDE,\n offset: 4 * FLOAT_BYTES,\n },\n ]\n : [];\n this.updateVaos = this.stateBuffers.map((buffer) =>\n this.createVao([\n ...stateAttributes(buffer, [\n [AttributeLocation.POSITION, 2, ParticleStateIndex.X],\n [AttributeLocation.VELOCITY, 2, ParticleStateIndex.VX],\n [AttributeLocation.ACCELERATION, 2, ParticleStateIndex.AX],\n [AttributeLocation.ALPHA, 1, ParticleStateIndex.ALPHA],\n [AttributeLocation.RELEASED_AT, 1, ParticleStateIndex.RELEASED_AT],\n ]),\n ...crackAttributes,\n ])\n );\n this.drawVaos = this.stateBuffers.map((buffer) =>\n this.createVao([\n ...stateAttributes(buffer, [\n [AttributeLocation.POSITION, 2, ParticleStateIndex.X],\n [AttributeLocation.ALPHA, 1, ParticleStateIndex.ALPHA],\n [AttributeLocation.RELEASED_AT, 1, ParticleStateIndex.RELEASED_AT],\n ]),\n ...crackAttributes,\n {\n buffer: colorBuffer,\n location: AttributeLocation.COLOR,\n size: 4,\n type: gl.UNSIGNED_BYTE,\n normalized: true,\n stride: 0,\n offset: 0,\n },\n ])\n );\n\n this.updateUniforms = this.uniformLocations(\n this.updateProgram,\n UPDATE_UNIFORMS\n );\n this.drawUniforms = this.uniformLocations(this.drawProgram, DRAW_UNIFORMS);\n\n // everything that stays the same for the whole animation is set once\n gl.useProgram(this.updateProgram);\n gl.uniform2f(this.updateUniforms.uSize, params.width, params.height);\n gl.uniform1f(\n this.updateUniforms.uParticleAcceleration,\n params.particleAcceleration\n );\n gl.uniform1f(this.updateUniforms.uSeed, params.seed);\n gl.uniform1i(this.updateUniforms.uCrumble, CRUMBLE_MODE[params.crumble]);\n gl.uniform1f(this.updateUniforms.uPixelScale, params.pixelScale);\n gl.useProgram(this.drawProgram);\n gl.uniform2f(this.drawUniforms.uSize, params.width, params.height);\n gl.uniform1f(this.drawUniforms.uPixelScale, params.pixelScale);\n\n gl.viewport(0, 0, params.width, params.height);\n gl.enable(gl.BLEND);\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n gl.clearColor(0, 0, 0, 0);\n }\n\n public render({ deltaTSec, animationT }: AnimationState): void {\n const { gl, params } = this;\n if (gl.isContextLost()) {\n return;\n }\n const next = 1 - this.current;\n const front = vaporizingFront(\n animationT,\n this.maxParticleX,\n this.minParticleY,\n params.height\n );\n const shape = crumbleShape(params.crumble, animationT);\n\n // simulate: read the current state, write the next one\n const uniforms = this.updateUniforms;\n gl.useProgram(this.updateProgram);\n gl.uniform1f(uniforms.uDeltaTSec, deltaTSec);\n gl.uniform1f(uniforms.uAnimationT, animationT);\n gl.uniform1f(uniforms.uFrontTime, front.time);\n gl.uniform1f(uniforms.uFrontRadiusPow, front.radiusPow);\n gl.uniform1f(uniforms.uFade, front.fade);\n gl.uniform1f(uniforms.uCoarseCrack, shape.coarseCrack * params.pixelScale);\n gl.uniform1f(uniforms.uFineCrack, shape.fineCrack * params.pixelScale);\n gl.uniform1f(uniforms.uShardGrow, shape.shardGrow);\n gl.bindVertexArray(this.updateVaos[this.current]);\n this.runTransformFeedback(this.stateBuffers[next]);\n\n // draw the next state\n gl.clear(gl.COLOR_BUFFER_BIT);\n gl.useProgram(this.drawProgram);\n gl.uniform1f(this.drawUniforms.uShardGrow, shape.shardGrow);\n gl.bindVertexArray(this.drawVaos[next]);\n gl.drawArrays(gl.POINTS, 0, this.count);\n gl.bindVertexArray(null);\n\n this.current = next;\n }\n\n public dispose(): void {\n const { gl } = this;\n [...this.updateVaos, ...this.drawVaos].forEach((vao) =>\n gl.deleteVertexArray(vao)\n );\n this.buffers.forEach((buffer) => gl.deleteBuffer(buffer));\n gl.deleteProgram(this.updateProgram);\n gl.deleteProgram(this.drawProgram);\n // browsers only allow a few live contexts, free this one right away\n gl.getExtension('WEBGL_lose_context')?.loseContext();\n this.canvas.remove();\n }\n\n /** run the bound vertex array through the bound program into the target buffer */\n private runTransformFeedback(target: WebGLBuffer): void {\n const { gl } = this;\n gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, target);\n gl.enable(gl.RASTERIZER_DISCARD);\n gl.beginTransformFeedback(gl.POINTS);\n gl.drawArrays(gl.POINTS, 0, this.count);\n gl.endTransformFeedback();\n gl.disable(gl.RASTERIZER_DISCARD);\n gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null);\n }\n\n /** run the crack program once: shard center and crack distances per particle */\n private createCracks(): WebGLBuffer {\n const { gl, params } = this;\n const crackBuffer = this.createBuffer(\n this.count * CRACK_STRIDE,\n gl.STATIC_COPY\n );\n const program = this.createProgram(\n CRACK_VERTEX_SHADER,\n FEEDBACK_FRAGMENT_SHADER,\n CRACK_FEEDBACK_VARYINGS\n );\n const elementSize = Math.min(\n params.width / EFFECT_WIDTH_SCALE,\n params.height / EFFECT_HEIGHT_SCALE\n );\n const cellSize = Math.max(\n MIN_CELL_SIZE * params.pixelScale,\n elementSize / 2.2\n );\n const uniforms = this.uniformLocations(program, [\n 'uCellSize',\n 'uSeed',\n ] as const);\n\n // the first state buffer still holds the start positions\n const vao = this.createVao(\n stateAttributes(this.stateBuffers[0], [\n [AttributeLocation.POSITION, 2, ParticleStateIndex.X],\n ])\n );\n gl.useProgram(program);\n gl.uniform1f(uniforms.uCellSize, cellSize);\n gl.uniform1f(uniforms.uSeed, params.seed);\n gl.bindVertexArray(vao);\n this.runTransformFeedback(crackBuffer);\n gl.bindVertexArray(null);\n\n gl.deleteVertexArray(vao);\n gl.deleteProgram(program);\n return crackBuffer;\n }\n\n private uniformLocations<T extends readonly string[]>(\n program: WebGLProgram,\n names: T\n ): Uniforms<T> {\n const uniforms = {} as Uniforms<T>;\n for (const name of names) {\n uniforms[name as T[number]] = this.gl.getUniformLocation(program, name);\n }\n return uniforms;\n }\n\n private createProgram(\n vertexSource: string,\n fragmentSource: string,\n transformFeedbackVaryings?: string[]\n ): WebGLProgram {\n const { gl } = this;\n const program = gl.createProgram();\n if (program == null) {\n throw new Error('Could not create WebGL program');\n }\n const vertexShader = this.compileShader(gl.VERTEX_SHADER, vertexSource);\n const fragmentShader = this.compileShader(\n gl.FRAGMENT_SHADER,\n fragmentSource\n );\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n if (transformFeedbackVaryings) {\n gl.transformFeedbackVaryings(\n program,\n transformFeedbackVaryings,\n gl.INTERLEAVED_ATTRIBS\n );\n }\n gl.linkProgram(program);\n gl.deleteShader(vertexShader);\n gl.deleteShader(fragmentShader);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n const log = gl.getProgramInfoLog(program);\n gl.deleteProgram(program);\n throw new Error(`Could not link WebGL program: ${log}`);\n }\n return program;\n }\n\n private compileShader(type: GLenum, source: string): WebGLShader {\n const { gl } = this;\n const shader = gl.createShader(type);\n if (shader == null) {\n throw new Error('Could not create WebGL shader');\n }\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const log = gl.getShaderInfoLog(shader);\n gl.deleteShader(shader);\n throw new Error(`Could not compile WebGL shader: ${log}`);\n }\n return shader;\n }\n\n /** a buffer with the given data, or of the given byte size when it is filled on the GPU */\n private createBuffer(\n data: Float32Array | Uint8Array | number,\n usage: GLenum\n ): WebGLBuffer {\n const { gl } = this;\n const buffer = gl.createBuffer();\n if (buffer == null) {\n throw new Error('Could not create WebGL buffer');\n }\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n // bufferData has separate overloads for a byte size and for data\n if (typeof data === 'number') {\n gl.bufferData(gl.ARRAY_BUFFER, data, usage);\n } else {\n gl.bufferData(gl.ARRAY_BUFFER, data, usage);\n }\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n this.buffers.push(buffer);\n return buffer;\n }\n\n private createVao(bindings: AttributeBinding[]): WebGLVertexArrayObject {\n const { gl } = this;\n const vao = gl.createVertexArray();\n if (vao == null) {\n throw new Error('Could not create WebGL vertex array');\n }\n gl.bindVertexArray(vao);\n for (const binding of bindings) {\n gl.bindBuffer(gl.ARRAY_BUFFER, binding.buffer);\n gl.enableVertexAttribArray(binding.location);\n gl.vertexAttribPointer(\n binding.location,\n binding.size,\n binding.type ?? gl.FLOAT,\n binding.normalized ?? false,\n binding.stride,\n binding.offset\n );\n }\n gl.bindVertexArray(null);\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n return vao;\n }\n}\n\n/** attributes read from the interleaved particle state */\nfunction stateAttributes(\n buffer: WebGLBuffer,\n attributes: [location: number, size: number, index: ParticleStateIndex][]\n): AttributeBinding[] {\n return attributes.map(([location, size, index]) => ({\n buffer,\n location,\n size,\n stride: STATE_STRIDE,\n offset: index * FLOAT_BYTES,\n }));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"webgl-particle-renderer.js","sourceRoot":"","sources":["../../../../../../../libs/public/ws-thanos/src/lib/webgl/webgl-particle-renderer.ts"],"names":[],"mappings":"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","sourcesContent":["import { AnimationState } from '../animation.state';\nimport { crumbleShape } from '../crumble-shape';\nimport { frameFade } from '../frame-rate';\nimport { ParticleRenderer, ParticleRendererParams } from '../particle-renderer';\nimport {\n PARTICLE_STATE_LENGTH,\n ParticleStateIndex,\n Particles,\n} from '../particles';\nimport { vaporizingFront } from '../vaporizing-front';\nimport { WsThanosCrumble } from '../ws-thanos.options';\nimport {\n AttributeLocation,\n CRACK_FEEDBACK_VARYINGS,\n CRACK_LENGTH,\n CRACK_VERTEX_SHADER,\n CRUMBLE_MODE,\n DRAW_FRAGMENT_SHADER,\n DRAW_VERTEX_SHADER,\n FEEDBACK_FRAGMENT_SHADER,\n FLOW_FIELD_FRAGMENT_SHADER,\n FULL_VIEWPORT_VERTEX_SHADER,\n UPDATE_FEEDBACK_VARYINGS,\n UPDATE_VERTEX_SHADER,\n} from './webgl-shaders';\n\nconst FLOAT_BYTES = Float32Array.BYTES_PER_ELEMENT;\nconst STATE_STRIDE = PARTICLE_STATE_LENGTH * FLOAT_BYTES;\nconst CRACK_STRIDE = CRACK_LENGTH * FLOAT_BYTES;\n\nconst UPDATE_UNIFORMS = [\n 'uSize',\n 'uDeltaTSec',\n 'uAnimationT',\n 'uParticleAcceleration',\n 'uSeed',\n 'uCrumble',\n 'uPixelScale',\n 'uFrontTime',\n 'uFrontRadiusPow',\n 'uFade',\n 'uCoarseCrack',\n 'uFineCrack',\n 'uShardGrow',\n 'uWind',\n 'uFrontOrigin',\n 'uFlowField',\n] as const;\n\nconst DRAW_UNIFORMS = ['uSize', 'uPixelScale', 'uShardGrow'] as const;\n\ntype Uniforms<T extends readonly string[]> = Record<\n T[number],\n WebGLUniformLocation | null\n>;\n\n/** one vertex attribute read from a buffer */\ninterface AttributeBinding {\n buffer: WebGLBuffer;\n location: number;\n size: number;\n type?: GLenum;\n normalized?: boolean;\n stride: number;\n offset: number;\n}\n\n/** smallest shard size in css pixels */\nconst MIN_CELL_SIZE = 28;\n\n/**\n * Device pixels per texel of the flow field. The noise changes over about a hundred pixels,\n * so the linear filtered texture looks the same as computing the noise for every particle.\n */\nconst FLOW_TEXTURE_CELL = 4;\n\n/**\n * Simulates and draws the particles on the GPU.\n * The particle state lives in two buffers: every frame the update program reads\n * one and writes the other via transform feedback, then the draw program renders it.\n * Once at the start the crack program computes the shard and crack distances of every particle.\n */\nexport class WebGlParticleRenderer implements ParticleRenderer {\n public readonly kind = 'webgl';\n public readonly crumble: WsThanosCrumble;\n private readonly count: number;\n private readonly updateProgram: WebGLProgram;\n private readonly drawProgram: WebGLProgram;\n private readonly buffers: WebGLBuffer[] = [];\n private readonly flowField: WebGLTexture;\n private readonly stateBuffers: WebGLBuffer[];\n private readonly updateVaos: WebGLVertexArrayObject[];\n private readonly drawVaos: WebGLVertexArrayObject[];\n private readonly updateUniforms: Uniforms<typeof UPDATE_UNIFORMS>;\n private readonly drawUniforms: Uniforms<typeof DRAW_UNIFORMS>;\n private current = 0;\n\n /** get a WebGL2 context for the canvas or null if the browser can't */\n public static createContext(\n canvas: HTMLCanvasElement\n ): WebGL2RenderingContext | null {\n try {\n return canvas.getContext('webgl2', {\n alpha: true,\n premultipliedAlpha: true,\n antialias: false,\n depth: false,\n stencil: false,\n });\n } catch {\n return null;\n }\n }\n\n /** the largest canvas size the GPU can render into */\n public static maxCanvasSize(gl: WebGL2RenderingContext): number {\n const viewport: ArrayLike<number> =\n gl.getParameter(gl.MAX_VIEWPORT_DIMS) ?? [];\n return Math.min(\n gl.getParameter(gl.MAX_RENDERBUFFER_SIZE),\n viewport[0] ?? Infinity,\n viewport[1] ?? Infinity\n );\n }\n\n public constructor(\n public readonly canvas: HTMLCanvasElement,\n private readonly gl: WebGL2RenderingContext,\n // only the scalars are kept, the particle arrays live on the GPU\n particles: Particles,\n private readonly params: ParticleRendererParams\n ) {\n this.crumble = params.crumble;\n this.count = particles.count;\n canvas.width = params.width;\n canvas.height = params.height;\n\n this.updateProgram = this.createProgram(\n UPDATE_VERTEX_SHADER,\n FEEDBACK_FRAGMENT_SHADER,\n UPDATE_FEEDBACK_VARYINGS\n );\n this.drawProgram = this.createProgram(\n DRAW_VERTEX_SHADER,\n DRAW_FRAGMENT_SHADER\n );\n\n // the second state buffer is written by the first frame, it needs no data\n this.stateBuffers = [\n this.createBuffer(particles.state, gl.DYNAMIC_COPY),\n this.createBuffer(particles.state.byteLength, gl.DYNAMIC_COPY),\n ];\n const colorBuffer = this.createBuffer(particles.colors, gl.STATIC_DRAW);\n // dust has no cracks, the shaders then read the default attribute values\n const crackBuffer =\n params.crumble === 'dust' ? undefined : this.createCracks(particles);\n this.flowField = this.createFlowField();\n\n const crackAttributes: AttributeBinding[] = crackBuffer\n ? [\n {\n buffer: crackBuffer,\n location: AttributeLocation.CRACK,\n size: 4,\n stride: CRACK_STRIDE,\n offset: 0,\n },\n {\n buffer: crackBuffer,\n location: AttributeLocation.CELL_RANDOM,\n size: 1,\n stride: CRACK_STRIDE,\n offset: 4 * FLOAT_BYTES,\n },\n ]\n : [];\n this.updateVaos = this.stateBuffers.map((buffer) =>\n this.createVao([\n ...stateAttributes(buffer, [\n [AttributeLocation.POSITION, 2, ParticleStateIndex.X],\n [AttributeLocation.VELOCITY, 2, ParticleStateIndex.VX],\n [AttributeLocation.ACCELERATION, 2, ParticleStateIndex.AX],\n [AttributeLocation.ALPHA, 1, ParticleStateIndex.ALPHA],\n [AttributeLocation.RELEASED_AT, 1, ParticleStateIndex.RELEASED_AT],\n ]),\n ...crackAttributes,\n ])\n );\n this.drawVaos = this.stateBuffers.map((buffer) =>\n this.createVao([\n ...stateAttributes(buffer, [\n [AttributeLocation.POSITION, 2, ParticleStateIndex.X],\n [AttributeLocation.ALPHA, 1, ParticleStateIndex.ALPHA],\n [AttributeLocation.RELEASED_AT, 1, ParticleStateIndex.RELEASED_AT],\n ]),\n ...crackAttributes,\n {\n buffer: colorBuffer,\n location: AttributeLocation.COLOR,\n size: 4,\n type: gl.UNSIGNED_BYTE,\n normalized: true,\n stride: 0,\n offset: 0,\n },\n ])\n );\n\n this.updateUniforms = this.uniformLocations(\n this.updateProgram,\n UPDATE_UNIFORMS\n );\n this.drawUniforms = this.uniformLocations(this.drawProgram, DRAW_UNIFORMS);\n\n // everything that stays the same for the whole animation is set once\n gl.useProgram(this.updateProgram);\n gl.uniform2f(this.updateUniforms.uSize, params.width, params.height);\n gl.uniform1f(\n this.updateUniforms.uParticleAcceleration,\n params.particleAcceleration\n );\n gl.uniform1f(this.updateUniforms.uSeed, params.seed);\n gl.uniform1i(this.updateUniforms.uCrumble, CRUMBLE_MODE[params.crumble]);\n gl.uniform1f(this.updateUniforms.uPixelScale, params.pixelScale);\n const { cos, sin } = params.wind;\n gl.uniformMatrix2fv(this.updateUniforms.uWind, false, [\n cos,\n sin,\n -sin,\n cos,\n ]);\n gl.uniform2f(\n this.updateUniforms.uFrontOrigin,\n params.front.originX,\n params.front.originY\n );\n gl.uniform1i(this.updateUniforms.uFlowField, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, this.flowField);\n gl.useProgram(this.drawProgram);\n gl.uniform2f(this.drawUniforms.uSize, params.width, params.height);\n gl.uniform1f(this.drawUniforms.uPixelScale, params.pixelScale);\n\n gl.viewport(0, 0, params.width, params.height);\n gl.enable(gl.BLEND);\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n gl.clearColor(0, 0, 0, 0);\n }\n\n public render({ deltaTSec, animationT }: AnimationState): void {\n const { gl, params } = this;\n if (gl.isContextLost()) {\n return;\n }\n const next = 1 - this.current;\n const front = vaporizingFront(animationT, params.front);\n const shape = crumbleShape(params.crumble, animationT);\n\n // simulate: read the current state, write the next one\n const uniforms = this.updateUniforms;\n gl.useProgram(this.updateProgram);\n gl.uniform1f(uniforms.uDeltaTSec, deltaTSec);\n gl.uniform1f(uniforms.uAnimationT, animationT);\n gl.uniform1f(uniforms.uFrontTime, front.time);\n gl.uniform1f(uniforms.uFrontRadiusPow, front.radiusPow);\n gl.uniform1f(uniforms.uFade, frameFade(front.fade, deltaTSec));\n gl.uniform1f(uniforms.uCoarseCrack, shape.coarseCrack * params.pixelScale);\n gl.uniform1f(uniforms.uFineCrack, shape.fineCrack * params.pixelScale);\n gl.uniform1f(uniforms.uShardGrow, shape.shardGrow);\n gl.bindVertexArray(this.updateVaos[this.current]);\n this.runTransformFeedback(this.stateBuffers[next]);\n\n // draw the next state\n gl.clear(gl.COLOR_BUFFER_BIT);\n gl.useProgram(this.drawProgram);\n gl.uniform1f(this.drawUniforms.uShardGrow, shape.shardGrow);\n gl.bindVertexArray(this.drawVaos[next]);\n gl.drawArrays(gl.POINTS, 0, this.count);\n gl.bindVertexArray(null);\n\n this.current = next;\n }\n\n public dispose(): void {\n const { gl } = this;\n [...this.updateVaos, ...this.drawVaos].forEach((vao) =>\n gl.deleteVertexArray(vao)\n );\n this.buffers.forEach((buffer) => gl.deleteBuffer(buffer));\n gl.deleteTexture(this.flowField);\n gl.deleteProgram(this.updateProgram);\n gl.deleteProgram(this.drawProgram);\n // browsers only allow a few live contexts, free this one right away\n gl.getExtension('WEBGL_lose_context')?.loseContext();\n this.canvas.remove();\n }\n\n /** run the bound vertex array through the bound program into the target buffer */\n private runTransformFeedback(target: WebGLBuffer): void {\n const { gl } = this;\n gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, target);\n gl.enable(gl.RASTERIZER_DISCARD);\n gl.beginTransformFeedback(gl.POINTS);\n gl.drawArrays(gl.POINTS, 0, this.count);\n gl.endTransformFeedback();\n gl.disable(gl.RASTERIZER_DISCARD);\n gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null);\n }\n\n /** render the flow field once into a texture, the update program samples it */\n private createFlowField(): WebGLTexture {\n const { gl, params } = this;\n const width = Math.ceil(params.width / FLOW_TEXTURE_CELL);\n const height = Math.ceil(params.height / FLOW_TEXTURE_CELL);\n const texture = gl.createTexture();\n const framebuffer = gl.createFramebuffer();\n const vao = gl.createVertexArray();\n if (texture == null || framebuffer == null || vao == null) {\n throw new Error('Could not create the WebGL flow field');\n }\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RG8, width, height);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.bindTexture(gl.TEXTURE_2D, null);\n\n const program = this.createProgram(\n FULL_VIEWPORT_VERTEX_SHADER,\n FLOW_FIELD_FRAGMENT_SHADER\n );\n const uniforms = this.uniformLocations(program, [\n 'uSeed',\n 'uCell',\n ] as const);\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.TEXTURE_2D,\n texture,\n 0\n );\n gl.viewport(0, 0, width, height);\n gl.useProgram(program);\n gl.uniform1f(uniforms.uSeed, params.seed);\n gl.uniform2f(uniforms.uCell, params.width / width, params.height / height);\n // the vertex shader needs no attributes, the triangle comes from gl_VertexID\n gl.bindVertexArray(vao);\n gl.drawArrays(gl.TRIANGLES, 0, 3);\n gl.bindVertexArray(null);\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n\n gl.deleteVertexArray(vao);\n gl.deleteFramebuffer(framebuffer);\n gl.deleteProgram(program);\n return texture;\n }\n\n /** run the crack program once: shard center and crack distances per particle */\n private createCracks({ bounds }: Particles): WebGLBuffer {\n const { gl, params } = this;\n const crackBuffer = this.createBuffer(\n this.count * CRACK_STRIDE,\n gl.STATIC_COPY\n );\n const program = this.createProgram(\n CRACK_VERTEX_SHADER,\n FEEDBACK_FRAGMENT_SHADER,\n CRACK_FEEDBACK_VARYINGS\n );\n const elementSize = Math.min(\n bounds.right - bounds.left + 1,\n bounds.bottom - bounds.top + 1\n );\n const cellSize = Math.max(\n MIN_CELL_SIZE * params.pixelScale,\n elementSize / 2.2\n );\n const uniforms = this.uniformLocations(program, [\n 'uCellSize',\n 'uSeed',\n ] as const);\n\n // the first state buffer still holds the start positions\n const vao = this.createVao(\n stateAttributes(this.stateBuffers[0], [\n [AttributeLocation.POSITION, 2, ParticleStateIndex.X],\n ])\n );\n gl.useProgram(program);\n gl.uniform1f(uniforms.uCellSize, cellSize);\n gl.uniform1f(uniforms.uSeed, params.seed);\n gl.bindVertexArray(vao);\n this.runTransformFeedback(crackBuffer);\n gl.bindVertexArray(null);\n\n gl.deleteVertexArray(vao);\n gl.deleteProgram(program);\n return crackBuffer;\n }\n\n private uniformLocations<T extends readonly string[]>(\n program: WebGLProgram,\n names: T\n ): Uniforms<T> {\n const uniforms = {} as Uniforms<T>;\n for (const name of names) {\n uniforms[name as T[number]] = this.gl.getUniformLocation(program, name);\n }\n return uniforms;\n }\n\n private createProgram(\n vertexSource: string,\n fragmentSource: string,\n transformFeedbackVaryings?: string[]\n ): WebGLProgram {\n const { gl } = this;\n const program = gl.createProgram();\n if (program == null) {\n throw new Error('Could not create WebGL program');\n }\n const vertexShader = this.compileShader(gl.VERTEX_SHADER, vertexSource);\n const fragmentShader = this.compileShader(\n gl.FRAGMENT_SHADER,\n fragmentSource\n );\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n if (transformFeedbackVaryings) {\n gl.transformFeedbackVaryings(\n program,\n transformFeedbackVaryings,\n gl.INTERLEAVED_ATTRIBS\n );\n }\n gl.linkProgram(program);\n gl.deleteShader(vertexShader);\n gl.deleteShader(fragmentShader);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n const log = gl.getProgramInfoLog(program);\n gl.deleteProgram(program);\n throw new Error(`Could not link WebGL program: ${log}`);\n }\n return program;\n }\n\n private compileShader(type: GLenum, source: string): WebGLShader {\n const { gl } = this;\n const shader = gl.createShader(type);\n if (shader == null) {\n throw new Error('Could not create WebGL shader');\n }\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const log = gl.getShaderInfoLog(shader);\n gl.deleteShader(shader);\n throw new Error(`Could not compile WebGL shader: ${log}`);\n }\n return shader;\n }\n\n /** a buffer with the given data, or of the given byte size when it is filled on the GPU */\n private createBuffer(\n data: Float32Array | Uint8Array | number,\n usage: GLenum\n ): WebGLBuffer {\n const { gl } = this;\n const buffer = gl.createBuffer();\n if (buffer == null) {\n throw new Error('Could not create WebGL buffer');\n }\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n // bufferData has separate overloads for a byte size and for data\n if (typeof data === 'number') {\n gl.bufferData(gl.ARRAY_BUFFER, data, usage);\n } else {\n gl.bufferData(gl.ARRAY_BUFFER, data, usage);\n }\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n this.buffers.push(buffer);\n return buffer;\n }\n\n private createVao(bindings: AttributeBinding[]): WebGLVertexArrayObject {\n const { gl } = this;\n const vao = gl.createVertexArray();\n if (vao == null) {\n throw new Error('Could not create WebGL vertex array');\n }\n gl.bindVertexArray(vao);\n for (const binding of bindings) {\n gl.bindBuffer(gl.ARRAY_BUFFER, binding.buffer);\n gl.enableVertexAttribArray(binding.location);\n gl.vertexAttribPointer(\n binding.location,\n binding.size,\n binding.type ?? gl.FLOAT,\n binding.normalized ?? false,\n binding.stride,\n binding.offset\n );\n }\n gl.bindVertexArray(null);\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n return vao;\n }\n}\n\n/** attributes read from the interleaved particle state */\nfunction stateAttributes(\n buffer: WebGLBuffer,\n attributes: [location: number, size: number, index: ParticleStateIndex][]\n): AttributeBinding[] {\n return attributes.map(([location, size, index]) => ({\n buffer,\n location,\n size,\n stride: STATE_STRIDE,\n offset: index * FLOAT_BYTES,\n }));\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { FRAME_RATE } from '../frame-rate';
|
|
1
2
|
import { MIN_PARTICLE_ALPHA } from '../particles';
|
|
2
3
|
import { FLOW_FIELD, FRONT_FRAY } from '../vaporizing-front';
|
|
3
4
|
import { SIMPLEX_NOISE_3D } from './simplex-noise.glsl';
|
|
@@ -163,6 +164,11 @@ uniform float uFade;
|
|
|
163
164
|
uniform float uCoarseCrack;
|
|
164
165
|
uniform float uFineCrack;
|
|
165
166
|
uniform float uShardGrow;
|
|
167
|
+
/** where the dust blows to, rotates the forces written for the default wind */
|
|
168
|
+
uniform mat2 uWind;
|
|
169
|
+
uniform vec2 uFrontOrigin;
|
|
170
|
+
/** see FlowField, sampled once by FLOW_FIELD_FRAGMENT_SHADER over the effect canvas */
|
|
171
|
+
uniform highp sampler2D uFlowField;
|
|
166
172
|
|
|
167
173
|
out vec2 vPosition;
|
|
168
174
|
out vec2 vVelocity;
|
|
@@ -174,19 +180,13 @@ out float vReleasedAt;
|
|
|
174
180
|
const int CHUNKS = ${CRUMBLE_MODE.chunks};
|
|
175
181
|
/** part of the animation a chunk flies before it crumbles */
|
|
176
182
|
const float CHUNK_LIFE = 0.12;
|
|
177
|
-
/** weak
|
|
183
|
+
/** weak and always down, chunks jump with the wind and arc */
|
|
178
184
|
const float CHUNK_GRAVITY = 4.0;
|
|
179
185
|
|
|
180
186
|
${IS_VISIBLE_INSIDE}
|
|
181
|
-
${SIMPLEX_NOISE_3D}
|
|
182
187
|
${HASH}
|
|
183
188
|
${SHARD_OFFSET}
|
|
184
189
|
|
|
185
|
-
/** simplex noise mapped to [0, 1] like SimplexNoise({ min: 0 }) */
|
|
186
|
-
float noise01(vec3 position) {
|
|
187
|
-
return snoise(position * ${f(FLOW_FIELD.frequency)}) * 0.5 + 0.5;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
190
|
/** random number in [0, 1] per particle, frame and salt */
|
|
191
191
|
float random(uint salt) {
|
|
192
192
|
uint frame = floatBitsToUint(uAnimationT) ^ floatBitsToUint(uSeed);
|
|
@@ -194,13 +194,13 @@ float random(uint salt) {
|
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
vec2 dustAcceleration() {
|
|
197
|
-
return vec2(random(1u), -random(2u));
|
|
197
|
+
return uWind * vec2(random(1u), -random(2u));
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
/** has the vaporizing front passed this position, see isBehindFront() */
|
|
201
201
|
bool isBehindFront(vec2 position) {
|
|
202
|
-
float pXLength = position.x + mod(position.x, uDeltaTSec) * 0.5;
|
|
203
|
-
float pYLength =
|
|
202
|
+
float pXLength = position.x - uFrontOrigin.x + mod(position.x, uDeltaTSec) * 0.5;
|
|
203
|
+
float pYLength = uFrontOrigin.y - position.y;
|
|
204
204
|
pXLength += sin((pXLength / ${f(FRONT_FRAY.xWave)} + ${f(FRONT_FRAY.xPhase)}) * uFrontTime
|
|
205
205
|
+ uSeed * ${f(FRONT_FRAY.xSeed)}) * ${f(FRONT_FRAY.xAmplitude)};
|
|
206
206
|
pYLength += cos((pYLength / ${f(FRONT_FRAY.yWave)} + ${f(FRONT_FRAY.yPhase)}) * uFrontTime
|
|
@@ -236,7 +236,7 @@ void main() {
|
|
|
236
236
|
} else if (uCrumble == CHUNKS) {
|
|
237
237
|
// the whole chunk shares velocity and gravity, so it flies in one piece
|
|
238
238
|
float side = fract(aCellRandom * 13.7) - 0.5;
|
|
239
|
-
vVelocity = vec2(side * 90.0, -60.0 - aCellRandom * 70.0) * uPixelScale;
|
|
239
|
+
vVelocity = uWind * vec2(side * 90.0, -60.0 - aCellRandom * 70.0) * uPixelScale;
|
|
240
240
|
vAcceleration = vec2(0.0, CHUNK_GRAVITY);
|
|
241
241
|
vReleasedAt = -releaseT;
|
|
242
242
|
} else {
|
|
@@ -250,11 +250,9 @@ void main() {
|
|
|
250
250
|
vReleasedAt = releaseT;
|
|
251
251
|
}
|
|
252
252
|
} else {
|
|
253
|
-
// flow along the noise velocity field
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
-noise01(vec3(aPosition.x, uSeed / ${f(FLOW_FIELD.ySeedDivisor)}, aPosition.y))
|
|
257
|
-
);
|
|
253
|
+
// flow along the noise velocity field, as much per second at any frame rate
|
|
254
|
+
vec2 flow = textureLod(uFlowField, aPosition / uSize, 0.0).rg;
|
|
255
|
+
vAcceleration += uWind * vec2(flow.x, -flow.y) * (uDeltaTSec * ${f(FRAME_RATE)});
|
|
258
256
|
}
|
|
259
257
|
|
|
260
258
|
vVelocity += vAcceleration * uParticleAcceleration * uDeltaTSec;
|
|
@@ -262,6 +260,42 @@ void main() {
|
|
|
262
260
|
vAlpha *= uFade;
|
|
263
261
|
}
|
|
264
262
|
`;
|
|
263
|
+
/** one triangle that covers the whole viewport */
|
|
264
|
+
export const FULL_VIEWPORT_VERTEX_SHADER = /* glsl */ `#version 300 es
|
|
265
|
+
void main() {
|
|
266
|
+
vec2 corner = vec2(float((gl_VertexID << 1) & 2), float(gl_VertexID & 2));
|
|
267
|
+
gl_Position = vec4(corner * 2.0 - 1.0, 0.0, 1.0);
|
|
268
|
+
}
|
|
269
|
+
`;
|
|
270
|
+
/**
|
|
271
|
+
* Runs once: the noise field released particles flow along, a texel covers uCell device pixels.
|
|
272
|
+
* Red and green are the x and y flow, simplex noise mapped to [0, 1], the same noise as FlowField on the CPU.
|
|
273
|
+
*/
|
|
274
|
+
export const FLOW_FIELD_FRAGMENT_SHADER = /* glsl */ `#version 300 es
|
|
275
|
+
precision highp float;
|
|
276
|
+
|
|
277
|
+
uniform float uSeed;
|
|
278
|
+
uniform vec2 uCell;
|
|
279
|
+
|
|
280
|
+
out vec4 outColor;
|
|
281
|
+
|
|
282
|
+
${SIMPLEX_NOISE_3D}
|
|
283
|
+
|
|
284
|
+
float noise01(vec3 position) {
|
|
285
|
+
return snoise(position * ${f(FLOW_FIELD.frequency)}) * 0.5 + 0.5;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
void main() {
|
|
289
|
+
// the texel centers, where linear filtering returns exactly this value
|
|
290
|
+
vec2 position = gl_FragCoord.xy * uCell;
|
|
291
|
+
outColor = vec4(
|
|
292
|
+
noise01(vec3(position, uSeed + ${f(FLOW_FIELD.xSeedOffset)})),
|
|
293
|
+
noise01(vec3(position.x, uSeed / ${f(FLOW_FIELD.ySeedDivisor)}, position.y)),
|
|
294
|
+
0.0,
|
|
295
|
+
1.0
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
`;
|
|
265
299
|
/** transform feedback only, nothing is rasterized */
|
|
266
300
|
export const FEEDBACK_FRAGMENT_SHADER = /* glsl */ `#version 300 es
|
|
267
301
|
precision mediump float;
|