@sangwonl/pocato-core 0.4.5 → 0.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -367,6 +367,7 @@ function bootstrapShaders() {
367
367
  // src/renderer/texture-loader.ts
368
368
  import * as THREE2 from "three";
369
369
  var VIDEO_EXTENSIONS = /\.(mp4|webm|mov|ogg)(\?|$)/i;
370
+ var VIDEO_LOAD_TIMEOUT_MS = 15e3;
370
371
  function isVideoSource(layer) {
371
372
  if (layer.type) return layer.type === "video";
372
373
  return VIDEO_EXTENSIONS.test(layer.src);
@@ -458,23 +459,53 @@ function loadVideoTexture(layer, onError) {
458
459
  document.body.appendChild(video);
459
460
  pendingVideos.add(video);
460
461
  let settled = false;
462
+ const timeoutId = globalThis.setTimeout(() => {
463
+ if (settled) return;
464
+ settled = true;
465
+ pendingVideos.delete(video);
466
+ video.src = "";
467
+ video.remove();
468
+ onError?.(new Error(`Timed out loading video texture: ${layer.src}`));
469
+ resolve({ texture: getTransparentTexture() });
470
+ }, VIDEO_LOAD_TIMEOUT_MS);
461
471
  video.addEventListener("error", () => {
462
472
  if (settled) return;
463
473
  settled = true;
474
+ globalThis.clearTimeout(timeoutId);
464
475
  pendingVideos.delete(video);
465
476
  const msg = video.error?.message ?? "Unknown video error";
466
477
  onError?.(new Error(`Failed to load video texture: ${layer.src} (${msg})`));
467
478
  video.remove();
468
479
  resolve({ texture: getTransparentTexture() });
469
480
  }, { once: true });
470
- video.addEventListener("loadeddata", () => {
481
+ const resolveWithFrame = () => {
471
482
  if (settled) return;
472
483
  settled = true;
484
+ globalThis.clearTimeout(timeoutId);
473
485
  video.pause();
474
486
  pendingVideos.delete(video);
475
- const texture = new THREE2.VideoTexture(video);
487
+ const canvas = document.createElement("canvas");
488
+ canvas.width = video.videoWidth || 1;
489
+ canvas.height = video.videoHeight || 1;
490
+ const ctx = canvas.getContext("2d");
491
+ let posterTexture = getTransparentTexture();
492
+ if (ctx) {
493
+ try {
494
+ ctx.drawImage(video, 0, 0);
495
+ posterTexture = new THREE2.CanvasTexture(canvas);
496
+ posterTexture.needsUpdate = true;
497
+ } catch (error) {
498
+ debugLog("video poster drawImage failed", {
499
+ src: layer.src,
500
+ error: error instanceof Error ? error.message : String(error)
501
+ });
502
+ onError?.(error instanceof Error ? error : new Error(String(error)));
503
+ }
504
+ }
505
+ const liveTexture = new THREE2.VideoTexture(video);
476
506
  resolve({
477
- texture,
507
+ texture: posterTexture,
508
+ liveTexture,
478
509
  videoEl: video,
479
510
  play: () => {
480
511
  video.play().catch(() => {
@@ -482,6 +513,9 @@ function loadVideoTexture(layer, onError) {
482
513
  });
483
514
  }
484
515
  });
516
+ };
517
+ video.addEventListener("loadeddata", () => {
518
+ resolveWithFrame();
485
519
  }, { once: true });
486
520
  video.src = layer.src;
487
521
  video.load();
@@ -651,6 +685,9 @@ function disposeLoadedLayer(loaded) {
651
685
  if (loaded.texture !== getTransparentTexture()) {
652
686
  loaded.texture.dispose();
653
687
  }
688
+ if (loaded.liveTexture && loaded.liveTexture !== loaded.texture && loaded.liveTexture !== getTransparentTexture()) {
689
+ loaded.liveTexture.dispose();
690
+ }
654
691
  }
655
692
  function cleanupPendingVideos() {
656
693
  for (const video of pendingVideos) {
@@ -2057,7 +2094,11 @@ var FaceRenderer = class {
2057
2094
  this.material.uniforms.uResolution.value.set(width, height);
2058
2095
  }
2059
2096
  playLoadedVideos() {
2060
- for (const loaded of this.loadedLayers) {
2097
+ for (let i = 0; i < this.loadedLayers.length; i++) {
2098
+ const loaded = this.loadedLayers[i];
2099
+ if (loaded.liveTexture) {
2100
+ this.material.uniforms[`uLayer${i}`].value = loaded.liveTexture;
2101
+ }
2061
2102
  loaded.play?.();
2062
2103
  }
2063
2104
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/event-emitter.ts","../src/renderer/index.ts","../src/renderer/face-renderer.ts","../src/renderer/shader-bootstrap.ts","../src/shaders/lygia/math/permute.glsl","../src/shaders/lygia/math/mod289.glsl","../src/shaders/lygia/math/taylorInvSqrt.glsl","../src/shaders/lygia/math/grad4.glsl","../src/shaders/lygia/math/rotate4d.glsl","../src/shaders/lygia/math/cubic.glsl","../src/shaders/lygia/math/quintic.glsl","../src/shaders/lygia/math/sum.glsl","../src/shaders/lygia/math/saturate.glsl","../src/shaders/lygia/math/gaussian.glsl","../src/shaders/lygia/space/ratio.glsl","../src/shaders/lygia/generative/random.glsl","../src/shaders/lygia/generative/srandom.glsl","../src/shaders/lygia/generative/gnoise.glsl","../src/shaders/lygia/generative/snoise.glsl","../src/shaders/lygia/generative/fbm.glsl","../src/shaders/lygia/morphological/dilation.glsl","../src/shaders/lygia/sampler.glsl","../src/shaders/lygia/sample/clamp2edge.glsl","../src/shaders/lygia/draw/digits.glsl","../src/shaders/lygia/filter/gaussianBlur.glsl","../src/shaders/lygia/filter/gaussianBlur/2D.glsl","../src/shaders/lygia/filter/gaussianBlur/1D.glsl","../src/shaders/lygia/filter/gaussianBlur/1D_fast13.glsl","../src/shaders/lygia/filter/gaussianBlur/1D_fast9.glsl","../src/shaders/lygia/filter/gaussianBlur/1D_fast5.glsl","../src/shaders/lygia/filter/kuwahara.glsl","../src/shaders/utils/glsl.ts","../src/shaders/utils/default-lighting.glsl.ts","../src/renderer/texture-loader.ts","../src/shaders/common.vert.ts","../src/shaders/glare.frag.ts","../src/shaders/glare-3d.frag.ts","../src/shaders/snowfall.frag.ts","../src/shaders/snowfall-3d.frag.ts","../src/shaders/brush.frag.ts","../src/shaders/brush-3d.frag.ts","../src/shaders/blur.frag.ts","../src/shaders/blur-3d.frag.ts","../src/shaders/holo.frag.ts","../src/shaders/holo-3d.frag.ts","../src/shaders/pulse-lines.frag.ts","../src/shaders/gradient-flow.frag.ts","../src/shaders/procedural-ocean.frag.ts","../src/shaders/rainbow-flow.frag.ts","../src/shaders/shock-wave.frag.ts","../src/shaders/ripple.frag.ts","../src/shaders/lenticular.frag.ts","../src/animation/spring.ts","../src/utils/math.ts","../src/interaction/index.ts","../src/animation/tween.ts","../src/animation/wiggle.ts","../src/poca-card.ts","../src/shaders/registry.ts"],"sourcesContent":["type Handler = (...args: any[]) => void\n\nexport class EventEmitter {\n private listeners = new Map<string, Set<Handler>>()\n\n on(event: string, handler: Handler): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set())\n }\n this.listeners.get(event)!.add(handler)\n }\n\n off(event: string, handler: Handler): void {\n this.listeners.get(event)?.delete(handler)\n }\n\n protected emit(event: string, ...args: any[]): void {\n this.listeners.get(event)?.forEach((handler) => {\n try {\n handler(...args)\n } catch (e) {\n console.error(`[pocato] Error in ${event} handler:`, e)\n }\n })\n }\n\n protected removeAllListeners(): void {\n this.listeners.clear()\n }\n}\n","import * as THREE from 'three'\nimport { FaceRenderer } from './face-renderer'\nimport { cleanupPendingVideos } from './texture-loader'\nimport type { FaceFrameOptions, FaceOptions, LayerSource } from '../types'\n\nexport interface RendererOptions {\n front: FaceOptions\n back?: FaceOptions\n preventTouchScroll?: boolean\n}\n\nexport class Renderer {\n private frontFace: FaceRenderer\n private backFace: FaceRenderer | null = null\n private frontRenderer: THREE.WebGLRenderer | null = null\n private backRenderer: THREE.WebGLRenderer | null = null\n private clock = new THREE.Clock()\n private rafId: number | null = null\n private frontCanvas: HTMLCanvasElement\n private backCanvas: HTMLCanvasElement | null = null\n private cardEl: HTMLDivElement\n private rotatorEl: HTMLDivElement\n private frontEl: HTMLDivElement\n private backEl: HTMLDivElement\n private frontContentEl: HTMLDivElement\n private backContentEl: HTMLDivElement\n private frontFrameEl: HTMLDivElement\n private backFrameEl: HTMLDivElement\n private frontFrameShadowEl: HTMLDivElement\n private backFrameShadowEl: HTMLDivElement\n private frontFrame?: FaceFrameOptions\n private backFrame?: FaceFrameOptions\n private resizeObserver: ResizeObserver | null = null\n private intersectionObserver: IntersectionObserver | null = null\n private visible = false\n private destroyed = false\n private layersReady = false\n private firstFrameEmitted = false\n private firstFrameScheduled = false\n\n private disposeWebGLRenderer(renderer: THREE.WebGLRenderer): void {\n renderer.forceContextLoss()\n renderer.dispose()\n }\n\n constructor(\n private container: HTMLElement,\n private options: RendererOptions,\n private onError?: (error: Error) => void,\n private onReady?: () => void,\n private onFirstFrame?: () => void,\n ) {\n // front.layers is required but we handle missing gracefully\n if (!options.front?.layers?.length) {\n console.warn('[pocato] front.layers must have at least 1 element')\n }\n\n this.injectStyles()\n\n // Build DOM\n this.cardEl = document.createElement('div')\n this.cardEl.className = 'pocato-card pocato-loading'\n if (options.preventTouchScroll) {\n this.cardEl.style.touchAction = 'none'\n }\n\n this.rotatorEl = document.createElement('div')\n this.rotatorEl.className = 'pocato-rotator'\n\n // Back face\n this.backEl = document.createElement('div')\n this.backEl.className = 'pocato-back'\n\n // Front face\n this.frontEl = document.createElement('div')\n this.frontEl.className = 'pocato-front'\n\n this.frontCanvas = document.createElement('canvas')\n this.frontCanvas.className = 'pocato-canvas'\n\n // Content containers\n this.frontContentEl = document.createElement('div')\n this.frontContentEl.className = 'pocato-content pocato-front-content'\n this.backContentEl = document.createElement('div')\n this.backContentEl.className = 'pocato-content pocato-back-content'\n this.frontFrameEl = document.createElement('div')\n this.frontFrameEl.className = 'pocato-frame'\n this.backFrameEl = document.createElement('div')\n this.backFrameEl.className = 'pocato-frame'\n this.frontFrameShadowEl = document.createElement('div')\n this.frontFrameShadowEl.className = 'pocato-frame-shadow'\n this.backFrameShadowEl = document.createElement('div')\n this.backFrameShadowEl.className = 'pocato-frame-shadow'\n\n this.frontEl.appendChild(this.frontCanvas)\n this.frontEl.appendChild(this.frontContentEl)\n this.frontEl.appendChild(this.frontFrameEl)\n this.frontEl.appendChild(this.frontFrameShadowEl)\n this.backEl.appendChild(this.backContentEl)\n this.backEl.appendChild(this.backFrameEl)\n this.backEl.appendChild(this.backFrameShadowEl)\n\n this.rotatorEl.appendChild(this.backEl)\n this.rotatorEl.appendChild(this.frontEl)\n this.cardEl.appendChild(this.rotatorEl)\n this.container.appendChild(this.cardEl)\n\n const { width, height } = this.container.getBoundingClientRect()\n const dpr = window.devicePixelRatio || 1\n const pixelWidth = Math.floor(width * dpr)\n const pixelHeight = Math.floor(height * dpr)\n\n // Set canvas size (used by FaceRenderer for uniforms)\n this.frontCanvas.width = pixelWidth\n this.frontCanvas.height = pixelHeight\n\n // Front face (always — lightweight, no WebGL context yet)\n this.frontFace = new FaceRenderer(\n options.front.shader, pixelWidth, pixelHeight, options.front.uniforms,\n )\n\n // Back face (always created so layers can be added later)\n this.backFace = new FaceRenderer(\n this.options.back?.shader, pixelWidth, pixelHeight, this.options.back?.uniforms,\n )\n\n this.backCanvas = document.createElement('canvas')\n this.backCanvas.className = 'pocato-canvas'\n this.backCanvas.width = pixelWidth\n this.backCanvas.height = pixelHeight\n this.backEl.insertBefore(this.backCanvas, this.backEl.firstChild)\n this.applyFrame(this.frontEl, this.frontFrameEl, this.frontFrameShadowEl, options.front.frame)\n this.applyFrame(this.backEl, this.backFrameEl, this.backFrameShadowEl, options.back?.frame)\n this.frontFrame = options.front.frame\n this.backFrame = options.back?.frame\n\n this.loadAllLayers()\n this.setupResizeObserver()\n this.setupIntersectionObserver()\n }\n\n private createFrontRenderer(): void {\n if (this.frontRenderer) return\n // Replace canvas to get a fresh WebGL context (disposed canvas can't get a new one)\n const newCanvas = document.createElement('canvas')\n newCanvas.className = 'pocato-canvas'\n this.frontEl.replaceChild(newCanvas, this.frontCanvas)\n this.frontCanvas = newCanvas\n\n this.frontRenderer = new THREE.WebGLRenderer({\n canvas: this.frontCanvas,\n alpha: true,\n })\n this.frontRenderer.setPixelRatio(window.devicePixelRatio)\n this.resizeFaceRenderer(this.frontEl, this.frontCanvas, this.frontFace, this.frontRenderer, this.frontFrame)\n }\n\n private createBackRenderer(): void {\n if (this.backRenderer || !this.backCanvas || !this.backFace) return\n const newCanvas = document.createElement('canvas')\n newCanvas.className = 'pocato-canvas'\n this.backEl.replaceChild(newCanvas, this.backCanvas)\n this.backCanvas = newCanvas\n\n this.backRenderer = new THREE.WebGLRenderer({\n canvas: this.backCanvas,\n alpha: true,\n })\n this.backRenderer.setPixelRatio(window.devicePixelRatio)\n this.resizeFaceRenderer(this.backEl, this.backCanvas, this.backFace, this.backRenderer, this.backFrame)\n }\n\n private disposeFrontRenderer(): void {\n if (!this.frontRenderer) return\n // Render one last frame to preserve static image on canvas\n this.frontRenderer.render(this.frontFace.scene, this.frontFace.camera)\n this.disposeWebGLRenderer(this.frontRenderer)\n this.frontRenderer = null\n }\n\n private disposeBackRenderer(): void {\n if (!this.backRenderer) return\n if (this.backFace) {\n this.backRenderer.render(this.backFace.scene, this.backFace.camera)\n }\n this.disposeWebGLRenderer(this.backRenderer)\n this.backRenderer = null\n }\n\n private activate(): void {\n if (this.visible) return\n this.visible = true\n this.createFrontRenderer()\n if (this.backFace) this.createBackRenderer()\n this.clock.getDelta() // reset clock to avoid time jump\n this.startRenderLoop()\n }\n\n private deactivate(): void {\n if (!this.visible) return\n this.visible = false\n this.stopRenderLoop()\n this.disposeFrontRenderer()\n this.disposeBackRenderer()\n }\n\n private setupIntersectionObserver(): void {\n this.intersectionObserver = new IntersectionObserver(\n (entries) => {\n const entry = entries[0]\n if (!entry || this.destroyed) return\n if (entry.isIntersecting) {\n this.activate()\n } else {\n this.deactivate()\n }\n },\n { rootMargin: '100px' }, // activate slightly before entering viewport\n )\n this.intersectionObserver.observe(this.cardEl)\n }\n\n private async loadAllLayers(): Promise<void> {\n const promises: Promise<void>[] = []\n\n if (this.options.front?.layers?.length) {\n promises.push(this.frontFace.loadLayers(this.options.front.layers, this.onError))\n }\n\n if (this.backFace && this.options.back?.layers?.length) {\n promises.push(this.backFace.loadLayers(this.options.back.layers, this.onError))\n }\n\n await Promise.all(promises)\n if (this.destroyed) return\n\n this.layersReady = true\n this.onReady?.()\n }\n\n private scheduleFirstFrame(): void {\n if (!this.layersReady || this.firstFrameEmitted || this.firstFrameScheduled) return\n\n this.firstFrameScheduled = true\n requestAnimationFrame(() => {\n if (this.destroyed || this.firstFrameEmitted) return\n this.firstFrameEmitted = true\n this.cardEl.classList.remove('pocato-loading')\n this.cardEl.classList.add('pocato-ready')\n this.onFirstFrame?.()\n requestAnimationFrame(() => {\n if (this.destroyed) return\n this.frontFace.playLoadedVideos()\n this.backFace?.playLoadedVideos()\n })\n })\n }\n\n private injectStyles(): void {\n const id = 'pocato-styles'\n if (document.getElementById(id)) return\n\n const style = document.createElement('style')\n style.id = id\n style.textContent = `\n .pocato-card {\n width: 100%;\n height: 100%;\n perspective: 1000px;\n user-select: none;\n transform: translate3d(0,0,0);\n opacity: 0;\n transition: opacity 0.5s ease;\n }\n .pocato-card.pocato-ready {\n opacity: 1;\n }\n .pocato-rotator {\n width: 100%;\n height: 100%;\n position: relative;\n transform-style: preserve-3d;\n transform-origin: center;\n transform: rotateY(var(--pocato-rotate-x, 0deg)) rotateX(var(--pocato-rotate-y, 0deg));\n border-radius: 2%;\n will-change: transform, box-shadow;\n transition: box-shadow 0.4s ease;\n box-shadow:\n 0px 10px 20px -5px rgba(0,0,0,0.4),\n 0 2px 15px -5px rgba(0,0,0,0.3);\n pointer-events: auto;\n }\n .pocato-front {\n position: absolute;\n top: 0; left: 0;\n width: 100%;\n height: 100%;\n backface-visibility: hidden;\n -webkit-backface-visibility: hidden;\n transform: translate3d(0,0,0);\n border-radius: 2%;\n overflow: hidden;\n }\n .pocato-back {\n position: absolute;\n top: 0; left: 0;\n width: 100%;\n height: 100%;\n backface-visibility: hidden;\n -webkit-backface-visibility: hidden;\n transform: rotateY(180deg) translateZ(0);\n border-radius: 2%;\n overflow: hidden;\n background-color: #1a1a2e;\n }\n .pocato-canvas {\n position: absolute;\n inset: var(--pocato-face-padding, 0px);\n width: calc(100% - var(--pocato-face-padding-total, 0px));\n height: calc(100% - var(--pocato-face-padding-total, 0px));\n display: block;\n }\n .pocato-content {\n position: absolute;\n inset: var(--pocato-face-padding, 0px);\n pointer-events: none;\n z-index: 1;\n }\n .pocato-content > * {\n pointer-events: auto;\n }\n .pocato-frame {\n position: absolute;\n inset: var(--pocato-frame-inset, 0px);\n z-index: 2;\n pointer-events: none;\n opacity: var(--pocato-frame-opacity, 0);\n }\n .pocato-frame::before {\n content: '';\n position: absolute;\n inset: 0;\n border: var(--pocato-frame-width, 0px) solid transparent;\n background: var(--pocato-frame-background, transparent) border-box;\n background-size: 220% 220%;\n -webkit-mask:\n linear-gradient(#000 0 0) padding-box,\n linear-gradient(#000 0 0);\n -webkit-mask-composite: xor;\n mask:\n linear-gradient(#000 0 0) padding-box,\n linear-gradient(#000 0 0);\n mask-composite: exclude;\n }\n .pocato-frame-shadow {\n position: absolute;\n inset: var(--pocato-frame-shadow-inset, 0px);\n z-index: 3;\n pointer-events: none;\n opacity: var(--pocato-frame-shadow-opacity, 0);\n box-shadow: inset 0 0 var(--pocato-frame-shadow-blur, 0px) var(--pocato-frame-shadow-color, rgba(0,0,0,0.4));\n }\n .pocato-frame[data-animated=\"true\"]::before {\n animation: pocato-frame-flow var(--pocato-frame-speed, 3s) linear infinite;\n }\n @keyframes pocato-frame-flow {\n 0% { background-position: 0% 50%; }\n 50% { background-position: 100% 50%; }\n 100% { background-position: 0% 50%; }\n }\n `\n document.head.appendChild(style)\n }\n\n private applyFrame(\n faceEl: HTMLDivElement,\n frameEl: HTMLDivElement,\n shadowEl: HTMLDivElement,\n frame?: FaceFrameOptions,\n ): void {\n const enabled = frame?.enabled ?? false\n const facePadding = enabled ? frame?.padding ?? 0 : 0\n const frameInset = enabled ? frame?.inset ?? 0 : 0\n const frameWidth = enabled ? frame?.width ?? 0 : 0\n const shadowEnabled = enabled && (frame?.innerShadow ?? false)\n faceEl.style.setProperty('--pocato-face-padding', `${facePadding}px`)\n faceEl.style.setProperty('--pocato-face-padding-total', `${facePadding * 2}px`)\n faceEl.style.background = enabled ? getFrameBackground(frame) : ''\n frameEl.style.setProperty('--pocato-frame-opacity', enabled ? '1' : '0')\n frameEl.style.setProperty('--pocato-frame-inset', `${frameInset}px`)\n frameEl.style.setProperty('--pocato-frame-width', `${frameWidth}px`)\n frameEl.style.setProperty('--pocato-frame-speed', `${frame?.animationSpeed ?? 3}s`)\n frameEl.dataset.animated = enabled && frameWidth > 0 && frame?.animated ? 'true' : 'false'\n\n frameEl.style.setProperty('--pocato-frame-background', getFrameBorderBackground(frame))\n shadowEl.style.setProperty('--pocato-frame-shadow-inset', `${frameInset + frameWidth}px`)\n shadowEl.style.setProperty('--pocato-frame-shadow-blur', `${frame?.innerShadowBlur ?? 16}px`)\n shadowEl.style.setProperty('--pocato-frame-shadow-color', toRgba(frame?.innerShadowColor ?? '#000000', frame?.innerShadowOpacity ?? 0.28))\n shadowEl.style.setProperty('--pocato-frame-shadow-opacity', shadowEnabled ? '1' : '0')\n }\n\n private setupResizeObserver(): void {\n this.resizeObserver = new ResizeObserver((entries) => {\n const entry = entries[0]\n if (!entry) return\n const { width, height } = entry.contentRect\n if (width === 0 || height === 0) return\n\n if (this.frontRenderer) {\n this.resizeFaceRenderer(this.frontEl, this.frontCanvas, this.frontFace, this.frontRenderer, this.frontFrame)\n } else {\n this.resizeFaceRenderer(this.frontEl, this.frontCanvas, this.frontFace, null, this.frontFrame)\n }\n\n if (this.backFace && this.backCanvas) {\n if (this.backRenderer) {\n this.resizeFaceRenderer(this.backEl, this.backCanvas, this.backFace, this.backRenderer, this.backFrame)\n } else {\n this.resizeFaceRenderer(this.backEl, this.backCanvas, this.backFace, null, this.backFrame)\n }\n }\n })\n this.resizeObserver.observe(this.container)\n }\n\n private startRenderLoop(): void {\n if (this.rafId !== null) return\n const animate = () => {\n if (!this.visible || this.destroyed) return\n this.rafId = requestAnimationFrame(animate)\n const delta = this.clock.getDelta()\n\n // Render front face\n this.frontFace.material.uniforms.uTime.value += delta\n if (this.frontRenderer) {\n this.frontRenderer.render(this.frontFace.scene, this.frontFace.camera)\n }\n\n // Render back face if it exists\n if (this.backFace && this.backRenderer) {\n this.backFace.material.uniforms.uTime.value += delta\n this.backRenderer.render(this.backFace.scene, this.backFace.camera)\n }\n\n this.scheduleFirstFrame()\n }\n this.rafId = requestAnimationFrame(animate)\n }\n\n private stopRenderLoop(): void {\n if (this.rafId !== null) {\n cancelAnimationFrame(this.rafId)\n this.rafId = null\n }\n }\n\n updateUniforms(updates: {\n rotate?: { x: number; y: number }\n mouse?: { x: number; y: number }\n move?: { x: number; y: number }\n opacity?: number\n }): void {\n if (updates.rotate) {\n this.rotatorEl.style.setProperty('--pocato-rotate-x', `${updates.rotate.x}deg`)\n this.rotatorEl.style.setProperty('--pocato-rotate-y', `${updates.rotate.y}deg`)\n }\n\n this.frontFace.updateUniforms({\n rotate: updates.rotate,\n mouse: updates.mouse,\n move: updates.move,\n opacity: updates.opacity,\n })\n\n if (this.backFace) {\n this.backFace.updateUniforms({\n rotate: updates.rotate,\n mouse: updates.mouse,\n move: updates.move,\n opacity: updates.opacity,\n })\n }\n }\n\n updateShader(fragmentShader: string): void {\n this.frontFace.updateShader(fragmentShader)\n }\n\n updateBackShader(fragmentShader: string): void {\n this.backFace?.updateShader(fragmentShader)\n }\n\n updateEffectUniforms(\n frontUniforms?: FaceOptions['uniforms'],\n backUniforms?: FaceOptions['uniforms'],\n ): void {\n this.frontFace.updateEffectUniforms(frontUniforms)\n this.backFace?.updateEffectUniforms(backUniforms)\n }\n\n updateFrames(\n frontFrame?: FaceFrameOptions,\n backFrame?: FaceFrameOptions,\n ): void {\n if (frontFrame) {\n this.frontFrame = frontFrame\n this.applyFrame(this.frontEl, this.frontFrameEl, this.frontFrameShadowEl, frontFrame)\n this.resizeFaceRenderer(this.frontEl, this.frontCanvas, this.frontFace, this.frontRenderer, this.frontFrame)\n }\n if (backFrame) {\n this.backFrame = backFrame\n this.applyFrame(this.backEl, this.backFrameEl, this.backFrameShadowEl, backFrame)\n if (this.backFace && this.backCanvas) {\n this.resizeFaceRenderer(this.backEl, this.backCanvas, this.backFace, this.backRenderer, this.backFrame)\n }\n }\n }\n\n private resizeFaceRenderer(\n faceEl: HTMLDivElement,\n canvas: HTMLCanvasElement,\n face: FaceRenderer,\n renderer: THREE.WebGLRenderer | null,\n frame?: FaceFrameOptions,\n ): void {\n const { width, height } = faceEl.getBoundingClientRect()\n const padding = frame?.enabled ? frame.padding ?? 0 : 0\n const nextWidth = Math.max(1, width - padding * 2)\n const nextHeight = Math.max(1, height - padding * 2)\n\n if (renderer) {\n renderer.setSize(nextWidth, nextHeight)\n } else {\n const dpr = window.devicePixelRatio || 1\n canvas.width = Math.floor(nextWidth * dpr)\n canvas.height = Math.floor(nextHeight * dpr)\n }\n\n face.updateResolution(canvas.width, canvas.height)\n }\n\n async updateLayers(\n frontLayers?: LayerSource[],\n backLayers?: LayerSource[],\n ): Promise<void> {\n const promises: Promise<void>[] = []\n\n if (frontLayers) {\n promises.push(this.frontFace.loadLayers(frontLayers, this.onError))\n }\n\n if (backLayers && this.backFace) {\n promises.push(this.backFace.loadLayers(backLayers, this.onError))\n }\n\n await Promise.all(promises)\n }\n\n getRotatorEl(): HTMLDivElement {\n return this.rotatorEl\n }\n\n getFrontContentEl(): HTMLDivElement {\n return this.frontContentEl\n }\n\n getBackContentEl(): HTMLDivElement {\n return this.backContentEl\n }\n\n destroy(): void {\n this.destroyed = true\n this.stopRenderLoop()\n this.resizeObserver?.disconnect()\n this.intersectionObserver?.disconnect()\n\n cleanupPendingVideos()\n\n this.frontFace.destroy()\n if (this.frontRenderer) {\n this.disposeWebGLRenderer(this.frontRenderer)\n this.frontRenderer = null\n }\n\n if (this.backFace) {\n this.backFace.destroy()\n if (this.backRenderer) {\n this.disposeWebGLRenderer(this.backRenderer)\n this.backRenderer = null\n }\n }\n\n if (this.cardEl.parentNode) {\n this.cardEl.parentNode.removeChild(this.cardEl)\n }\n }\n}\n\nfunction getFrameBackground(frame?: FaceFrameOptions): string {\n const color = frame?.backgroundColor ?? '#111827'\n const gradientFrom = frame?.backgroundGradientFrom ?? color\n const gradientTo = frame?.backgroundGradientTo ?? color\n return frame?.backgroundGradient\n ? `linear-gradient(135deg, ${gradientFrom}, ${gradientTo})`\n : color\n}\n\nfunction getFrameBorderBackground(frame?: FaceFrameOptions): string {\n const color = frame?.color ?? '#ffffff'\n const gradientFrom = frame?.gradientFrom ?? color\n const gradientTo = frame?.gradientTo ?? color\n const opacity = frame?.borderOpacity ?? 1\n return frame?.gradient\n ? `linear-gradient(120deg, ${toRgba(gradientFrom, opacity)}, ${toRgba(gradientTo, opacity)}, ${toRgba(gradientFrom, opacity)})`\n : toRgba(color, opacity)\n}\n\nfunction toRgba(hex: string, opacity: number): string {\n const value = hex.replace('#', '')\n if (value.length !== 6) return `rgba(0, 0, 0, ${opacity})`\n const red = Number.parseInt(value.slice(0, 2), 16)\n const green = Number.parseInt(value.slice(2, 4), 16)\n const blue = Number.parseInt(value.slice(4, 6), 16)\n if ([red, green, blue].some((channel) => Number.isNaN(channel))) {\n return `rgba(0, 0, 0, ${opacity})`\n }\n return `rgba(${red}, ${green}, ${blue}, ${opacity})`\n}\n","import * as THREE from 'three'\nimport { bootstrapShaders, resolveIncludes } from './shader-bootstrap'\nimport { loadLayerTexture, disposeLoadedLayer, getTransparentTexture, type LoadedLayer } from './texture-loader'\nimport type { EffectUniformValue, LayerSource } from '../types'\nimport vertexShader from '../shaders/common.vert'\n\nimport fragShaderGlare from '../shaders/glare.frag'\nimport fragShaderGlare3d from '../shaders/glare-3d.frag'\nimport fragShaderSnowfall from '../shaders/snowfall.frag'\nimport fragShaderSnowfall3d from '../shaders/snowfall-3d.frag'\nimport fragShaderBrush from '../shaders/brush.frag'\nimport fragShaderBrush3d from '../shaders/brush-3d.frag'\nimport fragShaderBlur from '../shaders/blur.frag'\nimport fragShaderBlur3d from '../shaders/blur-3d.frag'\nimport fragShaderHolo from '../shaders/holo.frag'\nimport fragShaderHolo3d from '../shaders/holo-3d.frag'\nimport fragShaderPulseLines from '../shaders/pulse-lines.frag'\nimport fragShaderGradientFlow from '../shaders/gradient-flow.frag'\nimport fragShaderProceduralOcean from '../shaders/procedural-ocean.frag'\nimport fragShaderRainbowFlow from '../shaders/rainbow-flow.frag'\nimport fragShaderShockWave from '../shaders/shock-wave.frag'\nimport fragShaderRipple from '../shaders/ripple.frag'\nimport fragShaderLenticular from '../shaders/lenticular.frag'\n\nexport const FRAG_SHADERS: Record<string, string> = {\n 'glare': fragShaderGlare,\n 'glare-3d': fragShaderGlare3d,\n 'snowfall': fragShaderSnowfall,\n 'snowfall-3d': fragShaderSnowfall3d,\n 'brush': fragShaderBrush,\n 'brush-3d': fragShaderBrush3d,\n 'blur': fragShaderBlur,\n 'blur-3d': fragShaderBlur3d,\n 'holo': fragShaderHolo,\n 'holo-3d': fragShaderHolo3d,\n 'pulse-lines': fragShaderPulseLines,\n 'gradient-flow': fragShaderGradientFlow,\n 'procedural-ocean': fragShaderProceduralOcean,\n 'rainbow-flow': fragShaderRainbowFlow,\n 'shock-wave': fragShaderShockWave,\n 'ripple': fragShaderRipple,\n lenticular: fragShaderLenticular,\n}\n\nconst MAX_LAYERS = 8\n\nexport class FaceRenderer {\n material: THREE.ShaderMaterial\n mesh: THREE.Mesh\n scene: THREE.Scene\n camera: THREE.Camera\n private loadedLayers: LoadedLayer[] = []\n private layerLoadVersion = 0\n\n constructor(\n shader: string | undefined,\n width: number,\n height: number,\n effectUniforms?: Record<string, EffectUniformValue>,\n ) {\n bootstrapShaders()\n\n this.scene = new THREE.Scene()\n this.camera = new THREE.Camera()\n\n const uniforms = this.createUniforms(width, height, effectUniforms)\n const rawFrag = shader ?? FRAG_SHADERS['glare']\n const fragmentShader = resolveIncludes(rawFrag)\n\n this.material = new THREE.ShaderMaterial({\n vertexShader: resolveIncludes(vertexShader),\n fragmentShader,\n uniforms,\n transparent: true,\n })\n\n const geometry = new THREE.PlaneGeometry(2, 2)\n this.mesh = new THREE.Mesh(geometry, this.material)\n this.scene.add(this.mesh)\n }\n\n private createUniforms(\n width: number,\n height: number,\n effectUniforms?: Record<string, EffectUniformValue>,\n ): Record<string, THREE.IUniform> {\n const uniforms: Record<string, THREE.IUniform> = {\n uTime: { value: 0 },\n uResolution: { value: new THREE.Vector2(width, height) },\n uMouse: { value: new THREE.Vector2(0, 0) },\n uMove: { value: new THREE.Vector2(0, 0) },\n uRotate: { value: new THREE.Vector2(0, 0) },\n uCardOpacity: { value: 1.0 },\n uLayerCount: { value: 0 },\n }\n\n const transparent = getTransparentTexture()\n for (let i = 0; i < MAX_LAYERS; i++) {\n uniforms[`uLayer${i}`] = { value: transparent }\n }\n\n if (effectUniforms) {\n for (const [name, value] of Object.entries(effectUniforms)) {\n uniforms[name] = { value: toThreeUniformValue(value) }\n }\n }\n\n return uniforms\n }\n\n updateEffectUniforms(values?: Record<string, EffectUniformValue>): void {\n if (!values) return\n for (const [name, value] of Object.entries(values)) {\n const nextValue = toThreeUniformValue(value)\n if (this.material.uniforms[name]) {\n this.material.uniforms[name].value = nextValue\n } else {\n this.material.uniforms[name] = { value: nextValue }\n }\n }\n }\n\n async loadLayers(\n layers: LayerSource[],\n onError?: (error: Error) => void,\n ): Promise<void> {\n const version = ++this.layerLoadVersion\n this.disposeLayers()\n\n const count = Math.min(layers.length, MAX_LAYERS)\n this.material.uniforms.uLayerCount.value = count\n\n const promises = layers.slice(0, MAX_LAYERS).map((layer) =>\n loadLayerTexture(layer, onError)\n )\n\n const results = await Promise.all(promises)\n if (version !== this.layerLoadVersion) {\n for (const loaded of results) {\n disposeLoadedLayer(loaded)\n }\n return\n }\n\n this.loadedLayers = results\n\n for (let i = 0; i < results.length; i++) {\n this.material.uniforms[`uLayer${i}`].value = results[i].texture\n }\n }\n\n updateUniforms(updates: {\n rotate?: { x: number; y: number }\n mouse?: { x: number; y: number }\n move?: { x: number; y: number }\n opacity?: number\n time?: number\n }): void {\n const u = this.material.uniforms\n if (updates.rotate) u.uRotate.value.set(\n updates.rotate.x * (Math.PI / 180),\n updates.rotate.y * (Math.PI / 180),\n )\n if (updates.mouse) u.uMouse.value.set(updates.mouse.x, updates.mouse.y)\n if (updates.move) u.uMove.value.set(updates.move.x, updates.move.y)\n if (updates.opacity !== undefined) u.uCardOpacity.value = updates.opacity\n if (updates.time !== undefined) u.uTime.value = updates.time\n }\n\n updateResolution(width: number, height: number): void {\n this.material.uniforms.uResolution.value.set(width, height)\n }\n\n playLoadedVideos(): void {\n for (const loaded of this.loadedLayers) {\n loaded.play?.()\n }\n }\n\n updateShader(fragmentShader: string): void {\n this.material.fragmentShader = resolveIncludes(fragmentShader)\n this.material.needsUpdate = true\n }\n\n private disposeLayers(): void {\n for (const loaded of this.loadedLayers) {\n disposeLoadedLayer(loaded)\n }\n this.loadedLayers = []\n\n const transparent = getTransparentTexture()\n for (let i = 0; i < MAX_LAYERS; i++) {\n this.material.uniforms[`uLayer${i}`].value = transparent\n }\n this.material.uniforms.uLayerCount.value = 0\n }\n\n destroy(): void {\n this.layerLoadVersion++\n this.disposeLayers()\n this.mesh.geometry.dispose()\n this.material.dispose()\n }\n}\n\nfunction toThreeUniformValue(value: EffectUniformValue) {\n if (typeof value === 'string') {\n return value.startsWith('#') ? new THREE.Color(value) : value\n }\n if (Array.isArray(value)) {\n if (value.length === 2) return new THREE.Vector2(value[0], value[1])\n if (value.length === 3) return new THREE.Vector3(value[0], value[1], value[2])\n return new THREE.Vector4(value[0], value[1], value[2], value[3])\n }\n return value\n}\n","import * as THREE from 'three'\n\nimport permute from '../shaders/lygia/math/permute.glsl'\nimport mod289 from '../shaders/lygia/math/mod289.glsl'\nimport taylorInvSqrt from '../shaders/lygia/math/taylorInvSqrt.glsl'\nimport grad4 from '../shaders/lygia/math/grad4.glsl'\nimport rotate4d from '../shaders/lygia/math/rotate4d.glsl'\nimport cubic from '../shaders/lygia/math/cubic.glsl'\nimport quintic from '../shaders/lygia/math/quintic.glsl'\nimport sum from '../shaders/lygia/math/sum.glsl'\nimport saturate from '../shaders/lygia/math/saturate.glsl'\nimport gaussian from '../shaders/lygia/math/gaussian.glsl'\nimport ratio from '../shaders/lygia/space/ratio.glsl'\nimport random from '../shaders/lygia/generative/random.glsl'\nimport srandom from '../shaders/lygia/generative/srandom.glsl'\nimport gnoise from '../shaders/lygia/generative/gnoise.glsl'\nimport snoise from '../shaders/lygia/generative/snoise.glsl'\nimport fbm from '../shaders/lygia/generative/fbm.glsl'\nimport dilation from '../shaders/lygia/morphological/dilation.glsl'\nimport sampler from '../shaders/lygia/sampler.glsl'\nimport clamp2edge from '../shaders/lygia/sample/clamp2edge.glsl'\nimport digits from '../shaders/lygia/draw/digits.glsl'\nimport gaussianBlur from '../shaders/lygia/filter/gaussianBlur.glsl'\nimport gaussianBlur2D from '../shaders/lygia/filter/gaussianBlur/2D.glsl'\nimport gaussianBlur1D from '../shaders/lygia/filter/gaussianBlur/1D.glsl'\nimport gaussianBlur1DFast13 from '../shaders/lygia/filter/gaussianBlur/1D_fast13.glsl'\nimport gaussianBlur1DFast9 from '../shaders/lygia/filter/gaussianBlur/1D_fast9.glsl'\nimport gaussianBlur1DFast5 from '../shaders/lygia/filter/gaussianBlur/1D_fast5.glsl'\nimport kuwahara from '../shaders/lygia/filter/kuwahara.glsl'\n\nimport defaultLighting from '../shaders/utils/default-lighting.glsl'\n\nlet bootstrapped = false\n\n// Build a reverse lookup: short name (e.g. \"mod289\") → full chunk key (e.g. \"lygia/math/mod289\")\nconst shortNameMap = new Map<string, string>()\n\nfunction buildShortNameMap(): void {\n const chunks = THREE.ShaderChunk as any\n for (const key of Object.keys(chunks)) {\n // Extract short name from full path\n const parts = key.split('/')\n const shortName = parts[parts.length - 1]\n if (!shortNameMap.has(shortName)) {\n shortNameMap.set(shortName, key)\n }\n }\n}\n\n/**\n * Recursively resolve #include directives using THREE.ShaderChunk.\n * Handles:\n * - #include <lygia/math/mod289> (angle bracket, full path)\n * - #include <utils/defaultLighting> (angle bracket, registered key)\n * - #include \"mod289.glsl\" (quote, short name from LYGIA internals)\n * - #include \"../math/cubic.glsl\" (quote, relative path from LYGIA internals)\n */\nexport function resolveIncludes(source: string): string {\n if (shortNameMap.size === 0) buildShortNameMap()\n\n const pattern = /^[ \\t]*#include\\s+[<\"]([^>\"]+)[>\"]/gm\n const resolved = new Set<string>() // prevent infinite recursion via guard set\n\n function resolve(src: string, depth = 0): string {\n if (depth > 15) return src\n return src.replace(pattern, (_match, rawName: string) => {\n // Normalize: strip .glsl extension\n const name = rawName.replace(/\\.glsl$/, '')\n\n // Prevent re-including the same chunk\n if (resolved.has(name)) return ''\n\n const chunks = THREE.ShaderChunk as any\n\n // 1. Try exact key match\n let chunk = chunks[name]\n\n // 2. Try short name lookup (e.g. \"mod289\" → \"lygia/math/mod289\")\n if (chunk === undefined) {\n const shortName = name.split('/').pop()!\n const fullKey = shortNameMap.get(shortName)\n if (fullKey) chunk = chunks[fullKey]\n }\n\n // 3. Try normalizing relative paths (e.g. \"../math/cubic\" → \"lygia/math/cubic\")\n if (chunk === undefined && (name.startsWith('../') || name.startsWith('./'))) {\n // Try stripping relative prefix and prepending lygia/\n const cleaned = name.replace(/^\\.\\.\\//, '').replace(/^\\.\\//, '')\n chunk = chunks['lygia/' + cleaned]\n if (chunk === undefined) {\n // Try just the short name\n const shortName = cleaned.split('/').pop()!\n const fullKey = shortNameMap.get(shortName)\n if (fullKey) chunk = chunks[fullKey]\n }\n }\n\n if (chunk !== undefined) {\n resolved.add(name)\n return resolve(chunk, depth + 1)\n }\n\n // Chunk not found — leave a comment so shader doesn't break silently\n console.warn(`[pocato] Shader chunk not found: ${rawName}`)\n return `/* chunk not found: ${rawName} */`\n })\n }\n return resolve(source)\n}\n\nexport function bootstrapShaders(): void {\n if (bootstrapped) return\n bootstrapped = true\n\n const ThreeShaderChunk = THREE.ShaderChunk as any\n ThreeShaderChunk['lygia/math/permute'] = permute\n ThreeShaderChunk['lygia/math/mod289'] = mod289\n ThreeShaderChunk['lygia/math/taylorInvSqrt'] = taylorInvSqrt\n ThreeShaderChunk['lygia/math/grad4'] = grad4\n ThreeShaderChunk['lygia/math/rotate4d'] = rotate4d\n ThreeShaderChunk['lygia/math/cubic'] = cubic\n ThreeShaderChunk['lygia/math/quintic'] = quintic\n ThreeShaderChunk['lygia/math/sum'] = sum\n ThreeShaderChunk['lygia/math/saturate'] = saturate\n ThreeShaderChunk['lygia/math/gaussian'] = gaussian\n ThreeShaderChunk['lygia/space/ratio'] = ratio\n ThreeShaderChunk['lygia/generative/random'] = random\n ThreeShaderChunk['lygia/generative/srandom'] = srandom\n ThreeShaderChunk['lygia/generative/gnoise'] = gnoise\n ThreeShaderChunk['lygia/generative/snoise'] = snoise\n ThreeShaderChunk['lygia/generative/fbm'] = fbm\n ThreeShaderChunk['lygia/morphological/dilation'] = dilation\n ThreeShaderChunk['lygia/sampler'] = sampler\n ThreeShaderChunk['lygia/sample/clamp2edge'] = clamp2edge\n ThreeShaderChunk['lygia/draw/digits'] = digits\n ThreeShaderChunk['lygia/filter/gaussianBlur'] = gaussianBlur\n ThreeShaderChunk['lygia/filter/gaussianBlur/2D'] = gaussianBlur2D\n ThreeShaderChunk['lygia/filter/gaussianBlur/1D'] = gaussianBlur1D\n ThreeShaderChunk['lygia/filter/gaussianBlur/1D_fast13'] = gaussianBlur1DFast13\n ThreeShaderChunk['lygia/filter/gaussianBlur/1D_fast9'] = gaussianBlur1DFast9\n ThreeShaderChunk['lygia/filter/gaussianBlur/1D_fast5'] = gaussianBlur1DFast5\n ThreeShaderChunk['lygia/filter/kuwahara'] = kuwahara\n ThreeShaderChunk['utils/defaultLighting'] = defaultLighting\n}\n","#include \"mod289.glsl\"\n\n/*\ncontributors: [Stefan Gustavson, Ian McEwan]\ndescription: permute\nuse: <float|vec2|vec3|vec4> permute(<float|vec2|vec3|vec4> x)\nexamples:\n - https://raw.githubusercontent.com/patriciogonzalezvivo/lygia_examples/main/math_functions.frag\n*/\n\n#ifndef FNC_PERMUTE\n#define FNC_PERMUTE\n\nfloat permute(const in float v) { return mod289(((v * 34.0) + 1.0) * v); }\nvec2 permute(const in vec2 v) { return mod289(((v * 34.0) + 1.0) * v); }\nvec3 permute(const in vec3 v) { return mod289(((v * 34.0) + 1.0) * v); }\nvec4 permute(const in vec4 v) { return mod289(((v * 34.0) + 1.0) * v); }\n\n#endif\n","/*\ncontributors: [Stefan Gustavson, Ian McEwan]\ndescription: modulus of 289\nuse: <float|vec2|vec3|vec4> mod289(<float|vec2|vec3|vec4> x)\n*/\n\n#ifndef FNC_MOD289\n#define FNC_MOD289\n\nfloat mod289(const in float x) { return x - floor(x * (1. / 289.)) * 289.; }\nvec2 mod289(const in vec2 x) { return x - floor(x * (1. / 289.)) * 289.; }\nvec3 mod289(const in vec3 x) { return x - floor(x * (1. / 289.)) * 289.; }\nvec4 mod289(const in vec4 x) { return x - floor(x * (1. / 289.)) * 289.; }\n\n#endif\n","/*\ncontributors: [Stefan Gustavson, Ian McEwan]\ndescription: Fast, accurate inverse square root. \nuse: <float|vec2|vec3|vec4> taylorInvSqrt(<float|vec2|vec3|vec4> x)\n*/\n\n#ifndef FNC_TAYLORINVSQRT\n#define FNC_TAYLORINVSQRT\nfloat taylorInvSqrt(in float r) { return 1.79284291400159 - 0.85373472095314 * r; }\nvec2 taylorInvSqrt(in vec2 r) { return 1.79284291400159 - 0.85373472095314 * r; }\nvec3 taylorInvSqrt(in vec3 r) { return 1.79284291400159 - 0.85373472095314 * r; }\nvec4 taylorInvSqrt(in vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; }\n#endif","/*\ncontributors: [Stefan Gustavson, Ian McEwan]\ndescription: grad4, used for snoise(vec4 v)\nuse: grad4(<float> j, <vec4> ip)\n*/\n\n#ifndef FNC_GRAD4\n#define FNC_GRAD4\nvec4 grad4(float j, vec4 ip) {\n const vec4 ones = vec4(1.0, 1.0, 1.0, -1.0);\n vec4 p,s;\n p.xyz = floor( fract (vec3(j) * ip.xyz) * 7.0) * ip.z - 1.0;\n p.w = 1.5 - dot(abs(p.xyz), ones.xyz);\n s = vec4(lessThan(p, vec4(0.0)));\n p.xyz = p.xyz + (s.xyz*2.0 - 1.0) * s.www;\n return p;\n}\n#endif\n","/*\ncontributors: Patricio Gonzalez Vivo\ndescription: returns a 4x4 rotation matrix\nuse: <mat4> rotate4d(<vec3> axis, <float> radians)\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#ifndef FNC_ROTATE4D\n#define FNC_ROTATE4D\nmat4 rotate4d(in vec3 a, const in float r) {\n a = normalize(a);\n float s = sin(r);\n float c = cos(r);\n float oc = 1.0 - c;\n vec4 col1 = vec4(oc * a.x * a.x + c, oc * a.x * a.y + a.z * s, oc * a.z * a.x - a.y * s, 0.0);\n vec4 col2 = vec4(oc * a.x * a.y - a.z * s, oc * a.y * a.y + c, oc * a.y * a.z + a.x * s, 0.0);\n vec4 col3 = vec4(oc * a.z * a.x + a.y * s, oc * a.y * a.z - a.x * s, oc * a.z * a.z + c, 0.0);\n vec4 col4 = vec4(0.0, 0.0, 0.0, 1.0);\n return mat4(col1, col2, col3, col4);\n}\n#endif\n","/*\ncontributors: Inigo Quiles\ndescription: cubic polynomial https://iquilezles.org/articles/smoothsteps/\nuse: <float|vec2|vec3|vec4> cubic(<float|vec2|vec3|vec4> value[, <float> in, <float> out]);\nexamples:\n - https://raw.githubusercontent.com/patriciogonzalezvivo/lygia_examples/main/math_functions.frag\n*/\n\n#ifndef FNC_CUBIC\n#define FNC_CUBIC \nfloat cubic(const in float v) { return v*v*(3.0-2.0*v); }\nvec2 cubic(const in vec2 v) { return v*v*(3.0-2.0*v); }\nvec3 cubic(const in vec3 v) { return v*v*(3.0-2.0*v); }\nvec4 cubic(const in vec4 v) { return v*v*(3.0-2.0*v); }\n\nfloat cubic(const in float v, in float slope0, in float slope1) {\n float a = slope0 + slope1 - 2.;\n float b = -2. * slope0 - slope1 + 3.;\n float c = slope0;\n float v2 = v * v;\n float v3 = v * v2;\n return a * v3 + b * v2 + c * v;\n}\n\nvec2 cubic(const in vec2 v, in float slope0, in float slope1) {\n float a = slope0 + slope1 - 2.;\n float b = -2. * slope0 - slope1 + 3.;\n float c = slope0;\n vec2 v2 = v * v;\n vec2 v3 = v * v2;\n return a * v3 + b * v2 + c * v;\n}\n\nvec3 cubic(const in vec3 v, in float slope0, in float slope1) {\n float a = slope0 + slope1 - 2.;\n float b = -2. * slope0 - slope1 + 3.;\n float c = slope0;\n vec3 v2 = v * v;\n vec3 v3 = v * v2;\n return a * v3 + b * v2 + c * v;\n}\n\nvec4 cubic(const in vec4 v, in float slope0, in float slope1) {\n float a = slope0 + slope1 - 2.;\n float b = -2. * slope0 - slope1 + 3.;\n float c = slope0;\n vec4 v2 = v * v;\n vec4 v3 = v * v2;\n return a * v3 + b * v2 + c * v;\n}\n#endif","/*\ncontributors: Inigo Quiles\ndescription: quintic polynomial https://iquilezles.org/articles/smoothsteps/\nuse: <float|vec2|vec3|vec4> quintic(<float|vec2|vec3|vec4> value);\nexamples:\n - https://raw.githubusercontent.com/patriciogonzalezvivo/lygia_examples/main/math_functions.frag\n*/\n\n#ifndef FNC_QUINTIC\n#define FNC_QUINTIC \n\nfloat quintic(const in float v) { return v*v*v*(v*(v*6.0-15.0)+10.0); }\nvec2 quintic(const in vec2 v) { return v*v*v*(v*(v*6.0-15.0)+10.0); }\nvec3 quintic(const in vec3 v) { return v*v*v*(v*(v*6.0-15.0)+10.0); }\nvec4 quintic(const in vec4 v) { return v*v*v*(v*(v*6.0-15.0)+10.0); }\n\n#endif","/*\ncontributors: Patricio Gonzalez Vivo\ndescription: Sum elements of a vector\nuse: <float> sum(<vec2|vec3|vec4> value)\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#ifndef FNC_SUM\n#define FNC_SUM\nfloat sum( float v ) { return v; }\nfloat sum( vec2 v ) { return v.x+v.y; }\nfloat sum( vec3 v ) { return v.x+v.y+v.z; }\nfloat sum( vec4 v ) { return v.x+v.y+v.z+v.w; }\n#endif\n","/*\ncontributors: Patricio Gonzalez Vivo\ndescription: clamp a value between 0 and 1\nuse: <float|vec2|vec3|vec4> saturation(<float|vec2|vec3|vec4> value)\nexamples:\n - https://raw.githubusercontent.com/patriciogonzalezvivo/lygia_examples/main/math_functions.frag\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#if !defined(FNC_SATURATE) && !defined(saturate)\n#define FNC_SATURATE\n#define saturate(V) clamp(V, 0.0, 1.0)\n#endif","/*\ncontributors: Patricio Gonzalez Vivo\ndescription: gaussian coefficient\nuse: <vec4|vec3|vec2|float> gaussian(<float> sigma, <vec4|vec3|vec2|float> d)\nexamples:\n - https://raw.githubusercontent.com/patriciogonzalezvivo/lygia_examples/main/math_gaussian.frag\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#ifndef FNC_GAUSSIAN\n#define FNC_GAUSSIAN\nfloat gaussian(float d, float s) { return exp(-(d*d) / (2.0 * s*s)); }\nfloat gaussian( vec2 d, float s) { return exp(-( d.x*d.x + d.y*d.y) / (2.0 * s*s)); }\nfloat gaussian( vec3 d, float s) { return exp(-( d.x*d.x + d.y*d.y + d.z*d.z ) / (2.0 * s*s)); }\nfloat gaussian( vec4 d, float s) { return exp(-( d.x*d.x + d.y*d.y + d.z*d.z + d.w*d.w ) / (2.0 * s*s)); }\n#endif","/*\ncontributors: Patricio Gonzalez Vivo\ndescription: \"Fix the aspect ratio of a space keeping things squared for you, \\nin\\\n \\ a similar way that aspect.glsl does, but while scaling the \\nspace to keep the\\\n \\ entire 0.0,0.0 ~ 1.0,1.0 range visible\\n\"\nuse: <vec2> ratio(<vec2> st, <vec2> st_size)\nexamples:\n - https://raw.githubusercontent.com/patriciogonzalezvivo/lygia_examples/main/draw_shapes.frag\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#ifndef FNC_RATIO\n#define FNC_RATIO\nvec2 ratio(in vec2 v, in vec2 s) {\n return mix( vec2((v.x*s.x/s.y)-(s.x*.5-s.y*.5)/s.y,v.y),\n vec2(v.x,v.y*(s.y/s.x)-(s.y*.5-s.x*.5)/s.x),\n step(s.x,s.y));\n}\n#endif\n","/*\ncontributors: [\"Patricio Gonzalez Vivo\", \"David Hoskins\", \"Inigo Quilez\"]\ndescription: Pass a value and get some random normalize value between 0 and 1\nuse: float random[2|3](<float|vec2|vec3> value)\noptions:\n - RANDOM_HIGHER_RANGE: for working with a range over 0 and 1\n - RANDOM_SINLESS: Use sin-less random, which tolerates bigger values before producing pattern. From https://www.shadertoy.com/view/4djSRW\n - RANDOM_SCALE: by default this scale if for number with a big range. For producing good random between 0 and 1 use bigger range\nexamples:\n - /shaders/generative_random.frag\nlicense:\n - MIT License (MIT) Copyright 2014, David Hoskins\n*/\n\n#ifndef RANDOM_SCALE\n#ifdef RANDOM_HIGHER_RANGE\n#define RANDOM_SCALE vec4(.1031, .1030, .0973, .1099)\n#else\n#define RANDOM_SCALE vec4(443.897, 441.423, .0973, .1099)\n#endif\n#endif\n\n#ifndef FNC_RANDOM\n#define FNC_RANDOM\nfloat random(in float x) {\n#ifdef RANDOM_SINLESS\n x = fract(x * RANDOM_SCALE.x);\n x *= x + 33.33;\n x *= x + x;\n return fract(x);\n#else\n return fract(sin(x) * 43758.5453);\n#endif\n}\n\nfloat random(in vec2 st) {\n#ifdef RANDOM_SINLESS\n vec3 p3 = fract(vec3(st.xyx) * RANDOM_SCALE.xyz);\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n#else\n return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453);\n#endif\n}\n\nfloat random(in vec3 pos) {\n#ifdef RANDOM_SINLESS\n pos = fract(pos * RANDOM_SCALE.xyz);\n pos += dot(pos, pos.zyx + 31.32);\n return fract((pos.x + pos.y) * pos.z);\n#else\n return fract(sin(dot(pos.xyz, vec3(70.9898, 78.233, 32.4355))) * 43758.5453123);\n#endif\n}\n\nfloat random(in vec4 pos) {\n#ifdef RANDOM_SINLESS\n pos = fract(pos * RANDOM_SCALE);\n pos += dot(pos, pos.wzxy + 33.33);\n return fract((pos.x + pos.y) * (pos.z + pos.w));\n#else\n float dot_product = dot(pos, vec4(12.9898,78.233,45.164,94.673));\n return fract(sin(dot_product) * 43758.5453);\n#endif\n}\n\nvec2 random2(float p) {\n vec3 p3 = fract(vec3(p) * RANDOM_SCALE.xyz);\n p3 += dot(p3, p3.yzx + 19.19);\n return fract((p3.xx + p3.yz) * p3.zy);\n}\n\nvec2 random2(vec2 p) {\n vec3 p3 = fract(p.xyx * RANDOM_SCALE.xyz);\n p3 += dot(p3, p3.yzx + 19.19);\n return fract((p3.xx + p3.yz) * p3.zy);\n}\n\nvec2 random2(vec3 p3) {\n p3 = fract(p3 * RANDOM_SCALE.xyz);\n p3 += dot(p3, p3.yzx + 19.19);\n return fract((p3.xx + p3.yz) * p3.zy);\n}\n\nvec3 random3(float p) {\n vec3 p3 = fract(vec3(p) * RANDOM_SCALE.xyz);\n p3 += dot(p3, p3.yzx + 19.19);\n return fract((p3.xxy + p3.yzz) * p3.zyx); \n}\n\nvec3 random3(vec2 p) {\n vec3 p3 = fract(vec3(p.xyx) * RANDOM_SCALE.xyz);\n p3 += dot(p3, p3.yxz + 19.19);\n return fract((p3.xxy + p3.yzz) * p3.zyx);\n}\n\nvec3 random3(vec3 p) {\n p = fract(p * RANDOM_SCALE.xyz);\n p += dot(p, p.yxz + 19.19);\n return fract((p.xxy + p.yzz) * p.zyx);\n}\n\nvec4 random4(float p) {\n vec4 p4 = fract(p * RANDOM_SCALE);\n p4 += dot(p4, p4.wzxy + 19.19);\n return fract((p4.xxyz + p4.yzzw) * p4.zywx); \n}\n\nvec4 random4(vec2 p) {\n vec4 p4 = fract(p.xyxy * RANDOM_SCALE);\n p4 += dot(p4, p4.wzxy + 19.19);\n return fract((p4.xxyz + p4.yzzw) * p4.zywx);\n}\n\nvec4 random4(vec3 p) {\n vec4 p4 = fract(p.xyzx * RANDOM_SCALE);\n p4 += dot(p4, p4.wzxy + 19.19);\n return fract((p4.xxyz + p4.yzzw) * p4.zywx);\n}\n\nvec4 random4(vec4 p4) {\n p4 = fract(p4 * RANDOM_SCALE);\n p4 += dot(p4, p4.wzxy + 19.19);\n return fract((p4.xxyz + p4.yzzw) * p4.zywx);\n}\n#endif","/*\ncontributors: Patricio Gonzalez Vivo\ndescription: Signed Random\nuse: srandomX(<vec2|vec3> x)\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#ifndef FNC_SRANDOM\n#define FNC_SRANDOM\n\nfloat srandom(in float x) {\n return -1. + 2. * fract(sin(x) * 43758.5453);\n}\n\nfloat srandom(in vec2 st) {\n return -1. + 2. * fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453);\n}\n\nfloat srandom(in vec3 pos) {\n return -1. + 2. * fract(sin(dot(pos.xyz, vec3(70.9898, 78.233, 32.4355))) * 43758.5453123);\n}\n\nfloat srandom(in vec4 pos) {\n float dot_product = dot(pos, vec4(12.9898,78.233,45.164,94.673));\n return -1. + 2. * fract(sin(dot_product) * 43758.5453);\n}\n\nvec2 srandom2(in vec2 st) {\n const vec2 k = vec2(.3183099, .3678794);\n st = st * k + k.yx;\n return -1. + 2. * fract(16. * k * fract(st.x * st.y * (st.x + st.y)));\n}\n\nvec3 srandom3(in vec3 p) {\n p = vec3( dot(p, vec3(127.1, 311.7, 74.7)),\n dot(p, vec3(269.5, 183.3, 246.1)),\n dot(p, vec3(113.5, 271.9, 124.6)));\n return -1. + 2. * fract(sin(p) * 43758.5453123);\n}\n\nvec2 srandom2(in vec2 p, const in float tileLength) {\n p = mod(p, vec2(tileLength));\n return srandom2(p);\n}\n\nvec3 srandom3(in vec3 p, const in float tileLength) {\n p = mod(p, vec3(tileLength));\n return srandom3(p);\n}\n\n#endif","#include \"random.glsl\"\n#include \"srandom.glsl\"\n#include \"../math/cubic.glsl\"\n#include \"../math/quintic.glsl\"\n\n/*\ncontributors: Patricio Gonzalez Vivo\ndescription: Gradient Noise\nuse: gnoise(<float> x)\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#ifndef FNC_GNOISE\n#define FNC_GNOISE\n\nfloat gnoise(float x) {\n float i = floor(x); // integer\n float f = fract(x); // fraction\n return mix(random(i), random(i + 1.0), smoothstep(0.,1.,f)); \n}\n\nfloat gnoise(vec2 st) {\n vec2 i = floor(st);\n vec2 f = fract(st);\n float a = random(i);\n float b = random(i + vec2(1.0, 0.0));\n float c = random(i + vec2(0.0, 1.0));\n float d = random(i + vec2(1.0, 1.0));\n vec2 u = cubic(f);\n return mix( a, b, u.x) +\n (c - a)* u.y * (1.0 - u.x) +\n (d - b) * u.x * u.y;\n}\n\nfloat gnoise(vec3 p) {\n vec3 i = floor(p);\n vec3 f = fract(p);\n vec3 u = quintic(f);\n return -1.0 + 2.0 * mix( mix( mix( random(i + vec3(0.0,0.0,0.0)), \n random(i + vec3(1.0,0.0,0.0)), u.x),\n mix( random(i + vec3(0.0,1.0,0.0)), \n random(i + vec3(1.0,1.0,0.0)), u.x), u.y),\n mix( mix( random(i + vec3(0.0,0.0,1.0)), \n random(i + vec3(1.0,0.0,1.0)), u.x),\n mix( random(i + vec3(0.0,1.0,1.0)), \n random(i + vec3(1.0,1.0,1.0)), u.x), u.y), u.z );\n}\n\nfloat gnoise(vec3 p, float tileLength) {\n vec3 i = floor(p);\n vec3 f = fract(p);\n \n vec3 u = quintic(f);\n \n return mix( mix( mix( dot( srandom3(i + vec3(0.0,0.0,0.0), tileLength), f - vec3(0.0,0.0,0.0)), \n dot( srandom3(i + vec3(1.0,0.0,0.0), tileLength), f - vec3(1.0,0.0,0.0)), u.x),\n mix( dot( srandom3(i + vec3(0.0,1.0,0.0), tileLength), f - vec3(0.0,1.0,0.0)), \n dot( srandom3(i + vec3(1.0,1.0,0.0), tileLength), f - vec3(1.0,1.0,0.0)), u.x), u.y),\n mix( mix( dot( srandom3(i + vec3(0.0,0.0,1.0), tileLength), f - vec3(0.0,0.0,1.0)), \n dot( srandom3(i + vec3(1.0,0.0,1.0), tileLength), f - vec3(1.0,0.0,1.0)), u.x),\n mix( dot( srandom3(i + vec3(0.0,1.0,1.0), tileLength), f - vec3(0.0,1.0,1.0)), \n dot( srandom3(i + vec3(1.0,1.0,1.0), tileLength), f - vec3(1.0,1.0,1.0)), u.x), u.y), u.z );\n}\n\nvec3 gnoise3(vec3 x) {\n return vec3(gnoise(x+vec3(123.456, 0.567, 0.37)),\n gnoise(x+vec3(0.11, 47.43, 19.17)),\n gnoise(x) );\n}\n\n#endif","#include \"../math/mod289.glsl\"\n#include \"../math/permute.glsl\"\n#include \"../math/taylorInvSqrt.glsl\"\n#include \"../math/grad4.glsl\"\n\n/*\ncontributors: [Stefan Gustavson, Ian McEwan]\ndescription: Simplex Noise https://github.com/stegu/webgl-noise\nuse: snoise(<vec2|vec3|vec4> pos)\nlicense: |\n Copyright 2021-2023 by Stefan Gustavson and Ian McEwan.\n Published under the terms of the MIT license:\n https://opensource.org/license/mit/\nexamples:\n - /shaders/generative_snoise.frag\n*/\n\n#ifndef FNC_SNOISE\n#define FNC_SNOISE\nfloat snoise(in vec2 v) {\n const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0\n 0.366025403784439, // 0.5*(sqrt(3.0)-1.0)\n -0.577350269189626, // -1.0 + 2.0 * C.x\n 0.024390243902439); // 1.0 / 41.0\n // First corner\n vec2 i = floor(v + dot(v, C.yy) );\n vec2 x0 = v - i + dot(i, C.xx);\n\n // Other corners\n vec2 i1;\n //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0\n //i1.y = 1.0 - i1.x;\n i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n // x0 = x0 - 0.0 + 0.0 * C.xx ;\n // x1 = x0 - i1 + 1.0 * C.xx ;\n // x2 = x0 - 1.0 + 2.0 * C.xx ;\n vec4 x12 = x0.xyxy + C.xxzz;\n x12.xy -= i1;\n\n // Permutations\n i = mod289(i); // Avoid truncation effects in permutation\n vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))\n + i.x + vec3(0.0, i1.x, 1.0 ));\n\n vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);\n m = m*m ;\n m = m*m ;\n\n // Gradients: 41 points uniformly over a line, mapped onto a diamond.\n // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)\n\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\n vec3 h = abs(x) - 0.5;\n vec3 ox = floor(x + 0.5);\n vec3 a0 = x - ox;\n\n // Normalise gradients implicitly by scaling m\n // Approximation of: m *= inversesqrt( a0*a0 + h*h );\n m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );\n\n // Compute final noise value at P\n vec3 g;\n g.x = a0.x * x0.x + h.x * x0.y;\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n return 130.0 * dot(m, g);\n}\n\n\nfloat snoise(in vec3 v) {\n const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;\n const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);\n\n // First corner\n vec3 i = floor(v + dot(v, C.yyy) );\n vec3 x0 = v - i + dot(i, C.xxx) ;\n\n // Other corners\n vec3 g = step(x0.yzx, x0.xyz);\n vec3 l = 1.0 - g;\n vec3 i1 = min( g.xyz, l.zxy );\n vec3 i2 = max( g.xyz, l.zxy );\n\n // x0 = x0 - 0.0 + 0.0 * C.xxx;\n // x1 = x0 - i1 + 1.0 * C.xxx;\n // x2 = x0 - i2 + 2.0 * C.xxx;\n // x3 = x0 - 1.0 + 3.0 * C.xxx;\n vec3 x1 = x0 - i1 + C.xxx;\n vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y\n vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y\n\n // Permutations\n i = mod289(i);\n vec4 p = permute( permute( permute(\n i.z + vec4(0.0, i1.z, i2.z, 1.0 ))\n + i.y + vec4(0.0, i1.y, i2.y, 1.0 ))\n + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));\n\n // Gradients: 7x7 points over a square, mapped onto an octahedron.\n // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)\n float n_ = 0.142857142857; // 1.0/7.0\n vec3 ns = n_ * D.wyz - D.xzx;\n\n vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)\n\n vec4 x_ = floor(j * ns.z);\n vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)\n\n vec4 x = x_ *ns.x + ns.yyyy;\n vec4 y = y_ *ns.x + ns.yyyy;\n vec4 h = 1.0 - abs(x) - abs(y);\n\n vec4 b0 = vec4( x.xy, y.xy );\n vec4 b1 = vec4( x.zw, y.zw );\n\n //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;\n //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;\n vec4 s0 = floor(b0)*2.0 + 1.0;\n vec4 s1 = floor(b1)*2.0 + 1.0;\n vec4 sh = -step(h, vec4(0.0));\n\n vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;\n vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;\n\n vec3 p0 = vec3(a0.xy,h.x);\n vec3 p1 = vec3(a0.zw,h.y);\n vec3 p2 = vec3(a1.xy,h.z);\n vec3 p3 = vec3(a1.zw,h.w);\n\n //Normalise gradients\n vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));\n p0 *= norm.x;\n p1 *= norm.y;\n p2 *= norm.z;\n p3 *= norm.w;\n\n // Mix final noise value\n vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);\n m = m * m;\n return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1),\n dot(p2,x2), dot(p3,x3) ) );\n}\n\nfloat snoise(in vec4 v) {\n const vec4 C = vec4( 0.138196601125011, // (5 - sqrt(5))/20 G4\n 0.276393202250021, // 2 * G4\n 0.414589803375032, // 3 * G4\n -0.447213595499958); // -1 + 4 * G4\n\n // First corner\n vec4 i = floor(v + dot(v, vec4(.309016994374947451)) ); // (sqrt(5) - 1)/4\n vec4 x0 = v - i + dot(i, C.xxxx);\n\n // Other corners\n\n // Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI)\n vec4 i0;\n vec3 isX = step( x0.yzw, x0.xxx );\n vec3 isYZ = step( x0.zww, x0.yyz );\n // i0.x = dot( isX, vec3( 1.0 ) );\n i0.x = isX.x + isX.y + isX.z;\n i0.yzw = 1.0 - isX;\n // i0.y += dot( isYZ.xy, vec2( 1.0 ) );\n i0.y += isYZ.x + isYZ.y;\n i0.zw += 1.0 - isYZ.xy;\n i0.z += isYZ.z;\n i0.w += 1.0 - isYZ.z;\n\n // i0 now contains the unique values 0,1,2,3 in each channel\n vec4 i3 = clamp( i0, 0.0, 1.0 );\n vec4 i2 = clamp( i0-1.0, 0.0, 1.0 );\n vec4 i1 = clamp( i0-2.0, 0.0, 1.0 );\n\n // x0 = x0 - 0.0 + 0.0 * C.xxxx\n // x1 = x0 - i1 + 1.0 * C.xxxx\n // x2 = x0 - i2 + 2.0 * C.xxxx\n // x3 = x0 - i3 + 3.0 * C.xxxx\n // x4 = x0 - 1.0 + 4.0 * C.xxxx\n vec4 x1 = x0 - i1 + C.xxxx;\n vec4 x2 = x0 - i2 + C.yyyy;\n vec4 x3 = x0 - i3 + C.zzzz;\n vec4 x4 = x0 + C.wwww;\n\n // Permutations\n i = mod289(i);\n float j0 = permute( permute( permute( permute(i.w) + i.z) + i.y) + i.x);\n vec4 j1 = permute( permute( permute( permute (\n i.w + vec4(i1.w, i2.w, i3.w, 1.0 ))\n + i.z + vec4(i1.z, i2.z, i3.z, 1.0 ))\n + i.y + vec4(i1.y, i2.y, i3.y, 1.0 ))\n + i.x + vec4(i1.x, i2.x, i3.x, 1.0 ));\n\n // Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope\n // 7*7*6 = 294, which is close to the ring size 17*17 = 289.\n vec4 ip = vec4(1.0/294.0, 1.0/49.0, 1.0/7.0, 0.0) ;\n\n vec4 p0 = grad4(j0, ip);\n vec4 p1 = grad4(j1.x, ip);\n vec4 p2 = grad4(j1.y, ip);\n vec4 p3 = grad4(j1.z, ip);\n vec4 p4 = grad4(j1.w, ip);\n\n // Normalise gradients\n vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));\n p0 *= norm.x;\n p1 *= norm.y;\n p2 *= norm.z;\n p3 *= norm.w;\n p4 *= taylorInvSqrt(dot(p4,p4));\n\n // Mix contributions from the five corners\n vec3 m0 = max(0.6 - vec3(dot(x0,x0), dot(x1,x1), dot(x2,x2)), 0.0);\n vec2 m1 = max(0.6 - vec2(dot(x3,x3), dot(x4,x4) ), 0.0);\n m0 = m0 * m0;\n m1 = m1 * m1;\n return 49.0 * ( dot(m0*m0, vec3( dot( p0, x0 ), dot( p1, x1 ), dot( p2, x2 )))\n + dot(m1*m1, vec2( dot( p3, x3 ), dot( p4, x4 ) ) ) ) ;\n}\n\nvec2 snoise2( vec2 x ){\n float s = snoise(vec2( x ));\n float s1 = snoise(vec2( x.y - 19.1, x.x + 47.2 ));\n return vec2( s , s1 );\n}\n\nvec3 snoise3( vec3 x ){\n float s = snoise(vec3( x ));\n float s1 = snoise(vec3( x.y - 19.1 , x.z + 33.4 , x.x + 47.2 ));\n float s2 = snoise(vec3( x.z + 74.2 , x.x - 124.5 , x.y + 99.4 ));\n return vec3( s , s1 , s2 );\n}\n\nvec3 snoise3( vec4 x ){\n float s = snoise(vec4( x ));\n float s1 = snoise(vec4( x.y - 19.1 , x.z + 33.4 , x.x + 47.2, x.w ));\n float s2 = snoise(vec4( x.z + 74.2 , x.x - 124.5 , x.y + 99.4, x.w ));\n return vec3( s , s1 , s2 );\n}\n\n#endif\n","#include \"snoise.glsl\"\n#include \"gnoise.glsl\"\n\n\n/*\ncontributors: Patricio Gonzalez Vivo\ndescription: Fractal Brownian Motion\nuse: fbm(<vec2> pos)\noptions:\n FBM_OCTAVES: numbers of octaves. Default is 4.\n FBM_NOISE_FNC(UV): noise function to use Default 'snoise(UV)' (simplex noise)\n FBM_VALUE_INITIAL: initial value. Default is 0.\n FBM_SCALE_SCALAR: scalar. Default is 2.\n FBM_AMPLITUDE_INITIAL: initial amplitude value. Default is 0.5\n FBM_AMPLITUDE_SCALAR: amplitude scalar. Default is 0.5\nexamples:\n - /shaders/generative_fbm.frag\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#ifndef FBM_OCTAVES\n#define FBM_OCTAVES 4\n#endif\n\n#ifndef FBM_NOISE_FNC\n#define FBM_NOISE_FNC(UV) snoise(UV)\n#endif\n\n#ifndef FBM_NOISE2_FNC\n#define FBM_NOISE2_FNC(UV) FBM_NOISE_FNC(UV)\n#endif\n\n#ifndef FBM_NOISE3_FNC\n#define FBM_NOISE3_FNC(UV) FBM_NOISE_FNC(UV)\n#endif\n\n#ifndef FBM_NOISE_TILABLE_FNC\n#define FBM_NOISE_TILABLE_FNC(UV, TILE) gnoise(UV, TILE)\n#endif\n\n#ifndef FBM_NOISE3_TILABLE_FNC\n#define FBM_NOISE3_TILABLE_FNC(UV, TILE) FBM_NOISE_TILABLE_FNC(UV, TILE)\n#endif\n\n#ifndef FBM_NOISE_TYPE\n#define FBM_NOISE_TYPE float\n#endif\n\n#ifndef FBM_VALUE_INITIAL\n#define FBM_VALUE_INITIAL 0.0\n#endif\n\n#ifndef FBM_SCALE_SCALAR\n#define FBM_SCALE_SCALAR 2.0\n#endif\n\n#ifndef FBM_AMPLITUDE_INITIAL\n#define FBM_AMPLITUDE_INITIAL 0.5\n#endif\n\n#ifndef FBM_AMPLITUDE_SCALAR\n#define FBM_AMPLITUDE_SCALAR 0.5\n#endif\n\n#ifndef FNC_FBM\n#define FNC_FBM\nFBM_NOISE_TYPE fbm(in vec2 st) {\n // Initial values\n FBM_NOISE_TYPE value = FBM_NOISE_TYPE(FBM_VALUE_INITIAL);\n float amplitude = FBM_AMPLITUDE_INITIAL;\n\n // Loop of octaves\n for (int i = 0; i < FBM_OCTAVES; i++) {\n value += amplitude * FBM_NOISE2_FNC(st);\n st *= FBM_SCALE_SCALAR;\n amplitude *= FBM_AMPLITUDE_SCALAR;\n }\n return value;\n}\n\nFBM_NOISE_TYPE fbm(in vec3 pos) {\n // Initial values\n FBM_NOISE_TYPE value = FBM_NOISE_TYPE(FBM_VALUE_INITIAL);\n float amplitude = FBM_AMPLITUDE_INITIAL;\n\n // Loop of octaves\n for (int i = 0; i < FBM_OCTAVES; i++) {\n value += amplitude * FBM_NOISE3_FNC(pos);\n pos *= FBM_SCALE_SCALAR;\n amplitude *= FBM_AMPLITUDE_SCALAR;\n }\n return value;\n}\n\nFBM_NOISE_TYPE fbm(vec3 p, float tileLength) {\n const float persistence = 0.5;\n const float lacunarity = 2.0;\n\n float amplitude = 0.5;\n FBM_NOISE_TYPE total = FBM_NOISE_TYPE(0.0);\n float normalization = 0.0;\n\n for (int i = 0; i < FBM_OCTAVES; ++i) {\n float noiseValue = FBM_NOISE3_TILABLE_FNC(p, tileLength * lacunarity * 0.5) * 0.5 + 0.5;\n total += noiseValue * amplitude;\n normalization += amplitude;\n amplitude *= persistence;\n p = p * lacunarity;\n }\n\n return total / normalization;\n}\n#endif\n","#include \"../sampler.glsl\"\n#include \"../math/saturate.glsl\"\n#include \"../math/sum.glsl\"\n\n/*\ncontributors: Patricio Gonzalez Vivo\ndescription: \"morphological dilation operation. Based on: \\n https://lettier.github.io/3d-game-shaders-for-beginners/dilation.html\\n\\\n \\ https://www.shadertoy.com/view/WsyXWc\\n\"\nuse: dilation(<SAMPLER_TYPE> texture, <float2> st, <float2> pixels_scale, <int> passes)\noptions:\n - SAMPLER_FNC(TEX, UV): optional depending the target version of GLSL (texture2D(...) or texture(...))\n - DILATION_TYPE\n - DILATION_SAMPLE_FNC(TEX, UV)\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#ifndef DILATION_TYPE\n#define DILATION_TYPE float\n#endif\n\n#ifndef DILATION_MAX_RADIUS\n#define DILATION_MAX_RADIUS 16\n#endif\n\n#ifndef DILATION_SAMPLE_FNC\n#define DILATION_SAMPLE_FNC(TEX, UV) SAMPLER_FNC(TEX, UV).r\n#endif\n\n#ifndef FNC_DILATE\n#define FNC_DILATE\n\nDILATION_TYPE dilation(SAMPLER_TYPE tex, vec2 st, vec2 pixel, int radius) {\n float invKR = 1.0 / float(radius);\n DILATION_TYPE acc = DILATION_TYPE(0.0);\n float w = 0.0;\n\n #ifdef PLATFORM_WEBGL\n for(int i = -DILATION_MAX_RADIUS; i <= DILATION_MAX_RADIUS; ++i) {\n if (i >= radius) break;\n for(int j = -DILATION_MAX_RADIUS; j <= DILATION_MAX_RADIUS; ++j) {\n if (j >= radius) break;\n #else\n for(int i = -radius; i <= radius; ++i) {\n for(int j = -radius; j <= radius; ++j) {\n #endif\n vec2 rxy = vec2(ivec2(i, j));\n vec2 kst = rxy * invKR * 2.0;\n vec2 texOffset = st + rxy * pixel;\n float kernel = saturate(1.0 - dot(kst, kst));\n DILATION_TYPE t = DILATION_SAMPLE_FNC(tex, texOffset);\n DILATION_TYPE v = t + kernel;\n if (sum(v) > sum(acc)) {\n acc = v;\n w = kernel;\n }\n }\n }\n \n return acc - w;\n}\n\n#endif","/*\ncontributors: Patricio Gonzalez Vivo\ndescription: It defines the default sampler type and function for the shader based on the version of GLSL.\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n#ifndef SAMPLER_FNC\n#if __VERSION__ >= 300\n#define SAMPLER_FNC(TEX, UV) texture(TEX, UV)\n#else\n#define SAMPLER_FNC(TEX, UV) texture2D(TEX, UV)\n#endif\n#endif\n\n#ifndef SAMPLER_TYPE\n#define SAMPLER_TYPE sampler2D\n#endif","#include \"../sampler.glsl\"\n\n/*\ncontributors: Patricio Gonzalez Vivo\ndescription: fakes a clamp to edge texture\nuse: <vec4> sampleClamp2edge(<SAMPLER_TYPE> tex, <vec2> st [, <vec2> texResolution]);\noptions:\n - SAMPLER_FNC(TEX, UV)\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#ifndef FNC_SAMPLECLAMP2EDGE\n#define FNC_SAMPLECLAMP2EDGE\nvec4 sampleClamp2edge(SAMPLER_TYPE tex, vec2 st, vec2 texResolution) {\n vec2 pixel = 1.0/texResolution;\n return SAMPLER_FNC( tex, clamp(st, pixel, 1.0-pixel) );\n}\n\nvec4 sampleClamp2edge(SAMPLER_TYPE tex, vec2 st) { \n return SAMPLER_FNC( tex, clamp(st, vec2(0.01), vec2(0.99) ) ); \n}\n\nvec4 sampleClamp2edge(SAMPLER_TYPE tex, vec2 st, float edge) { \n return SAMPLER_FNC( tex, clamp(st, vec2(edge), vec2(1.0 - edge) ) ); \n}\n#endif","/*\ncontributors: Patricio Gonzalez Vivo\ndescription: |\n Draws all the digits of a floating point number, useful for debugging.\n Requires high precision to work properly.\nuse: digits(<vec2> st, <float> value [, <float> nDecDigit])\noptions:\n DIGITS_DECIMALS: number of decimals after the point, defaults to 2\n DIGITS_SIZE: size of the font, defaults to vec2(.025)\nexamples:\n - /shaders/draw_digits.frag\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#ifndef DIGITS_SIZE\n#define DIGITS_SIZE vec2(.02)\n#endif\n\n#ifndef DIGITS_DECIMALS\n#define DIGITS_DECIMALS 2.0\n#endif\n\n#ifndef DIGITS_VALUE_OFFSET\n#define DIGITS_VALUE_OFFSET vec2(-6.0, 3.0) \n#endif\n\n#ifndef FNC_DIGITS\n#define FNC_DIGITS\nfloat digits(in vec2 st, in float value, in float nDecDigit) {\n st /= DIGITS_SIZE;\n\n float absValue = abs(value);\n float biggestDigitIndex = max(floor(log2(absValue) / log2(10.)), 0.);\n float counter = floor(absValue);\n float nIntDigits = 1.;\n for (int i = 0; i < 9; i++) {\n counter = floor(counter*.1);\n nIntDigits++;\n if (counter == 0.)\n break;\n }\n\n float digit = 12.;\n float digitIndex = (nIntDigits-1.) - floor(st.x);\n if (digitIndex > (-nDecDigit - 1.5)) {\n if (digitIndex > biggestDigitIndex) {\n if (value < 0.) {\n if (digitIndex < (biggestDigitIndex+1.5)) {\n digit = 11.;\n }\n }\n } \n else {\n if (digitIndex == -1.) {\n if (nDecDigit > 0.) {\n digit = 10.;\n }\n } \n else {\n if (digitIndex < 0.) {\n digitIndex += 1.;\n }\n float digitValue = (absValue / (pow(10., digitIndex)));\n digit = mod(floor(0.0001+digitValue), 10.);\n }\n }\n }\n vec2 pos = vec2(fract(st.x), st.y);\n\n if (pos.x < 0.) return 0.;\n if (pos.y < 0.) return 0.;\n if (pos.x >= 1.) return 0.;\n if (pos.y >= 1.) return 0.;\n\n // make a 4x5 array of bits\n float bin = 0.;\n if (digit < 0.5) // 0\n bin = 7. + 5. * 16. + 5. * 256. + 5. * 4096. + 7. * 65536.; \n else if (digit < 1.5) // 1\n bin = 2. + 2. * 16. + 2. * 256. + 2. * 4096. + 2. * 65536.;\n else if (digit < 2.5) // 2\n bin = 7. + 1. * 16. + 7. * 256. + 4. * 4096. + 7. * 65536.;\n else if (digit < 3.5) // 3\n bin = 7. + 4. * 16. + 7. * 256. + 4. * 4096. + 7. * 65536.;\n else if (digit < 4.5) // 4\n bin = 4. + 7. * 16. + 5. * 256. + 1. * 4096. + 1. * 65536.;\n else if (digit < 5.5) // 5\n bin = 7. + 4. * 16. + 7. * 256. + 1. * 4096. + 7. * 65536.;\n else if (digit < 6.5) // 6\n bin = 7. + 5. * 16. + 7. * 256. + 1. * 4096. + 7. * 65536.;\n else if (digit < 7.5) // 7\n bin = 4. + 4. * 16. + 4. * 256. + 4. * 4096. + 7. * 65536.;\n else if (digit < 8.5) // 8\n bin = 7. + 5. * 16. + 7. * 256. + 5. * 4096. + 7. * 65536.;\n else if (digit < 9.5) // 9\n bin = 7. + 4. * 16. + 7. * 256. + 5. * 4096. + 7. * 65536.;\n else if (digit < 10.5) // '.'\n bin = 2. + 0. * 16. + 0. * 256. + 0. * 4096. + 0. * 65536.;\n else if (digit < 11.5) // '-'\n bin = 0. + 0. * 16. + 7. * 256. + 0. * 4096. + 0. * 65536.;\n\n vec2 pixel = floor(pos * vec2(4., 5.));\n return mod(floor(bin / pow(2., (pixel.x + (pixel.y * 4.)))), 2.);\n}\n\nfloat digits(in vec2 st, in float value, in float nDecDigit, in float nIntDigits) {\n vec2 st2 = st;\n float result = 0.0;\n float dig = nDecDigit;\n\n #ifndef DIGITS_LEADING_INT\n #if defined(PLATFORM_WEBGL)\n #define DIGITS_LEADING_INT 1.0\n #else\n #define DIGITS_LEADING_INT nIntDigits\n #endif\n #endif\n\n for (float i = DIGITS_LEADING_INT - 1.0; i > 0.0 ; i--) {\n if (i * 10.0 > value) {\n result += digits(st2, 0.0, 0.0);\n st2.x -= DIGITS_SIZE.x;\n }\n }\n result += digits(st2, value, nDecDigit);\n return result; \n}\n\nfloat digits(in vec2 st, in int value) {\n return digits(st, float(value), 0.0);\n}\n\nfloat digits(in vec2 st, in float value) {\n return digits(st, value, (DIGITS_DECIMALS));\n}\n\nfloat digits(in vec2 st, in vec2 v) {\n float rta = 0.0;\n for (int i = 0; i < 2; i++) {\n vec2 pos = st + vec2(float(i), 0.0) * DIGITS_SIZE * DIGITS_VALUE_OFFSET;\n float value = i == 0 ? v.x : v.y;\n rta += digits( pos, value );\n }\n return rta;\n}\n\nfloat digits(in vec2 st, in vec3 v) {\n float rta = 0.0;\n for (int i = 0; i < 3; i++) {\n vec2 pos = st + vec2(float(i), 0.0) * DIGITS_SIZE * DIGITS_VALUE_OFFSET;\n float value = i == 0 ? v.x : i == 1 ? v.y : v.z;\n rta += digits( pos, value );\n }\n return rta;\n}\n\nfloat digits(in vec2 st, in vec4 v) {\n float rta = 0.0;\n for (int i = 0; i < 4; i++) {\n vec2 pos = st + vec2(float(i), 0.0) * DIGITS_SIZE * DIGITS_VALUE_OFFSET;\n float value = i == 0 ? v.x : i == 1 ? v.y : i == 2 ? v.z : v.w;\n rta += digits( pos, value );\n }\n return rta;\n}\n\nfloat digits(in vec2 st, in mat2 _matrix) {\n float rta = 0.0;\n for (int i = 0; i < 2; i++) {\n for (int j = 0; j < 2; j++) {\n vec2 pos = st + vec2(float(i), float(j)) * DIGITS_SIZE * DIGITS_VALUE_OFFSET - DIGITS_SIZE * vec2(0.0, 3.0);\n float value = _matrix[j][i];\n rta += digits( pos, value );\n }\n }\n return rta;\n}\n\nfloat digits(in vec2 st, in mat3 _matrix) {\n float rta = 0.0;\n for (int i = 0; i < 3; i++) {\n for (int j = 0; j < 3; j++) {\n vec2 pos = st + vec2(float(i), float(j)) * DIGITS_SIZE * DIGITS_VALUE_OFFSET - DIGITS_SIZE * vec2(0.0, 6.0);\n float value = _matrix[j][i];\n rta += digits( pos, value );\n }\n }\n return rta;\n}\n\nfloat digits(in vec2 st, in mat4 _matrix) {\n float rta = 0.0;\n for (int i = 0; i < 4; i++) {\n for (int j = 0; j < 4; j++) {\n vec2 pos = st + vec2(float(i), float(j)) * DIGITS_SIZE * DIGITS_VALUE_OFFSET - DIGITS_SIZE * vec2(0.0, 9.0);\n float value = _matrix[j][i];\n rta += digits( pos, value );\n }\n }\n return rta;\n}\n#endif\n","#include \"../sampler.glsl\"\n\n/*\ncontributors:\n - Matt DesLauriers\n - Patricio Gonzalez Vivo\ndescription: Adapted versions from 5, 9 and 13 gaussian fast blur from https://github.com/Jam3/glsl-fast-gaussian-blur\nuse: gaussianBlur(<SAMPLER_TYPE> texture, <vec2> st, <vec2> pixel_direction [, const int kernelSize])\noptions:\n - GAUSSIANBLUR_AMOUNT: gaussianBlur5 gaussianBlur9 gaussianBlur13\n - GAUSSIANBLUR_2D: default to 1D\n - SAMPLER_FNC(TEX, UV): optional depending the target version of GLSL (texture2D(...) or texture(...))\nexamples:\n - /shaders/filter_gaussianBlur2D.frag\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#ifndef GAUSSIANBLUR_AMOUNT\n#define GAUSSIANBLUR_AMOUNT gaussianBlur13\n#endif\n\n#ifndef GAUSSIANBLUR_TYPE\n#define GAUSSIANBLUR_TYPE vec4\n#endif\n\n#ifndef GAUSSIANBLUR_SAMPLER_FNC\n#define GAUSSIANBLUR_SAMPLER_FNC(TEX, UV) SAMPLER_FNC(TEX, UV)\n#endif\n\n#include \"gaussianBlur/2D.glsl\"\n#include \"gaussianBlur/1D.glsl\"\n#include \"gaussianBlur/1D_fast13.glsl\"\n#include \"gaussianBlur/1D_fast9.glsl\"\n#include \"gaussianBlur/1D_fast5.glsl\"\n\n#ifndef FNC_GAUSSIANBLUR\n#define FNC_GAUSSIANBLUR\nGAUSSIANBLUR_TYPE gaussianBlur13(in SAMPLER_TYPE tex, in vec2 st, in vec2 offset) {\n#ifdef GAUSSIANBLUR_2D\n return gaussianBlur2D(tex, st, offset, 7);\n#else\n return gaussianBlur1D_fast13(tex, st, offset);\n#endif\n}\n\nGAUSSIANBLUR_TYPE gaussianBlur9(in SAMPLER_TYPE tex, in vec2 st, in vec2 offset) {\n#ifdef GAUSSIANBLUR_2D\n return gaussianBlur2D(tex, st, offset, 5);\n#else\n return gaussianBlur1D_fast9(tex, st, offset);\n#endif\n}\n\nGAUSSIANBLUR_TYPE gaussianBlur5(in SAMPLER_TYPE tex, in vec2 st, in vec2 offset) {\n#ifdef GAUSSIANBLUR_2D\n return gaussianBlur2D(tex, st, offset, 3);\n#else\n return gaussianBlur1D_fast5(tex, st, offset);\n#endif\n}\n\nGAUSSIANBLUR_TYPE gaussianBlur(in SAMPLER_TYPE tex, in vec2 st, in vec2 offset, const int kernelSize) {\n#ifdef GAUSSIANBLUR_2D\n return gaussianBlur2D(tex, st, offset, kernelSize);\n#else\n return gaussianBlur1D(tex, st, offset, kernelSize);\n#endif\n}\n\nGAUSSIANBLUR_TYPE gaussianBlur(in SAMPLER_TYPE tex, in vec2 st, in vec2 offset) {\n return GAUSSIANBLUR_AMOUNT(tex, st, offset);\n}\n#endif\n","#include \"../../math/gaussian.glsl\"\n#include \"../../sample/clamp2edge.glsl\"\n\n/*\ncontributors: Patricio Gonzalez Vivo\ndescription: Two dimension Gaussian Blur to be applied in only one passes\nuse: gaussianBlur2D(<SAMPLER_TYPE> texture, <vec2> st, <vec2> pixel_direction, const int kernelSize)\noptions:\n - SAMPLER_FNC(TEX, UV): optional depending the target version of GLSL (texture2D(...) or texture(...))\n - GAUSSIANBLUR2D_TYPE: Default `vec4`\n - GAUSSIANBLUR2D_SAMPLER_FNC(TEX, UV): Default `texture2D(tex, TEX, UV)`\n - GAUSSIANBLUR2D_KERNELSIZE: Use only for WebGL 1.0 and OpenGL ES 2.0 . For example RaspberryPis is not happy with dynamic loops. Default is 'kernelSize'\nexamples:\n - /shaders/filter_gaussianBlur2D.frag\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#ifndef GAUSSIANBLUR2D_TYPE\n#ifdef GAUSSIANBLUR_TYPE\n#define GAUSSIANBLUR2D_TYPE GAUSSIANBLUR_TYPE\n#else\n#define GAUSSIANBLUR2D_TYPE vec4\n#endif\n#endif\n\n#ifndef GAUSSIANBLUR2D_SAMPLER_FNC\n#ifdef GAUSSIANBLUR_SAMPLER_FNC\n#define GAUSSIANBLUR2D_SAMPLER_FNC(TEX, UV) GAUSSIANBLUR_SAMPLER_FNC(TEX, UV)\n#else\n#define GAUSSIANBLUR2D_SAMPLER_FNC(TEX, UV) sampleClamp2edge(TEX, UV)\n#endif\n#endif\n\n#ifndef FNC_GAUSSIANBLUR2D\n#define FNC_GAUSSIANBLUR2D\nGAUSSIANBLUR2D_TYPE gaussianBlur2D(in SAMPLER_TYPE tex, in vec2 st, in vec2 offset, const int kernelSize) {\n GAUSSIANBLUR2D_TYPE accumColor = GAUSSIANBLUR2D_TYPE(0.);\n \n #ifndef GAUSSIANBLUR2D_KERNELSIZE\n \n #if defined(PLATFORM_WEBGL)\n #define GAUSSIANBLUR2D_KERNELSIZE 20\n float kernelSizef = float(kernelSize);\n #else\n #define GAUSSIANBLUR2D_KERNELSIZE kernelSize\n float kernelSizef = float(GAUSSIANBLUR2D_KERNELSIZE);\n #endif\n\n #else\n float kernelSizef = float(GAUSSIANBLUR2D_KERNELSIZE);\n #endif\n\n float accumWeight = 0.;\n const float k = 0.15915494; // 1 / (2*PI)\n vec2 xy = vec2(0.0);\n for (int j = 0; j < GAUSSIANBLUR2D_KERNELSIZE; j++) {\n #if defined(PLATFORM_WEBGL)\n if (j >= kernelSize)\n break;\n #endif\n xy.y = -.5 * (kernelSizef - 1.) + float(j);\n for (int i = 0; i < GAUSSIANBLUR2D_KERNELSIZE; i++) {\n #if defined(PLATFORM_WEBGL)\n if (i >= kernelSize)\n break;\n #endif\n xy.x = -0.5 * (kernelSizef - 1.) + float(i);\n float weight = (k / kernelSizef) * gaussian(xy, kernelSizef);\n accumColor += weight * GAUSSIANBLUR2D_SAMPLER_FNC(tex, st + xy * offset);\n accumWeight += weight;\n }\n }\n return accumColor / accumWeight;\n}\n#endif\n","#include \"../../math/gaussian.glsl\"\n#include \"../../sample/clamp2edge.glsl\"\n\n/*\ncontributors: Patricio Gonzalez Vivo\ndescription: One dimension Gaussian Blur to be applied in two passes\nuse: gaussianBlur1D(<SAMPLER_TYPE> texture, <vec2> st, <vec2> pixel_direction , const int kernelSize)\noptions:\n - SAMPLER_FNC(TEX, UV): optional depending the target version of GLSL (texture2D(...) or texture(...))\n - GAUSSIANBLUR1D_TYPE: null\n - GAUSSIANBLUR1D_SAMPLER_FNC(TEX, UV): null\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#ifndef GAUSSIANBLUR1D_TYPE\n#ifdef GAUSSIANBLUR_TYPE\n#define GAUSSIANBLUR1D_TYPE GAUSSIANBLUR_TYPE\n#else\n#define GAUSSIANBLUR1D_TYPE vec4\n#endif\n#endif\n\n#ifndef GAUSSIANBLUR1D_SAMPLER_FNC\n#ifdef GAUSSIANBLUR_SAMPLER_FNC\n#define GAUSSIANBLUR1D_SAMPLER_FNC(TEX, UV) GAUSSIANBLUR_SAMPLER_FNC(TEX, UV)\n#else\n#define GAUSSIANBLUR1D_SAMPLER_FNC(TEX, UV) sampleClamp2edge(TEX, UV)\n#endif\n#endif\n\n#ifndef FNC_GAUSSIANBLUR1D\n#define FNC_GAUSSIANBLUR1D\n\n#ifdef PLATFORM_WEBGL\n\nGAUSSIANBLUR1D_TYPE gaussianBlur1D(in SAMPLER_TYPE tex,in vec2 st,in vec2 offset,const int kernelSize){\n GAUSSIANBLUR1D_TYPE accumColor = GAUSSIANBLUR1D_TYPE(0.0);\n\n float kernelSizef = float(kernelSize);\n float accumWeight = 0.0;\n const float k = 0.39894228;// 1 / sqrt(2*PI)\n for (int i = 0; i < 16; i++) {\n if( i >= kernelSize)\n break;\n float x = -0.5 * (float(kernelSize) - 1.0)+float(i);\n float weight = (k/float(kernelSize)) * gaussian(x, kernelSizef);\n GAUSSIANBLUR1D_TYPE tex = GAUSSIANBLUR1D_SAMPLER_FNC(tex, st + x * offset);\n accumColor += weight * tex;\n accumWeight += weight;\n }\n return accumColor/accumWeight;\n}\n\n#else\n\nGAUSSIANBLUR1D_TYPE gaussianBlur1D(in SAMPLER_TYPE tex,in vec2 st,in vec2 offset,const int kernelSize){\n GAUSSIANBLUR1D_TYPE accumColor=GAUSSIANBLUR1D_TYPE(0.);\n\n float kernelSizef = float(kernelSize);\n \n float accumWeight = 0.0;\n const float k = 0.39894228;// 1 / sqrt(2*PI)\n for (int i = 0; i < kernelSize; i++) {\n float x = -0.5 * ( kernelSizef -1.0) + float(i);\n float weight = (k / kernelSizef) * gaussian(x, kernelSizef);\n GAUSSIANBLUR1D_TYPE tex = GAUSSIANBLUR1D_SAMPLER_FNC(tex, st + x * offset);\n accumColor += weight * tex;\n accumWeight += weight;\n }\n return accumColor/accumWeight;\n}\n#endif\n\n#endif\n","#include \"../../sample/clamp2edge.glsl\"\n\n/*\nfunction: gaussianBlur1D_fast13\ncontributors: Matt DesLauriers\ndescription: Adapted versions of gaussian fast blur 13 from https://github.com/Jam3/glsl-fast-gaussian-blur\nuse: gaussianBlur1D_fast13(<SAMPLER_TYPE> texture, <vec2> st, <vec2> pixel_direction)\noptions:\n - SAMPLER_FNC(TEX, UV): optional depending the target version of GLSL (texture2D(...) or texture(...))\n - GAUSSIANBLUR1D_FAST13_TYPE\n - GAUSSIANBLUR1D_FAST13_SAMPLER_FNC(TEX, UV)\n*/\n\n#ifndef GAUSSIANBLUR1D_FAST13_TYPE\n#ifdef GAUSSIANBLUR_TYPE\n#define GAUSSIANBLUR1D_FAST13_TYPE GAUSSIANBLUR_TYPE\n#else\n#define GAUSSIANBLUR1D_FAST13_TYPE vec4\n#endif\n#endif\n\n#ifndef GAUSSIANBLUR1D_FAST13_SAMPLER_FNC\n#ifdef GAUSSIANBLUR_SAMPLER_FNC\n#define GAUSSIANBLUR1D_FAST13_SAMPLER_FNC(TEX, UV) GAUSSIANBLUR_SAMPLER_FNC(TEX, UV)\n#else\n#define GAUSSIANBLUR1D_FAST13_SAMPLER_FNC(TEX, UV) sampleClamp2edge(TEX, UV)\n#endif\n#endif\n\n#ifndef FNC_GAUSSIANBLUR1D_FAST13\n#define FNC_GAUSSIANBLUR1D_FAST13\nGAUSSIANBLUR1D_FAST13_TYPE gaussianBlur1D_fast13(in SAMPLER_TYPE tex, in vec2 st, in vec2 offset) {\n GAUSSIANBLUR1D_FAST13_TYPE color = GAUSSIANBLUR1D_FAST13_TYPE(0.);\n vec2 off1 = vec2(1.411764705882353) * offset;\n vec2 off2 = vec2(3.2941176470588234) * offset;\n vec2 off3 = vec2(5.176470588235294) * offset;\n color += GAUSSIANBLUR1D_FAST13_SAMPLER_FNC(tex, st) * .1964825501511404;\n color += GAUSSIANBLUR1D_FAST13_SAMPLER_FNC(tex, st + (off1)) * .2969069646728344;\n color += GAUSSIANBLUR1D_FAST13_SAMPLER_FNC(tex, st - (off1)) * .2969069646728344;\n color += GAUSSIANBLUR1D_FAST13_SAMPLER_FNC(tex, st + (off2)) * .09447039785044732;\n color += GAUSSIANBLUR1D_FAST13_SAMPLER_FNC(tex, st - (off2)) * .09447039785044732;\n color += GAUSSIANBLUR1D_FAST13_SAMPLER_FNC(tex, st + (off3)) * .010381362401148057;\n color += GAUSSIANBLUR1D_FAST13_SAMPLER_FNC(tex, st - (off3)) * .010381362401148057;\n return color;\n}\n#endif\n","#include \"../../sample/clamp2edge.glsl\"\n\n/*\ncontributors: Matt DesLauriers\ndescription: Adapted versions of gaussian fast blur 13 from https://github.com/Jam3/glsl-fast-gaussian-blur\nuse: gaussianBlur1D_fast9(<SAMPLER_TYPE> texture, <vec2> st, <vec2> pixel_direction)\noptions:\n - SAMPLER_FNC(TEX, UV): optional depending the target version of GLSL (texture2D(...) or texture(...))\n - GAUSSIANBLUR1D_FAST9_TYPE\n - GAUSSIANBLUR1D_FAST9_SAMPLER_FNC(TEX, UV)\n*/\n\n#ifndef GAUSSIANBLUR1D_FAST9_TYPE\n#ifdef GAUSSIANBLUR_TYPE\n#define GAUSSIANBLUR1D_FAST9_TYPE GAUSSIANBLUR_TYPE\n#else\n#define GAUSSIANBLUR1D_FAST9_TYPE vec4\n#endif\n#endif\n\n#ifndef GAUSSIANBLUR1D_FAST9_SAMPLER_FNC\n#ifdef GAUSSIANBLUR_SAMPLER_FNC\n#define GAUSSIANBLUR1D_FAST9_SAMPLER_FNC(TEX, UV) GAUSSIANBLUR_SAMPLER_FNC(TEX, UV)\n#else\n#define GAUSSIANBLUR1D_FAST9_SAMPLER_FNC(TEX, UV) sampleClamp2edge(TEX, UV)\n#endif\n#endif\n\n#ifndef FNC_GAUSSIANBLUR1D_FAST9\n#define FNC_GAUSSIANBLUR1D_FAST9\nGAUSSIANBLUR1D_FAST9_TYPE gaussianBlur1D_fast9(in SAMPLER_TYPE tex, in vec2 st, in vec2 offset) {\n GAUSSIANBLUR1D_FAST9_TYPE color = GAUSSIANBLUR1D_FAST9_TYPE(0.);\n vec2 off1 = vec2(1.3846153846) * offset;\n vec2 off2 = vec2(3.2307692308) * offset;\n color += GAUSSIANBLUR1D_FAST9_SAMPLER_FNC(tex, st) * .2270270270;\n color += GAUSSIANBLUR1D_FAST9_SAMPLER_FNC(tex, st + (off1)) * .3162162162;\n color += GAUSSIANBLUR1D_FAST9_SAMPLER_FNC(tex, st - (off1)) * .3162162162;\n color += GAUSSIANBLUR1D_FAST9_SAMPLER_FNC(tex, st + (off2)) * .0702702703;\n color += GAUSSIANBLUR1D_FAST9_SAMPLER_FNC(tex, st - (off2)) * .0702702703;\n return color;\n}\n#endif\n","#include \"../../sample/clamp2edge.glsl\"\n\n/*\ncontributors: Matt DesLauriers\ndescription: Adapted versions of gaussian fast blur 13 from https://github.com/Jam3/glsl-fast-gaussian-blur\nuse: gaussianBlur1D_fast5(<SAMPLER_TYPE> texture, <vec2> st, <vec2> pixel_direction)\noptions:\n - SAMPLER_FNC(TEX, UV): optional depending the target version of GLSL (texture2D(...) or texture(...))\n - GAUSSIANBLUR1D_FAST5_TYPE\n - GAUSSIANBLUR1D_FAST5_SAMPLER_FNC(TEX, UV)\n*/\n\n#ifndef GAUSSIANBLUR1D_FAST5_TYPE\n#ifdef GAUSSIANBLUR_TYPE\n#define GAUSSIANBLUR1D_FAST5_TYPE GAUSSIANBLUR_TYPE\n#else\n#define GAUSSIANBLUR1D_FAST5_TYPE vec4\n#endif\n#endif\n\n#ifndef GAUSSIANBLUR1D_FAST5_SAMPLER_FNC\n#ifdef GAUSSIANBLUR_SAMPLER_FNC\n#define GAUSSIANBLUR1D_FAST5_SAMPLER_FNC(TEX, UV) GAUSSIANBLUR_SAMPLER_FNC(TEX, UV)\n#else\n#define GAUSSIANBLUR1D_FAST5_SAMPLER_FNC(TEX, UV) sampleClamp2edge(TEX, UV)\n#endif\n#endif\n\n#ifndef FNC_GAUSSIANBLUR1D_FAST5\n#define FNC_GAUSSIANBLUR1D_FAST5\nGAUSSIANBLUR1D_FAST5_TYPE gaussianBlur1D_fast5(in SAMPLER_TYPE tex, in vec2 st, in vec2 offset) {\n GAUSSIANBLUR1D_FAST5_TYPE color = GAUSSIANBLUR1D_FAST5_TYPE(0.);\n vec2 off1 = vec2(1.3333333333333333) * offset;\n color += GAUSSIANBLUR1D_FAST5_SAMPLER_FNC(tex, st) * .29411764705882354;\n color += GAUSSIANBLUR1D_FAST5_SAMPLER_FNC(tex, st + (off1)) * .35294117647058826;\n color += GAUSSIANBLUR1D_FAST5_SAMPLER_FNC(tex, st - (off1)) * .35294117647058826;\n return color;\n}\n#endif\n","#include \"../sampler.glsl\"\n\n/*\ncontributors: [Brad Larson, Ben Cochran, Hugues Lismonde, Keitaroh Kobayashi, Alaric Cole, Matthew Clark, Jacob Gundersen, Chris Williams.]\ndescription: Kuwahara image abstraction, drawn from the work of Kyprianidis, et. al. in their publication \"Anisotropic Kuwahara Filtering on the GPU\" within the GPU Pro collection. This produces an oil-painting-like image, but it is extremely computationally expensive, so it can take seconds to render a frame on an iPad 2. This might be best used for still images.\nuse: kuwahara(<SAMPLER_TYPE> texture, <vec2> st, <vec2> pixel, <float> radius)\noptions:\n - KUWAHARA_TYPE: defaults to vec3\n - KUWAHARA_SAMPLER_FNC(TEX, UV): defaults to texture2D(tex, TEX, UV).rgb\n - KUWAHARA_RADIUS radius\n - SAMPLER_FNC(TEX, UV): optional depending the target version of GLSL (texture2D(...) or texture(...))\n*/\n\n#ifndef KUWAHARA_TYPE\n#define KUWAHARA_TYPE vec4\n#endif\n\n#ifndef KUWAHARA_SAMPLER_FNC\n#define KUWAHARA_SAMPLER_FNC(TEX, UV) SAMPLER_FNC(TEX, UV)\n#endif\n\n#ifndef FNC_KUWAHARA\n#define FNC_KUWAHARA\n\n#ifdef TARGET_MOBILE\nKUWAHARA_TYPE kuwahara(in SAMPLER_TYPE tex, in vec2 st, in vec2 pixel, in float radius) {\n\n #ifndef KUWAHARA_RADIUS\n #define KUWAHARA_RADIUS radius\n #endif\n\n float n = (KUWAHARA_RADIUS + 1.0) * (KUWAHARA_RADIUS + 1.0);\n KUWAHARA_TYPE m0 = KUWAHARA_TYPE(0.0); KUWAHARA_TYPE m1 = KUWAHARA_TYPE(0.0); KUWAHARA_TYPE m2 = KUWAHARA_TYPE(0.0); KUWAHARA_TYPE m3 = KUWAHARA_TYPE(0.0);\n KUWAHARA_TYPE s0 = KUWAHARA_TYPE(0.0); KUWAHARA_TYPE s1 = KUWAHARA_TYPE(0.0); KUWAHARA_TYPE s2 = KUWAHARA_TYPE(0.0); KUWAHARA_TYPE s3 = KUWAHARA_TYPE(0.0);\n KUWAHARA_TYPE rta = KUWAHARA_TYPE(0.0);\n KUWAHARA_TYPE c = KUWAHARA_TYPE(0.0);\n\n for (float j = -KUWAHARA_RADIUS; j <= 0.0; ++j) {\n for (float i = -KUWAHARA_RADIUS; i <= 0.0; ++i) {\n c = KUWAHARA_SAMPLER_FNC(tex, st + vec2(i,j) * pixel);\n m0 += c;\n s0 += c * c;\n }\n }\n\n for (float j = -KUWAHARA_RADIUS; j <= 0.0; ++j) {\n for (float i = 0.0; i <= KUWAHARA_RADIUS; ++i) {\n c = KUWAHARA_SAMPLER_FNC(tex, st + vec2(i,j) * pixel);\n m1 += c;\n s1 += c * c;\n }\n }\n\n for (float j = 0.0; j <= KUWAHARA_RADIUS; ++j) {\n for (float i = 0.0; i <= KUWAHARA_RADIUS; ++i) {\n c = KUWAHARA_SAMPLER_FNC(tex, st + vec2(i,j) * pixel);\n m2 += c;\n s2 += c * c;\n }\n }\n\n for (float j = 0.0; j <= KUWAHARA_RADIUS; ++j) {\n for (float i = -KUWAHARA_RADIUS; i <= 0.0; ++i) {\n c = KUWAHARA_SAMPLER_FNC(tex, st + vec2(i,j) * pixel);\n m3 += c;\n s3 += c * c;\n }\n }\n\n float min_sigma2 = 1e+2;\n m0 /= n;\n s0 = abs(s0 / n - m0 * m0);\n\n float sigma2 = s0.r + s0.g + s0.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n rta = m0;\n }\n\n m1 /= n;\n s1 = abs(s1 / n - m1 * m1);\n\n sigma2 = s1.r + s1.g + s1.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n rta = m1;\n }\n\n m2 /= n;\n s2 = abs(s2 / n - m2 * m2);\n\n sigma2 = s2.r + s2.g + s2.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n rta = m2;\n }\n\n m3 /= n;\n s3 = abs(s3 / n - m3 * m3);\n\n sigma2 = s3.r + s3.g + s3.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n rta = m3;\n }\n\n return rta;\n}\n\n#else\n\nKUWAHARA_TYPE kuwahara(in SAMPLER_TYPE tex, in vec2 st, in vec2 pixel, in float radius) {\n\n #ifndef KUWAHARA_RADIUS\n\n #if defined(PLATFORM_WEBGL)\n #define KUWAHARA_RADIUS 20.0\n float n = (radius + 1.0) * (radius + 1.0);\n #else\n #define KUWAHARA_RADIUS radius\n float n = (KUWAHARA_RADIUS + 1.0) * (KUWAHARA_RADIUS + 1.0);\n #endif\n\n #else\n float n = (KUWAHARA_RADIUS + 1.0) * (KUWAHARA_RADIUS + 1.0);\n #endif\n\n KUWAHARA_TYPE m0 = KUWAHARA_TYPE(0.0); KUWAHARA_TYPE m1 = KUWAHARA_TYPE(0.0); KUWAHARA_TYPE m2 = KUWAHARA_TYPE(0.0); KUWAHARA_TYPE m3 = KUWAHARA_TYPE(0.0);\n KUWAHARA_TYPE s0 = KUWAHARA_TYPE(0.0); KUWAHARA_TYPE s1 = KUWAHARA_TYPE(0.0); KUWAHARA_TYPE s2 = KUWAHARA_TYPE(0.0); KUWAHARA_TYPE s3 = KUWAHARA_TYPE(0.0);\n KUWAHARA_TYPE rta = KUWAHARA_TYPE(0.0);\n KUWAHARA_TYPE c = KUWAHARA_TYPE(0.0);\n \n for (float j = -KUWAHARA_RADIUS; j <= 0.0; ++j) { \n for (float i = -KUWAHARA_RADIUS; i <= 0.0; ++i) {\n c = KUWAHARA_SAMPLER_FNC(tex, st + vec2(i,j) * pixel);\n m0 += c;\n s0 += c * c;\n }\n }\n \n for (float j = -KUWAHARA_RADIUS; j <= 0.0; ++j) {\n for (float i = 0.0; i <= KUWAHARA_RADIUS; ++i) {\n #if defined(PLATFORM_WEBGL)\n if (i > radius)\n break;\n #endif\n c = KUWAHARA_SAMPLER_FNC(tex, st + vec2(i,j) * pixel);\n m1 += c;\n s1 += c * c;\n }\n }\n \n for (float j = 0.0; j <= KUWAHARA_RADIUS; ++j) {\n #if defined(PLATFORM_WEBGL)\n if (j > radius)\n break;\n #endif\n for (float i = 0.0; i <= KUWAHARA_RADIUS; ++i) {\n #if defined(PLATFORM_WEBGL)\n if (i > radius)\n break;\n #endif\n c = KUWAHARA_SAMPLER_FNC(tex, st + vec2(i,j) * pixel);\n m2 += c;\n s2 += c * c;\n }\n }\n \n for (float j = 0.0; j <= KUWAHARA_RADIUS; ++j) {\n for (float i = -KUWAHARA_RADIUS; i <= 0.0; ++i) {\n c = KUWAHARA_SAMPLER_FNC(tex, st + vec2(i,j) * pixel);\n m3 += c;\n s3 += c * c;\n }\n }\n \n \n float min_sigma2 = 1e+2;\n m0 /= n;\n s0 = abs(s0 / n - m0 * m0);\n \n float sigma2 = s0.r + s0.g + s0.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n rta = m0;\n }\n \n m1 /= n;\n s1 = abs(s1 / n - m1 * m1);\n \n sigma2 = s1.r + s1.g + s1.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n rta = m1;\n }\n \n m2 /= n;\n s2 = abs(s2 / n - m2 * m2);\n \n sigma2 = s2.r + s2.g + s2.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n rta = m2;\n }\n \n m3 /= n;\n s3 = abs(s3 / n - m3 * m3);\n \n sigma2 = s3.r + s3.g + s3.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n rta = m3;\n }\n\n return rta;\n}\n\n#endif\n\n#endif","export const glsl = (x: TemplateStringsArray): string => String.raw(x)\n","import { glsl } from './glsl'\n\nexport default glsl`\nmat3 rotationX(float angle) {\n float s = sin(angle);\n float c = cos(angle);\n return mat3(\n 1.0, 0.0, 0.0,\n 0.0, c, -s,\n 0.0, s, c\n );\n}\n\nmat3 rotationY(float angle) {\n float s = sin(angle);\n float c = cos(angle);\n return mat3(\n c, 0.0, s,\n 0.0, 1.0, 0.0,\n -s, 0.0, c\n );\n}\n\nvec4 defaultLighting(vec4 color, vec2 res, vec2 rot, float diff) {\n float aspectRatio = res.y / res.x;\n vec2 uv = (gl_FragCoord.xy / res.xy) * 2.0 - 1.0;\n vec2 specPos = vec2(rot.x * 3.8, rot.y * 2.2);\n\n vec3 baseNormal = vec3(0.0, 0.0, 1.0);\n mat3 rotMatrix = rotationX(rot.y) * rotationY(rot.x);\n vec3 normal = normalize(rotMatrix * baseNormal);\n\n vec3 lightDir = normalize(vec3(0.1, 0.5, 1.0));\n vec3 viewDir = normalize(vec3(0.0, 0.0, 1.0));\n\n vec3 halfDir = normalize(lightDir + viewDir);\n float spec = pow(max(dot(normal, halfDir), 0.0), 64.0);\n\n vec2 diffPos = uv - specPos;\n diffPos.y *= aspectRatio;\n float dist = length(diffPos);\n float mask = exp(-dist * 0.6);\n float lightFalloff = 1.0 / (dist + 1.3);\n spec *= mask * lightFalloff;\n\n return vec4(color.rgb * diff + vec3(1.0) * spec, 1.0);\n}\n`\n","import * as THREE from 'three'\nimport type { LayerSource } from '../types'\n\nconst VIDEO_EXTENSIONS = /\\.(mp4|webm|mov|ogg)(\\?|$)/i\n\nfunction isVideoSource(layer: LayerSource): boolean {\n if (layer.type) return layer.type === 'video'\n return VIDEO_EXTENSIONS.test(layer.src)\n}\n\nlet transparentTexture: THREE.Texture | null = null\nexport function getTransparentTexture(): THREE.Texture {\n if (!transparentTexture) {\n const data = new Uint8Array([0, 0, 0, 0])\n transparentTexture = new THREE.DataTexture(data, 1, 1, THREE.RGBAFormat)\n transparentTexture.needsUpdate = true\n }\n return transparentTexture\n}\n\nexport interface LoadedLayer {\n texture: THREE.Texture\n videoEl?: HTMLVideoElement\n play?: () => void\n}\n\nconst pendingVideos = new Set<HTMLVideoElement>()\n\nfunction debugLog(message: string, data?: Record<string, unknown>): void {\n try {\n if (globalThis.localStorage?.getItem('pocatoDebug') === '1') {\n console.warn(`[pocato] ${message}`, data ?? {})\n }\n } catch {\n // Ignore storage access errors.\n }\n}\n\nfunction applyVideoPlaybackOptions(video: HTMLVideoElement, layer: LayerSource): void {\n const playbackRate = layer.playbackRate ?? 1\n video.defaultPlaybackRate = playbackRate\n video.playbackRate = playbackRate\n}\n\nfunction getRandomValue(seed?: number): number {\n if (seed == null || !Number.isFinite(seed)) return Math.random()\n return Math.abs(seed) % 1\n}\n\nfunction getFreezeTargetTime(freezeTime: number, duration: number, seed?: number): number {\n if (freezeTime < 0) {\n return getRandomValue(seed) * (Number.isFinite(duration) ? duration : 1)\n }\n return Number.isFinite(duration) ? Math.min(freezeTime, duration) : freezeTime\n}\n\nfunction isAtTargetTime(video: HTMLVideoElement, targetTime: number): boolean {\n return Math.abs(video.currentTime - targetTime) < 0.05\n}\n\nexport function loadLayerTexture(\n layer: LayerSource,\n onError?: (error: Error) => void,\n): Promise<LoadedLayer> {\n if (isVideoSource(layer)) {\n if (layer.freeze != null) {\n return loadFrozenVideoTexture(layer, layer.freeze === 'random' ? -1 : layer.freeze, onError)\n }\n return loadVideoTexture(layer, onError)\n }\n return loadImageTexture(layer.src, onError)\n}\n\n// Dedup concurrent loads of the same URL\nconst inflight = new Map<string, Promise<THREE.Texture>>()\n\nfunction loadImageTexture(\n src: string,\n onError?: (error: Error) => void,\n): Promise<LoadedLayer> {\n let pending = inflight.get(src)\n if (!pending) {\n pending = new Promise<THREE.Texture>((resolve) => {\n const loader = new THREE.TextureLoader()\n loader.load(\n src,\n (texture) => { inflight.delete(src); resolve(texture) },\n undefined,\n () => {\n inflight.delete(src)\n onError?.(new Error(`Failed to load image texture: ${src}`))\n resolve(getTransparentTexture())\n },\n )\n })\n inflight.set(src, pending)\n }\n return pending.then((texture) => ({ texture }))\n}\n\nfunction loadVideoTexture(\n layer: LayerSource,\n onError?: (error: Error) => void,\n): Promise<LoadedLayer> {\n return new Promise((resolve) => {\n const video = document.createElement('video')\n video.crossOrigin = 'anonymous'\n video.muted = true\n video.loop = layer.loop ?? true\n applyVideoPlaybackOptions(video, layer)\n video.playsInline = true\n video.preload = 'auto'\n // Chrome/Safari won't decode frames for display:none elements.\n // Use off-screen 1px element instead.\n video.style.position = 'fixed'\n video.style.width = '1px'\n video.style.height = '1px'\n video.style.opacity = '0.01'\n video.style.pointerEvents = 'none'\n video.style.zIndex = '-9999'\n document.body.appendChild(video)\n\n pendingVideos.add(video)\n\n let settled = false\n\n video.addEventListener('error', () => {\n if (settled) return\n settled = true\n pendingVideos.delete(video)\n const msg = video.error?.message ?? 'Unknown video error'\n onError?.(new Error(`Failed to load video texture: ${layer.src} (${msg})`))\n video.remove()\n resolve({ texture: getTransparentTexture() })\n }, { once: true })\n\n video.addEventListener('loadeddata', () => {\n if (settled) return\n settled = true\n video.pause()\n pendingVideos.delete(video)\n const texture = new THREE.VideoTexture(video)\n resolve({\n texture,\n videoEl: video,\n play: () => {\n video.play().catch(() => {\n onError?.(new Error(`Video autoplay blocked: ${layer.src}`))\n })\n },\n })\n }, { once: true })\n\n video.src = layer.src\n video.load()\n })\n}\n\nfunction loadFrozenVideoTexture(\n layer: LayerSource,\n freezeTime: number,\n onError?: (error: Error) => void,\n): Promise<LoadedLayer> {\n return new Promise((resolve) => {\n debugLog('freeze load start', {\n src: layer.src,\n freezeTime,\n freezeSeed: layer.freezeSeed,\n })\n\n const video = document.createElement('video')\n video.crossOrigin = 'anonymous'\n video.muted = true\n applyVideoPlaybackOptions(video, layer)\n video.playsInline = true\n video.preload = 'auto'\n video.style.position = 'fixed'\n video.style.width = '1px'\n video.style.height = '1px'\n video.style.opacity = '0.01'\n video.style.pointerEvents = 'none'\n video.style.zIndex = '-9999'\n document.body.appendChild(video)\n\n pendingVideos.add(video)\n\n let settled = false\n let targetTime = 0\n let retrySeekRegistered = false\n\n const captureFrame = () => {\n if (settled) return\n settled = true\n video.pause()\n debugLog('freeze capture frame', {\n src: layer.src,\n currentTime: video.currentTime,\n duration: video.duration,\n readyState: video.readyState,\n videoWidth: video.videoWidth,\n videoHeight: video.videoHeight,\n })\n\n const canvas = document.createElement('canvas')\n canvas.width = video.videoWidth || 1\n canvas.height = video.videoHeight || 1\n const ctx = canvas.getContext('2d')\n if (!ctx) {\n pendingVideos.delete(video)\n video.src = ''\n video.remove()\n resolve({ texture: getTransparentTexture() })\n return\n }\n try {\n ctx.drawImage(video, 0, 0)\n } catch (error) {\n debugLog('freeze drawImage failed', {\n src: layer.src,\n error: error instanceof Error ? error.message : String(error),\n })\n pendingVideos.delete(video)\n video.src = ''\n video.remove()\n onError?.(error instanceof Error ? error : new Error(String(error)))\n resolve({ texture: getTransparentTexture() })\n return\n }\n\n const texture = new THREE.CanvasTexture(canvas)\n texture.needsUpdate = true\n debugLog('freeze canvas texture ready', {\n src: layer.src,\n width: canvas.width,\n height: canvas.height,\n })\n\n pendingVideos.delete(video)\n video.src = ''\n video.remove()\n resolve({ texture })\n }\n\n const captureReadyFrame = () => {\n debugLog('freeze wait decoded frame', {\n src: layer.src,\n currentTime: video.currentTime,\n readyState: video.readyState,\n })\n if ('requestVideoFrameCallback' in video) {\n video.requestVideoFrameCallback(() => captureFrame())\n }\n\n const playPromise = video.play()\n playPromise.catch(() => {\n debugLog('freeze play rejected, fallback capture', { src: layer.src })\n window.setTimeout(captureFrame, 0)\n })\n\n if (!('requestVideoFrameCallback' in video)) {\n window.setTimeout(captureFrame, 0)\n }\n }\n\n const retrySeekWhenReady = () => {\n if (settled) return\n if (retrySeekRegistered) return\n retrySeekRegistered = true\n\n const retry = () => {\n retrySeekRegistered = false\n if (settled) return\n debugLog('freeze retry seek', {\n src: layer.src,\n targetTime,\n currentTime: video.currentTime,\n duration: video.duration,\n readyState: video.readyState,\n })\n video.currentTime = targetTime\n }\n\n video.addEventListener('durationchange', retry, { once: true })\n video.addEventListener('canplay', retry, { once: true })\n video.addEventListener('loadeddata', retry, { once: true })\n }\n\n video.addEventListener('error', () => {\n pendingVideos.delete(video)\n const msg = video.error?.message ?? 'Unknown video error'\n onError?.(new Error(`Failed to load video texture: ${layer.src} (${msg})`))\n video.remove()\n resolve({ texture: getTransparentTexture() })\n }, { once: true })\n\n video.addEventListener('loadedmetadata', () => {\n const time = getFreezeTargetTime(freezeTime, video.duration, layer.freezeSeed)\n targetTime = time\n debugLog('freeze metadata loaded', {\n src: layer.src,\n targetTime: time,\n duration: video.duration,\n readyState: video.readyState,\n })\n if (isAtTargetTime(video, time)) {\n if (video.readyState >= 2) {\n captureReadyFrame()\n } else {\n video.addEventListener('loadeddata', () => captureReadyFrame(), { once: true })\n }\n return\n }\n video.currentTime = time\n }, { once: true })\n\n video.addEventListener('seeked', () => {\n debugLog('freeze seeked', {\n src: layer.src,\n targetTime,\n currentTime: video.currentTime,\n duration: video.duration,\n readyState: video.readyState,\n })\n if (!isAtTargetTime(video, targetTime)) {\n retrySeekWhenReady()\n return\n }\n captureReadyFrame()\n })\n\n video.src = layer.src\n video.load()\n })\n}\n\nexport function disposeLoadedLayer(loaded: LoadedLayer): void {\n if (loaded.videoEl) {\n loaded.videoEl.pause()\n loaded.videoEl.src = ''\n loaded.videoEl.remove()\n }\n if (loaded.texture !== getTransparentTexture()) {\n loaded.texture.dispose()\n }\n}\n\nexport function cleanupPendingVideos(): void {\n for (const video of pendingVideos) {\n video.pause()\n video.src = ''\n video.remove()\n }\n pendingVideos.clear()\n}\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n// three.js built-in attributes\n// attribute vec3 position;\n// attribute vec3 normal;\n// attribute vec2 uv;\n\n// three.js built-in uniforms\n// uniform mat4 modelMatrix; // a.k.a worldMatrix\n// uniform mat4 viewMatrix;\n// uniform mat4 modelViewMatrix;\n// uniform mat3 normalMatrix;\n// uniform mat4 projectionMatrix;\n// uniform vec3 cameraPosition;\n\n// world transformed attributes for the fragment shader\nvarying vec3 vNormal;\nvarying vec3 vPosition;\nvarying vec2 vUv;\nvarying vec3 vView;\n\nvoid main() {\n // vec4 pos = viewMatrix * modelMatrix * vec4(position, 1.0);\n vec4 pos = modelViewMatrix * vec4(position, 1.0);\n\n // normalMatrix = transpose(inverse(mat3(modelMatrix)));\n // because transform matrix for normal vector is L^-1T\n vUv = uv;\n vPosition = pos.xyz;\n vView = normalize(cameraPosition - vPosition);\n vNormal = normalize(normalMatrix * normal);\n\n // transform the position to clip space\n gl_Position = projectionMatrix * pos;\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMouse;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n#include <utils/defaultLighting>\n\nvoid main() {\n // 기본 카드 텍스처 샘플링\n vec4 baseColor = texture2D(uLayer0, vUv);\n\n // 팝업 텍스처 샘플링 (움직임 반영)\n float popupOffset = 0.0;\n vec2 popupUv = vUv + (uMove / uResolution) * popupOffset; // 팝업 이동 효과\n vec4 popupColor = texture2D(uLayer1, popupUv);\n\n float aSoft = smoothstep(0.4, 1.0, popupColor.a);\n vec4 pocaColor = mix(baseColor, popupColor, aSoft);\n\n gl_FragColor = defaultLighting(pocaColor, uResolution, uRotate, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMouse;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n#include <utils/defaultLighting>\n\nvoid main() {\n // 기본 카드 텍스처 샘플링\n vec4 baseColor = texture2D(uLayer0, vUv);\n\n // 팝업 텍스처 샘플링 (움직임 반영)\n vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);\n vec2 popupUv = vUv + popupOffset; // 팝업 이동 효과\n vec4 popupColor = texture2D(uLayer1, popupUv);\n\n float aSoft = smoothstep(0.4, 1.0, popupColor.a);\n vec4 pocaColor = mix(baseColor, popupColor, aSoft);\n\n gl_FragColor = defaultLighting(pocaColor, uResolution, uRotate, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMouse;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform float uEffectSpeed;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n#define mod289(x) mod(x, 289.)\n\nvec3 permute(vec3 x) { return mod289(((x * 34.0) + 1.0) * x); }\n\nfloat snoise(vec2 coord) {\n const vec4 C = vec4(0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439);\n vec2 intPart = floor(coord + dot(coord, C.yy));\n vec2 fracPart = coord - intPart + dot(intPart, C.xx);\n\n vec2 offset;\n offset = (fracPart.x > fracPart.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n vec4 combined = fracPart.xyxy + C.xxzz;\n combined.xy -= offset;\n\n intPart = mod289(intPart);\n vec3 perm = permute(permute(intPart.y + vec3(0.0, offset.y, 1.0))\n + intPart.x + vec3(0.0, offset.x, 1.0));\n\n vec3 gradient = max(0.5 - vec3(dot(fracPart, fracPart), dot(combined.xy, combined.xy), dot(combined.zw, combined.zw)), 0.0);\n gradient *= gradient;\n gradient *= gradient;\n\n vec3 noiseVec = 2.0 * fract(perm * C.www) - 1.0;\n vec3 absDiff = abs(noiseVec) - 0.5;\n vec3 offsetVec = floor(noiseVec + 0.5);\n vec3 gradientVec = noiseVec - offsetVec;\n\n gradient *= 1.79284291400159 - 0.85373472095314 * (gradientVec * gradientVec + absDiff * absDiff);\n\n vec3 finalGrad;\n finalGrad.x = gradientVec.x * fracPart.x + absDiff.x * fracPart.y;\n finalGrad.yz = gradientVec.yz * combined.xz + absDiff.yz * combined.yw;\n\n return 130.0 * dot(gradient, finalGrad);\n}\n\nfloat fbm(vec2 position) {\n float result = 0.0;\n float weight = 0.5;\n for (int i = 0; i < 5; i++) {\n result += weight * snoise(position);\n position *= 2.0;\n weight *= 0.5;\n }\n return result;\n}\n\n// snowfall\nconst int LAYERS = 66;\nconst float DEPTH_NEAR = 0.3;\nconst float WIDTH_NEAR = 0.4;\nconst float SPEED_NEAR = 0.6;\nconst float DEPTH_FAR = 0.1;\nconst float WIDTH_FAR = 0.3;\nconst float SPEED_FAR = 0.1;\n\nfloat effectTime() {\n float speed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;\n return uTime * speed;\n}\n\nfloat computeSnow(in vec2 uv, int layerStart, int layerEnd) {\n const mat3 permutationMatrix = mat3(13.323122, 23.5112, 21.71123, 21.1212, 28.7312, 11.9312, 21.8112, 14.7212, 61.3934);\n vec2 moveNormalized = uMove.xy / uResolution.xy;\n moveNormalized.x = max(0.15, smoothstep(0.15, 0.8, moveNormalized.x));\n uv.x += moveNormalized.x * 0.2;\n float totalLayers = float(LAYERS);\n float accumulation = 0.0;\n float snowTime = effectTime();\n float depthOfField = 5.0 * sin(snowTime * 0.1);\n for (int i = max(layerStart, 0); i < min(layerEnd, LAYERS); i++) {\n float layer = float(i);\n float depthFactor = smoothstep(DEPTH_NEAR, DEPTH_FAR, layer / totalLayers);\n float widthFactor = smoothstep(WIDTH_NEAR, WIDTH_FAR, layer / totalLayers);\n float speedFactor = smoothstep(SPEED_NEAR, SPEED_FAR, layer / totalLayers);\n vec2 offsetUv = uv * (1.0 + layer * depthFactor);\n float windEffect = widthFactor * mod(layer * 7.238917, 1.0) - widthFactor * 0.1 * sin(snowTime * 2.0 + layer);\n offsetUv += vec2(offsetUv.y * windEffect, speedFactor * snowTime / (1.0 + layer * depthFactor * 0.03));\n vec3 noiseInput = vec3(floor(offsetUv), 31.189 + layer);\n vec3 permuted = floor(noiseInput) * 0.00001 + fract(noiseInput);\n vec3 noise = fract((31415.9 + permuted) / fract(permutationMatrix * permuted));\n vec2 particleShape = abs(mod(offsetUv, 1.0) - 0.5 + 0.9 * noise.xy - 0.45);\n particleShape += 0.01 * abs(2.0 * fract(10.0 * offsetUv.yx) - 1.0);\n float distance = 0.6 * max(particleShape.x - particleShape.y, particleShape.x + particleShape.y) + max(particleShape.x, particleShape.y) - 0.01;\n float edgeThreshold = 0.05 + 0.05 * min(0.5 * abs(layer - 5.0 - depthOfField), 1.0);\n accumulation += smoothstep(edgeThreshold, -edgeThreshold, distance) * (noise.x / (1.0 + 0.02 * layer * depthFactor));\n }\n return accumulation;\n}\n\nvoid main() {\n vec4 baseTexture = texture2D(uLayer0, vUv);\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n gl_FragColor = mix(gl_FragColor, baseTexture, baseTexture.a);\n\n float snowEffect = computeSnow(vUv, 5, 15);\n gl_FragColor += vec4(vec3(snowEffect * effectIntensity), 1.0);\n\n float popupMoveOffset = 0.0;\n vec2 popupOffsetUv = vUv + (uMove.xy / uResolution.xy) * popupMoveOffset;\n vec4 popupTexture = texture2D(uLayer1, popupOffsetUv);\n gl_FragColor = mix(gl_FragColor, popupTexture, popupTexture.a);\n\n snowEffect = computeSnow(vUv, 16, 20);\n gl_FragColor += vec4(vec3(snowEffect * effectIntensity), 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMouse;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform float uEffectSpeed;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n#define mod289(x) mod(x, 289.)\n\nvec3 permute(vec3 x) { return mod289(((x * 34.0) + 1.0) * x); }\n\nfloat snoise(vec2 coord) {\n const vec4 C = vec4(0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439);\n vec2 intPart = floor(coord + dot(coord, C.yy));\n vec2 fracPart = coord - intPart + dot(intPart, C.xx);\n\n vec2 offset;\n offset = (fracPart.x > fracPart.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n vec4 combined = fracPart.xyxy + C.xxzz;\n combined.xy -= offset;\n\n intPart = mod289(intPart);\n vec3 perm = permute(permute(intPart.y + vec3(0.0, offset.y, 1.0))\n + intPart.x + vec3(0.0, offset.x, 1.0));\n\n vec3 gradient = max(0.5 - vec3(dot(fracPart, fracPart), dot(combined.xy, combined.xy), dot(combined.zw, combined.zw)), 0.0);\n gradient *= gradient;\n gradient *= gradient;\n\n vec3 noiseVec = 2.0 * fract(perm * C.www) - 1.0;\n vec3 absDiff = abs(noiseVec) - 0.5;\n vec3 offsetVec = floor(noiseVec + 0.5);\n vec3 gradientVec = noiseVec - offsetVec;\n\n gradient *= 1.79284291400159 - 0.85373472095314 * (gradientVec * gradientVec + absDiff * absDiff);\n\n vec3 finalGrad;\n finalGrad.x = gradientVec.x * fracPart.x + absDiff.x * fracPart.y;\n finalGrad.yz = gradientVec.yz * combined.xz + absDiff.yz * combined.yw;\n\n return 130.0 * dot(gradient, finalGrad);\n}\n\nfloat fbm(vec2 position) {\n float result = 0.0;\n float weight = 0.5;\n for (int i = 0; i < 5; i++) {\n result += weight * snoise(position);\n position *= 2.0;\n weight *= 0.5;\n }\n return result;\n}\n\n// snowfall\nconst int LAYERS = 66;\nconst float DEPTH_NEAR = 0.3;\nconst float WIDTH_NEAR = 0.4;\nconst float SPEED_NEAR = 0.6;\nconst float DEPTH_FAR = 0.1;\nconst float WIDTH_FAR = 0.3;\nconst float SPEED_FAR = 0.1;\n\nfloat effectTime() {\n float speed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;\n return uTime * speed;\n}\n\nfloat computeSnow(in vec2 uv, int layerStart, int layerEnd) {\n const mat3 permutationMatrix = mat3(13.323122, 23.5112, 21.71123, 21.1212, 28.7312, 11.9312, 21.8112, 14.7212, 61.3934);\n vec2 moveNormalized = uMove.xy / uResolution.xy;\n moveNormalized.x = max(0.15, smoothstep(0.15, 0.8, moveNormalized.x));\n uv.x += moveNormalized.x * 0.2;\n float totalLayers = float(LAYERS);\n float accumulation = 0.0;\n float snowTime = effectTime();\n float depthOfField = 5.0 * sin(snowTime * 0.1);\n for (int i = max(layerStart, 0); i < min(layerEnd, LAYERS); i++) {\n float layer = float(i);\n float depthFactor = smoothstep(DEPTH_NEAR, DEPTH_FAR, layer / totalLayers);\n float widthFactor = smoothstep(WIDTH_NEAR, WIDTH_FAR, layer / totalLayers);\n float speedFactor = smoothstep(SPEED_NEAR, SPEED_FAR, layer / totalLayers);\n vec2 offsetUv = uv * (1.0 + layer * depthFactor);\n float windEffect = widthFactor * mod(layer * 7.238917, 1.0) - widthFactor * 0.1 * sin(snowTime * 2.0 + layer);\n offsetUv += vec2(offsetUv.y * windEffect, speedFactor * snowTime / (1.0 + layer * depthFactor * 0.03));\n vec3 noiseInput = vec3(floor(offsetUv), 31.189 + layer);\n vec3 permuted = floor(noiseInput) * 0.00001 + fract(noiseInput);\n vec3 noise = fract((31415.9 + permuted) / fract(permutationMatrix * permuted));\n vec2 particleShape = abs(mod(offsetUv, 1.0) - 0.5 + 0.9 * noise.xy - 0.45);\n particleShape += 0.01 * abs(2.0 * fract(10.0 * offsetUv.yx) - 1.0);\n float distance = 0.6 * max(particleShape.x - particleShape.y, particleShape.x + particleShape.y) + max(particleShape.x, particleShape.y) - 0.01;\n float edgeThreshold = 0.05 + 0.05 * min(0.5 * abs(layer - 5.0 - depthOfField), 1.0);\n accumulation += smoothstep(edgeThreshold, -edgeThreshold, distance) * (noise.x / (1.0 + 0.02 * layer * depthFactor));\n }\n return accumulation;\n}\n\nvoid main() {\n vec4 baseTexture = texture2D(uLayer0, vUv);\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n gl_FragColor = mix(gl_FragColor, baseTexture, baseTexture.a);\n\n float snowEffect = computeSnow(vUv, 5, 15);\n gl_FragColor += vec4(vec3(snowEffect * effectIntensity), 1.0);\n\n // 3D parallax offset for popup layer\n vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);\n vec2 popupOffsetUv = vUv + popupOffset;\n vec4 popupTexture = texture2D(uLayer1, popupOffsetUv);\n gl_FragColor = mix(gl_FragColor, popupTexture, popupTexture.a);\n\n snowEffect = computeSnow(vUv, 16, 20);\n gl_FragColor += vec4(vec3(snowEffect * effectIntensity), 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMouse;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n#include <lygia/sample/clamp2edge>\n#define KUWAHARA_SAMPLER_FNC(TEX, UV) sampleClamp2edge(TEX, UV)\n#include <lygia/filter/kuwahara>\n#include <lygia/draw/digits>\n#include <utils/defaultLighting>\n\nvoid main() {\n vec2 pixel = 1.0 / uResolution.xy;\n vec2 popUpUv = vUv + (uMove.xy / uResolution.xy) * 0.008;\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n\n vec4 originalBaseColor = texture2D(uLayer0, vUv);\n vec4 originalPopupColor = texture2D(uLayer1, popUpUv);\n vec4 brushedBaseColor = kuwahara(uLayer0, vUv, pixel, 4.0);\n vec4 brushedPopupColor = kuwahara(uLayer1, popUpUv, pixel, 4.0);\n vec4 baseColor = mix(originalBaseColor, brushedBaseColor, effectIntensity);\n vec4 popupColor = mix(originalPopupColor, brushedPopupColor, effectIntensity);\n\n float aSoft = smoothstep(0.4, 1.0, popupColor.a);\n vec4 pocaColor = mix(baseColor, popupColor, aSoft);\n\n gl_FragColor = defaultLighting(pocaColor, uResolution, uRotate, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMouse;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n#include <lygia/sample/clamp2edge>\n#define KUWAHARA_SAMPLER_FNC(TEX, UV) sampleClamp2edge(TEX, UV)\n#include <lygia/filter/kuwahara>\n#include <lygia/draw/digits>\n#include <utils/defaultLighting>\n\nvoid main() {\n vec2 pixel = 1.0 / uResolution.xy;\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n\n // 3D parallax offset for popup layer\n vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);\n vec2 popUpUv = vUv + popupOffset;\n\n vec4 originalBaseColor = texture2D(uLayer0, vUv);\n vec4 originalPopupColor = texture2D(uLayer1, popUpUv);\n vec4 brushedBaseColor = kuwahara(uLayer0, vUv, pixel, 4.0);\n vec4 brushedPopupColor = kuwahara(uLayer1, popUpUv, pixel, 4.0);\n vec4 baseColor = mix(originalBaseColor, brushedBaseColor, effectIntensity);\n vec4 popupColor = mix(originalPopupColor, brushedPopupColor, effectIntensity);\n\n float aSoft = smoothstep(0.4, 1.0, popupColor.a);\n vec4 pocaColor = mix(baseColor, popupColor, aSoft);\n\n gl_FragColor = defaultLighting(pocaColor, uResolution, uRotate, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMouse;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n// #define GAUSSIANBLUR_2D\n#include <lygia/sample/clamp2edge>\n#define GAUSSIANBLUR_SAMPLER_FNC(TEX, UV) sampleClamp2edge(TEX, UV)\n#include <lygia/filter/gaussianBlur>\n#include <lygia/draw/digits>\n#include <utils/defaultLighting>\n\nvoid main() {\n vec2 pixel = 1.0 / uResolution.xy;\n vec2 popUpUv = vUv + (uMove.xy / uResolution.xy) * 0.008;\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n\n vec4 originalBaseColor = texture2D(uLayer0, vUv);\n vec4 blurredBaseColor = gaussianBlur(uLayer0, vUv, pixel, 12);\n vec4 baseColor = mix(originalBaseColor, blurredBaseColor, effectIntensity);\n vec4 popupColor = texture2D(uLayer1, popUpUv);\n\n float aSoft = smoothstep(0.4, 1.0, popupColor.a);\n vec4 pocaColor = mix(baseColor, popupColor, aSoft);\n\n gl_FragColor = defaultLighting(pocaColor, uResolution, uRotate, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMouse;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n// #define GAUSSIANBLUR_2D\n#include <lygia/sample/clamp2edge>\n#define GAUSSIANBLUR_SAMPLER_FNC(TEX, UV) sampleClamp2edge(TEX, UV)\n#include <lygia/filter/gaussianBlur>\n#include <lygia/draw/digits>\n#include <utils/defaultLighting>\n\nvoid main() {\n vec2 pixel = 1.0 / uResolution.xy;\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n\n // 3D parallax offset for popup layer\n vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);\n vec2 popUpUv = vUv + popupOffset;\n\n vec4 originalBaseColor = texture2D(uLayer0, vUv);\n vec4 blurredBaseColor = gaussianBlur(uLayer0, vUv, pixel, 12);\n vec4 baseColor = mix(originalBaseColor, blurredBaseColor, effectIntensity);\n vec4 popupColor = texture2D(uLayer1, popUpUv);\n\n float aSoft = smoothstep(0.4, 1.0, popupColor.a);\n vec4 pocaColor = mix(baseColor, popupColor, aSoft);\n\n gl_FragColor = defaultLighting(pocaColor, uResolution, uRotate, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMouse;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform float uEffectSpeed;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n#include <utils/defaultLighting>\n\n// HSV to RGB conversion\nvec3 hsv2rgb(vec3 c) {\n vec4 K = vec4(1.0, 2.0/3.0, 1.0/3.0, 3.0);\n vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n}\n\nvoid main() {\n vec4 baseColor = texture2D(uLayer0, vUv);\n vec4 popupColor = texture2D(uLayer1, vUv);\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n float effectSpeed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;\n\n // Iridescence on base only\n float angle = uRotate.x * 2.0 + uRotate.y * 1.5;\n float hue = fract(vUv.y * 0.8 + vUv.x * 0.3 + angle * 0.5 + uTime * 0.05 * effectSpeed);\n vec3 rainbow = hsv2rgb(vec3(hue, 0.6, 1.0));\n\n float tiltAmount = length(uRotate) * 3.0;\n float holoIntensity = smoothstep(0.0, 1.0, tiltAmount) * 0.35 * effectIntensity;\n\n vec3 holoBase = baseColor.rgb + rainbow * holoIntensity;\n\n // Composite popup on top without holo\n float aSoft = smoothstep(0.4, 1.0, popupColor.a);\n vec3 finalColor = mix(holoBase, popupColor.rgb, aSoft);\n\n gl_FragColor = defaultLighting(vec4(finalColor, 1.0), uResolution, uRotate, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMouse;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform float uEffectSpeed;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n#include <utils/defaultLighting>\n\n// HSV to RGB conversion\nvec3 hsv2rgb(vec3 c) {\n vec4 K = vec4(1.0, 2.0/3.0, 1.0/3.0, 3.0);\n vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n}\n\nvoid main() {\n vec4 baseColor = texture2D(uLayer0, vUv);\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n float effectSpeed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;\n\n // 3D parallax offset for popup layer\n vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);\n vec2 popupUv = vUv + popupOffset;\n vec4 popupColor = texture2D(uLayer1, popupUv);\n\n // Iridescence on base only\n float angle = uRotate.x * 2.0 + uRotate.y * 1.5;\n float hue = fract(vUv.y * 0.8 + vUv.x * 0.3 + angle * 0.5 + uTime * 0.05 * effectSpeed);\n vec3 rainbow = hsv2rgb(vec3(hue, 0.6, 1.0));\n\n float tiltAmount = length(uRotate) * 3.0;\n float holoIntensity = smoothstep(0.0, 1.0, tiltAmount) * 0.35 * effectIntensity;\n\n vec3 holoBase = baseColor.rgb + rainbow * holoIntensity;\n\n // Composite popup on top without holo\n float aSoft = smoothstep(0.4, 1.0, popupColor.a);\n vec3 finalColor = mix(holoBase, popupColor.rgb, aSoft);\n\n gl_FragColor = defaultLighting(vec4(finalColor, 1.0), uResolution, uRotate, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMouse;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform float uEffectSpeed;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n#include <utils/defaultLighting>\n\nfloat pulseField(vec2 uv, float t) {\n float dist = length(uv);\n float band = abs(fract(t - dist * 0.9) - 0.5);\n float ring = 1.0 - smoothstep(0.03, 0.12, band);\n float wave = 0.5 + 0.5 * sin((uv.x + uv.y) * 8.0 + t * 2.0);\n float stripes = 0.5 + 0.5 * sin((uv.x - uv.y) * 14.0 - t * 3.0);\n return ring * 0.55 + wave * 0.25 + stripes * 0.20;\n}\n\nvoid main() {\n vec4 baseColor = texture2D(uLayer0, vUv);\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n float effectSpeed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;\n vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);\n vec4 popupColor = texture2D(uLayer1, vUv + popupOffset);\n float popupMix = smoothstep(0.35, 1.0, popupColor.a);\n vec3 layeredColor = mix(baseColor.rgb, popupColor.rgb, popupMix);\n\n vec2 centered = (vUv * 2.0 - 1.0);\n centered.x *= uResolution.x / max(uResolution.y, 1.0);\n\n float time = uTime * 0.35 * effectSpeed;\n float field = 0.0;\n\n for (int j = 0; j < 3; j++) {\n float jf = float(j);\n float offset = jf * 0.24;\n vec2 lane = centered;\n lane.x += sin(lane.y * 3.0 + time + jf) * 0.18;\n lane.y += cos(lane.x * 2.2 - time * 1.2 + jf * 0.7) * 0.14;\n field += pulseField(lane + vec2(offset), time + jf * 0.6);\n }\n field /= 3.0;\n\n float edge = smoothstep(1.2, 0.1, length(centered));\n float highlight = smoothstep(0.25, 0.95, field) * edge;\n float glow = smoothstep(0.18, 0.95, field + 0.12 * sin(time + centered.x * 4.0));\n\n float luminance = dot(layeredColor, vec3(0.299, 0.587, 0.114));\n vec3 lifted = mix(layeredColor, vec3(luminance), 0.08);\n vec3 pulseColor = lifted + layeredColor * (0.22 + glow * 0.18) + vec3(0.04) * glow;\n vec3 finalColor = mix(layeredColor, pulseColor, highlight * 0.88 * effectIntensity);\n finalColor += (pulseColor - layeredColor) * glow * 0.10 * effectIntensity;\n\n float finalAlpha = max(baseColor.a, popupColor.a);\n gl_FragColor = defaultLighting(vec4(finalColor, finalAlpha), uResolution, uRotate, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMouse;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform float uEffectSpeed;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n#include <utils/defaultLighting>\n\n#define S(a,b,t) smoothstep(a,b,t)\n\nmat2 Rot(float a) {\n float s = sin(a);\n float c = cos(a);\n return mat2(c, -s, s, c);\n}\n\nvec2 hash(vec2 p) {\n p = vec2(dot(p, vec2(2127.1, 81.17)), dot(p, vec2(1269.5, 283.37)));\n return fract(sin(p) * 43758.5453);\n}\n\nfloat noise(in vec2 p) {\n vec2 i = floor(p);\n vec2 f = fract(p);\n vec2 u = f * f * (3.0 - 2.0 * f);\n\n float n = mix(\n mix(\n dot(-1.0 + 2.0 * hash(i + vec2(0.0, 0.0)), f - vec2(0.0, 0.0)),\n dot(-1.0 + 2.0 * hash(i + vec2(1.0, 0.0)), f - vec2(1.0, 0.0)),\n u.x\n ),\n mix(\n dot(-1.0 + 2.0 * hash(i + vec2(0.0, 1.0)), f - vec2(0.0, 1.0)),\n dot(-1.0 + 2.0 * hash(i + vec2(1.0, 1.0)), f - vec2(1.0, 1.0)),\n u.x\n ),\n u.y\n );\n\n return 0.5 + 0.5 * n;\n}\n\nvoid main() {\n vec4 baseColor = texture2D(uLayer0, vUv);\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n float effectSpeed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;\n vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);\n vec4 popupColor = texture2D(uLayer1, vUv + popupOffset);\n float popupMix = smoothstep(0.35, 1.0, popupColor.a);\n vec3 layeredColor = mix(baseColor.rgb, popupColor.rgb, popupMix);\n\n vec2 uv = vUv;\n float ratio = uResolution.x / max(uResolution.y, 1.0);\n\n vec2 tuv = uv - 0.5;\n\n float effectTime = uTime * effectSpeed;\n float degree = noise(vec2(effectTime * 0.1, tuv.x * tuv.y));\n\n tuv.y *= 1.0 / ratio;\n tuv *= Rot(radians((degree - 0.5) * 720.0 + 180.0));\n tuv.y *= ratio;\n\n float frequency = 5.0;\n float amplitude = 30.0;\n float speed = effectTime * 2.0;\n tuv.x += sin(tuv.y * frequency + speed) / amplitude;\n tuv.y += sin(tuv.x * frequency * 1.5 + speed) / (amplitude * 0.5);\n\n vec3 colorYellow = vec3(0.957, 0.804, 0.623);\n vec3 colorDeepBlue = vec3(0.192, 0.384, 0.933);\n vec3 layer1 = mix(colorYellow, colorDeepBlue, S(-0.3, 0.2, (tuv * Rot(radians(-5.0))).x));\n\n vec3 colorRed = vec3(0.910, 0.510, 0.800);\n vec3 colorBlue = vec3(0.350, 0.710, 0.953);\n vec3 layer2 = mix(colorRed, colorBlue, S(-0.3, 0.2, (tuv * Rot(radians(-5.0))).x));\n\n vec3 waveComp = mix(layer1, layer2, S(0.5, -0.3, tuv.y));\n\n float luminance = dot(layeredColor, vec3(0.299, 0.587, 0.114));\n vec3 neutralBase = mix(layeredColor, vec3(luminance), 0.12);\n vec3 finalComp = mix(neutralBase, waveComp, 0.78 * effectIntensity);\n finalComp = mix(layeredColor, finalComp, 0.18 * effectIntensity);\n\n float vignette = smoothstep(1.25, 0.15, length((uv - 0.5) * vec2(ratio, 1.0)));\n finalComp = mix(finalComp * 0.75, finalComp, vignette);\n\n gl_FragColor = defaultLighting(vec4(finalComp, max(baseColor.a, popupColor.a)), uResolution, uRotate, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision highp float;\n#endif\n\n#define DRAG_MULT 0.048\n#define ITERATIONS_RAYMARCH 13\n#define ITERATIONS_NORMAL 48\n\nuniform vec2 uResolution;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform float uEffectSpeed;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\nconst vec2 DEFAULT_VIEW = vec2(0.0, 0.0);\n\nfloat effectTime() {\n float speed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;\n return uTime * speed;\n}\n\nvec2 wavedx(vec2 position, vec2 direction, float speed, float frequency, float timeshift) {\n float x = dot(direction, position) * frequency + timeshift * speed;\n float wave = exp(sin(x) - 1.0);\n float dx = wave * cos(x);\n return vec2(wave, -dx);\n}\n\nfloat getwaves(vec2 position, int iterations) {\n float iter = 0.0;\n float phase = 6.0;\n float speed = 0.4;\n float weight = 1.0;\n float w = 0.0;\n float ws = 0.0;\n for (int i = 0; i < iterations; i++) {\n vec2 p = vec2(sin(iter), cos(iter));\n vec2 res = wavedx(position, p, speed, phase, effectTime());\n position += p * res.y * weight * DRAG_MULT;\n w += res.x * weight;\n iter += 12.0;\n ws += weight;\n weight = mix(weight, 0.0, 0.2);\n phase *= 1.18;\n speed *= 1.07;\n }\n return w / ws;\n}\n\nfloat raymarchwater(vec3 camera, vec3 start, vec3 end, float depth) {\n vec3 pos = start;\n float h = 0.0;\n vec3 dir = normalize(end - start);\n float eps = 0.01;\n for (int i = 0; i < 318; i++) {\n h = getwaves(pos.xz * 0.1, ITERATIONS_RAYMARCH) * depth - depth;\n float dist_pos = distance(pos, camera);\n if (h + eps * dist_pos > pos.y) {\n return dist_pos;\n }\n pos += dir * (pos.y - h);\n }\n return -1.0;\n}\n\nvec3 normal(vec2 pos, float e, float depth) {\n vec2 ex = vec2(e, 0.0);\n float h = getwaves(pos * 0.1, ITERATIONS_NORMAL) * depth - depth;\n float hx = getwaves((pos + ex.xy) * 0.1, ITERATIONS_NORMAL) * depth - depth;\n float hy = getwaves((pos + ex.yx) * 0.1, ITERATIONS_NORMAL) * depth - depth;\n vec3 a = vec3(pos.x, h, pos.y);\n vec3 b = vec3(pos.x + e, hx, pos.y);\n vec3 c = vec3(pos.x, hy, pos.y + e);\n return normalize(cross(b - a, c - a));\n}\n\nmat3 rotmat(vec3 axis, float angle) {\n axis = normalize(axis);\n float s = sin(angle);\n float c = cos(angle);\n float oc = 1.0 - c;\n return mat3(\n oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s,\n oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s,\n oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c\n );\n}\n\nvec3 getRay(vec2 uv) {\n uv = (uv * 2.0 - 1.0) * vec2(uResolution.x / uResolution.y, 1.0);\n vec3 proj = normalize(vec3(uv.x, uv.y, 1.0) + vec3(uv.x, uv.y, -1.0) * pow(length(uv), 2.0) * 0.05);\n vec3 ray = rotmat(vec3(0.0, -1.0, 0.0), 3.0 * (DEFAULT_VIEW.x * 2.0 - 1.0) + uRotate.x * 0.06) *\n rotmat(vec3(1.0, 0.0, 0.0), 1.5 * (DEFAULT_VIEW.y * 2.0 - 1.0) + uRotate.y * 0.04) *\n proj;\n return ray;\n}\n\nfloat intersectPlane(vec3 origin, vec3 direction, vec3 point, vec3 normal) {\n return clamp(dot(point - origin, normal) / dot(direction, normal), -1.0, 9991999.0);\n}\n\nvec3 extra_cheap_atmosphere(vec3 raydir, vec3 sundir) {\n sundir.y = max(sundir.y, -0.07);\n float special_trick = 1.0 / (raydir.y * 1.0 + 0.1);\n float special_trick2 = 1.0 / (sundir.y * 11.0 + 1.0);\n float raysundt = pow(abs(dot(sundir, raydir)), 2.0);\n float sundt = pow(max(0.0, dot(sundir, raydir)), 8.0);\n float mymie = sundt * special_trick * 0.2;\n vec3 suncolor = mix(vec3(1.0), max(vec3(0.0), vec3(1.0) - vec3(5.5, 13.0, 22.4) / 22.4), special_trick2);\n vec3 bluesky = vec3(5.5, 13.0, 22.4) / 22.4 * suncolor;\n vec3 bluesky2 = max(vec3(0.0), bluesky - vec3(5.5, 13.0, 22.4) * 0.002 * (special_trick + -6.0 * sundir.y * sundir.y));\n bluesky2 *= special_trick * (0.24 + raysundt * 0.24);\n return bluesky2 * (1.0 + 1.0 * pow(1.0 - raydir.y, 3.0)) + mymie * suncolor;\n}\n\nvec3 getatm(vec3 ray) {\n return extra_cheap_atmosphere(ray, normalize(vec3(1.0))) * 0.5;\n}\n\nfloat sun(vec3 ray) {\n vec3 sd = normalize(vec3(1.0));\n return pow(max(0.0, dot(ray, sd)), 528.0) * 110.0;\n}\n\nvec3 aces_tonemap(vec3 color) {\n mat3 m1 = mat3(\n 0.59719, 0.07600, 0.02840,\n 0.35458, 0.90834, 0.13383,\n 0.04823, 0.01566, 0.83777\n );\n mat3 m2 = mat3(\n 1.60475, -0.10208, -0.00327,\n -0.53108, 1.10813, -0.07276,\n -0.07367, -0.00605, 1.07602\n );\n vec3 v = m1 * color;\n vec3 a = v * (v + 0.0245786) - 0.000090537;\n vec3 b = v * (0.983729 * v + 0.4329510) + 0.238081;\n return pow(clamp(m2 * (a / b), 0.0, 1.0), vec3(1.0 / 2.2));\n}\n\nvoid main() {\n vec2 uv = vUv;\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n float waterdepth = 2.1;\n vec3 wfloor = vec3(0.0, -waterdepth, 0.0);\n vec3 wceil = vec3(0.0, 0.0, 0.0);\n // vec3 orig = vec3(uMove.x * 0.12, 2.0 + uMove.y * 0.08, 0.0);\n vec3 orig = vec3(0.0, 2.0, 0.0);\n vec3 ray = getRay(uv);\n\n vec4 baseColor = texture2D(uLayer0, uv);\n // vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);\n vec2 popupOffset = vec2(0.0, 0.0);\n vec4 popupColor = texture2D(uLayer1, uv + popupOffset);\n float popupMix = smoothstep(0.35, 1.0, popupColor.a);\n vec3 layeredColor = mix(baseColor.rgb, popupColor.rgb, popupMix);\n vec3 tint = mix(layeredColor, vec3(dot(layeredColor, vec3(0.299, 0.587, 0.114))), 0.15);\n\n float hihit = intersectPlane(orig, ray, wceil, vec3(0.0, 1.0, 0.0));\n if (ray.y >= -0.01) {\n vec3 C = getatm(ray) * 2.0 + sun(ray);\n C = aces_tonemap(C);\n C = mix(C, tint, 0.38 * effectIntensity); // sky tint\n gl_FragColor = vec4(C, 1.0);\n return;\n }\n\n float lohit = intersectPlane(orig, ray, wfloor, vec3(0.0, 1.0, 0.0));\n vec3 hipos = orig + ray * hihit;\n vec3 lopos = orig + ray * lohit;\n float dist = raymarchwater(orig, hipos, lopos, waterdepth);\n vec3 pos = orig + ray * dist;\n\n vec3 N = normal(pos.xz, 0.001, waterdepth);\n vec2 velocity = N.xz * (1.0 - N.y);\n N = mix(vec3(0.0, 1.0, 0.0), N, 1.0 / (dist * dist * 0.01 + 1.0));\n vec3 R = reflect(ray, N);\n float fresnel = 0.04 + (1.0 - 0.04) * pow(1.0 - max(0.0, dot(-N, ray)), 5.0);\n\n vec3 C = fresnel * getatm(R) * 2.0 + fresnel * sun(R);\n C = mix(C, tint, 0.32 * effectIntensity); // water tint\n C += vec3(velocity.xyx) * 0.01;\n C = aces_tonemap(C);\n C = mix(C, layeredColor, 0.75 * effectIntensity); // final color mix\n\n gl_FragColor = vec4(C, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform float uEffectSpeed;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n#include <utils/defaultLighting>\n\nvec3 hsv2rgb(vec3 c) {\n vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n}\n\nvoid main() {\n vec4 baseColor = texture2D(uLayer0, vUv);\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n float effectSpeed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;\n vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);\n vec4 popupColor = texture2D(uLayer1, vUv + popupOffset);\n\n float popupMix = smoothstep(0.35, 1.0, popupColor.a);\n vec3 layeredColor = mix(baseColor.rgb, popupColor.rgb, popupMix);\n\n vec2 uv = vUv;\n float ratio = uResolution.x / max(uResolution.y, 1.0);\n vec2 centered = (uv - 0.5) * vec2(ratio, 1.0);\n\n float effectTime = uTime * effectSpeed;\n float hue = fract((uv.x + uv.y) * 0.25 + effectTime * 0.5);\n vec3 rainbow = hsv2rgb(vec3(hue, 0.6, 1.0));\n\n float flow = 0.5 + 0.5 * sin((centered.x + centered.y) * 7.0 + effectTime * 1.8);\n float stripe = 0.5 + 0.5 * sin((centered.x - centered.y) * 11.0 - effectTime * 1.2);\n float mask = smoothstep(0.15, 0.95, 0.35 * flow + 0.65 * stripe);\n float vignette = smoothstep(1.2, 0.15, length(centered));\n\n vec3 tint = mix(layeredColor, layeredColor * rainbow, 0.22);\n vec3 finalColor = mix(layeredColor, tint, mask * 0.65 * effectIntensity);\n finalColor = mix(finalColor * 0.85, finalColor, vignette);\n\n gl_FragColor = defaultLighting(vec4(finalColor, max(baseColor.a, popupColor.a)), uResolution, uRotate, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform float uEffectSpeed;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n#include <utils/defaultLighting>\n\n#define CENTER vec2(0.5, 0.5)\n#define PI 3.1415926\n\n#define force 0.04\n#define thickness 0.075\n#define feathering 0.05\n#define aberrationOffset 0.006\n#define flashIntensity 3.0\n#define waveSpeed 0.42\n\nvec2 centerScaleUV(vec2 uv, vec2 factor) {\n return (uv - vec2(0.5)) * factor + vec2(0.5);\n}\n\nfloat easeOutSine(float t) {\n return sin((t * PI) / 2.0);\n}\n\nvoid main() {\n vec4 baseColor = texture2D(uLayer0, vUv);\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n float effectSpeed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;\n vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);\n vec4 popupColor = texture2D(uLayer1, vUv + popupOffset);\n float popupMix = smoothstep(0.35, 1.0, popupColor.a);\n vec3 layeredColor = mix(baseColor.rgb, popupColor.rgb, popupMix);\n\n vec2 screenUV = vUv;\n float pos = easeOutSine(fract(uTime * waveSpeed * effectSpeed));\n\n float aspectRatio = uResolution.x / max(uResolution.y, 1.0);\n vec2 scalingFactor = vec2(aspectRatio, 1.0);\n scalingFactor *= 2.0;\n scalingFactor *= 1.0 - thickness - feathering;\n scalingFactor /= sqrt(pow(aspectRatio, 2.0) + 1.0);\n\n vec2 scaledUV = centerScaleUV(screenUV, scalingFactor);\n vec2 displacement = normalize(scaledUV - CENTER + vec2(1e-5)) * force * effectIntensity;\n float distanceFromCenter = distance(scaledUV, CENTER);\n\n float innerBound = smoothstep(\n pos - thickness - feathering,\n pos - thickness,\n distanceFromCenter\n );\n float outerBound = smoothstep(\n pos - feathering,\n pos,\n distanceFromCenter\n );\n float shapeMask = innerBound - outerBound;\n\n vec2 coords = vUv;\n\n vec2 texelOffset = displacement * shapeMask;\n vec2 chromaOffset = texelOffset * 0.5;\n\n vec3 background;\n background.r = texture2D(uLayer0, clamp(coords - (texelOffset - aberrationOffset * chromaOffset), vec2(0.0), vec2(1.0))).r;\n background.g = texture2D(uLayer0, clamp(coords - texelOffset, vec2(0.0), vec2(1.0))).g;\n background.b = texture2D(uLayer0, clamp(coords - (texelOffset + aberrationOffset * chromaOffset), vec2(0.0), vec2(1.0))).b;\n\n float flashOpacity = pow(1.0 - pos, 4.0);\n float flashMask = 1.0 - innerBound;\n background += flashIntensity * background * flashMask * flashOpacity * 0.12 * effectIntensity;\n\n vec3 finalColor = mix(background, layeredColor, 0.35);\n finalColor = mix(finalColor, layeredColor, popupMix * 0.25);\n\n gl_FragColor = defaultLighting(vec4(finalColor, max(baseColor.a, popupColor.a)), uResolution, uRotate, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform float uEffectSpeed;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n#include <utils/defaultLighting>\n\nconst vec2 CENTER = vec2(0.5, 0.5);\nconst float EffectDuration = 2.0;\nconst float EffectFadeInTimeFactor = 0.5;\nconst float EffectWidth = 0.8;\nconst float EffectMaxTexelOffset = 0.01;\n\nvec2 getOffsetFromCenter(vec2 screenCoords, vec2 screenSize) {\n vec2 halfScreenSize = screenSize / 2.0;\n return (screenCoords - halfScreenSize) / min(halfScreenSize.x, halfScreenSize.y);\n}\n\nvec2 getDistortion(vec2 offsetDirection, float offsetDistance, float time) {\n float progress = mod(time, EffectDuration) / EffectDuration;\n\n float halfWidth = EffectWidth / 2.0;\n float lower = 1.0 - smoothstep(progress - halfWidth, progress, offsetDistance);\n float upper = smoothstep(progress, progress + halfWidth, offsetDistance);\n float band = 1.0 - (upper + lower);\n\n float strength = 1.0 - progress;\n float fadeStrength = smoothstep(0.0, EffectFadeInTimeFactor, progress);\n float distortion = band * strength * fadeStrength;\n\n return distortion * offsetDirection * EffectMaxTexelOffset;\n}\n\nvoid main() {\n vec4 baseColor = texture2D(uLayer0, vUv);\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n float effectSpeed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;\n vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);\n vec4 popupColor = texture2D(uLayer1, vUv + popupOffset);\n float popupMix = smoothstep(0.35, 1.0, popupColor.a);\n vec3 layeredColor = mix(baseColor.rgb, popupColor.rgb, popupMix);\n\n vec2 screenSize = max(uResolution, vec2(1.0));\n vec2 screenCoords = vUv * screenSize;\n vec2 offsetFromCenter = getOffsetFromCenter(screenCoords, screenSize);\n offsetFromCenter += uMove * 0.12 + uRotate * 0.04;\n\n float offsetDistance = length(offsetFromCenter);\n vec2 offsetDirection = normalize(-offsetFromCenter + vec2(1e-5));\n float effectTime = uTime * effectSpeed;\n vec2 offset = getDistortion(offsetDirection, offsetDistance, effectTime * 1.2);\n offset *= effectIntensity;\n\n vec2 warpedUv = clamp(vUv + offset, vec2(0.0), vec2(1.0));\n vec3 rippleColor = texture2D(uLayer0, warpedUv).rgb;\n\n float dist = length((vUv - CENTER) * vec2(screenSize.x / screenSize.y, 1.0));\n float ring = 1.0 - smoothstep(0.0, 0.55, abs(fract(effectTime * 0.8 - dist * 2.5) - 0.5));\n float rippleMix = smoothstep(0.15, 0.9, ring);\n\n vec3 finalColor = mix(layeredColor, rippleColor, rippleMix * 0.8 * effectIntensity);\n finalColor = mix(finalColor, layeredColor, 0.45);\n finalColor += layeredColor * rippleMix * 0.05;\n\n gl_FragColor = defaultLighting(vec4(finalColor, max(baseColor.a, popupColor.a)), uResolution, uRotate, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\nuniform float uEffectIntensity;\nuniform float uEffectThreshold;\n\nvarying vec2 vUv;\n\n#include <utils/defaultLighting>\n\nvoid main() {\n vec4 baseColor = texture2D(uLayer0, vUv);\n vec4 topColor = texture2D(uLayer1, vUv);\n\n float intensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.8;\n float threshold = uEffectThreshold > 0.0 ? uEffectThreshold : 0.5;\n float tilt = clamp(abs(uRotate.x) * intensity, 0.0, 1.0);\n float blend = smoothstep(0.0, threshold, tilt);\n float baseWeight = 1.0 - blend;\n float topWeight = blend;\n\n vec3 finalColor = baseColor.rgb * baseWeight + topColor.rgb * topWeight;\n float alpha = baseColor.a * baseWeight + topColor.a * topWeight;\n\n gl_FragColor = defaultLighting(vec4(finalColor, alpha), uResolution, uRotate, 1.0);\n}\n`\n","export interface SpringOpts {\n stiffness?: number\n damping?: number\n precision?: number\n}\n\nexport interface SpringUpdateOpts {\n hard?: boolean\n soft?: number | boolean\n}\n\nexport interface Spring<T> {\n set(value: T, opts?: SpringUpdateOpts): Promise<void>\n get(): T\n stiffness: number\n damping: number\n precision: number\n}\n\n// Global animation loop shared across all springs\nconst tasks: Set<() => boolean> = new Set()\nlet rafId: number | null = null\n\nfunction runLoop() {\n if (tasks.size === 0) {\n rafId = null\n return\n }\n for (const task of tasks) {\n if (!task()) {\n tasks.delete(task)\n }\n }\n rafId = requestAnimationFrame(runLoop)\n}\n\nfunction scheduleTask(task: () => boolean) {\n tasks.add(task)\n if (rafId === null) {\n rafId = requestAnimationFrame(runLoop)\n }\n}\n\nfunction tickSpring(\n ctx: { val: number; lastVal: number; target: number; invMass: number },\n stiffness: number,\n damping: number,\n precision: number,\n): boolean {\n const delta = ctx.target - ctx.val\n const velocity = ctx.val - ctx.lastVal\n const springForce = stiffness * delta\n const damperForce = damping * velocity\n const acceleration = (springForce - damperForce) * ctx.invMass\n const d = velocity + acceleration\n\n if (Math.abs(d) < precision && Math.abs(delta) < precision) {\n ctx.val = ctx.target\n ctx.lastVal = ctx.target\n return false // settled\n }\n\n ctx.lastVal = ctx.val\n ctx.val += d\n return true // still moving\n}\n\nexport function spring(\n initialValue: number,\n onChange: (value: number) => void,\n opts: SpringOpts = {},\n): Spring<number> {\n const stiffness = opts.stiffness ?? 0.15\n const damping = opts.damping ?? 0.8\n const precision = opts.precision ?? 0.01\n\n const ctx = {\n val: initialValue,\n lastVal: initialValue,\n target: initialValue,\n invMass: 1,\n }\n let currentResolve: (() => void) | null = null\n let currentTask: (() => boolean) | null = null\n\n const s: Spring<number> = {\n stiffness,\n damping,\n precision,\n get() {\n return ctx.val\n },\n set(value: number, updateOpts?: SpringUpdateOpts) {\n ctx.target = value\n\n // Remove previous task to prevent duplicate ticking\n if (currentTask) {\n tasks.delete(currentTask)\n currentTask = null\n }\n\n if (updateOpts?.hard) {\n ctx.val = value\n ctx.lastVal = value\n onChange(value)\n currentResolve?.()\n currentResolve = null\n return Promise.resolve()\n }\n\n if (updateOpts?.soft) {\n const rate = typeof updateOpts.soft === 'number' ? updateOpts.soft : 0.5\n ctx.invMass = Math.min(ctx.invMass, rate)\n }\n\n return new Promise<void>((resolve) => {\n currentResolve = resolve\n const task = () => {\n const invMassTarget = 1\n ctx.invMass = Math.min(ctx.invMass + 0.02, invMassTarget)\n\n const moving = tickSpring(ctx, s.stiffness, s.damping, s.precision)\n onChange(ctx.val)\n\n if (!moving) {\n currentResolve?.()\n currentResolve = null\n currentTask = null\n }\n return moving\n }\n currentTask = task\n scheduleTask(task)\n })\n },\n }\n\n return s\n}\n\n// Convenience: spring for {x, y} objects\n// Uses batched onChange — ticks all components per frame, calls onChange once\nexport function springVec2(\n initial: { x: number; y: number },\n onChange: (value: { x: number; y: number }) => void,\n opts: SpringOpts = {},\n): Spring<{ x: number; y: number }> {\n const state = { x: initial.x, y: initial.y }\n let dirty = false\n\n const flush = () => {\n if (dirty) {\n dirty = false\n onChange({ ...state })\n }\n }\n\n const sx = spring(initial.x, (v) => {\n state.x = v\n dirty = true\n // Use microtask to batch x+y updates within the same frame\n queueMicrotask(flush)\n }, opts)\n\n const sy = spring(initial.y, (v) => {\n state.y = v\n dirty = true\n queueMicrotask(flush)\n }, opts)\n\n return {\n get stiffness() { return sx.stiffness },\n set stiffness(v) { sx.stiffness = v; sy.stiffness = v },\n get damping() { return sx.damping },\n set damping(v) { sx.damping = v; sy.damping = v },\n get precision() { return sx.precision },\n set precision(v) { sx.precision = v; sy.precision = v },\n get() {\n return { x: sx.get(), y: sy.get() }\n },\n async set(value, updateOpts) {\n await Promise.all([\n sx.set(value.x, updateOpts),\n sy.set(value.y, updateOpts),\n ])\n },\n }\n}\n\n// Convenience: spring for {x, y, o} (glare)\nexport function springVec3(\n initial: { x: number; y: number; o: number },\n onChange: (value: { x: number; y: number; o: number }) => void,\n opts: SpringOpts = {},\n): Spring<{ x: number; y: number; o: number }> {\n const state = { x: initial.x, y: initial.y, o: initial.o }\n let dirty = false\n\n const flush = () => {\n if (dirty) {\n dirty = false\n onChange({ ...state })\n }\n }\n\n const sx = spring(initial.x, (v) => {\n state.x = v\n dirty = true\n queueMicrotask(flush)\n }, opts)\n\n const sy = spring(initial.y, (v) => {\n state.y = v\n dirty = true\n queueMicrotask(flush)\n }, opts)\n\n const so = spring(initial.o, (v) => {\n state.o = v\n dirty = true\n queueMicrotask(flush)\n }, opts)\n\n return {\n get stiffness() { return sx.stiffness },\n set stiffness(v) { sx.stiffness = v; sy.stiffness = v; so.stiffness = v },\n get damping() { return sx.damping },\n set damping(v) { sx.damping = v; sy.damping = v; so.damping = v },\n get precision() { return sx.precision },\n set precision(v) { sx.precision = v; sy.precision = v; so.precision = v },\n get() {\n return { x: sx.get(), y: sy.get(), o: so.get() }\n },\n async set(value, updateOpts) {\n await Promise.all([\n sx.set(value.x, updateOpts),\n sy.set(value.y, updateOpts),\n so.set(value.o, updateOpts),\n ])\n },\n }\n}\n","export const round = (value: number, precision = 3): number =>\n parseFloat(value.toFixed(precision))\n\nexport const clamp = (value: number, min = 0, max = 100): number =>\n Math.min(Math.max(value, min), max)\n\nexport const adjust = (\n value: number,\n fromMin: number,\n fromMax: number,\n toMin: number,\n toMax: number,\n): number =>\n round(toMin + ((toMax - toMin) * (value - fromMin)) / (fromMax - fromMin))\n\nexport const distance = (x1: number, y1: number, x2: number, y2: number): number =>\n Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)\n","import { springVec2, springVec3, type Spring } from '../animation/spring';\nimport { clamp, distance, round } from '../utils/math';\n\nexport interface InteractionCallbacks {\n onRotate: (rotate: { x: number; y: number }) => void\n onGlare: (glare: { x: number; y: number; o: number }) => void\n onMousePos: (pos: { x: number; y: number }) => void\n onMoveDelta: (delta: { x: number; y: number }) => void\n onDistFromCenter: (dist: number) => void\n onFlip: (flipped: boolean) => void\n}\n\nexport interface InteractionOptions {\n interactive?: boolean\n preventTouchScroll?: boolean\n}\n\ninterface Rect {\n left: number\n top: number\n width: number\n height: number\n}\n\nconst SPRING_INTERACT = { stiffness: 0.095, damping: 0.5 }\nconst SPRING_FLIP = { stiffness: 0.03, damping: 0.25 }\nconst THROTTLE_MS = 1000 / 60\nconst DBLCLICK_MS = 200\n\nexport class InteractionHandler {\n private flipped = false\n private interacting = false\n private boundingRect: Rect = { left: 0, top: 0, width: 0, height: 0 }\n private interactionOrigin = { x: 0, y: 0 }\n\n private springRotate: Spring<{ x: number; y: number }>\n private springGlare: Spring<{ x: number; y: number; o: number }>\n\n private lastThrottleTime = 0\n private clickCount = 0\n private dblClickTimer: ReturnType<typeof setTimeout> | null = null\n private activePointerId: number | null = null\n\n private boundPointerDown: (e: PointerEvent) => void\n private boundPointerMove: (e: PointerEvent) => void\n private boundPointerUp: (e: PointerEvent) => void\n private boundClick: (e: MouseEvent) => void\n private boundTouchHandler: (e: TouchEvent) => void\n\n private _flipSpeed = 1\n private _flipId = 0\n\n constructor(\n private container: HTMLElement,\n private callbacks: InteractionCallbacks,\n private flippable: boolean,\n initialFlipped: boolean,\n private options: InteractionOptions = {},\n ) {\n this.flipped = initialFlipped\n\n // Spring rotate onChange: apply flip-aware sign to CSS rotation\n // Angular: { x: flipped ? 180 - v.x : -v.x, y: flipped ? -v.y : v.y }\n this.springRotate = springVec2({ x: 0, y: 0 }, (v) => {\n callbacks.onRotate(v)\n callbacks.onDistFromCenter(clamp(distance(v.x, v.y, 0, 0) / 50, 0, 1))\n }, SPRING_INTERACT)\n\n this.springGlare = springVec3({ x: 50, y: 50, o: 0 }, (v) => {\n callbacks.onGlare(v)\n }, SPRING_INTERACT)\n\n this.boundPointerDown = this.onPointerDown.bind(this)\n this.boundPointerMove = this.onPointerMove.bind(this)\n this.boundPointerUp = this.onPointerUp.bind(this)\n this.boundClick = this.onClick.bind(this)\n this.boundTouchHandler = (e: TouchEvent) => {\n e.preventDefault()\n e.stopPropagation()\n }\n\n if (this.options.interactive ?? true) {\n this.container.addEventListener('pointerdown', this.boundPointerDown)\n this.container.addEventListener('pointermove', this.boundPointerMove)\n this.container.addEventListener('pointerup', this.boundPointerUp)\n this.container.addEventListener('pointercancel', this.boundPointerUp)\n this.container.addEventListener('click', this.boundClick)\n }\n\n if (this.options.preventTouchScroll) {\n this.container.addEventListener('touchstart', this.boundTouchHandler, { passive: false })\n this.container.addEventListener('touchmove', this.boundTouchHandler, { passive: false })\n }\n }\n\n updateRect(rect: Rect): void {\n this.boundingRect = rect\n }\n\n private onPointerDown(e: PointerEvent): void {\n e.preventDefault()\n e.stopPropagation()\n this.interacting = true\n this.activePointerId = e.pointerId\n this.container.setPointerCapture(e.pointerId)\n\n const rect = this.container.getBoundingClientRect()\n this.boundingRect = { left: rect.left, top: rect.top, width: rect.width, height: rect.height }\n this.interactionOrigin = { x: e.clientX, y: e.clientY }\n this.doInteract(e.clientX, e.clientY)\n }\n\n private onPointerMove(e: PointerEvent): void {\n if (!this.interacting) return\n const now = performance.now()\n if (now - this.lastThrottleTime < THROTTLE_MS) return\n this.lastThrottleTime = now\n this.doInteract(e.clientX, e.clientY)\n }\n\n private onPointerUp(_e: PointerEvent): void {\n if (!this.interacting) return\n this.interacting = false\n if (this.activePointerId !== null) {\n try { this.container.releasePointerCapture(this.activePointerId) } catch {}\n this.activePointerId = null\n }\n this.endInteract()\n }\n\n private onClick(_e: MouseEvent): void {\n if (!this.flippable) return\n this.clickCount++\n if (this.dblClickTimer) clearTimeout(this.dblClickTimer)\n this.dblClickTimer = setTimeout(() => {\n if (this.clickCount >= 2) {\n this.flip()\n }\n this.clickCount = 0\n }, DBLCLICK_MS)\n }\n\n /**\n * Core interaction math — faithfully ported from Angular move.service.ts doInteract()\n */\n private doInteract(clientX: number, clientY: number): void {\n const rect = this.boundingRect\n if (rect.width === 0 || rect.height === 0) return\n\n const deltaX = clientX - this.interactionOrigin.x\n const deltaY = clientY - this.interactionOrigin.y\n\n // touchPosFromLT: absolute position within card (for glare)\n const touchPosFromLT = {\n x: clientX - rect.left,\n y: clientY - rect.top,\n }\n const touchPercentFromLT = {\n x: clamp(round((100 / rect.width) * touchPosFromLT.x)),\n y: clamp(round((100 / rect.height) * touchPosFromLT.y)),\n }\n\n // touchPosFromCenter: delta-based center offset (for rotation)\n const touchPosFromCenter = {\n x: rect.width / 2 + deltaX,\n y: rect.height / 2 + deltaY,\n }\n const touchPercentFromCenter = {\n x: clamp(round((100 / rect.width) * touchPosFromCenter.x)),\n y: clamp(round((100 / rect.height) * touchPosFromCenter.y)),\n }\n const touchPercentBasedCenter = {\n x: touchPercentFromCenter.x - 50,\n y: touchPercentFromCenter.y - 50,\n }\n\n // moveDelta: raw pixel delta (no DPR)\n this.callbacks.onMoveDelta({ x: deltaX, y: deltaY })\n\n // mousePos: absolute position in card, DPR-scaled, Y-flipped for WebGL\n const dpr = window.devicePixelRatio || 1\n this.callbacks.onMousePos({\n x: (clientX - rect.left) * dpr,\n y: (rect.height - (clientY - rect.top)) * dpr,\n })\n\n // Rotation: basedCenter / divisor\n const rotate = {\n x: round(touchPercentBasedCenter.x / 3.5),\n y: round(touchPercentBasedCenter.y / 2),\n }\n\n // Glare: absolute percentage from left-top\n const glare = {\n x: round(touchPercentFromLT.x),\n y: round(touchPercentFromLT.y),\n o: 1 as number,\n }\n\n this.updateSprings(glare, rotate)\n }\n\n /**\n * Apply spring targets with flip-aware rotation sign.\n * Angular: { x: flipped ? 180 - rotate.x : -rotate.x, y: flipped ? -rotate.y : rotate.y }\n */\n private updateSprings(\n glare: { x: number; y: number; o: number },\n rotate: { x: number; y: number },\n ): void {\n this.springGlare.stiffness = SPRING_INTERACT.stiffness\n this.springGlare.damping = SPRING_INTERACT.damping\n this.springGlare.set(glare)\n\n this.springRotate.stiffness = SPRING_INTERACT.stiffness\n this.springRotate.damping = SPRING_INTERACT.damping\n this.springRotate.set({\n x: this.flipped ? 180 - rotate.x : -rotate.x,\n y: this.flipped ? -rotate.y : rotate.y,\n })\n }\n\n private endInteract(): void {\n this.springRotate.set({ x: this.flipped ? 180 : 0, y: 0 })\n this.springGlare.set({ x: 50, y: 50, o: 0 })\n this.callbacks.onMoveDelta({ x: 0, y: 0 })\n\n const rect = this.boundingRect\n const dpr = window.devicePixelRatio || 1\n this.callbacks.onMousePos({\n x: (rect.width / 2) * dpr,\n y: (rect.height / 2) * dpr,\n })\n }\n\n set flipSpeed(speed: number) {\n this._flipSpeed = speed\n }\n\n flip(flipped?: boolean): boolean {\n this.flipped = flipped ?? !this.flipped\n const targetX = this.flipped ? 180 : 0\n\n // Snapshot current position and kill velocity\n const current = this.springRotate.get()\n this.springRotate.set({ x: current.x, y: current.y }, { hard: true })\n\n // Invalidate any previous flip's completion callback\n const flipId = ++this._flipId\n\n this.springRotate.stiffness = SPRING_FLIP.stiffness * this._flipSpeed\n this.springRotate.damping = SPRING_FLIP.damping\n this.springRotate.set({ x: targetX, y: 0 }).then(() => {\n // Only restore interact spring if this is still the latest flip\n if (this._flipId === flipId) {\n this.springRotate.stiffness = SPRING_INTERACT.stiffness\n this.springRotate.damping = SPRING_INTERACT.damping\n }\n })\n\n this.callbacks.onFlip(this.flipped)\n return this.flipped\n }\n\n /**\n * Wiggle support: start a synthetic interaction.\n * Matches Angular: startInteraction(0, 0, false)\n * Sets origin at (0,0) so wiggle coordinates become deltas directly.\n */\n startSyntheticInteraction(): void {\n const rect = this.container.getBoundingClientRect()\n this.boundingRect = { left: rect.left, top: rect.top, width: rect.width, height: rect.height }\n this.interactionOrigin = { x: 0, y: 0 }\n }\n\n /**\n * Feed raw clientX/Y directly to doInteract.\n * Used by wiggle where coordinates come from DefaultWiggler(0,0,100).\n */\n simulateInteractRaw(clientX: number, clientY: number): void {\n this.doInteract(clientX, clientY)\n }\n\n simulateEndInteract(): void {\n this.endInteract()\n }\n\n isInteracting(): boolean {\n return this.interacting\n }\n\n isFlipped(): boolean {\n return this.flipped\n }\n\n destroy(): void {\n if (this.activePointerId !== null) {\n try { this.container.releasePointerCapture(this.activePointerId) } catch {}\n }\n this.container.removeEventListener('pointerdown', this.boundPointerDown)\n this.container.removeEventListener('pointermove', this.boundPointerMove)\n this.container.removeEventListener('pointerup', this.boundPointerUp)\n this.container.removeEventListener('pointercancel', this.boundPointerUp)\n this.container.removeEventListener('click', this.boundClick)\n this.container.removeEventListener('touchstart', this.boundTouchHandler)\n this.container.removeEventListener('touchmove', this.boundTouchHandler)\n if (this.dblClickTimer) clearTimeout(this.dblClickTimer)\n }\n}\n","export type EasingFn = (t: number) => number\n\nexport const easeOut: EasingFn = (t) => 1 - (1 - t) ** 3\nexport const easeInOut: EasingFn = (t) =>\n t < 0.5 ? 4 * t * t * t : 1 - (-2 * t + 2) ** 3 / 2\nexport const easeIn: EasingFn = (t) => t * t * t\n\nexport interface TweenOpts {\n from: number\n to: number\n duration: number\n easing: EasingFn\n onUpdate: (value: number) => void\n}\n\nexport function tween(opts: TweenOpts): Promise<void> & { cancel: () => void } {\n let cancelled = false\n let rafId: number | null = null\n\n const promise = new Promise<void>((resolve) => {\n const start = performance.now()\n const range = opts.to - opts.from\n\n function tick(now: number) {\n if (cancelled) { resolve(); return }\n const elapsed = now - start\n const t = Math.min(elapsed / opts.duration, 1)\n const value = opts.from + range * opts.easing(t)\n opts.onUpdate(value)\n\n if (t < 1) {\n rafId = requestAnimationFrame(tick)\n } else {\n resolve()\n }\n }\n rafId = requestAnimationFrame(tick)\n })\n\n return Object.assign(promise, {\n cancel() {\n cancelled = true\n if (rafId !== null) cancelAnimationFrame(rafId)\n },\n })\n}\n","import { tween, easeOut, easeInOut, easeIn } from './tween'\n\nexport interface WiggleController {\n stop(): void\n}\n\nexport function wiggle(\n cx: number,\n cy: number,\n radius: number,\n onUpdate: (pos: { x: number; y: number }, done: boolean) => void,\n): WiggleController {\n let stopped = false\n const cancellers: (() => void)[] = []\n\n async function run() {\n let currentRadius = 0\n let theta = 0\n\n // Phase 1: Expand (0.5s)\n const expand = tween({\n from: 0, to: radius,\n duration: 500, easing: easeOut,\n onUpdate: (r) => {\n if (stopped) return\n currentRadius = r\n onUpdate({ x: cx + r, y: cy }, false)\n },\n })\n cancellers.push(expand.cancel)\n await expand\n if (stopped) return\n\n // Phase 2: Rotate (0.5s, 0 → π)\n const rotate = tween({\n from: 0, to: Math.PI,\n duration: 500, easing: easeInOut,\n onUpdate: (t) => {\n if (stopped) return\n theta = t\n onUpdate({\n x: cx + currentRadius * Math.cos(theta),\n y: cy + currentRadius * Math.sin(theta),\n }, false)\n },\n })\n cancellers.push(rotate.cancel)\n await rotate\n if (stopped) return\n\n // Phase 3: Shrink (0.3s)\n const shrink = tween({\n from: currentRadius, to: 0,\n duration: 300, easing: easeIn,\n onUpdate: (r) => {\n if (stopped) return\n currentRadius = r\n onUpdate({ x: cx + r * Math.cos(theta), y: cy }, false)\n },\n })\n cancellers.push(shrink.cancel)\n await shrink\n\n if (!stopped) {\n onUpdate({ x: cx, y: cy }, true)\n }\n }\n\n run()\n\n return {\n stop() {\n stopped = true\n cancellers.forEach((c) => c())\n },\n }\n}\n","import { EventEmitter } from './event-emitter'\nimport { Renderer, type RendererOptions } from './renderer'\nimport { InteractionHandler } from './interaction'\nimport { wiggle, type WiggleController } from './animation/wiggle'\nimport type { FaceOptions } from './types'\n\nexport interface PocaCardOptions {\n front: FaceOptions\n back?: FaceOptions\n flippable?: boolean\n initialFlipped?: boolean\n flipSpeed?: number\n interactive?: boolean\n preventTouchScroll?: boolean\n}\n\nexport class PocaCard extends EventEmitter {\n private renderer: Renderer\n private interaction: InteractionHandler\n private wiggleController: WiggleController | null = null\n\n constructor(container: HTMLElement, options: PocaCardOptions) {\n super()\n\n this.renderer = new Renderer(\n container,\n {\n front: options.front,\n back: options.back,\n preventTouchScroll: options.preventTouchScroll,\n },\n (error) => this.emit('error', error),\n () => this.emit('ready'),\n () => this.emit('firstFrame'),\n )\n\n this.interaction = new InteractionHandler(\n this.renderer.getRotatorEl(),\n {\n onRotate: (rotate) => this.renderer.updateUniforms({ rotate }),\n onGlare: () => {},\n onMousePos: (pos) => this.renderer.updateUniforms({ mouse: pos }),\n onMoveDelta: (delta) => this.renderer.updateUniforms({ move: delta }),\n onDistFromCenter: (_dist) => {},\n onFlip: (flipped) => {\n this.emit('flip', flipped)\n },\n },\n options.flippable ?? false,\n options.initialFlipped ?? false,\n {\n interactive: options.interactive,\n preventTouchScroll: options.preventTouchScroll,\n },\n )\n\n // Cancel wiggle when user starts interacting\n if (options.interactive ?? true) {\n this.renderer.getRotatorEl().addEventListener('pointerdown', () => {\n if (this.wiggleController) {\n this.wiggleController.stop()\n this.wiggleController = null\n }\n })\n }\n\n if (options.flipSpeed != null) {\n this.interaction.flipSpeed = options.flipSpeed\n }\n }\n\n getFrontContentEl(): HTMLDivElement {\n return this.renderer.getFrontContentEl()\n }\n\n getBackContentEl(): HTMLDivElement {\n return this.renderer.getBackContentEl()\n }\n\n flip(): void {\n this.interaction.flip()\n }\n\n wiggle(): void {\n // Don't wiggle while user is interacting\n if (this.interaction.isInteracting()) return\n\n this.wiggleController?.stop()\n this.interaction.startSyntheticInteraction()\n\n this.wiggleController = wiggle(0, 0, 100, (pos, done) => {\n if (done) {\n this.interaction.simulateEndInteract()\n this.wiggleController = null\n } else {\n this.interaction.simulateInteractRaw(pos.x, pos.y)\n }\n })\n }\n\n reset(): void {\n this.wiggleController?.stop()\n this.wiggleController = null\n this.interaction.simulateEndInteract()\n }\n\n updateOptions(options: Omit<Partial<PocaCardOptions>, 'front' | 'back'> & {\n front?: Partial<FaceOptions>\n back?: Partial<FaceOptions>\n }): void {\n if (options.flipSpeed != null) {\n this.interaction.flipSpeed = options.flipSpeed\n }\n if (options.front?.shader) {\n this.renderer.updateShader(options.front.shader)\n }\n if (options.back?.shader) {\n this.renderer.updateBackShader(options.back.shader)\n }\n if (options.front?.layers || options.back?.layers) {\n this.renderer.updateLayers(options.front?.layers, options.back?.layers)\n }\n if (options.front?.uniforms || options.back?.uniforms) {\n this.renderer.updateEffectUniforms(options.front?.uniforms, options.back?.uniforms)\n }\n if (options.front?.frame || options.back?.frame) {\n this.renderer.updateFrames(options.front?.frame, options.back?.frame)\n }\n }\n\n destroy(): void {\n this.wiggleController?.stop()\n this.interaction.destroy()\n this.renderer.destroy()\n this.removeAllListeners()\n }\n}\n","import glare from './glare.frag'\nimport glare3d from './glare-3d.frag'\nimport holo from './holo.frag'\nimport holo3d from './holo-3d.frag'\nimport snowfall from './snowfall.frag'\nimport snowfall3d from './snowfall-3d.frag'\nimport blur from './blur.frag'\nimport blur3d from './blur-3d.frag'\nimport brush from './brush.frag'\nimport brush3d from './brush-3d.frag'\nimport pulseLines from './pulse-lines.frag'\nimport gradientFlow from './gradient-flow.frag'\nimport proceduralOcean from './procedural-ocean.frag'\nimport rainbowFlow from './rainbow-flow.frag'\nimport shockWave from './shock-wave.frag'\nimport ripple from './ripple.frag'\nimport lenticular from './lenticular.frag'\n\nexport const builtinShaders: Record<string, string> = {\n glare,\n 'glare-3d': glare3d,\n holo,\n 'holo-3d': holo3d,\n snowfall,\n 'snowfall-3d': snowfall3d,\n blur,\n 'blur-3d': blur3d,\n brush,\n 'brush-3d': brush3d,\n 'pulse-lines': pulseLines,\n 'gradient-flow': gradientFlow,\n 'procedural-ocean': proceduralOcean,\n 'rainbow-flow': rainbowFlow,\n 'shock-wave': shockWave,\n 'ripple': ripple,\n lenticular,\n}\n"],"mappings":"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A;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAf,IAAO,2BAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAf,IAAO,qBAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAf,IAAO,wBAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAf,IAAO,oBAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAf,IAAO,uBAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAf,IAAO,oBAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAf,IAAO,uBAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAf,IAAO,2BAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAf,IAAO,6BAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAf,IAAO,gCAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAf,IAAO,4BAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAf,IAAO,0BAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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","names":["THREE","THREE","D_default","D_default","THREE","rafId"]}
1
+ {"version":3,"sources":["../src/event-emitter.ts","../src/renderer/index.ts","../src/renderer/face-renderer.ts","../src/renderer/shader-bootstrap.ts","../src/shaders/lygia/math/permute.glsl","../src/shaders/lygia/math/mod289.glsl","../src/shaders/lygia/math/taylorInvSqrt.glsl","../src/shaders/lygia/math/grad4.glsl","../src/shaders/lygia/math/rotate4d.glsl","../src/shaders/lygia/math/cubic.glsl","../src/shaders/lygia/math/quintic.glsl","../src/shaders/lygia/math/sum.glsl","../src/shaders/lygia/math/saturate.glsl","../src/shaders/lygia/math/gaussian.glsl","../src/shaders/lygia/space/ratio.glsl","../src/shaders/lygia/generative/random.glsl","../src/shaders/lygia/generative/srandom.glsl","../src/shaders/lygia/generative/gnoise.glsl","../src/shaders/lygia/generative/snoise.glsl","../src/shaders/lygia/generative/fbm.glsl","../src/shaders/lygia/morphological/dilation.glsl","../src/shaders/lygia/sampler.glsl","../src/shaders/lygia/sample/clamp2edge.glsl","../src/shaders/lygia/draw/digits.glsl","../src/shaders/lygia/filter/gaussianBlur.glsl","../src/shaders/lygia/filter/gaussianBlur/2D.glsl","../src/shaders/lygia/filter/gaussianBlur/1D.glsl","../src/shaders/lygia/filter/gaussianBlur/1D_fast13.glsl","../src/shaders/lygia/filter/gaussianBlur/1D_fast9.glsl","../src/shaders/lygia/filter/gaussianBlur/1D_fast5.glsl","../src/shaders/lygia/filter/kuwahara.glsl","../src/shaders/utils/glsl.ts","../src/shaders/utils/default-lighting.glsl.ts","../src/renderer/texture-loader.ts","../src/shaders/common.vert.ts","../src/shaders/glare.frag.ts","../src/shaders/glare-3d.frag.ts","../src/shaders/snowfall.frag.ts","../src/shaders/snowfall-3d.frag.ts","../src/shaders/brush.frag.ts","../src/shaders/brush-3d.frag.ts","../src/shaders/blur.frag.ts","../src/shaders/blur-3d.frag.ts","../src/shaders/holo.frag.ts","../src/shaders/holo-3d.frag.ts","../src/shaders/pulse-lines.frag.ts","../src/shaders/gradient-flow.frag.ts","../src/shaders/procedural-ocean.frag.ts","../src/shaders/rainbow-flow.frag.ts","../src/shaders/shock-wave.frag.ts","../src/shaders/ripple.frag.ts","../src/shaders/lenticular.frag.ts","../src/animation/spring.ts","../src/utils/math.ts","../src/interaction/index.ts","../src/animation/tween.ts","../src/animation/wiggle.ts","../src/poca-card.ts","../src/shaders/registry.ts"],"sourcesContent":["type Handler = (...args: any[]) => void\n\nexport class EventEmitter {\n private listeners = new Map<string, Set<Handler>>()\n\n on(event: string, handler: Handler): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set())\n }\n this.listeners.get(event)!.add(handler)\n }\n\n off(event: string, handler: Handler): void {\n this.listeners.get(event)?.delete(handler)\n }\n\n protected emit(event: string, ...args: any[]): void {\n this.listeners.get(event)?.forEach((handler) => {\n try {\n handler(...args)\n } catch (e) {\n console.error(`[pocato] Error in ${event} handler:`, e)\n }\n })\n }\n\n protected removeAllListeners(): void {\n this.listeners.clear()\n }\n}\n","import * as THREE from 'three'\nimport { FaceRenderer } from './face-renderer'\nimport { cleanupPendingVideos } from './texture-loader'\nimport type { FaceFrameOptions, FaceOptions, LayerSource } from '../types'\n\nexport interface RendererOptions {\n front: FaceOptions\n back?: FaceOptions\n preventTouchScroll?: boolean\n}\n\nexport class Renderer {\n private frontFace: FaceRenderer\n private backFace: FaceRenderer | null = null\n private frontRenderer: THREE.WebGLRenderer | null = null\n private backRenderer: THREE.WebGLRenderer | null = null\n private clock = new THREE.Clock()\n private rafId: number | null = null\n private frontCanvas: HTMLCanvasElement\n private backCanvas: HTMLCanvasElement | null = null\n private cardEl: HTMLDivElement\n private rotatorEl: HTMLDivElement\n private frontEl: HTMLDivElement\n private backEl: HTMLDivElement\n private frontContentEl: HTMLDivElement\n private backContentEl: HTMLDivElement\n private frontFrameEl: HTMLDivElement\n private backFrameEl: HTMLDivElement\n private frontFrameShadowEl: HTMLDivElement\n private backFrameShadowEl: HTMLDivElement\n private frontFrame?: FaceFrameOptions\n private backFrame?: FaceFrameOptions\n private resizeObserver: ResizeObserver | null = null\n private intersectionObserver: IntersectionObserver | null = null\n private visible = false\n private destroyed = false\n private layersReady = false\n private firstFrameEmitted = false\n private firstFrameScheduled = false\n\n private disposeWebGLRenderer(renderer: THREE.WebGLRenderer): void {\n renderer.forceContextLoss()\n renderer.dispose()\n }\n\n constructor(\n private container: HTMLElement,\n private options: RendererOptions,\n private onError?: (error: Error) => void,\n private onReady?: () => void,\n private onFirstFrame?: () => void,\n ) {\n // front.layers is required but we handle missing gracefully\n if (!options.front?.layers?.length) {\n console.warn('[pocato] front.layers must have at least 1 element')\n }\n\n this.injectStyles()\n\n // Build DOM\n this.cardEl = document.createElement('div')\n this.cardEl.className = 'pocato-card pocato-loading'\n if (options.preventTouchScroll) {\n this.cardEl.style.touchAction = 'none'\n }\n\n this.rotatorEl = document.createElement('div')\n this.rotatorEl.className = 'pocato-rotator'\n\n // Back face\n this.backEl = document.createElement('div')\n this.backEl.className = 'pocato-back'\n\n // Front face\n this.frontEl = document.createElement('div')\n this.frontEl.className = 'pocato-front'\n\n this.frontCanvas = document.createElement('canvas')\n this.frontCanvas.className = 'pocato-canvas'\n\n // Content containers\n this.frontContentEl = document.createElement('div')\n this.frontContentEl.className = 'pocato-content pocato-front-content'\n this.backContentEl = document.createElement('div')\n this.backContentEl.className = 'pocato-content pocato-back-content'\n this.frontFrameEl = document.createElement('div')\n this.frontFrameEl.className = 'pocato-frame'\n this.backFrameEl = document.createElement('div')\n this.backFrameEl.className = 'pocato-frame'\n this.frontFrameShadowEl = document.createElement('div')\n this.frontFrameShadowEl.className = 'pocato-frame-shadow'\n this.backFrameShadowEl = document.createElement('div')\n this.backFrameShadowEl.className = 'pocato-frame-shadow'\n\n this.frontEl.appendChild(this.frontCanvas)\n this.frontEl.appendChild(this.frontContentEl)\n this.frontEl.appendChild(this.frontFrameEl)\n this.frontEl.appendChild(this.frontFrameShadowEl)\n this.backEl.appendChild(this.backContentEl)\n this.backEl.appendChild(this.backFrameEl)\n this.backEl.appendChild(this.backFrameShadowEl)\n\n this.rotatorEl.appendChild(this.backEl)\n this.rotatorEl.appendChild(this.frontEl)\n this.cardEl.appendChild(this.rotatorEl)\n this.container.appendChild(this.cardEl)\n\n const { width, height } = this.container.getBoundingClientRect()\n const dpr = window.devicePixelRatio || 1\n const pixelWidth = Math.floor(width * dpr)\n const pixelHeight = Math.floor(height * dpr)\n\n // Set canvas size (used by FaceRenderer for uniforms)\n this.frontCanvas.width = pixelWidth\n this.frontCanvas.height = pixelHeight\n\n // Front face (always — lightweight, no WebGL context yet)\n this.frontFace = new FaceRenderer(\n options.front.shader, pixelWidth, pixelHeight, options.front.uniforms,\n )\n\n // Back face (always created so layers can be added later)\n this.backFace = new FaceRenderer(\n this.options.back?.shader, pixelWidth, pixelHeight, this.options.back?.uniforms,\n )\n\n this.backCanvas = document.createElement('canvas')\n this.backCanvas.className = 'pocato-canvas'\n this.backCanvas.width = pixelWidth\n this.backCanvas.height = pixelHeight\n this.backEl.insertBefore(this.backCanvas, this.backEl.firstChild)\n this.applyFrame(this.frontEl, this.frontFrameEl, this.frontFrameShadowEl, options.front.frame)\n this.applyFrame(this.backEl, this.backFrameEl, this.backFrameShadowEl, options.back?.frame)\n this.frontFrame = options.front.frame\n this.backFrame = options.back?.frame\n\n this.loadAllLayers()\n this.setupResizeObserver()\n this.setupIntersectionObserver()\n }\n\n private createFrontRenderer(): void {\n if (this.frontRenderer) return\n // Replace canvas to get a fresh WebGL context (disposed canvas can't get a new one)\n const newCanvas = document.createElement('canvas')\n newCanvas.className = 'pocato-canvas'\n this.frontEl.replaceChild(newCanvas, this.frontCanvas)\n this.frontCanvas = newCanvas\n\n this.frontRenderer = new THREE.WebGLRenderer({\n canvas: this.frontCanvas,\n alpha: true,\n })\n this.frontRenderer.setPixelRatio(window.devicePixelRatio)\n this.resizeFaceRenderer(this.frontEl, this.frontCanvas, this.frontFace, this.frontRenderer, this.frontFrame)\n }\n\n private createBackRenderer(): void {\n if (this.backRenderer || !this.backCanvas || !this.backFace) return\n const newCanvas = document.createElement('canvas')\n newCanvas.className = 'pocato-canvas'\n this.backEl.replaceChild(newCanvas, this.backCanvas)\n this.backCanvas = newCanvas\n\n this.backRenderer = new THREE.WebGLRenderer({\n canvas: this.backCanvas,\n alpha: true,\n })\n this.backRenderer.setPixelRatio(window.devicePixelRatio)\n this.resizeFaceRenderer(this.backEl, this.backCanvas, this.backFace, this.backRenderer, this.backFrame)\n }\n\n private disposeFrontRenderer(): void {\n if (!this.frontRenderer) return\n // Render one last frame to preserve static image on canvas\n this.frontRenderer.render(this.frontFace.scene, this.frontFace.camera)\n this.disposeWebGLRenderer(this.frontRenderer)\n this.frontRenderer = null\n }\n\n private disposeBackRenderer(): void {\n if (!this.backRenderer) return\n if (this.backFace) {\n this.backRenderer.render(this.backFace.scene, this.backFace.camera)\n }\n this.disposeWebGLRenderer(this.backRenderer)\n this.backRenderer = null\n }\n\n private activate(): void {\n if (this.visible) return\n this.visible = true\n this.createFrontRenderer()\n if (this.backFace) this.createBackRenderer()\n this.clock.getDelta() // reset clock to avoid time jump\n this.startRenderLoop()\n }\n\n private deactivate(): void {\n if (!this.visible) return\n this.visible = false\n this.stopRenderLoop()\n this.disposeFrontRenderer()\n this.disposeBackRenderer()\n }\n\n private setupIntersectionObserver(): void {\n this.intersectionObserver = new IntersectionObserver(\n (entries) => {\n const entry = entries[0]\n if (!entry || this.destroyed) return\n if (entry.isIntersecting) {\n this.activate()\n } else {\n this.deactivate()\n }\n },\n { rootMargin: '100px' }, // activate slightly before entering viewport\n )\n this.intersectionObserver.observe(this.cardEl)\n }\n\n private async loadAllLayers(): Promise<void> {\n const promises: Promise<void>[] = []\n\n if (this.options.front?.layers?.length) {\n promises.push(this.frontFace.loadLayers(this.options.front.layers, this.onError))\n }\n\n if (this.backFace && this.options.back?.layers?.length) {\n promises.push(this.backFace.loadLayers(this.options.back.layers, this.onError))\n }\n\n await Promise.all(promises)\n if (this.destroyed) return\n\n this.layersReady = true\n this.onReady?.()\n }\n\n private scheduleFirstFrame(): void {\n if (!this.layersReady || this.firstFrameEmitted || this.firstFrameScheduled) return\n\n this.firstFrameScheduled = true\n requestAnimationFrame(() => {\n if (this.destroyed || this.firstFrameEmitted) return\n this.firstFrameEmitted = true\n this.cardEl.classList.remove('pocato-loading')\n this.cardEl.classList.add('pocato-ready')\n this.onFirstFrame?.()\n requestAnimationFrame(() => {\n if (this.destroyed) return\n this.frontFace.playLoadedVideos()\n this.backFace?.playLoadedVideos()\n })\n })\n }\n\n private injectStyles(): void {\n const id = 'pocato-styles'\n if (document.getElementById(id)) return\n\n const style = document.createElement('style')\n style.id = id\n style.textContent = `\n .pocato-card {\n width: 100%;\n height: 100%;\n perspective: 1000px;\n user-select: none;\n transform: translate3d(0,0,0);\n opacity: 0;\n transition: opacity 0.5s ease;\n }\n .pocato-card.pocato-ready {\n opacity: 1;\n }\n .pocato-rotator {\n width: 100%;\n height: 100%;\n position: relative;\n transform-style: preserve-3d;\n transform-origin: center;\n transform: rotateY(var(--pocato-rotate-x, 0deg)) rotateX(var(--pocato-rotate-y, 0deg));\n border-radius: 2%;\n will-change: transform, box-shadow;\n transition: box-shadow 0.4s ease;\n box-shadow:\n 0px 10px 20px -5px rgba(0,0,0,0.4),\n 0 2px 15px -5px rgba(0,0,0,0.3);\n pointer-events: auto;\n }\n .pocato-front {\n position: absolute;\n top: 0; left: 0;\n width: 100%;\n height: 100%;\n backface-visibility: hidden;\n -webkit-backface-visibility: hidden;\n transform: translate3d(0,0,0);\n border-radius: 2%;\n overflow: hidden;\n }\n .pocato-back {\n position: absolute;\n top: 0; left: 0;\n width: 100%;\n height: 100%;\n backface-visibility: hidden;\n -webkit-backface-visibility: hidden;\n transform: rotateY(180deg) translateZ(0);\n border-radius: 2%;\n overflow: hidden;\n background-color: #1a1a2e;\n }\n .pocato-canvas {\n position: absolute;\n inset: var(--pocato-face-padding, 0px);\n width: calc(100% - var(--pocato-face-padding-total, 0px));\n height: calc(100% - var(--pocato-face-padding-total, 0px));\n display: block;\n }\n .pocato-content {\n position: absolute;\n inset: var(--pocato-face-padding, 0px);\n pointer-events: none;\n z-index: 1;\n }\n .pocato-content > * {\n pointer-events: auto;\n }\n .pocato-frame {\n position: absolute;\n inset: var(--pocato-frame-inset, 0px);\n z-index: 2;\n pointer-events: none;\n opacity: var(--pocato-frame-opacity, 0);\n }\n .pocato-frame::before {\n content: '';\n position: absolute;\n inset: 0;\n border: var(--pocato-frame-width, 0px) solid transparent;\n background: var(--pocato-frame-background, transparent) border-box;\n background-size: 220% 220%;\n -webkit-mask:\n linear-gradient(#000 0 0) padding-box,\n linear-gradient(#000 0 0);\n -webkit-mask-composite: xor;\n mask:\n linear-gradient(#000 0 0) padding-box,\n linear-gradient(#000 0 0);\n mask-composite: exclude;\n }\n .pocato-frame-shadow {\n position: absolute;\n inset: var(--pocato-frame-shadow-inset, 0px);\n z-index: 3;\n pointer-events: none;\n opacity: var(--pocato-frame-shadow-opacity, 0);\n box-shadow: inset 0 0 var(--pocato-frame-shadow-blur, 0px) var(--pocato-frame-shadow-color, rgba(0,0,0,0.4));\n }\n .pocato-frame[data-animated=\"true\"]::before {\n animation: pocato-frame-flow var(--pocato-frame-speed, 3s) linear infinite;\n }\n @keyframes pocato-frame-flow {\n 0% { background-position: 0% 50%; }\n 50% { background-position: 100% 50%; }\n 100% { background-position: 0% 50%; }\n }\n `\n document.head.appendChild(style)\n }\n\n private applyFrame(\n faceEl: HTMLDivElement,\n frameEl: HTMLDivElement,\n shadowEl: HTMLDivElement,\n frame?: FaceFrameOptions,\n ): void {\n const enabled = frame?.enabled ?? false\n const facePadding = enabled ? frame?.padding ?? 0 : 0\n const frameInset = enabled ? frame?.inset ?? 0 : 0\n const frameWidth = enabled ? frame?.width ?? 0 : 0\n const shadowEnabled = enabled && (frame?.innerShadow ?? false)\n faceEl.style.setProperty('--pocato-face-padding', `${facePadding}px`)\n faceEl.style.setProperty('--pocato-face-padding-total', `${facePadding * 2}px`)\n faceEl.style.background = enabled ? getFrameBackground(frame) : ''\n frameEl.style.setProperty('--pocato-frame-opacity', enabled ? '1' : '0')\n frameEl.style.setProperty('--pocato-frame-inset', `${frameInset}px`)\n frameEl.style.setProperty('--pocato-frame-width', `${frameWidth}px`)\n frameEl.style.setProperty('--pocato-frame-speed', `${frame?.animationSpeed ?? 3}s`)\n frameEl.dataset.animated = enabled && frameWidth > 0 && frame?.animated ? 'true' : 'false'\n\n frameEl.style.setProperty('--pocato-frame-background', getFrameBorderBackground(frame))\n shadowEl.style.setProperty('--pocato-frame-shadow-inset', `${frameInset + frameWidth}px`)\n shadowEl.style.setProperty('--pocato-frame-shadow-blur', `${frame?.innerShadowBlur ?? 16}px`)\n shadowEl.style.setProperty('--pocato-frame-shadow-color', toRgba(frame?.innerShadowColor ?? '#000000', frame?.innerShadowOpacity ?? 0.28))\n shadowEl.style.setProperty('--pocato-frame-shadow-opacity', shadowEnabled ? '1' : '0')\n }\n\n private setupResizeObserver(): void {\n this.resizeObserver = new ResizeObserver((entries) => {\n const entry = entries[0]\n if (!entry) return\n const { width, height } = entry.contentRect\n if (width === 0 || height === 0) return\n\n if (this.frontRenderer) {\n this.resizeFaceRenderer(this.frontEl, this.frontCanvas, this.frontFace, this.frontRenderer, this.frontFrame)\n } else {\n this.resizeFaceRenderer(this.frontEl, this.frontCanvas, this.frontFace, null, this.frontFrame)\n }\n\n if (this.backFace && this.backCanvas) {\n if (this.backRenderer) {\n this.resizeFaceRenderer(this.backEl, this.backCanvas, this.backFace, this.backRenderer, this.backFrame)\n } else {\n this.resizeFaceRenderer(this.backEl, this.backCanvas, this.backFace, null, this.backFrame)\n }\n }\n })\n this.resizeObserver.observe(this.container)\n }\n\n private startRenderLoop(): void {\n if (this.rafId !== null) return\n const animate = () => {\n if (!this.visible || this.destroyed) return\n this.rafId = requestAnimationFrame(animate)\n const delta = this.clock.getDelta()\n\n // Render front face\n this.frontFace.material.uniforms.uTime.value += delta\n if (this.frontRenderer) {\n this.frontRenderer.render(this.frontFace.scene, this.frontFace.camera)\n }\n\n // Render back face if it exists\n if (this.backFace && this.backRenderer) {\n this.backFace.material.uniforms.uTime.value += delta\n this.backRenderer.render(this.backFace.scene, this.backFace.camera)\n }\n\n this.scheduleFirstFrame()\n }\n this.rafId = requestAnimationFrame(animate)\n }\n\n private stopRenderLoop(): void {\n if (this.rafId !== null) {\n cancelAnimationFrame(this.rafId)\n this.rafId = null\n }\n }\n\n updateUniforms(updates: {\n rotate?: { x: number; y: number }\n mouse?: { x: number; y: number }\n move?: { x: number; y: number }\n opacity?: number\n }): void {\n if (updates.rotate) {\n this.rotatorEl.style.setProperty('--pocato-rotate-x', `${updates.rotate.x}deg`)\n this.rotatorEl.style.setProperty('--pocato-rotate-y', `${updates.rotate.y}deg`)\n }\n\n this.frontFace.updateUniforms({\n rotate: updates.rotate,\n mouse: updates.mouse,\n move: updates.move,\n opacity: updates.opacity,\n })\n\n if (this.backFace) {\n this.backFace.updateUniforms({\n rotate: updates.rotate,\n mouse: updates.mouse,\n move: updates.move,\n opacity: updates.opacity,\n })\n }\n }\n\n updateShader(fragmentShader: string): void {\n this.frontFace.updateShader(fragmentShader)\n }\n\n updateBackShader(fragmentShader: string): void {\n this.backFace?.updateShader(fragmentShader)\n }\n\n updateEffectUniforms(\n frontUniforms?: FaceOptions['uniforms'],\n backUniforms?: FaceOptions['uniforms'],\n ): void {\n this.frontFace.updateEffectUniforms(frontUniforms)\n this.backFace?.updateEffectUniforms(backUniforms)\n }\n\n updateFrames(\n frontFrame?: FaceFrameOptions,\n backFrame?: FaceFrameOptions,\n ): void {\n if (frontFrame) {\n this.frontFrame = frontFrame\n this.applyFrame(this.frontEl, this.frontFrameEl, this.frontFrameShadowEl, frontFrame)\n this.resizeFaceRenderer(this.frontEl, this.frontCanvas, this.frontFace, this.frontRenderer, this.frontFrame)\n }\n if (backFrame) {\n this.backFrame = backFrame\n this.applyFrame(this.backEl, this.backFrameEl, this.backFrameShadowEl, backFrame)\n if (this.backFace && this.backCanvas) {\n this.resizeFaceRenderer(this.backEl, this.backCanvas, this.backFace, this.backRenderer, this.backFrame)\n }\n }\n }\n\n private resizeFaceRenderer(\n faceEl: HTMLDivElement,\n canvas: HTMLCanvasElement,\n face: FaceRenderer,\n renderer: THREE.WebGLRenderer | null,\n frame?: FaceFrameOptions,\n ): void {\n const { width, height } = faceEl.getBoundingClientRect()\n const padding = frame?.enabled ? frame.padding ?? 0 : 0\n const nextWidth = Math.max(1, width - padding * 2)\n const nextHeight = Math.max(1, height - padding * 2)\n\n if (renderer) {\n renderer.setSize(nextWidth, nextHeight)\n } else {\n const dpr = window.devicePixelRatio || 1\n canvas.width = Math.floor(nextWidth * dpr)\n canvas.height = Math.floor(nextHeight * dpr)\n }\n\n face.updateResolution(canvas.width, canvas.height)\n }\n\n async updateLayers(\n frontLayers?: LayerSource[],\n backLayers?: LayerSource[],\n ): Promise<void> {\n const promises: Promise<void>[] = []\n\n if (frontLayers) {\n promises.push(this.frontFace.loadLayers(frontLayers, this.onError))\n }\n\n if (backLayers && this.backFace) {\n promises.push(this.backFace.loadLayers(backLayers, this.onError))\n }\n\n await Promise.all(promises)\n }\n\n getRotatorEl(): HTMLDivElement {\n return this.rotatorEl\n }\n\n getFrontContentEl(): HTMLDivElement {\n return this.frontContentEl\n }\n\n getBackContentEl(): HTMLDivElement {\n return this.backContentEl\n }\n\n destroy(): void {\n this.destroyed = true\n this.stopRenderLoop()\n this.resizeObserver?.disconnect()\n this.intersectionObserver?.disconnect()\n\n cleanupPendingVideos()\n\n this.frontFace.destroy()\n if (this.frontRenderer) {\n this.disposeWebGLRenderer(this.frontRenderer)\n this.frontRenderer = null\n }\n\n if (this.backFace) {\n this.backFace.destroy()\n if (this.backRenderer) {\n this.disposeWebGLRenderer(this.backRenderer)\n this.backRenderer = null\n }\n }\n\n if (this.cardEl.parentNode) {\n this.cardEl.parentNode.removeChild(this.cardEl)\n }\n }\n}\n\nfunction getFrameBackground(frame?: FaceFrameOptions): string {\n const color = frame?.backgroundColor ?? '#111827'\n const gradientFrom = frame?.backgroundGradientFrom ?? color\n const gradientTo = frame?.backgroundGradientTo ?? color\n return frame?.backgroundGradient\n ? `linear-gradient(135deg, ${gradientFrom}, ${gradientTo})`\n : color\n}\n\nfunction getFrameBorderBackground(frame?: FaceFrameOptions): string {\n const color = frame?.color ?? '#ffffff'\n const gradientFrom = frame?.gradientFrom ?? color\n const gradientTo = frame?.gradientTo ?? color\n const opacity = frame?.borderOpacity ?? 1\n return frame?.gradient\n ? `linear-gradient(120deg, ${toRgba(gradientFrom, opacity)}, ${toRgba(gradientTo, opacity)}, ${toRgba(gradientFrom, opacity)})`\n : toRgba(color, opacity)\n}\n\nfunction toRgba(hex: string, opacity: number): string {\n const value = hex.replace('#', '')\n if (value.length !== 6) return `rgba(0, 0, 0, ${opacity})`\n const red = Number.parseInt(value.slice(0, 2), 16)\n const green = Number.parseInt(value.slice(2, 4), 16)\n const blue = Number.parseInt(value.slice(4, 6), 16)\n if ([red, green, blue].some((channel) => Number.isNaN(channel))) {\n return `rgba(0, 0, 0, ${opacity})`\n }\n return `rgba(${red}, ${green}, ${blue}, ${opacity})`\n}\n","import * as THREE from 'three'\nimport { bootstrapShaders, resolveIncludes } from './shader-bootstrap'\nimport { loadLayerTexture, disposeLoadedLayer, getTransparentTexture, type LoadedLayer } from './texture-loader'\nimport type { EffectUniformValue, LayerSource } from '../types'\nimport vertexShader from '../shaders/common.vert'\n\nimport fragShaderGlare from '../shaders/glare.frag'\nimport fragShaderGlare3d from '../shaders/glare-3d.frag'\nimport fragShaderSnowfall from '../shaders/snowfall.frag'\nimport fragShaderSnowfall3d from '../shaders/snowfall-3d.frag'\nimport fragShaderBrush from '../shaders/brush.frag'\nimport fragShaderBrush3d from '../shaders/brush-3d.frag'\nimport fragShaderBlur from '../shaders/blur.frag'\nimport fragShaderBlur3d from '../shaders/blur-3d.frag'\nimport fragShaderHolo from '../shaders/holo.frag'\nimport fragShaderHolo3d from '../shaders/holo-3d.frag'\nimport fragShaderPulseLines from '../shaders/pulse-lines.frag'\nimport fragShaderGradientFlow from '../shaders/gradient-flow.frag'\nimport fragShaderProceduralOcean from '../shaders/procedural-ocean.frag'\nimport fragShaderRainbowFlow from '../shaders/rainbow-flow.frag'\nimport fragShaderShockWave from '../shaders/shock-wave.frag'\nimport fragShaderRipple from '../shaders/ripple.frag'\nimport fragShaderLenticular from '../shaders/lenticular.frag'\n\nexport const FRAG_SHADERS: Record<string, string> = {\n 'glare': fragShaderGlare,\n 'glare-3d': fragShaderGlare3d,\n 'snowfall': fragShaderSnowfall,\n 'snowfall-3d': fragShaderSnowfall3d,\n 'brush': fragShaderBrush,\n 'brush-3d': fragShaderBrush3d,\n 'blur': fragShaderBlur,\n 'blur-3d': fragShaderBlur3d,\n 'holo': fragShaderHolo,\n 'holo-3d': fragShaderHolo3d,\n 'pulse-lines': fragShaderPulseLines,\n 'gradient-flow': fragShaderGradientFlow,\n 'procedural-ocean': fragShaderProceduralOcean,\n 'rainbow-flow': fragShaderRainbowFlow,\n 'shock-wave': fragShaderShockWave,\n 'ripple': fragShaderRipple,\n lenticular: fragShaderLenticular,\n}\n\nconst MAX_LAYERS = 8\n\nexport class FaceRenderer {\n material: THREE.ShaderMaterial\n mesh: THREE.Mesh\n scene: THREE.Scene\n camera: THREE.Camera\n private loadedLayers: LoadedLayer[] = []\n private layerLoadVersion = 0\n\n constructor(\n shader: string | undefined,\n width: number,\n height: number,\n effectUniforms?: Record<string, EffectUniformValue>,\n ) {\n bootstrapShaders()\n\n this.scene = new THREE.Scene()\n this.camera = new THREE.Camera()\n\n const uniforms = this.createUniforms(width, height, effectUniforms)\n const rawFrag = shader ?? FRAG_SHADERS['glare']\n const fragmentShader = resolveIncludes(rawFrag)\n\n this.material = new THREE.ShaderMaterial({\n vertexShader: resolveIncludes(vertexShader),\n fragmentShader,\n uniforms,\n transparent: true,\n })\n\n const geometry = new THREE.PlaneGeometry(2, 2)\n this.mesh = new THREE.Mesh(geometry, this.material)\n this.scene.add(this.mesh)\n }\n\n private createUniforms(\n width: number,\n height: number,\n effectUniforms?: Record<string, EffectUniformValue>,\n ): Record<string, THREE.IUniform> {\n const uniforms: Record<string, THREE.IUniform> = {\n uTime: { value: 0 },\n uResolution: { value: new THREE.Vector2(width, height) },\n uMouse: { value: new THREE.Vector2(0, 0) },\n uMove: { value: new THREE.Vector2(0, 0) },\n uRotate: { value: new THREE.Vector2(0, 0) },\n uCardOpacity: { value: 1.0 },\n uLayerCount: { value: 0 },\n }\n\n const transparent = getTransparentTexture()\n for (let i = 0; i < MAX_LAYERS; i++) {\n uniforms[`uLayer${i}`] = { value: transparent }\n }\n\n if (effectUniforms) {\n for (const [name, value] of Object.entries(effectUniforms)) {\n uniforms[name] = { value: toThreeUniformValue(value) }\n }\n }\n\n return uniforms\n }\n\n updateEffectUniforms(values?: Record<string, EffectUniformValue>): void {\n if (!values) return\n for (const [name, value] of Object.entries(values)) {\n const nextValue = toThreeUniformValue(value)\n if (this.material.uniforms[name]) {\n this.material.uniforms[name].value = nextValue\n } else {\n this.material.uniforms[name] = { value: nextValue }\n }\n }\n }\n\n async loadLayers(\n layers: LayerSource[],\n onError?: (error: Error) => void,\n ): Promise<void> {\n const version = ++this.layerLoadVersion\n this.disposeLayers()\n\n const count = Math.min(layers.length, MAX_LAYERS)\n this.material.uniforms.uLayerCount.value = count\n\n const promises = layers.slice(0, MAX_LAYERS).map((layer) =>\n loadLayerTexture(layer, onError)\n )\n\n const results = await Promise.all(promises)\n if (version !== this.layerLoadVersion) {\n for (const loaded of results) {\n disposeLoadedLayer(loaded)\n }\n return\n }\n\n this.loadedLayers = results\n\n for (let i = 0; i < results.length; i++) {\n this.material.uniforms[`uLayer${i}`].value = results[i].texture\n }\n }\n\n updateUniforms(updates: {\n rotate?: { x: number; y: number }\n mouse?: { x: number; y: number }\n move?: { x: number; y: number }\n opacity?: number\n time?: number\n }): void {\n const u = this.material.uniforms\n if (updates.rotate) u.uRotate.value.set(\n updates.rotate.x * (Math.PI / 180),\n updates.rotate.y * (Math.PI / 180),\n )\n if (updates.mouse) u.uMouse.value.set(updates.mouse.x, updates.mouse.y)\n if (updates.move) u.uMove.value.set(updates.move.x, updates.move.y)\n if (updates.opacity !== undefined) u.uCardOpacity.value = updates.opacity\n if (updates.time !== undefined) u.uTime.value = updates.time\n }\n\n updateResolution(width: number, height: number): void {\n this.material.uniforms.uResolution.value.set(width, height)\n }\n\n playLoadedVideos(): void {\n for (let i = 0; i < this.loadedLayers.length; i++) {\n const loaded = this.loadedLayers[i]\n if (loaded.liveTexture) {\n this.material.uniforms[`uLayer${i}`].value = loaded.liveTexture\n }\n loaded.play?.()\n }\n }\n\n updateShader(fragmentShader: string): void {\n this.material.fragmentShader = resolveIncludes(fragmentShader)\n this.material.needsUpdate = true\n }\n\n private disposeLayers(): void {\n for (const loaded of this.loadedLayers) {\n disposeLoadedLayer(loaded)\n }\n this.loadedLayers = []\n\n const transparent = getTransparentTexture()\n for (let i = 0; i < MAX_LAYERS; i++) {\n this.material.uniforms[`uLayer${i}`].value = transparent\n }\n this.material.uniforms.uLayerCount.value = 0\n }\n\n destroy(): void {\n this.layerLoadVersion++\n this.disposeLayers()\n this.mesh.geometry.dispose()\n this.material.dispose()\n }\n}\n\nfunction toThreeUniformValue(value: EffectUniformValue) {\n if (typeof value === 'string') {\n return value.startsWith('#') ? new THREE.Color(value) : value\n }\n if (Array.isArray(value)) {\n if (value.length === 2) return new THREE.Vector2(value[0], value[1])\n if (value.length === 3) return new THREE.Vector3(value[0], value[1], value[2])\n return new THREE.Vector4(value[0], value[1], value[2], value[3])\n }\n return value\n}\n","import * as THREE from 'three'\n\nimport permute from '../shaders/lygia/math/permute.glsl'\nimport mod289 from '../shaders/lygia/math/mod289.glsl'\nimport taylorInvSqrt from '../shaders/lygia/math/taylorInvSqrt.glsl'\nimport grad4 from '../shaders/lygia/math/grad4.glsl'\nimport rotate4d from '../shaders/lygia/math/rotate4d.glsl'\nimport cubic from '../shaders/lygia/math/cubic.glsl'\nimport quintic from '../shaders/lygia/math/quintic.glsl'\nimport sum from '../shaders/lygia/math/sum.glsl'\nimport saturate from '../shaders/lygia/math/saturate.glsl'\nimport gaussian from '../shaders/lygia/math/gaussian.glsl'\nimport ratio from '../shaders/lygia/space/ratio.glsl'\nimport random from '../shaders/lygia/generative/random.glsl'\nimport srandom from '../shaders/lygia/generative/srandom.glsl'\nimport gnoise from '../shaders/lygia/generative/gnoise.glsl'\nimport snoise from '../shaders/lygia/generative/snoise.glsl'\nimport fbm from '../shaders/lygia/generative/fbm.glsl'\nimport dilation from '../shaders/lygia/morphological/dilation.glsl'\nimport sampler from '../shaders/lygia/sampler.glsl'\nimport clamp2edge from '../shaders/lygia/sample/clamp2edge.glsl'\nimport digits from '../shaders/lygia/draw/digits.glsl'\nimport gaussianBlur from '../shaders/lygia/filter/gaussianBlur.glsl'\nimport gaussianBlur2D from '../shaders/lygia/filter/gaussianBlur/2D.glsl'\nimport gaussianBlur1D from '../shaders/lygia/filter/gaussianBlur/1D.glsl'\nimport gaussianBlur1DFast13 from '../shaders/lygia/filter/gaussianBlur/1D_fast13.glsl'\nimport gaussianBlur1DFast9 from '../shaders/lygia/filter/gaussianBlur/1D_fast9.glsl'\nimport gaussianBlur1DFast5 from '../shaders/lygia/filter/gaussianBlur/1D_fast5.glsl'\nimport kuwahara from '../shaders/lygia/filter/kuwahara.glsl'\n\nimport defaultLighting from '../shaders/utils/default-lighting.glsl'\n\nlet bootstrapped = false\n\n// Build a reverse lookup: short name (e.g. \"mod289\") → full chunk key (e.g. \"lygia/math/mod289\")\nconst shortNameMap = new Map<string, string>()\n\nfunction buildShortNameMap(): void {\n const chunks = THREE.ShaderChunk as any\n for (const key of Object.keys(chunks)) {\n // Extract short name from full path\n const parts = key.split('/')\n const shortName = parts[parts.length - 1]\n if (!shortNameMap.has(shortName)) {\n shortNameMap.set(shortName, key)\n }\n }\n}\n\n/**\n * Recursively resolve #include directives using THREE.ShaderChunk.\n * Handles:\n * - #include <lygia/math/mod289> (angle bracket, full path)\n * - #include <utils/defaultLighting> (angle bracket, registered key)\n * - #include \"mod289.glsl\" (quote, short name from LYGIA internals)\n * - #include \"../math/cubic.glsl\" (quote, relative path from LYGIA internals)\n */\nexport function resolveIncludes(source: string): string {\n if (shortNameMap.size === 0) buildShortNameMap()\n\n const pattern = /^[ \\t]*#include\\s+[<\"]([^>\"]+)[>\"]/gm\n const resolved = new Set<string>() // prevent infinite recursion via guard set\n\n function resolve(src: string, depth = 0): string {\n if (depth > 15) return src\n return src.replace(pattern, (_match, rawName: string) => {\n // Normalize: strip .glsl extension\n const name = rawName.replace(/\\.glsl$/, '')\n\n // Prevent re-including the same chunk\n if (resolved.has(name)) return ''\n\n const chunks = THREE.ShaderChunk as any\n\n // 1. Try exact key match\n let chunk = chunks[name]\n\n // 2. Try short name lookup (e.g. \"mod289\" → \"lygia/math/mod289\")\n if (chunk === undefined) {\n const shortName = name.split('/').pop()!\n const fullKey = shortNameMap.get(shortName)\n if (fullKey) chunk = chunks[fullKey]\n }\n\n // 3. Try normalizing relative paths (e.g. \"../math/cubic\" → \"lygia/math/cubic\")\n if (chunk === undefined && (name.startsWith('../') || name.startsWith('./'))) {\n // Try stripping relative prefix and prepending lygia/\n const cleaned = name.replace(/^\\.\\.\\//, '').replace(/^\\.\\//, '')\n chunk = chunks['lygia/' + cleaned]\n if (chunk === undefined) {\n // Try just the short name\n const shortName = cleaned.split('/').pop()!\n const fullKey = shortNameMap.get(shortName)\n if (fullKey) chunk = chunks[fullKey]\n }\n }\n\n if (chunk !== undefined) {\n resolved.add(name)\n return resolve(chunk, depth + 1)\n }\n\n // Chunk not found — leave a comment so shader doesn't break silently\n console.warn(`[pocato] Shader chunk not found: ${rawName}`)\n return `/* chunk not found: ${rawName} */`\n })\n }\n return resolve(source)\n}\n\nexport function bootstrapShaders(): void {\n if (bootstrapped) return\n bootstrapped = true\n\n const ThreeShaderChunk = THREE.ShaderChunk as any\n ThreeShaderChunk['lygia/math/permute'] = permute\n ThreeShaderChunk['lygia/math/mod289'] = mod289\n ThreeShaderChunk['lygia/math/taylorInvSqrt'] = taylorInvSqrt\n ThreeShaderChunk['lygia/math/grad4'] = grad4\n ThreeShaderChunk['lygia/math/rotate4d'] = rotate4d\n ThreeShaderChunk['lygia/math/cubic'] = cubic\n ThreeShaderChunk['lygia/math/quintic'] = quintic\n ThreeShaderChunk['lygia/math/sum'] = sum\n ThreeShaderChunk['lygia/math/saturate'] = saturate\n ThreeShaderChunk['lygia/math/gaussian'] = gaussian\n ThreeShaderChunk['lygia/space/ratio'] = ratio\n ThreeShaderChunk['lygia/generative/random'] = random\n ThreeShaderChunk['lygia/generative/srandom'] = srandom\n ThreeShaderChunk['lygia/generative/gnoise'] = gnoise\n ThreeShaderChunk['lygia/generative/snoise'] = snoise\n ThreeShaderChunk['lygia/generative/fbm'] = fbm\n ThreeShaderChunk['lygia/morphological/dilation'] = dilation\n ThreeShaderChunk['lygia/sampler'] = sampler\n ThreeShaderChunk['lygia/sample/clamp2edge'] = clamp2edge\n ThreeShaderChunk['lygia/draw/digits'] = digits\n ThreeShaderChunk['lygia/filter/gaussianBlur'] = gaussianBlur\n ThreeShaderChunk['lygia/filter/gaussianBlur/2D'] = gaussianBlur2D\n ThreeShaderChunk['lygia/filter/gaussianBlur/1D'] = gaussianBlur1D\n ThreeShaderChunk['lygia/filter/gaussianBlur/1D_fast13'] = gaussianBlur1DFast13\n ThreeShaderChunk['lygia/filter/gaussianBlur/1D_fast9'] = gaussianBlur1DFast9\n ThreeShaderChunk['lygia/filter/gaussianBlur/1D_fast5'] = gaussianBlur1DFast5\n ThreeShaderChunk['lygia/filter/kuwahara'] = kuwahara\n ThreeShaderChunk['utils/defaultLighting'] = defaultLighting\n}\n","#include \"mod289.glsl\"\n\n/*\ncontributors: [Stefan Gustavson, Ian McEwan]\ndescription: permute\nuse: <float|vec2|vec3|vec4> permute(<float|vec2|vec3|vec4> x)\nexamples:\n - https://raw.githubusercontent.com/patriciogonzalezvivo/lygia_examples/main/math_functions.frag\n*/\n\n#ifndef FNC_PERMUTE\n#define FNC_PERMUTE\n\nfloat permute(const in float v) { return mod289(((v * 34.0) + 1.0) * v); }\nvec2 permute(const in vec2 v) { return mod289(((v * 34.0) + 1.0) * v); }\nvec3 permute(const in vec3 v) { return mod289(((v * 34.0) + 1.0) * v); }\nvec4 permute(const in vec4 v) { return mod289(((v * 34.0) + 1.0) * v); }\n\n#endif\n","/*\ncontributors: [Stefan Gustavson, Ian McEwan]\ndescription: modulus of 289\nuse: <float|vec2|vec3|vec4> mod289(<float|vec2|vec3|vec4> x)\n*/\n\n#ifndef FNC_MOD289\n#define FNC_MOD289\n\nfloat mod289(const in float x) { return x - floor(x * (1. / 289.)) * 289.; }\nvec2 mod289(const in vec2 x) { return x - floor(x * (1. / 289.)) * 289.; }\nvec3 mod289(const in vec3 x) { return x - floor(x * (1. / 289.)) * 289.; }\nvec4 mod289(const in vec4 x) { return x - floor(x * (1. / 289.)) * 289.; }\n\n#endif\n","/*\ncontributors: [Stefan Gustavson, Ian McEwan]\ndescription: Fast, accurate inverse square root. \nuse: <float|vec2|vec3|vec4> taylorInvSqrt(<float|vec2|vec3|vec4> x)\n*/\n\n#ifndef FNC_TAYLORINVSQRT\n#define FNC_TAYLORINVSQRT\nfloat taylorInvSqrt(in float r) { return 1.79284291400159 - 0.85373472095314 * r; }\nvec2 taylorInvSqrt(in vec2 r) { return 1.79284291400159 - 0.85373472095314 * r; }\nvec3 taylorInvSqrt(in vec3 r) { return 1.79284291400159 - 0.85373472095314 * r; }\nvec4 taylorInvSqrt(in vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; }\n#endif","/*\ncontributors: [Stefan Gustavson, Ian McEwan]\ndescription: grad4, used for snoise(vec4 v)\nuse: grad4(<float> j, <vec4> ip)\n*/\n\n#ifndef FNC_GRAD4\n#define FNC_GRAD4\nvec4 grad4(float j, vec4 ip) {\n const vec4 ones = vec4(1.0, 1.0, 1.0, -1.0);\n vec4 p,s;\n p.xyz = floor( fract (vec3(j) * ip.xyz) * 7.0) * ip.z - 1.0;\n p.w = 1.5 - dot(abs(p.xyz), ones.xyz);\n s = vec4(lessThan(p, vec4(0.0)));\n p.xyz = p.xyz + (s.xyz*2.0 - 1.0) * s.www;\n return p;\n}\n#endif\n","/*\ncontributors: Patricio Gonzalez Vivo\ndescription: returns a 4x4 rotation matrix\nuse: <mat4> rotate4d(<vec3> axis, <float> radians)\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#ifndef FNC_ROTATE4D\n#define FNC_ROTATE4D\nmat4 rotate4d(in vec3 a, const in float r) {\n a = normalize(a);\n float s = sin(r);\n float c = cos(r);\n float oc = 1.0 - c;\n vec4 col1 = vec4(oc * a.x * a.x + c, oc * a.x * a.y + a.z * s, oc * a.z * a.x - a.y * s, 0.0);\n vec4 col2 = vec4(oc * a.x * a.y - a.z * s, oc * a.y * a.y + c, oc * a.y * a.z + a.x * s, 0.0);\n vec4 col3 = vec4(oc * a.z * a.x + a.y * s, oc * a.y * a.z - a.x * s, oc * a.z * a.z + c, 0.0);\n vec4 col4 = vec4(0.0, 0.0, 0.0, 1.0);\n return mat4(col1, col2, col3, col4);\n}\n#endif\n","/*\ncontributors: Inigo Quiles\ndescription: cubic polynomial https://iquilezles.org/articles/smoothsteps/\nuse: <float|vec2|vec3|vec4> cubic(<float|vec2|vec3|vec4> value[, <float> in, <float> out]);\nexamples:\n - https://raw.githubusercontent.com/patriciogonzalezvivo/lygia_examples/main/math_functions.frag\n*/\n\n#ifndef FNC_CUBIC\n#define FNC_CUBIC \nfloat cubic(const in float v) { return v*v*(3.0-2.0*v); }\nvec2 cubic(const in vec2 v) { return v*v*(3.0-2.0*v); }\nvec3 cubic(const in vec3 v) { return v*v*(3.0-2.0*v); }\nvec4 cubic(const in vec4 v) { return v*v*(3.0-2.0*v); }\n\nfloat cubic(const in float v, in float slope0, in float slope1) {\n float a = slope0 + slope1 - 2.;\n float b = -2. * slope0 - slope1 + 3.;\n float c = slope0;\n float v2 = v * v;\n float v3 = v * v2;\n return a * v3 + b * v2 + c * v;\n}\n\nvec2 cubic(const in vec2 v, in float slope0, in float slope1) {\n float a = slope0 + slope1 - 2.;\n float b = -2. * slope0 - slope1 + 3.;\n float c = slope0;\n vec2 v2 = v * v;\n vec2 v3 = v * v2;\n return a * v3 + b * v2 + c * v;\n}\n\nvec3 cubic(const in vec3 v, in float slope0, in float slope1) {\n float a = slope0 + slope1 - 2.;\n float b = -2. * slope0 - slope1 + 3.;\n float c = slope0;\n vec3 v2 = v * v;\n vec3 v3 = v * v2;\n return a * v3 + b * v2 + c * v;\n}\n\nvec4 cubic(const in vec4 v, in float slope0, in float slope1) {\n float a = slope0 + slope1 - 2.;\n float b = -2. * slope0 - slope1 + 3.;\n float c = slope0;\n vec4 v2 = v * v;\n vec4 v3 = v * v2;\n return a * v3 + b * v2 + c * v;\n}\n#endif","/*\ncontributors: Inigo Quiles\ndescription: quintic polynomial https://iquilezles.org/articles/smoothsteps/\nuse: <float|vec2|vec3|vec4> quintic(<float|vec2|vec3|vec4> value);\nexamples:\n - https://raw.githubusercontent.com/patriciogonzalezvivo/lygia_examples/main/math_functions.frag\n*/\n\n#ifndef FNC_QUINTIC\n#define FNC_QUINTIC \n\nfloat quintic(const in float v) { return v*v*v*(v*(v*6.0-15.0)+10.0); }\nvec2 quintic(const in vec2 v) { return v*v*v*(v*(v*6.0-15.0)+10.0); }\nvec3 quintic(const in vec3 v) { return v*v*v*(v*(v*6.0-15.0)+10.0); }\nvec4 quintic(const in vec4 v) { return v*v*v*(v*(v*6.0-15.0)+10.0); }\n\n#endif","/*\ncontributors: Patricio Gonzalez Vivo\ndescription: Sum elements of a vector\nuse: <float> sum(<vec2|vec3|vec4> value)\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#ifndef FNC_SUM\n#define FNC_SUM\nfloat sum( float v ) { return v; }\nfloat sum( vec2 v ) { return v.x+v.y; }\nfloat sum( vec3 v ) { return v.x+v.y+v.z; }\nfloat sum( vec4 v ) { return v.x+v.y+v.z+v.w; }\n#endif\n","/*\ncontributors: Patricio Gonzalez Vivo\ndescription: clamp a value between 0 and 1\nuse: <float|vec2|vec3|vec4> saturation(<float|vec2|vec3|vec4> value)\nexamples:\n - https://raw.githubusercontent.com/patriciogonzalezvivo/lygia_examples/main/math_functions.frag\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#if !defined(FNC_SATURATE) && !defined(saturate)\n#define FNC_SATURATE\n#define saturate(V) clamp(V, 0.0, 1.0)\n#endif","/*\ncontributors: Patricio Gonzalez Vivo\ndescription: gaussian coefficient\nuse: <vec4|vec3|vec2|float> gaussian(<float> sigma, <vec4|vec3|vec2|float> d)\nexamples:\n - https://raw.githubusercontent.com/patriciogonzalezvivo/lygia_examples/main/math_gaussian.frag\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#ifndef FNC_GAUSSIAN\n#define FNC_GAUSSIAN\nfloat gaussian(float d, float s) { return exp(-(d*d) / (2.0 * s*s)); }\nfloat gaussian( vec2 d, float s) { return exp(-( d.x*d.x + d.y*d.y) / (2.0 * s*s)); }\nfloat gaussian( vec3 d, float s) { return exp(-( d.x*d.x + d.y*d.y + d.z*d.z ) / (2.0 * s*s)); }\nfloat gaussian( vec4 d, float s) { return exp(-( d.x*d.x + d.y*d.y + d.z*d.z + d.w*d.w ) / (2.0 * s*s)); }\n#endif","/*\ncontributors: Patricio Gonzalez Vivo\ndescription: \"Fix the aspect ratio of a space keeping things squared for you, \\nin\\\n \\ a similar way that aspect.glsl does, but while scaling the \\nspace to keep the\\\n \\ entire 0.0,0.0 ~ 1.0,1.0 range visible\\n\"\nuse: <vec2> ratio(<vec2> st, <vec2> st_size)\nexamples:\n - https://raw.githubusercontent.com/patriciogonzalezvivo/lygia_examples/main/draw_shapes.frag\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#ifndef FNC_RATIO\n#define FNC_RATIO\nvec2 ratio(in vec2 v, in vec2 s) {\n return mix( vec2((v.x*s.x/s.y)-(s.x*.5-s.y*.5)/s.y,v.y),\n vec2(v.x,v.y*(s.y/s.x)-(s.y*.5-s.x*.5)/s.x),\n step(s.x,s.y));\n}\n#endif\n","/*\ncontributors: [\"Patricio Gonzalez Vivo\", \"David Hoskins\", \"Inigo Quilez\"]\ndescription: Pass a value and get some random normalize value between 0 and 1\nuse: float random[2|3](<float|vec2|vec3> value)\noptions:\n - RANDOM_HIGHER_RANGE: for working with a range over 0 and 1\n - RANDOM_SINLESS: Use sin-less random, which tolerates bigger values before producing pattern. From https://www.shadertoy.com/view/4djSRW\n - RANDOM_SCALE: by default this scale if for number with a big range. For producing good random between 0 and 1 use bigger range\nexamples:\n - /shaders/generative_random.frag\nlicense:\n - MIT License (MIT) Copyright 2014, David Hoskins\n*/\n\n#ifndef RANDOM_SCALE\n#ifdef RANDOM_HIGHER_RANGE\n#define RANDOM_SCALE vec4(.1031, .1030, .0973, .1099)\n#else\n#define RANDOM_SCALE vec4(443.897, 441.423, .0973, .1099)\n#endif\n#endif\n\n#ifndef FNC_RANDOM\n#define FNC_RANDOM\nfloat random(in float x) {\n#ifdef RANDOM_SINLESS\n x = fract(x * RANDOM_SCALE.x);\n x *= x + 33.33;\n x *= x + x;\n return fract(x);\n#else\n return fract(sin(x) * 43758.5453);\n#endif\n}\n\nfloat random(in vec2 st) {\n#ifdef RANDOM_SINLESS\n vec3 p3 = fract(vec3(st.xyx) * RANDOM_SCALE.xyz);\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n#else\n return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453);\n#endif\n}\n\nfloat random(in vec3 pos) {\n#ifdef RANDOM_SINLESS\n pos = fract(pos * RANDOM_SCALE.xyz);\n pos += dot(pos, pos.zyx + 31.32);\n return fract((pos.x + pos.y) * pos.z);\n#else\n return fract(sin(dot(pos.xyz, vec3(70.9898, 78.233, 32.4355))) * 43758.5453123);\n#endif\n}\n\nfloat random(in vec4 pos) {\n#ifdef RANDOM_SINLESS\n pos = fract(pos * RANDOM_SCALE);\n pos += dot(pos, pos.wzxy + 33.33);\n return fract((pos.x + pos.y) * (pos.z + pos.w));\n#else\n float dot_product = dot(pos, vec4(12.9898,78.233,45.164,94.673));\n return fract(sin(dot_product) * 43758.5453);\n#endif\n}\n\nvec2 random2(float p) {\n vec3 p3 = fract(vec3(p) * RANDOM_SCALE.xyz);\n p3 += dot(p3, p3.yzx + 19.19);\n return fract((p3.xx + p3.yz) * p3.zy);\n}\n\nvec2 random2(vec2 p) {\n vec3 p3 = fract(p.xyx * RANDOM_SCALE.xyz);\n p3 += dot(p3, p3.yzx + 19.19);\n return fract((p3.xx + p3.yz) * p3.zy);\n}\n\nvec2 random2(vec3 p3) {\n p3 = fract(p3 * RANDOM_SCALE.xyz);\n p3 += dot(p3, p3.yzx + 19.19);\n return fract((p3.xx + p3.yz) * p3.zy);\n}\n\nvec3 random3(float p) {\n vec3 p3 = fract(vec3(p) * RANDOM_SCALE.xyz);\n p3 += dot(p3, p3.yzx + 19.19);\n return fract((p3.xxy + p3.yzz) * p3.zyx); \n}\n\nvec3 random3(vec2 p) {\n vec3 p3 = fract(vec3(p.xyx) * RANDOM_SCALE.xyz);\n p3 += dot(p3, p3.yxz + 19.19);\n return fract((p3.xxy + p3.yzz) * p3.zyx);\n}\n\nvec3 random3(vec3 p) {\n p = fract(p * RANDOM_SCALE.xyz);\n p += dot(p, p.yxz + 19.19);\n return fract((p.xxy + p.yzz) * p.zyx);\n}\n\nvec4 random4(float p) {\n vec4 p4 = fract(p * RANDOM_SCALE);\n p4 += dot(p4, p4.wzxy + 19.19);\n return fract((p4.xxyz + p4.yzzw) * p4.zywx); \n}\n\nvec4 random4(vec2 p) {\n vec4 p4 = fract(p.xyxy * RANDOM_SCALE);\n p4 += dot(p4, p4.wzxy + 19.19);\n return fract((p4.xxyz + p4.yzzw) * p4.zywx);\n}\n\nvec4 random4(vec3 p) {\n vec4 p4 = fract(p.xyzx * RANDOM_SCALE);\n p4 += dot(p4, p4.wzxy + 19.19);\n return fract((p4.xxyz + p4.yzzw) * p4.zywx);\n}\n\nvec4 random4(vec4 p4) {\n p4 = fract(p4 * RANDOM_SCALE);\n p4 += dot(p4, p4.wzxy + 19.19);\n return fract((p4.xxyz + p4.yzzw) * p4.zywx);\n}\n#endif","/*\ncontributors: Patricio Gonzalez Vivo\ndescription: Signed Random\nuse: srandomX(<vec2|vec3> x)\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#ifndef FNC_SRANDOM\n#define FNC_SRANDOM\n\nfloat srandom(in float x) {\n return -1. + 2. * fract(sin(x) * 43758.5453);\n}\n\nfloat srandom(in vec2 st) {\n return -1. + 2. * fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453);\n}\n\nfloat srandom(in vec3 pos) {\n return -1. + 2. * fract(sin(dot(pos.xyz, vec3(70.9898, 78.233, 32.4355))) * 43758.5453123);\n}\n\nfloat srandom(in vec4 pos) {\n float dot_product = dot(pos, vec4(12.9898,78.233,45.164,94.673));\n return -1. + 2. * fract(sin(dot_product) * 43758.5453);\n}\n\nvec2 srandom2(in vec2 st) {\n const vec2 k = vec2(.3183099, .3678794);\n st = st * k + k.yx;\n return -1. + 2. * fract(16. * k * fract(st.x * st.y * (st.x + st.y)));\n}\n\nvec3 srandom3(in vec3 p) {\n p = vec3( dot(p, vec3(127.1, 311.7, 74.7)),\n dot(p, vec3(269.5, 183.3, 246.1)),\n dot(p, vec3(113.5, 271.9, 124.6)));\n return -1. + 2. * fract(sin(p) * 43758.5453123);\n}\n\nvec2 srandom2(in vec2 p, const in float tileLength) {\n p = mod(p, vec2(tileLength));\n return srandom2(p);\n}\n\nvec3 srandom3(in vec3 p, const in float tileLength) {\n p = mod(p, vec3(tileLength));\n return srandom3(p);\n}\n\n#endif","#include \"random.glsl\"\n#include \"srandom.glsl\"\n#include \"../math/cubic.glsl\"\n#include \"../math/quintic.glsl\"\n\n/*\ncontributors: Patricio Gonzalez Vivo\ndescription: Gradient Noise\nuse: gnoise(<float> x)\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#ifndef FNC_GNOISE\n#define FNC_GNOISE\n\nfloat gnoise(float x) {\n float i = floor(x); // integer\n float f = fract(x); // fraction\n return mix(random(i), random(i + 1.0), smoothstep(0.,1.,f)); \n}\n\nfloat gnoise(vec2 st) {\n vec2 i = floor(st);\n vec2 f = fract(st);\n float a = random(i);\n float b = random(i + vec2(1.0, 0.0));\n float c = random(i + vec2(0.0, 1.0));\n float d = random(i + vec2(1.0, 1.0));\n vec2 u = cubic(f);\n return mix( a, b, u.x) +\n (c - a)* u.y * (1.0 - u.x) +\n (d - b) * u.x * u.y;\n}\n\nfloat gnoise(vec3 p) {\n vec3 i = floor(p);\n vec3 f = fract(p);\n vec3 u = quintic(f);\n return -1.0 + 2.0 * mix( mix( mix( random(i + vec3(0.0,0.0,0.0)), \n random(i + vec3(1.0,0.0,0.0)), u.x),\n mix( random(i + vec3(0.0,1.0,0.0)), \n random(i + vec3(1.0,1.0,0.0)), u.x), u.y),\n mix( mix( random(i + vec3(0.0,0.0,1.0)), \n random(i + vec3(1.0,0.0,1.0)), u.x),\n mix( random(i + vec3(0.0,1.0,1.0)), \n random(i + vec3(1.0,1.0,1.0)), u.x), u.y), u.z );\n}\n\nfloat gnoise(vec3 p, float tileLength) {\n vec3 i = floor(p);\n vec3 f = fract(p);\n \n vec3 u = quintic(f);\n \n return mix( mix( mix( dot( srandom3(i + vec3(0.0,0.0,0.0), tileLength), f - vec3(0.0,0.0,0.0)), \n dot( srandom3(i + vec3(1.0,0.0,0.0), tileLength), f - vec3(1.0,0.0,0.0)), u.x),\n mix( dot( srandom3(i + vec3(0.0,1.0,0.0), tileLength), f - vec3(0.0,1.0,0.0)), \n dot( srandom3(i + vec3(1.0,1.0,0.0), tileLength), f - vec3(1.0,1.0,0.0)), u.x), u.y),\n mix( mix( dot( srandom3(i + vec3(0.0,0.0,1.0), tileLength), f - vec3(0.0,0.0,1.0)), \n dot( srandom3(i + vec3(1.0,0.0,1.0), tileLength), f - vec3(1.0,0.0,1.0)), u.x),\n mix( dot( srandom3(i + vec3(0.0,1.0,1.0), tileLength), f - vec3(0.0,1.0,1.0)), \n dot( srandom3(i + vec3(1.0,1.0,1.0), tileLength), f - vec3(1.0,1.0,1.0)), u.x), u.y), u.z );\n}\n\nvec3 gnoise3(vec3 x) {\n return vec3(gnoise(x+vec3(123.456, 0.567, 0.37)),\n gnoise(x+vec3(0.11, 47.43, 19.17)),\n gnoise(x) );\n}\n\n#endif","#include \"../math/mod289.glsl\"\n#include \"../math/permute.glsl\"\n#include \"../math/taylorInvSqrt.glsl\"\n#include \"../math/grad4.glsl\"\n\n/*\ncontributors: [Stefan Gustavson, Ian McEwan]\ndescription: Simplex Noise https://github.com/stegu/webgl-noise\nuse: snoise(<vec2|vec3|vec4> pos)\nlicense: |\n Copyright 2021-2023 by Stefan Gustavson and Ian McEwan.\n Published under the terms of the MIT license:\n https://opensource.org/license/mit/\nexamples:\n - /shaders/generative_snoise.frag\n*/\n\n#ifndef FNC_SNOISE\n#define FNC_SNOISE\nfloat snoise(in vec2 v) {\n const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0\n 0.366025403784439, // 0.5*(sqrt(3.0)-1.0)\n -0.577350269189626, // -1.0 + 2.0 * C.x\n 0.024390243902439); // 1.0 / 41.0\n // First corner\n vec2 i = floor(v + dot(v, C.yy) );\n vec2 x0 = v - i + dot(i, C.xx);\n\n // Other corners\n vec2 i1;\n //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0\n //i1.y = 1.0 - i1.x;\n i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n // x0 = x0 - 0.0 + 0.0 * C.xx ;\n // x1 = x0 - i1 + 1.0 * C.xx ;\n // x2 = x0 - 1.0 + 2.0 * C.xx ;\n vec4 x12 = x0.xyxy + C.xxzz;\n x12.xy -= i1;\n\n // Permutations\n i = mod289(i); // Avoid truncation effects in permutation\n vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))\n + i.x + vec3(0.0, i1.x, 1.0 ));\n\n vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);\n m = m*m ;\n m = m*m ;\n\n // Gradients: 41 points uniformly over a line, mapped onto a diamond.\n // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)\n\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\n vec3 h = abs(x) - 0.5;\n vec3 ox = floor(x + 0.5);\n vec3 a0 = x - ox;\n\n // Normalise gradients implicitly by scaling m\n // Approximation of: m *= inversesqrt( a0*a0 + h*h );\n m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );\n\n // Compute final noise value at P\n vec3 g;\n g.x = a0.x * x0.x + h.x * x0.y;\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n return 130.0 * dot(m, g);\n}\n\n\nfloat snoise(in vec3 v) {\n const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;\n const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);\n\n // First corner\n vec3 i = floor(v + dot(v, C.yyy) );\n vec3 x0 = v - i + dot(i, C.xxx) ;\n\n // Other corners\n vec3 g = step(x0.yzx, x0.xyz);\n vec3 l = 1.0 - g;\n vec3 i1 = min( g.xyz, l.zxy );\n vec3 i2 = max( g.xyz, l.zxy );\n\n // x0 = x0 - 0.0 + 0.0 * C.xxx;\n // x1 = x0 - i1 + 1.0 * C.xxx;\n // x2 = x0 - i2 + 2.0 * C.xxx;\n // x3 = x0 - 1.0 + 3.0 * C.xxx;\n vec3 x1 = x0 - i1 + C.xxx;\n vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y\n vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y\n\n // Permutations\n i = mod289(i);\n vec4 p = permute( permute( permute(\n i.z + vec4(0.0, i1.z, i2.z, 1.0 ))\n + i.y + vec4(0.0, i1.y, i2.y, 1.0 ))\n + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));\n\n // Gradients: 7x7 points over a square, mapped onto an octahedron.\n // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)\n float n_ = 0.142857142857; // 1.0/7.0\n vec3 ns = n_ * D.wyz - D.xzx;\n\n vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)\n\n vec4 x_ = floor(j * ns.z);\n vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)\n\n vec4 x = x_ *ns.x + ns.yyyy;\n vec4 y = y_ *ns.x + ns.yyyy;\n vec4 h = 1.0 - abs(x) - abs(y);\n\n vec4 b0 = vec4( x.xy, y.xy );\n vec4 b1 = vec4( x.zw, y.zw );\n\n //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;\n //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;\n vec4 s0 = floor(b0)*2.0 + 1.0;\n vec4 s1 = floor(b1)*2.0 + 1.0;\n vec4 sh = -step(h, vec4(0.0));\n\n vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;\n vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;\n\n vec3 p0 = vec3(a0.xy,h.x);\n vec3 p1 = vec3(a0.zw,h.y);\n vec3 p2 = vec3(a1.xy,h.z);\n vec3 p3 = vec3(a1.zw,h.w);\n\n //Normalise gradients\n vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));\n p0 *= norm.x;\n p1 *= norm.y;\n p2 *= norm.z;\n p3 *= norm.w;\n\n // Mix final noise value\n vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);\n m = m * m;\n return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1),\n dot(p2,x2), dot(p3,x3) ) );\n}\n\nfloat snoise(in vec4 v) {\n const vec4 C = vec4( 0.138196601125011, // (5 - sqrt(5))/20 G4\n 0.276393202250021, // 2 * G4\n 0.414589803375032, // 3 * G4\n -0.447213595499958); // -1 + 4 * G4\n\n // First corner\n vec4 i = floor(v + dot(v, vec4(.309016994374947451)) ); // (sqrt(5) - 1)/4\n vec4 x0 = v - i + dot(i, C.xxxx);\n\n // Other corners\n\n // Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI)\n vec4 i0;\n vec3 isX = step( x0.yzw, x0.xxx );\n vec3 isYZ = step( x0.zww, x0.yyz );\n // i0.x = dot( isX, vec3( 1.0 ) );\n i0.x = isX.x + isX.y + isX.z;\n i0.yzw = 1.0 - isX;\n // i0.y += dot( isYZ.xy, vec2( 1.0 ) );\n i0.y += isYZ.x + isYZ.y;\n i0.zw += 1.0 - isYZ.xy;\n i0.z += isYZ.z;\n i0.w += 1.0 - isYZ.z;\n\n // i0 now contains the unique values 0,1,2,3 in each channel\n vec4 i3 = clamp( i0, 0.0, 1.0 );\n vec4 i2 = clamp( i0-1.0, 0.0, 1.0 );\n vec4 i1 = clamp( i0-2.0, 0.0, 1.0 );\n\n // x0 = x0 - 0.0 + 0.0 * C.xxxx\n // x1 = x0 - i1 + 1.0 * C.xxxx\n // x2 = x0 - i2 + 2.0 * C.xxxx\n // x3 = x0 - i3 + 3.0 * C.xxxx\n // x4 = x0 - 1.0 + 4.0 * C.xxxx\n vec4 x1 = x0 - i1 + C.xxxx;\n vec4 x2 = x0 - i2 + C.yyyy;\n vec4 x3 = x0 - i3 + C.zzzz;\n vec4 x4 = x0 + C.wwww;\n\n // Permutations\n i = mod289(i);\n float j0 = permute( permute( permute( permute(i.w) + i.z) + i.y) + i.x);\n vec4 j1 = permute( permute( permute( permute (\n i.w + vec4(i1.w, i2.w, i3.w, 1.0 ))\n + i.z + vec4(i1.z, i2.z, i3.z, 1.0 ))\n + i.y + vec4(i1.y, i2.y, i3.y, 1.0 ))\n + i.x + vec4(i1.x, i2.x, i3.x, 1.0 ));\n\n // Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope\n // 7*7*6 = 294, which is close to the ring size 17*17 = 289.\n vec4 ip = vec4(1.0/294.0, 1.0/49.0, 1.0/7.0, 0.0) ;\n\n vec4 p0 = grad4(j0, ip);\n vec4 p1 = grad4(j1.x, ip);\n vec4 p2 = grad4(j1.y, ip);\n vec4 p3 = grad4(j1.z, ip);\n vec4 p4 = grad4(j1.w, ip);\n\n // Normalise gradients\n vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));\n p0 *= norm.x;\n p1 *= norm.y;\n p2 *= norm.z;\n p3 *= norm.w;\n p4 *= taylorInvSqrt(dot(p4,p4));\n\n // Mix contributions from the five corners\n vec3 m0 = max(0.6 - vec3(dot(x0,x0), dot(x1,x1), dot(x2,x2)), 0.0);\n vec2 m1 = max(0.6 - vec2(dot(x3,x3), dot(x4,x4) ), 0.0);\n m0 = m0 * m0;\n m1 = m1 * m1;\n return 49.0 * ( dot(m0*m0, vec3( dot( p0, x0 ), dot( p1, x1 ), dot( p2, x2 )))\n + dot(m1*m1, vec2( dot( p3, x3 ), dot( p4, x4 ) ) ) ) ;\n}\n\nvec2 snoise2( vec2 x ){\n float s = snoise(vec2( x ));\n float s1 = snoise(vec2( x.y - 19.1, x.x + 47.2 ));\n return vec2( s , s1 );\n}\n\nvec3 snoise3( vec3 x ){\n float s = snoise(vec3( x ));\n float s1 = snoise(vec3( x.y - 19.1 , x.z + 33.4 , x.x + 47.2 ));\n float s2 = snoise(vec3( x.z + 74.2 , x.x - 124.5 , x.y + 99.4 ));\n return vec3( s , s1 , s2 );\n}\n\nvec3 snoise3( vec4 x ){\n float s = snoise(vec4( x ));\n float s1 = snoise(vec4( x.y - 19.1 , x.z + 33.4 , x.x + 47.2, x.w ));\n float s2 = snoise(vec4( x.z + 74.2 , x.x - 124.5 , x.y + 99.4, x.w ));\n return vec3( s , s1 , s2 );\n}\n\n#endif\n","#include \"snoise.glsl\"\n#include \"gnoise.glsl\"\n\n\n/*\ncontributors: Patricio Gonzalez Vivo\ndescription: Fractal Brownian Motion\nuse: fbm(<vec2> pos)\noptions:\n FBM_OCTAVES: numbers of octaves. Default is 4.\n FBM_NOISE_FNC(UV): noise function to use Default 'snoise(UV)' (simplex noise)\n FBM_VALUE_INITIAL: initial value. Default is 0.\n FBM_SCALE_SCALAR: scalar. Default is 2.\n FBM_AMPLITUDE_INITIAL: initial amplitude value. Default is 0.5\n FBM_AMPLITUDE_SCALAR: amplitude scalar. Default is 0.5\nexamples:\n - /shaders/generative_fbm.frag\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#ifndef FBM_OCTAVES\n#define FBM_OCTAVES 4\n#endif\n\n#ifndef FBM_NOISE_FNC\n#define FBM_NOISE_FNC(UV) snoise(UV)\n#endif\n\n#ifndef FBM_NOISE2_FNC\n#define FBM_NOISE2_FNC(UV) FBM_NOISE_FNC(UV)\n#endif\n\n#ifndef FBM_NOISE3_FNC\n#define FBM_NOISE3_FNC(UV) FBM_NOISE_FNC(UV)\n#endif\n\n#ifndef FBM_NOISE_TILABLE_FNC\n#define FBM_NOISE_TILABLE_FNC(UV, TILE) gnoise(UV, TILE)\n#endif\n\n#ifndef FBM_NOISE3_TILABLE_FNC\n#define FBM_NOISE3_TILABLE_FNC(UV, TILE) FBM_NOISE_TILABLE_FNC(UV, TILE)\n#endif\n\n#ifndef FBM_NOISE_TYPE\n#define FBM_NOISE_TYPE float\n#endif\n\n#ifndef FBM_VALUE_INITIAL\n#define FBM_VALUE_INITIAL 0.0\n#endif\n\n#ifndef FBM_SCALE_SCALAR\n#define FBM_SCALE_SCALAR 2.0\n#endif\n\n#ifndef FBM_AMPLITUDE_INITIAL\n#define FBM_AMPLITUDE_INITIAL 0.5\n#endif\n\n#ifndef FBM_AMPLITUDE_SCALAR\n#define FBM_AMPLITUDE_SCALAR 0.5\n#endif\n\n#ifndef FNC_FBM\n#define FNC_FBM\nFBM_NOISE_TYPE fbm(in vec2 st) {\n // Initial values\n FBM_NOISE_TYPE value = FBM_NOISE_TYPE(FBM_VALUE_INITIAL);\n float amplitude = FBM_AMPLITUDE_INITIAL;\n\n // Loop of octaves\n for (int i = 0; i < FBM_OCTAVES; i++) {\n value += amplitude * FBM_NOISE2_FNC(st);\n st *= FBM_SCALE_SCALAR;\n amplitude *= FBM_AMPLITUDE_SCALAR;\n }\n return value;\n}\n\nFBM_NOISE_TYPE fbm(in vec3 pos) {\n // Initial values\n FBM_NOISE_TYPE value = FBM_NOISE_TYPE(FBM_VALUE_INITIAL);\n float amplitude = FBM_AMPLITUDE_INITIAL;\n\n // Loop of octaves\n for (int i = 0; i < FBM_OCTAVES; i++) {\n value += amplitude * FBM_NOISE3_FNC(pos);\n pos *= FBM_SCALE_SCALAR;\n amplitude *= FBM_AMPLITUDE_SCALAR;\n }\n return value;\n}\n\nFBM_NOISE_TYPE fbm(vec3 p, float tileLength) {\n const float persistence = 0.5;\n const float lacunarity = 2.0;\n\n float amplitude = 0.5;\n FBM_NOISE_TYPE total = FBM_NOISE_TYPE(0.0);\n float normalization = 0.0;\n\n for (int i = 0; i < FBM_OCTAVES; ++i) {\n float noiseValue = FBM_NOISE3_TILABLE_FNC(p, tileLength * lacunarity * 0.5) * 0.5 + 0.5;\n total += noiseValue * amplitude;\n normalization += amplitude;\n amplitude *= persistence;\n p = p * lacunarity;\n }\n\n return total / normalization;\n}\n#endif\n","#include \"../sampler.glsl\"\n#include \"../math/saturate.glsl\"\n#include \"../math/sum.glsl\"\n\n/*\ncontributors: Patricio Gonzalez Vivo\ndescription: \"morphological dilation operation. Based on: \\n https://lettier.github.io/3d-game-shaders-for-beginners/dilation.html\\n\\\n \\ https://www.shadertoy.com/view/WsyXWc\\n\"\nuse: dilation(<SAMPLER_TYPE> texture, <float2> st, <float2> pixels_scale, <int> passes)\noptions:\n - SAMPLER_FNC(TEX, UV): optional depending the target version of GLSL (texture2D(...) or texture(...))\n - DILATION_TYPE\n - DILATION_SAMPLE_FNC(TEX, UV)\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#ifndef DILATION_TYPE\n#define DILATION_TYPE float\n#endif\n\n#ifndef DILATION_MAX_RADIUS\n#define DILATION_MAX_RADIUS 16\n#endif\n\n#ifndef DILATION_SAMPLE_FNC\n#define DILATION_SAMPLE_FNC(TEX, UV) SAMPLER_FNC(TEX, UV).r\n#endif\n\n#ifndef FNC_DILATE\n#define FNC_DILATE\n\nDILATION_TYPE dilation(SAMPLER_TYPE tex, vec2 st, vec2 pixel, int radius) {\n float invKR = 1.0 / float(radius);\n DILATION_TYPE acc = DILATION_TYPE(0.0);\n float w = 0.0;\n\n #ifdef PLATFORM_WEBGL\n for(int i = -DILATION_MAX_RADIUS; i <= DILATION_MAX_RADIUS; ++i) {\n if (i >= radius) break;\n for(int j = -DILATION_MAX_RADIUS; j <= DILATION_MAX_RADIUS; ++j) {\n if (j >= radius) break;\n #else\n for(int i = -radius; i <= radius; ++i) {\n for(int j = -radius; j <= radius; ++j) {\n #endif\n vec2 rxy = vec2(ivec2(i, j));\n vec2 kst = rxy * invKR * 2.0;\n vec2 texOffset = st + rxy * pixel;\n float kernel = saturate(1.0 - dot(kst, kst));\n DILATION_TYPE t = DILATION_SAMPLE_FNC(tex, texOffset);\n DILATION_TYPE v = t + kernel;\n if (sum(v) > sum(acc)) {\n acc = v;\n w = kernel;\n }\n }\n }\n \n return acc - w;\n}\n\n#endif","/*\ncontributors: Patricio Gonzalez Vivo\ndescription: It defines the default sampler type and function for the shader based on the version of GLSL.\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n#ifndef SAMPLER_FNC\n#if __VERSION__ >= 300\n#define SAMPLER_FNC(TEX, UV) texture(TEX, UV)\n#else\n#define SAMPLER_FNC(TEX, UV) texture2D(TEX, UV)\n#endif\n#endif\n\n#ifndef SAMPLER_TYPE\n#define SAMPLER_TYPE sampler2D\n#endif","#include \"../sampler.glsl\"\n\n/*\ncontributors: Patricio Gonzalez Vivo\ndescription: fakes a clamp to edge texture\nuse: <vec4> sampleClamp2edge(<SAMPLER_TYPE> tex, <vec2> st [, <vec2> texResolution]);\noptions:\n - SAMPLER_FNC(TEX, UV)\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#ifndef FNC_SAMPLECLAMP2EDGE\n#define FNC_SAMPLECLAMP2EDGE\nvec4 sampleClamp2edge(SAMPLER_TYPE tex, vec2 st, vec2 texResolution) {\n vec2 pixel = 1.0/texResolution;\n return SAMPLER_FNC( tex, clamp(st, pixel, 1.0-pixel) );\n}\n\nvec4 sampleClamp2edge(SAMPLER_TYPE tex, vec2 st) { \n return SAMPLER_FNC( tex, clamp(st, vec2(0.01), vec2(0.99) ) ); \n}\n\nvec4 sampleClamp2edge(SAMPLER_TYPE tex, vec2 st, float edge) { \n return SAMPLER_FNC( tex, clamp(st, vec2(edge), vec2(1.0 - edge) ) ); \n}\n#endif","/*\ncontributors: Patricio Gonzalez Vivo\ndescription: |\n Draws all the digits of a floating point number, useful for debugging.\n Requires high precision to work properly.\nuse: digits(<vec2> st, <float> value [, <float> nDecDigit])\noptions:\n DIGITS_DECIMALS: number of decimals after the point, defaults to 2\n DIGITS_SIZE: size of the font, defaults to vec2(.025)\nexamples:\n - /shaders/draw_digits.frag\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#ifndef DIGITS_SIZE\n#define DIGITS_SIZE vec2(.02)\n#endif\n\n#ifndef DIGITS_DECIMALS\n#define DIGITS_DECIMALS 2.0\n#endif\n\n#ifndef DIGITS_VALUE_OFFSET\n#define DIGITS_VALUE_OFFSET vec2(-6.0, 3.0) \n#endif\n\n#ifndef FNC_DIGITS\n#define FNC_DIGITS\nfloat digits(in vec2 st, in float value, in float nDecDigit) {\n st /= DIGITS_SIZE;\n\n float absValue = abs(value);\n float biggestDigitIndex = max(floor(log2(absValue) / log2(10.)), 0.);\n float counter = floor(absValue);\n float nIntDigits = 1.;\n for (int i = 0; i < 9; i++) {\n counter = floor(counter*.1);\n nIntDigits++;\n if (counter == 0.)\n break;\n }\n\n float digit = 12.;\n float digitIndex = (nIntDigits-1.) - floor(st.x);\n if (digitIndex > (-nDecDigit - 1.5)) {\n if (digitIndex > biggestDigitIndex) {\n if (value < 0.) {\n if (digitIndex < (biggestDigitIndex+1.5)) {\n digit = 11.;\n }\n }\n } \n else {\n if (digitIndex == -1.) {\n if (nDecDigit > 0.) {\n digit = 10.;\n }\n } \n else {\n if (digitIndex < 0.) {\n digitIndex += 1.;\n }\n float digitValue = (absValue / (pow(10., digitIndex)));\n digit = mod(floor(0.0001+digitValue), 10.);\n }\n }\n }\n vec2 pos = vec2(fract(st.x), st.y);\n\n if (pos.x < 0.) return 0.;\n if (pos.y < 0.) return 0.;\n if (pos.x >= 1.) return 0.;\n if (pos.y >= 1.) return 0.;\n\n // make a 4x5 array of bits\n float bin = 0.;\n if (digit < 0.5) // 0\n bin = 7. + 5. * 16. + 5. * 256. + 5. * 4096. + 7. * 65536.; \n else if (digit < 1.5) // 1\n bin = 2. + 2. * 16. + 2. * 256. + 2. * 4096. + 2. * 65536.;\n else if (digit < 2.5) // 2\n bin = 7. + 1. * 16. + 7. * 256. + 4. * 4096. + 7. * 65536.;\n else if (digit < 3.5) // 3\n bin = 7. + 4. * 16. + 7. * 256. + 4. * 4096. + 7. * 65536.;\n else if (digit < 4.5) // 4\n bin = 4. + 7. * 16. + 5. * 256. + 1. * 4096. + 1. * 65536.;\n else if (digit < 5.5) // 5\n bin = 7. + 4. * 16. + 7. * 256. + 1. * 4096. + 7. * 65536.;\n else if (digit < 6.5) // 6\n bin = 7. + 5. * 16. + 7. * 256. + 1. * 4096. + 7. * 65536.;\n else if (digit < 7.5) // 7\n bin = 4. + 4. * 16. + 4. * 256. + 4. * 4096. + 7. * 65536.;\n else if (digit < 8.5) // 8\n bin = 7. + 5. * 16. + 7. * 256. + 5. * 4096. + 7. * 65536.;\n else if (digit < 9.5) // 9\n bin = 7. + 4. * 16. + 7. * 256. + 5. * 4096. + 7. * 65536.;\n else if (digit < 10.5) // '.'\n bin = 2. + 0. * 16. + 0. * 256. + 0. * 4096. + 0. * 65536.;\n else if (digit < 11.5) // '-'\n bin = 0. + 0. * 16. + 7. * 256. + 0. * 4096. + 0. * 65536.;\n\n vec2 pixel = floor(pos * vec2(4., 5.));\n return mod(floor(bin / pow(2., (pixel.x + (pixel.y * 4.)))), 2.);\n}\n\nfloat digits(in vec2 st, in float value, in float nDecDigit, in float nIntDigits) {\n vec2 st2 = st;\n float result = 0.0;\n float dig = nDecDigit;\n\n #ifndef DIGITS_LEADING_INT\n #if defined(PLATFORM_WEBGL)\n #define DIGITS_LEADING_INT 1.0\n #else\n #define DIGITS_LEADING_INT nIntDigits\n #endif\n #endif\n\n for (float i = DIGITS_LEADING_INT - 1.0; i > 0.0 ; i--) {\n if (i * 10.0 > value) {\n result += digits(st2, 0.0, 0.0);\n st2.x -= DIGITS_SIZE.x;\n }\n }\n result += digits(st2, value, nDecDigit);\n return result; \n}\n\nfloat digits(in vec2 st, in int value) {\n return digits(st, float(value), 0.0);\n}\n\nfloat digits(in vec2 st, in float value) {\n return digits(st, value, (DIGITS_DECIMALS));\n}\n\nfloat digits(in vec2 st, in vec2 v) {\n float rta = 0.0;\n for (int i = 0; i < 2; i++) {\n vec2 pos = st + vec2(float(i), 0.0) * DIGITS_SIZE * DIGITS_VALUE_OFFSET;\n float value = i == 0 ? v.x : v.y;\n rta += digits( pos, value );\n }\n return rta;\n}\n\nfloat digits(in vec2 st, in vec3 v) {\n float rta = 0.0;\n for (int i = 0; i < 3; i++) {\n vec2 pos = st + vec2(float(i), 0.0) * DIGITS_SIZE * DIGITS_VALUE_OFFSET;\n float value = i == 0 ? v.x : i == 1 ? v.y : v.z;\n rta += digits( pos, value );\n }\n return rta;\n}\n\nfloat digits(in vec2 st, in vec4 v) {\n float rta = 0.0;\n for (int i = 0; i < 4; i++) {\n vec2 pos = st + vec2(float(i), 0.0) * DIGITS_SIZE * DIGITS_VALUE_OFFSET;\n float value = i == 0 ? v.x : i == 1 ? v.y : i == 2 ? v.z : v.w;\n rta += digits( pos, value );\n }\n return rta;\n}\n\nfloat digits(in vec2 st, in mat2 _matrix) {\n float rta = 0.0;\n for (int i = 0; i < 2; i++) {\n for (int j = 0; j < 2; j++) {\n vec2 pos = st + vec2(float(i), float(j)) * DIGITS_SIZE * DIGITS_VALUE_OFFSET - DIGITS_SIZE * vec2(0.0, 3.0);\n float value = _matrix[j][i];\n rta += digits( pos, value );\n }\n }\n return rta;\n}\n\nfloat digits(in vec2 st, in mat3 _matrix) {\n float rta = 0.0;\n for (int i = 0; i < 3; i++) {\n for (int j = 0; j < 3; j++) {\n vec2 pos = st + vec2(float(i), float(j)) * DIGITS_SIZE * DIGITS_VALUE_OFFSET - DIGITS_SIZE * vec2(0.0, 6.0);\n float value = _matrix[j][i];\n rta += digits( pos, value );\n }\n }\n return rta;\n}\n\nfloat digits(in vec2 st, in mat4 _matrix) {\n float rta = 0.0;\n for (int i = 0; i < 4; i++) {\n for (int j = 0; j < 4; j++) {\n vec2 pos = st + vec2(float(i), float(j)) * DIGITS_SIZE * DIGITS_VALUE_OFFSET - DIGITS_SIZE * vec2(0.0, 9.0);\n float value = _matrix[j][i];\n rta += digits( pos, value );\n }\n }\n return rta;\n}\n#endif\n","#include \"../sampler.glsl\"\n\n/*\ncontributors:\n - Matt DesLauriers\n - Patricio Gonzalez Vivo\ndescription: Adapted versions from 5, 9 and 13 gaussian fast blur from https://github.com/Jam3/glsl-fast-gaussian-blur\nuse: gaussianBlur(<SAMPLER_TYPE> texture, <vec2> st, <vec2> pixel_direction [, const int kernelSize])\noptions:\n - GAUSSIANBLUR_AMOUNT: gaussianBlur5 gaussianBlur9 gaussianBlur13\n - GAUSSIANBLUR_2D: default to 1D\n - SAMPLER_FNC(TEX, UV): optional depending the target version of GLSL (texture2D(...) or texture(...))\nexamples:\n - /shaders/filter_gaussianBlur2D.frag\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#ifndef GAUSSIANBLUR_AMOUNT\n#define GAUSSIANBLUR_AMOUNT gaussianBlur13\n#endif\n\n#ifndef GAUSSIANBLUR_TYPE\n#define GAUSSIANBLUR_TYPE vec4\n#endif\n\n#ifndef GAUSSIANBLUR_SAMPLER_FNC\n#define GAUSSIANBLUR_SAMPLER_FNC(TEX, UV) SAMPLER_FNC(TEX, UV)\n#endif\n\n#include \"gaussianBlur/2D.glsl\"\n#include \"gaussianBlur/1D.glsl\"\n#include \"gaussianBlur/1D_fast13.glsl\"\n#include \"gaussianBlur/1D_fast9.glsl\"\n#include \"gaussianBlur/1D_fast5.glsl\"\n\n#ifndef FNC_GAUSSIANBLUR\n#define FNC_GAUSSIANBLUR\nGAUSSIANBLUR_TYPE gaussianBlur13(in SAMPLER_TYPE tex, in vec2 st, in vec2 offset) {\n#ifdef GAUSSIANBLUR_2D\n return gaussianBlur2D(tex, st, offset, 7);\n#else\n return gaussianBlur1D_fast13(tex, st, offset);\n#endif\n}\n\nGAUSSIANBLUR_TYPE gaussianBlur9(in SAMPLER_TYPE tex, in vec2 st, in vec2 offset) {\n#ifdef GAUSSIANBLUR_2D\n return gaussianBlur2D(tex, st, offset, 5);\n#else\n return gaussianBlur1D_fast9(tex, st, offset);\n#endif\n}\n\nGAUSSIANBLUR_TYPE gaussianBlur5(in SAMPLER_TYPE tex, in vec2 st, in vec2 offset) {\n#ifdef GAUSSIANBLUR_2D\n return gaussianBlur2D(tex, st, offset, 3);\n#else\n return gaussianBlur1D_fast5(tex, st, offset);\n#endif\n}\n\nGAUSSIANBLUR_TYPE gaussianBlur(in SAMPLER_TYPE tex, in vec2 st, in vec2 offset, const int kernelSize) {\n#ifdef GAUSSIANBLUR_2D\n return gaussianBlur2D(tex, st, offset, kernelSize);\n#else\n return gaussianBlur1D(tex, st, offset, kernelSize);\n#endif\n}\n\nGAUSSIANBLUR_TYPE gaussianBlur(in SAMPLER_TYPE tex, in vec2 st, in vec2 offset) {\n return GAUSSIANBLUR_AMOUNT(tex, st, offset);\n}\n#endif\n","#include \"../../math/gaussian.glsl\"\n#include \"../../sample/clamp2edge.glsl\"\n\n/*\ncontributors: Patricio Gonzalez Vivo\ndescription: Two dimension Gaussian Blur to be applied in only one passes\nuse: gaussianBlur2D(<SAMPLER_TYPE> texture, <vec2> st, <vec2> pixel_direction, const int kernelSize)\noptions:\n - SAMPLER_FNC(TEX, UV): optional depending the target version of GLSL (texture2D(...) or texture(...))\n - GAUSSIANBLUR2D_TYPE: Default `vec4`\n - GAUSSIANBLUR2D_SAMPLER_FNC(TEX, UV): Default `texture2D(tex, TEX, UV)`\n - GAUSSIANBLUR2D_KERNELSIZE: Use only for WebGL 1.0 and OpenGL ES 2.0 . For example RaspberryPis is not happy with dynamic loops. Default is 'kernelSize'\nexamples:\n - /shaders/filter_gaussianBlur2D.frag\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#ifndef GAUSSIANBLUR2D_TYPE\n#ifdef GAUSSIANBLUR_TYPE\n#define GAUSSIANBLUR2D_TYPE GAUSSIANBLUR_TYPE\n#else\n#define GAUSSIANBLUR2D_TYPE vec4\n#endif\n#endif\n\n#ifndef GAUSSIANBLUR2D_SAMPLER_FNC\n#ifdef GAUSSIANBLUR_SAMPLER_FNC\n#define GAUSSIANBLUR2D_SAMPLER_FNC(TEX, UV) GAUSSIANBLUR_SAMPLER_FNC(TEX, UV)\n#else\n#define GAUSSIANBLUR2D_SAMPLER_FNC(TEX, UV) sampleClamp2edge(TEX, UV)\n#endif\n#endif\n\n#ifndef FNC_GAUSSIANBLUR2D\n#define FNC_GAUSSIANBLUR2D\nGAUSSIANBLUR2D_TYPE gaussianBlur2D(in SAMPLER_TYPE tex, in vec2 st, in vec2 offset, const int kernelSize) {\n GAUSSIANBLUR2D_TYPE accumColor = GAUSSIANBLUR2D_TYPE(0.);\n \n #ifndef GAUSSIANBLUR2D_KERNELSIZE\n \n #if defined(PLATFORM_WEBGL)\n #define GAUSSIANBLUR2D_KERNELSIZE 20\n float kernelSizef = float(kernelSize);\n #else\n #define GAUSSIANBLUR2D_KERNELSIZE kernelSize\n float kernelSizef = float(GAUSSIANBLUR2D_KERNELSIZE);\n #endif\n\n #else\n float kernelSizef = float(GAUSSIANBLUR2D_KERNELSIZE);\n #endif\n\n float accumWeight = 0.;\n const float k = 0.15915494; // 1 / (2*PI)\n vec2 xy = vec2(0.0);\n for (int j = 0; j < GAUSSIANBLUR2D_KERNELSIZE; j++) {\n #if defined(PLATFORM_WEBGL)\n if (j >= kernelSize)\n break;\n #endif\n xy.y = -.5 * (kernelSizef - 1.) + float(j);\n for (int i = 0; i < GAUSSIANBLUR2D_KERNELSIZE; i++) {\n #if defined(PLATFORM_WEBGL)\n if (i >= kernelSize)\n break;\n #endif\n xy.x = -0.5 * (kernelSizef - 1.) + float(i);\n float weight = (k / kernelSizef) * gaussian(xy, kernelSizef);\n accumColor += weight * GAUSSIANBLUR2D_SAMPLER_FNC(tex, st + xy * offset);\n accumWeight += weight;\n }\n }\n return accumColor / accumWeight;\n}\n#endif\n","#include \"../../math/gaussian.glsl\"\n#include \"../../sample/clamp2edge.glsl\"\n\n/*\ncontributors: Patricio Gonzalez Vivo\ndescription: One dimension Gaussian Blur to be applied in two passes\nuse: gaussianBlur1D(<SAMPLER_TYPE> texture, <vec2> st, <vec2> pixel_direction , const int kernelSize)\noptions:\n - SAMPLER_FNC(TEX, UV): optional depending the target version of GLSL (texture2D(...) or texture(...))\n - GAUSSIANBLUR1D_TYPE: null\n - GAUSSIANBLUR1D_SAMPLER_FNC(TEX, UV): null\nlicense:\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0\n - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license\n*/\n\n#ifndef GAUSSIANBLUR1D_TYPE\n#ifdef GAUSSIANBLUR_TYPE\n#define GAUSSIANBLUR1D_TYPE GAUSSIANBLUR_TYPE\n#else\n#define GAUSSIANBLUR1D_TYPE vec4\n#endif\n#endif\n\n#ifndef GAUSSIANBLUR1D_SAMPLER_FNC\n#ifdef GAUSSIANBLUR_SAMPLER_FNC\n#define GAUSSIANBLUR1D_SAMPLER_FNC(TEX, UV) GAUSSIANBLUR_SAMPLER_FNC(TEX, UV)\n#else\n#define GAUSSIANBLUR1D_SAMPLER_FNC(TEX, UV) sampleClamp2edge(TEX, UV)\n#endif\n#endif\n\n#ifndef FNC_GAUSSIANBLUR1D\n#define FNC_GAUSSIANBLUR1D\n\n#ifdef PLATFORM_WEBGL\n\nGAUSSIANBLUR1D_TYPE gaussianBlur1D(in SAMPLER_TYPE tex,in vec2 st,in vec2 offset,const int kernelSize){\n GAUSSIANBLUR1D_TYPE accumColor = GAUSSIANBLUR1D_TYPE(0.0);\n\n float kernelSizef = float(kernelSize);\n float accumWeight = 0.0;\n const float k = 0.39894228;// 1 / sqrt(2*PI)\n for (int i = 0; i < 16; i++) {\n if( i >= kernelSize)\n break;\n float x = -0.5 * (float(kernelSize) - 1.0)+float(i);\n float weight = (k/float(kernelSize)) * gaussian(x, kernelSizef);\n GAUSSIANBLUR1D_TYPE tex = GAUSSIANBLUR1D_SAMPLER_FNC(tex, st + x * offset);\n accumColor += weight * tex;\n accumWeight += weight;\n }\n return accumColor/accumWeight;\n}\n\n#else\n\nGAUSSIANBLUR1D_TYPE gaussianBlur1D(in SAMPLER_TYPE tex,in vec2 st,in vec2 offset,const int kernelSize){\n GAUSSIANBLUR1D_TYPE accumColor=GAUSSIANBLUR1D_TYPE(0.);\n\n float kernelSizef = float(kernelSize);\n \n float accumWeight = 0.0;\n const float k = 0.39894228;// 1 / sqrt(2*PI)\n for (int i = 0; i < kernelSize; i++) {\n float x = -0.5 * ( kernelSizef -1.0) + float(i);\n float weight = (k / kernelSizef) * gaussian(x, kernelSizef);\n GAUSSIANBLUR1D_TYPE tex = GAUSSIANBLUR1D_SAMPLER_FNC(tex, st + x * offset);\n accumColor += weight * tex;\n accumWeight += weight;\n }\n return accumColor/accumWeight;\n}\n#endif\n\n#endif\n","#include \"../../sample/clamp2edge.glsl\"\n\n/*\nfunction: gaussianBlur1D_fast13\ncontributors: Matt DesLauriers\ndescription: Adapted versions of gaussian fast blur 13 from https://github.com/Jam3/glsl-fast-gaussian-blur\nuse: gaussianBlur1D_fast13(<SAMPLER_TYPE> texture, <vec2> st, <vec2> pixel_direction)\noptions:\n - SAMPLER_FNC(TEX, UV): optional depending the target version of GLSL (texture2D(...) or texture(...))\n - GAUSSIANBLUR1D_FAST13_TYPE\n - GAUSSIANBLUR1D_FAST13_SAMPLER_FNC(TEX, UV)\n*/\n\n#ifndef GAUSSIANBLUR1D_FAST13_TYPE\n#ifdef GAUSSIANBLUR_TYPE\n#define GAUSSIANBLUR1D_FAST13_TYPE GAUSSIANBLUR_TYPE\n#else\n#define GAUSSIANBLUR1D_FAST13_TYPE vec4\n#endif\n#endif\n\n#ifndef GAUSSIANBLUR1D_FAST13_SAMPLER_FNC\n#ifdef GAUSSIANBLUR_SAMPLER_FNC\n#define GAUSSIANBLUR1D_FAST13_SAMPLER_FNC(TEX, UV) GAUSSIANBLUR_SAMPLER_FNC(TEX, UV)\n#else\n#define GAUSSIANBLUR1D_FAST13_SAMPLER_FNC(TEX, UV) sampleClamp2edge(TEX, UV)\n#endif\n#endif\n\n#ifndef FNC_GAUSSIANBLUR1D_FAST13\n#define FNC_GAUSSIANBLUR1D_FAST13\nGAUSSIANBLUR1D_FAST13_TYPE gaussianBlur1D_fast13(in SAMPLER_TYPE tex, in vec2 st, in vec2 offset) {\n GAUSSIANBLUR1D_FAST13_TYPE color = GAUSSIANBLUR1D_FAST13_TYPE(0.);\n vec2 off1 = vec2(1.411764705882353) * offset;\n vec2 off2 = vec2(3.2941176470588234) * offset;\n vec2 off3 = vec2(5.176470588235294) * offset;\n color += GAUSSIANBLUR1D_FAST13_SAMPLER_FNC(tex, st) * .1964825501511404;\n color += GAUSSIANBLUR1D_FAST13_SAMPLER_FNC(tex, st + (off1)) * .2969069646728344;\n color += GAUSSIANBLUR1D_FAST13_SAMPLER_FNC(tex, st - (off1)) * .2969069646728344;\n color += GAUSSIANBLUR1D_FAST13_SAMPLER_FNC(tex, st + (off2)) * .09447039785044732;\n color += GAUSSIANBLUR1D_FAST13_SAMPLER_FNC(tex, st - (off2)) * .09447039785044732;\n color += GAUSSIANBLUR1D_FAST13_SAMPLER_FNC(tex, st + (off3)) * .010381362401148057;\n color += GAUSSIANBLUR1D_FAST13_SAMPLER_FNC(tex, st - (off3)) * .010381362401148057;\n return color;\n}\n#endif\n","#include \"../../sample/clamp2edge.glsl\"\n\n/*\ncontributors: Matt DesLauriers\ndescription: Adapted versions of gaussian fast blur 13 from https://github.com/Jam3/glsl-fast-gaussian-blur\nuse: gaussianBlur1D_fast9(<SAMPLER_TYPE> texture, <vec2> st, <vec2> pixel_direction)\noptions:\n - SAMPLER_FNC(TEX, UV): optional depending the target version of GLSL (texture2D(...) or texture(...))\n - GAUSSIANBLUR1D_FAST9_TYPE\n - GAUSSIANBLUR1D_FAST9_SAMPLER_FNC(TEX, UV)\n*/\n\n#ifndef GAUSSIANBLUR1D_FAST9_TYPE\n#ifdef GAUSSIANBLUR_TYPE\n#define GAUSSIANBLUR1D_FAST9_TYPE GAUSSIANBLUR_TYPE\n#else\n#define GAUSSIANBLUR1D_FAST9_TYPE vec4\n#endif\n#endif\n\n#ifndef GAUSSIANBLUR1D_FAST9_SAMPLER_FNC\n#ifdef GAUSSIANBLUR_SAMPLER_FNC\n#define GAUSSIANBLUR1D_FAST9_SAMPLER_FNC(TEX, UV) GAUSSIANBLUR_SAMPLER_FNC(TEX, UV)\n#else\n#define GAUSSIANBLUR1D_FAST9_SAMPLER_FNC(TEX, UV) sampleClamp2edge(TEX, UV)\n#endif\n#endif\n\n#ifndef FNC_GAUSSIANBLUR1D_FAST9\n#define FNC_GAUSSIANBLUR1D_FAST9\nGAUSSIANBLUR1D_FAST9_TYPE gaussianBlur1D_fast9(in SAMPLER_TYPE tex, in vec2 st, in vec2 offset) {\n GAUSSIANBLUR1D_FAST9_TYPE color = GAUSSIANBLUR1D_FAST9_TYPE(0.);\n vec2 off1 = vec2(1.3846153846) * offset;\n vec2 off2 = vec2(3.2307692308) * offset;\n color += GAUSSIANBLUR1D_FAST9_SAMPLER_FNC(tex, st) * .2270270270;\n color += GAUSSIANBLUR1D_FAST9_SAMPLER_FNC(tex, st + (off1)) * .3162162162;\n color += GAUSSIANBLUR1D_FAST9_SAMPLER_FNC(tex, st - (off1)) * .3162162162;\n color += GAUSSIANBLUR1D_FAST9_SAMPLER_FNC(tex, st + (off2)) * .0702702703;\n color += GAUSSIANBLUR1D_FAST9_SAMPLER_FNC(tex, st - (off2)) * .0702702703;\n return color;\n}\n#endif\n","#include \"../../sample/clamp2edge.glsl\"\n\n/*\ncontributors: Matt DesLauriers\ndescription: Adapted versions of gaussian fast blur 13 from https://github.com/Jam3/glsl-fast-gaussian-blur\nuse: gaussianBlur1D_fast5(<SAMPLER_TYPE> texture, <vec2> st, <vec2> pixel_direction)\noptions:\n - SAMPLER_FNC(TEX, UV): optional depending the target version of GLSL (texture2D(...) or texture(...))\n - GAUSSIANBLUR1D_FAST5_TYPE\n - GAUSSIANBLUR1D_FAST5_SAMPLER_FNC(TEX, UV)\n*/\n\n#ifndef GAUSSIANBLUR1D_FAST5_TYPE\n#ifdef GAUSSIANBLUR_TYPE\n#define GAUSSIANBLUR1D_FAST5_TYPE GAUSSIANBLUR_TYPE\n#else\n#define GAUSSIANBLUR1D_FAST5_TYPE vec4\n#endif\n#endif\n\n#ifndef GAUSSIANBLUR1D_FAST5_SAMPLER_FNC\n#ifdef GAUSSIANBLUR_SAMPLER_FNC\n#define GAUSSIANBLUR1D_FAST5_SAMPLER_FNC(TEX, UV) GAUSSIANBLUR_SAMPLER_FNC(TEX, UV)\n#else\n#define GAUSSIANBLUR1D_FAST5_SAMPLER_FNC(TEX, UV) sampleClamp2edge(TEX, UV)\n#endif\n#endif\n\n#ifndef FNC_GAUSSIANBLUR1D_FAST5\n#define FNC_GAUSSIANBLUR1D_FAST5\nGAUSSIANBLUR1D_FAST5_TYPE gaussianBlur1D_fast5(in SAMPLER_TYPE tex, in vec2 st, in vec2 offset) {\n GAUSSIANBLUR1D_FAST5_TYPE color = GAUSSIANBLUR1D_FAST5_TYPE(0.);\n vec2 off1 = vec2(1.3333333333333333) * offset;\n color += GAUSSIANBLUR1D_FAST5_SAMPLER_FNC(tex, st) * .29411764705882354;\n color += GAUSSIANBLUR1D_FAST5_SAMPLER_FNC(tex, st + (off1)) * .35294117647058826;\n color += GAUSSIANBLUR1D_FAST5_SAMPLER_FNC(tex, st - (off1)) * .35294117647058826;\n return color;\n}\n#endif\n","#include \"../sampler.glsl\"\n\n/*\ncontributors: [Brad Larson, Ben Cochran, Hugues Lismonde, Keitaroh Kobayashi, Alaric Cole, Matthew Clark, Jacob Gundersen, Chris Williams.]\ndescription: Kuwahara image abstraction, drawn from the work of Kyprianidis, et. al. in their publication \"Anisotropic Kuwahara Filtering on the GPU\" within the GPU Pro collection. This produces an oil-painting-like image, but it is extremely computationally expensive, so it can take seconds to render a frame on an iPad 2. This might be best used for still images.\nuse: kuwahara(<SAMPLER_TYPE> texture, <vec2> st, <vec2> pixel, <float> radius)\noptions:\n - KUWAHARA_TYPE: defaults to vec3\n - KUWAHARA_SAMPLER_FNC(TEX, UV): defaults to texture2D(tex, TEX, UV).rgb\n - KUWAHARA_RADIUS radius\n - SAMPLER_FNC(TEX, UV): optional depending the target version of GLSL (texture2D(...) or texture(...))\n*/\n\n#ifndef KUWAHARA_TYPE\n#define KUWAHARA_TYPE vec4\n#endif\n\n#ifndef KUWAHARA_SAMPLER_FNC\n#define KUWAHARA_SAMPLER_FNC(TEX, UV) SAMPLER_FNC(TEX, UV)\n#endif\n\n#ifndef FNC_KUWAHARA\n#define FNC_KUWAHARA\n\n#ifdef TARGET_MOBILE\nKUWAHARA_TYPE kuwahara(in SAMPLER_TYPE tex, in vec2 st, in vec2 pixel, in float radius) {\n\n #ifndef KUWAHARA_RADIUS\n #define KUWAHARA_RADIUS radius\n #endif\n\n float n = (KUWAHARA_RADIUS + 1.0) * (KUWAHARA_RADIUS + 1.0);\n KUWAHARA_TYPE m0 = KUWAHARA_TYPE(0.0); KUWAHARA_TYPE m1 = KUWAHARA_TYPE(0.0); KUWAHARA_TYPE m2 = KUWAHARA_TYPE(0.0); KUWAHARA_TYPE m3 = KUWAHARA_TYPE(0.0);\n KUWAHARA_TYPE s0 = KUWAHARA_TYPE(0.0); KUWAHARA_TYPE s1 = KUWAHARA_TYPE(0.0); KUWAHARA_TYPE s2 = KUWAHARA_TYPE(0.0); KUWAHARA_TYPE s3 = KUWAHARA_TYPE(0.0);\n KUWAHARA_TYPE rta = KUWAHARA_TYPE(0.0);\n KUWAHARA_TYPE c = KUWAHARA_TYPE(0.0);\n\n for (float j = -KUWAHARA_RADIUS; j <= 0.0; ++j) {\n for (float i = -KUWAHARA_RADIUS; i <= 0.0; ++i) {\n c = KUWAHARA_SAMPLER_FNC(tex, st + vec2(i,j) * pixel);\n m0 += c;\n s0 += c * c;\n }\n }\n\n for (float j = -KUWAHARA_RADIUS; j <= 0.0; ++j) {\n for (float i = 0.0; i <= KUWAHARA_RADIUS; ++i) {\n c = KUWAHARA_SAMPLER_FNC(tex, st + vec2(i,j) * pixel);\n m1 += c;\n s1 += c * c;\n }\n }\n\n for (float j = 0.0; j <= KUWAHARA_RADIUS; ++j) {\n for (float i = 0.0; i <= KUWAHARA_RADIUS; ++i) {\n c = KUWAHARA_SAMPLER_FNC(tex, st + vec2(i,j) * pixel);\n m2 += c;\n s2 += c * c;\n }\n }\n\n for (float j = 0.0; j <= KUWAHARA_RADIUS; ++j) {\n for (float i = -KUWAHARA_RADIUS; i <= 0.0; ++i) {\n c = KUWAHARA_SAMPLER_FNC(tex, st + vec2(i,j) * pixel);\n m3 += c;\n s3 += c * c;\n }\n }\n\n float min_sigma2 = 1e+2;\n m0 /= n;\n s0 = abs(s0 / n - m0 * m0);\n\n float sigma2 = s0.r + s0.g + s0.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n rta = m0;\n }\n\n m1 /= n;\n s1 = abs(s1 / n - m1 * m1);\n\n sigma2 = s1.r + s1.g + s1.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n rta = m1;\n }\n\n m2 /= n;\n s2 = abs(s2 / n - m2 * m2);\n\n sigma2 = s2.r + s2.g + s2.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n rta = m2;\n }\n\n m3 /= n;\n s3 = abs(s3 / n - m3 * m3);\n\n sigma2 = s3.r + s3.g + s3.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n rta = m3;\n }\n\n return rta;\n}\n\n#else\n\nKUWAHARA_TYPE kuwahara(in SAMPLER_TYPE tex, in vec2 st, in vec2 pixel, in float radius) {\n\n #ifndef KUWAHARA_RADIUS\n\n #if defined(PLATFORM_WEBGL)\n #define KUWAHARA_RADIUS 20.0\n float n = (radius + 1.0) * (radius + 1.0);\n #else\n #define KUWAHARA_RADIUS radius\n float n = (KUWAHARA_RADIUS + 1.0) * (KUWAHARA_RADIUS + 1.0);\n #endif\n\n #else\n float n = (KUWAHARA_RADIUS + 1.0) * (KUWAHARA_RADIUS + 1.0);\n #endif\n\n KUWAHARA_TYPE m0 = KUWAHARA_TYPE(0.0); KUWAHARA_TYPE m1 = KUWAHARA_TYPE(0.0); KUWAHARA_TYPE m2 = KUWAHARA_TYPE(0.0); KUWAHARA_TYPE m3 = KUWAHARA_TYPE(0.0);\n KUWAHARA_TYPE s0 = KUWAHARA_TYPE(0.0); KUWAHARA_TYPE s1 = KUWAHARA_TYPE(0.0); KUWAHARA_TYPE s2 = KUWAHARA_TYPE(0.0); KUWAHARA_TYPE s3 = KUWAHARA_TYPE(0.0);\n KUWAHARA_TYPE rta = KUWAHARA_TYPE(0.0);\n KUWAHARA_TYPE c = KUWAHARA_TYPE(0.0);\n \n for (float j = -KUWAHARA_RADIUS; j <= 0.0; ++j) { \n for (float i = -KUWAHARA_RADIUS; i <= 0.0; ++i) {\n c = KUWAHARA_SAMPLER_FNC(tex, st + vec2(i,j) * pixel);\n m0 += c;\n s0 += c * c;\n }\n }\n \n for (float j = -KUWAHARA_RADIUS; j <= 0.0; ++j) {\n for (float i = 0.0; i <= KUWAHARA_RADIUS; ++i) {\n #if defined(PLATFORM_WEBGL)\n if (i > radius)\n break;\n #endif\n c = KUWAHARA_SAMPLER_FNC(tex, st + vec2(i,j) * pixel);\n m1 += c;\n s1 += c * c;\n }\n }\n \n for (float j = 0.0; j <= KUWAHARA_RADIUS; ++j) {\n #if defined(PLATFORM_WEBGL)\n if (j > radius)\n break;\n #endif\n for (float i = 0.0; i <= KUWAHARA_RADIUS; ++i) {\n #if defined(PLATFORM_WEBGL)\n if (i > radius)\n break;\n #endif\n c = KUWAHARA_SAMPLER_FNC(tex, st + vec2(i,j) * pixel);\n m2 += c;\n s2 += c * c;\n }\n }\n \n for (float j = 0.0; j <= KUWAHARA_RADIUS; ++j) {\n for (float i = -KUWAHARA_RADIUS; i <= 0.0; ++i) {\n c = KUWAHARA_SAMPLER_FNC(tex, st + vec2(i,j) * pixel);\n m3 += c;\n s3 += c * c;\n }\n }\n \n \n float min_sigma2 = 1e+2;\n m0 /= n;\n s0 = abs(s0 / n - m0 * m0);\n \n float sigma2 = s0.r + s0.g + s0.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n rta = m0;\n }\n \n m1 /= n;\n s1 = abs(s1 / n - m1 * m1);\n \n sigma2 = s1.r + s1.g + s1.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n rta = m1;\n }\n \n m2 /= n;\n s2 = abs(s2 / n - m2 * m2);\n \n sigma2 = s2.r + s2.g + s2.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n rta = m2;\n }\n \n m3 /= n;\n s3 = abs(s3 / n - m3 * m3);\n \n sigma2 = s3.r + s3.g + s3.b;\n if (sigma2 < min_sigma2) {\n min_sigma2 = sigma2;\n rta = m3;\n }\n\n return rta;\n}\n\n#endif\n\n#endif","export const glsl = (x: TemplateStringsArray): string => String.raw(x)\n","import { glsl } from './glsl'\n\nexport default glsl`\nmat3 rotationX(float angle) {\n float s = sin(angle);\n float c = cos(angle);\n return mat3(\n 1.0, 0.0, 0.0,\n 0.0, c, -s,\n 0.0, s, c\n );\n}\n\nmat3 rotationY(float angle) {\n float s = sin(angle);\n float c = cos(angle);\n return mat3(\n c, 0.0, s,\n 0.0, 1.0, 0.0,\n -s, 0.0, c\n );\n}\n\nvec4 defaultLighting(vec4 color, vec2 res, vec2 rot, float diff) {\n float aspectRatio = res.y / res.x;\n vec2 uv = (gl_FragCoord.xy / res.xy) * 2.0 - 1.0;\n vec2 specPos = vec2(rot.x * 3.8, rot.y * 2.2);\n\n vec3 baseNormal = vec3(0.0, 0.0, 1.0);\n mat3 rotMatrix = rotationX(rot.y) * rotationY(rot.x);\n vec3 normal = normalize(rotMatrix * baseNormal);\n\n vec3 lightDir = normalize(vec3(0.1, 0.5, 1.0));\n vec3 viewDir = normalize(vec3(0.0, 0.0, 1.0));\n\n vec3 halfDir = normalize(lightDir + viewDir);\n float spec = pow(max(dot(normal, halfDir), 0.0), 64.0);\n\n vec2 diffPos = uv - specPos;\n diffPos.y *= aspectRatio;\n float dist = length(diffPos);\n float mask = exp(-dist * 0.6);\n float lightFalloff = 1.0 / (dist + 1.3);\n spec *= mask * lightFalloff;\n\n return vec4(color.rgb * diff + vec3(1.0) * spec, 1.0);\n}\n`\n","import * as THREE from 'three'\nimport type { LayerSource } from '../types'\n\nconst VIDEO_EXTENSIONS = /\\.(mp4|webm|mov|ogg)(\\?|$)/i\nconst VIDEO_LOAD_TIMEOUT_MS = 15_000\n\nfunction isVideoSource(layer: LayerSource): boolean {\n if (layer.type) return layer.type === 'video'\n return VIDEO_EXTENSIONS.test(layer.src)\n}\n\nlet transparentTexture: THREE.Texture | null = null\nexport function getTransparentTexture(): THREE.Texture {\n if (!transparentTexture) {\n const data = new Uint8Array([0, 0, 0, 0])\n transparentTexture = new THREE.DataTexture(data, 1, 1, THREE.RGBAFormat)\n transparentTexture.needsUpdate = true\n }\n return transparentTexture\n}\n\nexport interface LoadedLayer {\n texture: THREE.Texture\n liveTexture?: THREE.Texture\n videoEl?: HTMLVideoElement\n play?: () => void\n}\n\nconst pendingVideos = new Set<HTMLVideoElement>()\n\nfunction debugLog(message: string, data?: Record<string, unknown>): void {\n try {\n if (globalThis.localStorage?.getItem('pocatoDebug') === '1') {\n console.warn(`[pocato] ${message}`, data ?? {})\n }\n } catch {\n // Ignore storage access errors.\n }\n}\n\nfunction applyVideoPlaybackOptions(video: HTMLVideoElement, layer: LayerSource): void {\n const playbackRate = layer.playbackRate ?? 1\n video.defaultPlaybackRate = playbackRate\n video.playbackRate = playbackRate\n}\n\nfunction getRandomValue(seed?: number): number {\n if (seed == null || !Number.isFinite(seed)) return Math.random()\n return Math.abs(seed) % 1\n}\n\nfunction getFreezeTargetTime(freezeTime: number, duration: number, seed?: number): number {\n if (freezeTime < 0) {\n return getRandomValue(seed) * (Number.isFinite(duration) ? duration : 1)\n }\n return Number.isFinite(duration) ? Math.min(freezeTime, duration) : freezeTime\n}\n\nfunction isAtTargetTime(video: HTMLVideoElement, targetTime: number): boolean {\n return Math.abs(video.currentTime - targetTime) < 0.05\n}\n\nexport function loadLayerTexture(\n layer: LayerSource,\n onError?: (error: Error) => void,\n): Promise<LoadedLayer> {\n if (isVideoSource(layer)) {\n if (layer.freeze != null) {\n return loadFrozenVideoTexture(layer, layer.freeze === 'random' ? -1 : layer.freeze, onError)\n }\n return loadVideoTexture(layer, onError)\n }\n return loadImageTexture(layer.src, onError)\n}\n\n// Dedup concurrent loads of the same URL\nconst inflight = new Map<string, Promise<THREE.Texture>>()\n\nfunction loadImageTexture(\n src: string,\n onError?: (error: Error) => void,\n): Promise<LoadedLayer> {\n let pending = inflight.get(src)\n if (!pending) {\n pending = new Promise<THREE.Texture>((resolve) => {\n const loader = new THREE.TextureLoader()\n loader.load(\n src,\n (texture) => { inflight.delete(src); resolve(texture) },\n undefined,\n () => {\n inflight.delete(src)\n onError?.(new Error(`Failed to load image texture: ${src}`))\n resolve(getTransparentTexture())\n },\n )\n })\n inflight.set(src, pending)\n }\n return pending.then((texture) => ({ texture }))\n}\n\nfunction loadVideoTexture(\n layer: LayerSource,\n onError?: (error: Error) => void,\n): Promise<LoadedLayer> {\n return new Promise((resolve) => {\n const video = document.createElement('video')\n video.crossOrigin = 'anonymous'\n video.muted = true\n video.loop = layer.loop ?? true\n applyVideoPlaybackOptions(video, layer)\n video.playsInline = true\n video.preload = 'auto'\n // Chrome/Safari won't decode frames for display:none elements.\n // Use off-screen 1px element instead.\n video.style.position = 'fixed'\n video.style.width = '1px'\n video.style.height = '1px'\n video.style.opacity = '0.01'\n video.style.pointerEvents = 'none'\n video.style.zIndex = '-9999'\n document.body.appendChild(video)\n\n pendingVideos.add(video)\n\n let settled = false\n const timeoutId = globalThis.setTimeout(() => {\n if (settled) return\n settled = true\n pendingVideos.delete(video)\n video.src = ''\n video.remove()\n onError?.(new Error(`Timed out loading video texture: ${layer.src}`))\n resolve({ texture: getTransparentTexture() })\n }, VIDEO_LOAD_TIMEOUT_MS)\n\n video.addEventListener('error', () => {\n if (settled) return\n settled = true\n globalThis.clearTimeout(timeoutId)\n pendingVideos.delete(video)\n const msg = video.error?.message ?? 'Unknown video error'\n onError?.(new Error(`Failed to load video texture: ${layer.src} (${msg})`))\n video.remove()\n resolve({ texture: getTransparentTexture() })\n }, { once: true })\n\n const resolveWithFrame = () => {\n if (settled) return\n settled = true\n globalThis.clearTimeout(timeoutId)\n video.pause()\n pendingVideos.delete(video)\n\n const canvas = document.createElement('canvas')\n canvas.width = video.videoWidth || 1\n canvas.height = video.videoHeight || 1\n const ctx = canvas.getContext('2d')\n let posterTexture: THREE.Texture = getTransparentTexture()\n if (ctx) {\n try {\n ctx.drawImage(video, 0, 0)\n posterTexture = new THREE.CanvasTexture(canvas)\n posterTexture.needsUpdate = true\n } catch (error) {\n debugLog('video poster drawImage failed', {\n src: layer.src,\n error: error instanceof Error ? error.message : String(error),\n })\n onError?.(error instanceof Error ? error : new Error(String(error)))\n }\n }\n\n const liveTexture = new THREE.VideoTexture(video)\n resolve({\n texture: posterTexture,\n liveTexture,\n videoEl: video,\n play: () => {\n video.play().catch(() => {\n onError?.(new Error(`Video autoplay blocked: ${layer.src}`))\n })\n },\n })\n }\n\n video.addEventListener('loadeddata', () => {\n resolveWithFrame()\n }, { once: true })\n\n video.src = layer.src\n video.load()\n })\n}\n\nfunction loadFrozenVideoTexture(\n layer: LayerSource,\n freezeTime: number,\n onError?: (error: Error) => void,\n): Promise<LoadedLayer> {\n return new Promise((resolve) => {\n debugLog('freeze load start', {\n src: layer.src,\n freezeTime,\n freezeSeed: layer.freezeSeed,\n })\n\n const video = document.createElement('video')\n video.crossOrigin = 'anonymous'\n video.muted = true\n applyVideoPlaybackOptions(video, layer)\n video.playsInline = true\n video.preload = 'auto'\n video.style.position = 'fixed'\n video.style.width = '1px'\n video.style.height = '1px'\n video.style.opacity = '0.01'\n video.style.pointerEvents = 'none'\n video.style.zIndex = '-9999'\n document.body.appendChild(video)\n\n pendingVideos.add(video)\n\n let settled = false\n let targetTime = 0\n let retrySeekRegistered = false\n\n const captureFrame = () => {\n if (settled) return\n settled = true\n video.pause()\n debugLog('freeze capture frame', {\n src: layer.src,\n currentTime: video.currentTime,\n duration: video.duration,\n readyState: video.readyState,\n videoWidth: video.videoWidth,\n videoHeight: video.videoHeight,\n })\n\n const canvas = document.createElement('canvas')\n canvas.width = video.videoWidth || 1\n canvas.height = video.videoHeight || 1\n const ctx = canvas.getContext('2d')\n if (!ctx) {\n pendingVideos.delete(video)\n video.src = ''\n video.remove()\n resolve({ texture: getTransparentTexture() })\n return\n }\n try {\n ctx.drawImage(video, 0, 0)\n } catch (error) {\n debugLog('freeze drawImage failed', {\n src: layer.src,\n error: error instanceof Error ? error.message : String(error),\n })\n pendingVideos.delete(video)\n video.src = ''\n video.remove()\n onError?.(error instanceof Error ? error : new Error(String(error)))\n resolve({ texture: getTransparentTexture() })\n return\n }\n\n const texture = new THREE.CanvasTexture(canvas)\n texture.needsUpdate = true\n debugLog('freeze canvas texture ready', {\n src: layer.src,\n width: canvas.width,\n height: canvas.height,\n })\n\n pendingVideos.delete(video)\n video.src = ''\n video.remove()\n resolve({ texture })\n }\n\n const captureReadyFrame = () => {\n debugLog('freeze wait decoded frame', {\n src: layer.src,\n currentTime: video.currentTime,\n readyState: video.readyState,\n })\n if ('requestVideoFrameCallback' in video) {\n video.requestVideoFrameCallback(() => captureFrame())\n }\n\n const playPromise = video.play()\n playPromise.catch(() => {\n debugLog('freeze play rejected, fallback capture', { src: layer.src })\n window.setTimeout(captureFrame, 0)\n })\n\n if (!('requestVideoFrameCallback' in video)) {\n window.setTimeout(captureFrame, 0)\n }\n }\n\n const retrySeekWhenReady = () => {\n if (settled) return\n if (retrySeekRegistered) return\n retrySeekRegistered = true\n\n const retry = () => {\n retrySeekRegistered = false\n if (settled) return\n debugLog('freeze retry seek', {\n src: layer.src,\n targetTime,\n currentTime: video.currentTime,\n duration: video.duration,\n readyState: video.readyState,\n })\n video.currentTime = targetTime\n }\n\n video.addEventListener('durationchange', retry, { once: true })\n video.addEventListener('canplay', retry, { once: true })\n video.addEventListener('loadeddata', retry, { once: true })\n }\n\n video.addEventListener('error', () => {\n pendingVideos.delete(video)\n const msg = video.error?.message ?? 'Unknown video error'\n onError?.(new Error(`Failed to load video texture: ${layer.src} (${msg})`))\n video.remove()\n resolve({ texture: getTransparentTexture() })\n }, { once: true })\n\n video.addEventListener('loadedmetadata', () => {\n const time = getFreezeTargetTime(freezeTime, video.duration, layer.freezeSeed)\n targetTime = time\n debugLog('freeze metadata loaded', {\n src: layer.src,\n targetTime: time,\n duration: video.duration,\n readyState: video.readyState,\n })\n if (isAtTargetTime(video, time)) {\n if (video.readyState >= 2) {\n captureReadyFrame()\n } else {\n video.addEventListener('loadeddata', () => captureReadyFrame(), { once: true })\n }\n return\n }\n video.currentTime = time\n }, { once: true })\n\n video.addEventListener('seeked', () => {\n debugLog('freeze seeked', {\n src: layer.src,\n targetTime,\n currentTime: video.currentTime,\n duration: video.duration,\n readyState: video.readyState,\n })\n if (!isAtTargetTime(video, targetTime)) {\n retrySeekWhenReady()\n return\n }\n captureReadyFrame()\n })\n\n video.src = layer.src\n video.load()\n })\n}\n\nexport function disposeLoadedLayer(loaded: LoadedLayer): void {\n if (loaded.videoEl) {\n loaded.videoEl.pause()\n loaded.videoEl.src = ''\n loaded.videoEl.remove()\n }\n if (loaded.texture !== getTransparentTexture()) {\n loaded.texture.dispose()\n }\n if (loaded.liveTexture && loaded.liveTexture !== loaded.texture && loaded.liveTexture !== getTransparentTexture()) {\n loaded.liveTexture.dispose()\n }\n}\n\nexport function cleanupPendingVideos(): void {\n for (const video of pendingVideos) {\n video.pause()\n video.src = ''\n video.remove()\n }\n pendingVideos.clear()\n}\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n// three.js built-in attributes\n// attribute vec3 position;\n// attribute vec3 normal;\n// attribute vec2 uv;\n\n// three.js built-in uniforms\n// uniform mat4 modelMatrix; // a.k.a worldMatrix\n// uniform mat4 viewMatrix;\n// uniform mat4 modelViewMatrix;\n// uniform mat3 normalMatrix;\n// uniform mat4 projectionMatrix;\n// uniform vec3 cameraPosition;\n\n// world transformed attributes for the fragment shader\nvarying vec3 vNormal;\nvarying vec3 vPosition;\nvarying vec2 vUv;\nvarying vec3 vView;\n\nvoid main() {\n // vec4 pos = viewMatrix * modelMatrix * vec4(position, 1.0);\n vec4 pos = modelViewMatrix * vec4(position, 1.0);\n\n // normalMatrix = transpose(inverse(mat3(modelMatrix)));\n // because transform matrix for normal vector is L^-1T\n vUv = uv;\n vPosition = pos.xyz;\n vView = normalize(cameraPosition - vPosition);\n vNormal = normalize(normalMatrix * normal);\n\n // transform the position to clip space\n gl_Position = projectionMatrix * pos;\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMouse;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n#include <utils/defaultLighting>\n\nvoid main() {\n // 기본 카드 텍스처 샘플링\n vec4 baseColor = texture2D(uLayer0, vUv);\n\n // 팝업 텍스처 샘플링 (움직임 반영)\n float popupOffset = 0.0;\n vec2 popupUv = vUv + (uMove / uResolution) * popupOffset; // 팝업 이동 효과\n vec4 popupColor = texture2D(uLayer1, popupUv);\n\n float aSoft = smoothstep(0.4, 1.0, popupColor.a);\n vec4 pocaColor = mix(baseColor, popupColor, aSoft);\n\n gl_FragColor = defaultLighting(pocaColor, uResolution, uRotate, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMouse;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n#include <utils/defaultLighting>\n\nvoid main() {\n // 기본 카드 텍스처 샘플링\n vec4 baseColor = texture2D(uLayer0, vUv);\n\n // 팝업 텍스처 샘플링 (움직임 반영)\n vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);\n vec2 popupUv = vUv + popupOffset; // 팝업 이동 효과\n vec4 popupColor = texture2D(uLayer1, popupUv);\n\n float aSoft = smoothstep(0.4, 1.0, popupColor.a);\n vec4 pocaColor = mix(baseColor, popupColor, aSoft);\n\n gl_FragColor = defaultLighting(pocaColor, uResolution, uRotate, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMouse;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform float uEffectSpeed;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n#define mod289(x) mod(x, 289.)\n\nvec3 permute(vec3 x) { return mod289(((x * 34.0) + 1.0) * x); }\n\nfloat snoise(vec2 coord) {\n const vec4 C = vec4(0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439);\n vec2 intPart = floor(coord + dot(coord, C.yy));\n vec2 fracPart = coord - intPart + dot(intPart, C.xx);\n\n vec2 offset;\n offset = (fracPart.x > fracPart.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n vec4 combined = fracPart.xyxy + C.xxzz;\n combined.xy -= offset;\n\n intPart = mod289(intPart);\n vec3 perm = permute(permute(intPart.y + vec3(0.0, offset.y, 1.0))\n + intPart.x + vec3(0.0, offset.x, 1.0));\n\n vec3 gradient = max(0.5 - vec3(dot(fracPart, fracPart), dot(combined.xy, combined.xy), dot(combined.zw, combined.zw)), 0.0);\n gradient *= gradient;\n gradient *= gradient;\n\n vec3 noiseVec = 2.0 * fract(perm * C.www) - 1.0;\n vec3 absDiff = abs(noiseVec) - 0.5;\n vec3 offsetVec = floor(noiseVec + 0.5);\n vec3 gradientVec = noiseVec - offsetVec;\n\n gradient *= 1.79284291400159 - 0.85373472095314 * (gradientVec * gradientVec + absDiff * absDiff);\n\n vec3 finalGrad;\n finalGrad.x = gradientVec.x * fracPart.x + absDiff.x * fracPart.y;\n finalGrad.yz = gradientVec.yz * combined.xz + absDiff.yz * combined.yw;\n\n return 130.0 * dot(gradient, finalGrad);\n}\n\nfloat fbm(vec2 position) {\n float result = 0.0;\n float weight = 0.5;\n for (int i = 0; i < 5; i++) {\n result += weight * snoise(position);\n position *= 2.0;\n weight *= 0.5;\n }\n return result;\n}\n\n// snowfall\nconst int LAYERS = 66;\nconst float DEPTH_NEAR = 0.3;\nconst float WIDTH_NEAR = 0.4;\nconst float SPEED_NEAR = 0.6;\nconst float DEPTH_FAR = 0.1;\nconst float WIDTH_FAR = 0.3;\nconst float SPEED_FAR = 0.1;\n\nfloat effectTime() {\n float speed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;\n return uTime * speed;\n}\n\nfloat computeSnow(in vec2 uv, int layerStart, int layerEnd) {\n const mat3 permutationMatrix = mat3(13.323122, 23.5112, 21.71123, 21.1212, 28.7312, 11.9312, 21.8112, 14.7212, 61.3934);\n vec2 moveNormalized = uMove.xy / uResolution.xy;\n moveNormalized.x = max(0.15, smoothstep(0.15, 0.8, moveNormalized.x));\n uv.x += moveNormalized.x * 0.2;\n float totalLayers = float(LAYERS);\n float accumulation = 0.0;\n float snowTime = effectTime();\n float depthOfField = 5.0 * sin(snowTime * 0.1);\n for (int i = max(layerStart, 0); i < min(layerEnd, LAYERS); i++) {\n float layer = float(i);\n float depthFactor = smoothstep(DEPTH_NEAR, DEPTH_FAR, layer / totalLayers);\n float widthFactor = smoothstep(WIDTH_NEAR, WIDTH_FAR, layer / totalLayers);\n float speedFactor = smoothstep(SPEED_NEAR, SPEED_FAR, layer / totalLayers);\n vec2 offsetUv = uv * (1.0 + layer * depthFactor);\n float windEffect = widthFactor * mod(layer * 7.238917, 1.0) - widthFactor * 0.1 * sin(snowTime * 2.0 + layer);\n offsetUv += vec2(offsetUv.y * windEffect, speedFactor * snowTime / (1.0 + layer * depthFactor * 0.03));\n vec3 noiseInput = vec3(floor(offsetUv), 31.189 + layer);\n vec3 permuted = floor(noiseInput) * 0.00001 + fract(noiseInput);\n vec3 noise = fract((31415.9 + permuted) / fract(permutationMatrix * permuted));\n vec2 particleShape = abs(mod(offsetUv, 1.0) - 0.5 + 0.9 * noise.xy - 0.45);\n particleShape += 0.01 * abs(2.0 * fract(10.0 * offsetUv.yx) - 1.0);\n float distance = 0.6 * max(particleShape.x - particleShape.y, particleShape.x + particleShape.y) + max(particleShape.x, particleShape.y) - 0.01;\n float edgeThreshold = 0.05 + 0.05 * min(0.5 * abs(layer - 5.0 - depthOfField), 1.0);\n accumulation += smoothstep(edgeThreshold, -edgeThreshold, distance) * (noise.x / (1.0 + 0.02 * layer * depthFactor));\n }\n return accumulation;\n}\n\nvoid main() {\n vec4 baseTexture = texture2D(uLayer0, vUv);\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n gl_FragColor = mix(gl_FragColor, baseTexture, baseTexture.a);\n\n float snowEffect = computeSnow(vUv, 5, 15);\n gl_FragColor += vec4(vec3(snowEffect * effectIntensity), 1.0);\n\n float popupMoveOffset = 0.0;\n vec2 popupOffsetUv = vUv + (uMove.xy / uResolution.xy) * popupMoveOffset;\n vec4 popupTexture = texture2D(uLayer1, popupOffsetUv);\n gl_FragColor = mix(gl_FragColor, popupTexture, popupTexture.a);\n\n snowEffect = computeSnow(vUv, 16, 20);\n gl_FragColor += vec4(vec3(snowEffect * effectIntensity), 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMouse;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform float uEffectSpeed;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n#define mod289(x) mod(x, 289.)\n\nvec3 permute(vec3 x) { return mod289(((x * 34.0) + 1.0) * x); }\n\nfloat snoise(vec2 coord) {\n const vec4 C = vec4(0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439);\n vec2 intPart = floor(coord + dot(coord, C.yy));\n vec2 fracPart = coord - intPart + dot(intPart, C.xx);\n\n vec2 offset;\n offset = (fracPart.x > fracPart.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n vec4 combined = fracPart.xyxy + C.xxzz;\n combined.xy -= offset;\n\n intPart = mod289(intPart);\n vec3 perm = permute(permute(intPart.y + vec3(0.0, offset.y, 1.0))\n + intPart.x + vec3(0.0, offset.x, 1.0));\n\n vec3 gradient = max(0.5 - vec3(dot(fracPart, fracPart), dot(combined.xy, combined.xy), dot(combined.zw, combined.zw)), 0.0);\n gradient *= gradient;\n gradient *= gradient;\n\n vec3 noiseVec = 2.0 * fract(perm * C.www) - 1.0;\n vec3 absDiff = abs(noiseVec) - 0.5;\n vec3 offsetVec = floor(noiseVec + 0.5);\n vec3 gradientVec = noiseVec - offsetVec;\n\n gradient *= 1.79284291400159 - 0.85373472095314 * (gradientVec * gradientVec + absDiff * absDiff);\n\n vec3 finalGrad;\n finalGrad.x = gradientVec.x * fracPart.x + absDiff.x * fracPart.y;\n finalGrad.yz = gradientVec.yz * combined.xz + absDiff.yz * combined.yw;\n\n return 130.0 * dot(gradient, finalGrad);\n}\n\nfloat fbm(vec2 position) {\n float result = 0.0;\n float weight = 0.5;\n for (int i = 0; i < 5; i++) {\n result += weight * snoise(position);\n position *= 2.0;\n weight *= 0.5;\n }\n return result;\n}\n\n// snowfall\nconst int LAYERS = 66;\nconst float DEPTH_NEAR = 0.3;\nconst float WIDTH_NEAR = 0.4;\nconst float SPEED_NEAR = 0.6;\nconst float DEPTH_FAR = 0.1;\nconst float WIDTH_FAR = 0.3;\nconst float SPEED_FAR = 0.1;\n\nfloat effectTime() {\n float speed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;\n return uTime * speed;\n}\n\nfloat computeSnow(in vec2 uv, int layerStart, int layerEnd) {\n const mat3 permutationMatrix = mat3(13.323122, 23.5112, 21.71123, 21.1212, 28.7312, 11.9312, 21.8112, 14.7212, 61.3934);\n vec2 moveNormalized = uMove.xy / uResolution.xy;\n moveNormalized.x = max(0.15, smoothstep(0.15, 0.8, moveNormalized.x));\n uv.x += moveNormalized.x * 0.2;\n float totalLayers = float(LAYERS);\n float accumulation = 0.0;\n float snowTime = effectTime();\n float depthOfField = 5.0 * sin(snowTime * 0.1);\n for (int i = max(layerStart, 0); i < min(layerEnd, LAYERS); i++) {\n float layer = float(i);\n float depthFactor = smoothstep(DEPTH_NEAR, DEPTH_FAR, layer / totalLayers);\n float widthFactor = smoothstep(WIDTH_NEAR, WIDTH_FAR, layer / totalLayers);\n float speedFactor = smoothstep(SPEED_NEAR, SPEED_FAR, layer / totalLayers);\n vec2 offsetUv = uv * (1.0 + layer * depthFactor);\n float windEffect = widthFactor * mod(layer * 7.238917, 1.0) - widthFactor * 0.1 * sin(snowTime * 2.0 + layer);\n offsetUv += vec2(offsetUv.y * windEffect, speedFactor * snowTime / (1.0 + layer * depthFactor * 0.03));\n vec3 noiseInput = vec3(floor(offsetUv), 31.189 + layer);\n vec3 permuted = floor(noiseInput) * 0.00001 + fract(noiseInput);\n vec3 noise = fract((31415.9 + permuted) / fract(permutationMatrix * permuted));\n vec2 particleShape = abs(mod(offsetUv, 1.0) - 0.5 + 0.9 * noise.xy - 0.45);\n particleShape += 0.01 * abs(2.0 * fract(10.0 * offsetUv.yx) - 1.0);\n float distance = 0.6 * max(particleShape.x - particleShape.y, particleShape.x + particleShape.y) + max(particleShape.x, particleShape.y) - 0.01;\n float edgeThreshold = 0.05 + 0.05 * min(0.5 * abs(layer - 5.0 - depthOfField), 1.0);\n accumulation += smoothstep(edgeThreshold, -edgeThreshold, distance) * (noise.x / (1.0 + 0.02 * layer * depthFactor));\n }\n return accumulation;\n}\n\nvoid main() {\n vec4 baseTexture = texture2D(uLayer0, vUv);\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n gl_FragColor = mix(gl_FragColor, baseTexture, baseTexture.a);\n\n float snowEffect = computeSnow(vUv, 5, 15);\n gl_FragColor += vec4(vec3(snowEffect * effectIntensity), 1.0);\n\n // 3D parallax offset for popup layer\n vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);\n vec2 popupOffsetUv = vUv + popupOffset;\n vec4 popupTexture = texture2D(uLayer1, popupOffsetUv);\n gl_FragColor = mix(gl_FragColor, popupTexture, popupTexture.a);\n\n snowEffect = computeSnow(vUv, 16, 20);\n gl_FragColor += vec4(vec3(snowEffect * effectIntensity), 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMouse;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n#include <lygia/sample/clamp2edge>\n#define KUWAHARA_SAMPLER_FNC(TEX, UV) sampleClamp2edge(TEX, UV)\n#include <lygia/filter/kuwahara>\n#include <lygia/draw/digits>\n#include <utils/defaultLighting>\n\nvoid main() {\n vec2 pixel = 1.0 / uResolution.xy;\n vec2 popUpUv = vUv + (uMove.xy / uResolution.xy) * 0.008;\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n\n vec4 originalBaseColor = texture2D(uLayer0, vUv);\n vec4 originalPopupColor = texture2D(uLayer1, popUpUv);\n vec4 brushedBaseColor = kuwahara(uLayer0, vUv, pixel, 4.0);\n vec4 brushedPopupColor = kuwahara(uLayer1, popUpUv, pixel, 4.0);\n vec4 baseColor = mix(originalBaseColor, brushedBaseColor, effectIntensity);\n vec4 popupColor = mix(originalPopupColor, brushedPopupColor, effectIntensity);\n\n float aSoft = smoothstep(0.4, 1.0, popupColor.a);\n vec4 pocaColor = mix(baseColor, popupColor, aSoft);\n\n gl_FragColor = defaultLighting(pocaColor, uResolution, uRotate, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMouse;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n#include <lygia/sample/clamp2edge>\n#define KUWAHARA_SAMPLER_FNC(TEX, UV) sampleClamp2edge(TEX, UV)\n#include <lygia/filter/kuwahara>\n#include <lygia/draw/digits>\n#include <utils/defaultLighting>\n\nvoid main() {\n vec2 pixel = 1.0 / uResolution.xy;\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n\n // 3D parallax offset for popup layer\n vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);\n vec2 popUpUv = vUv + popupOffset;\n\n vec4 originalBaseColor = texture2D(uLayer0, vUv);\n vec4 originalPopupColor = texture2D(uLayer1, popUpUv);\n vec4 brushedBaseColor = kuwahara(uLayer0, vUv, pixel, 4.0);\n vec4 brushedPopupColor = kuwahara(uLayer1, popUpUv, pixel, 4.0);\n vec4 baseColor = mix(originalBaseColor, brushedBaseColor, effectIntensity);\n vec4 popupColor = mix(originalPopupColor, brushedPopupColor, effectIntensity);\n\n float aSoft = smoothstep(0.4, 1.0, popupColor.a);\n vec4 pocaColor = mix(baseColor, popupColor, aSoft);\n\n gl_FragColor = defaultLighting(pocaColor, uResolution, uRotate, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMouse;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n// #define GAUSSIANBLUR_2D\n#include <lygia/sample/clamp2edge>\n#define GAUSSIANBLUR_SAMPLER_FNC(TEX, UV) sampleClamp2edge(TEX, UV)\n#include <lygia/filter/gaussianBlur>\n#include <lygia/draw/digits>\n#include <utils/defaultLighting>\n\nvoid main() {\n vec2 pixel = 1.0 / uResolution.xy;\n vec2 popUpUv = vUv + (uMove.xy / uResolution.xy) * 0.008;\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n\n vec4 originalBaseColor = texture2D(uLayer0, vUv);\n vec4 blurredBaseColor = gaussianBlur(uLayer0, vUv, pixel, 12);\n vec4 baseColor = mix(originalBaseColor, blurredBaseColor, effectIntensity);\n vec4 popupColor = texture2D(uLayer1, popUpUv);\n\n float aSoft = smoothstep(0.4, 1.0, popupColor.a);\n vec4 pocaColor = mix(baseColor, popupColor, aSoft);\n\n gl_FragColor = defaultLighting(pocaColor, uResolution, uRotate, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMouse;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n// #define GAUSSIANBLUR_2D\n#include <lygia/sample/clamp2edge>\n#define GAUSSIANBLUR_SAMPLER_FNC(TEX, UV) sampleClamp2edge(TEX, UV)\n#include <lygia/filter/gaussianBlur>\n#include <lygia/draw/digits>\n#include <utils/defaultLighting>\n\nvoid main() {\n vec2 pixel = 1.0 / uResolution.xy;\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n\n // 3D parallax offset for popup layer\n vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);\n vec2 popUpUv = vUv + popupOffset;\n\n vec4 originalBaseColor = texture2D(uLayer0, vUv);\n vec4 blurredBaseColor = gaussianBlur(uLayer0, vUv, pixel, 12);\n vec4 baseColor = mix(originalBaseColor, blurredBaseColor, effectIntensity);\n vec4 popupColor = texture2D(uLayer1, popUpUv);\n\n float aSoft = smoothstep(0.4, 1.0, popupColor.a);\n vec4 pocaColor = mix(baseColor, popupColor, aSoft);\n\n gl_FragColor = defaultLighting(pocaColor, uResolution, uRotate, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMouse;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform float uEffectSpeed;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n#include <utils/defaultLighting>\n\n// HSV to RGB conversion\nvec3 hsv2rgb(vec3 c) {\n vec4 K = vec4(1.0, 2.0/3.0, 1.0/3.0, 3.0);\n vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n}\n\nvoid main() {\n vec4 baseColor = texture2D(uLayer0, vUv);\n vec4 popupColor = texture2D(uLayer1, vUv);\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n float effectSpeed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;\n\n // Iridescence on base only\n float angle = uRotate.x * 2.0 + uRotate.y * 1.5;\n float hue = fract(vUv.y * 0.8 + vUv.x * 0.3 + angle * 0.5 + uTime * 0.05 * effectSpeed);\n vec3 rainbow = hsv2rgb(vec3(hue, 0.6, 1.0));\n\n float tiltAmount = length(uRotate) * 3.0;\n float holoIntensity = smoothstep(0.0, 1.0, tiltAmount) * 0.35 * effectIntensity;\n\n vec3 holoBase = baseColor.rgb + rainbow * holoIntensity;\n\n // Composite popup on top without holo\n float aSoft = smoothstep(0.4, 1.0, popupColor.a);\n vec3 finalColor = mix(holoBase, popupColor.rgb, aSoft);\n\n gl_FragColor = defaultLighting(vec4(finalColor, 1.0), uResolution, uRotate, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMouse;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform float uEffectSpeed;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n#include <utils/defaultLighting>\n\n// HSV to RGB conversion\nvec3 hsv2rgb(vec3 c) {\n vec4 K = vec4(1.0, 2.0/3.0, 1.0/3.0, 3.0);\n vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n}\n\nvoid main() {\n vec4 baseColor = texture2D(uLayer0, vUv);\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n float effectSpeed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;\n\n // 3D parallax offset for popup layer\n vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);\n vec2 popupUv = vUv + popupOffset;\n vec4 popupColor = texture2D(uLayer1, popupUv);\n\n // Iridescence on base only\n float angle = uRotate.x * 2.0 + uRotate.y * 1.5;\n float hue = fract(vUv.y * 0.8 + vUv.x * 0.3 + angle * 0.5 + uTime * 0.05 * effectSpeed);\n vec3 rainbow = hsv2rgb(vec3(hue, 0.6, 1.0));\n\n float tiltAmount = length(uRotate) * 3.0;\n float holoIntensity = smoothstep(0.0, 1.0, tiltAmount) * 0.35 * effectIntensity;\n\n vec3 holoBase = baseColor.rgb + rainbow * holoIntensity;\n\n // Composite popup on top without holo\n float aSoft = smoothstep(0.4, 1.0, popupColor.a);\n vec3 finalColor = mix(holoBase, popupColor.rgb, aSoft);\n\n gl_FragColor = defaultLighting(vec4(finalColor, 1.0), uResolution, uRotate, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMouse;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform float uEffectSpeed;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n#include <utils/defaultLighting>\n\nfloat pulseField(vec2 uv, float t) {\n float dist = length(uv);\n float band = abs(fract(t - dist * 0.9) - 0.5);\n float ring = 1.0 - smoothstep(0.03, 0.12, band);\n float wave = 0.5 + 0.5 * sin((uv.x + uv.y) * 8.0 + t * 2.0);\n float stripes = 0.5 + 0.5 * sin((uv.x - uv.y) * 14.0 - t * 3.0);\n return ring * 0.55 + wave * 0.25 + stripes * 0.20;\n}\n\nvoid main() {\n vec4 baseColor = texture2D(uLayer0, vUv);\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n float effectSpeed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;\n vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);\n vec4 popupColor = texture2D(uLayer1, vUv + popupOffset);\n float popupMix = smoothstep(0.35, 1.0, popupColor.a);\n vec3 layeredColor = mix(baseColor.rgb, popupColor.rgb, popupMix);\n\n vec2 centered = (vUv * 2.0 - 1.0);\n centered.x *= uResolution.x / max(uResolution.y, 1.0);\n\n float time = uTime * 0.35 * effectSpeed;\n float field = 0.0;\n\n for (int j = 0; j < 3; j++) {\n float jf = float(j);\n float offset = jf * 0.24;\n vec2 lane = centered;\n lane.x += sin(lane.y * 3.0 + time + jf) * 0.18;\n lane.y += cos(lane.x * 2.2 - time * 1.2 + jf * 0.7) * 0.14;\n field += pulseField(lane + vec2(offset), time + jf * 0.6);\n }\n field /= 3.0;\n\n float edge = smoothstep(1.2, 0.1, length(centered));\n float highlight = smoothstep(0.25, 0.95, field) * edge;\n float glow = smoothstep(0.18, 0.95, field + 0.12 * sin(time + centered.x * 4.0));\n\n float luminance = dot(layeredColor, vec3(0.299, 0.587, 0.114));\n vec3 lifted = mix(layeredColor, vec3(luminance), 0.08);\n vec3 pulseColor = lifted + layeredColor * (0.22 + glow * 0.18) + vec3(0.04) * glow;\n vec3 finalColor = mix(layeredColor, pulseColor, highlight * 0.88 * effectIntensity);\n finalColor += (pulseColor - layeredColor) * glow * 0.10 * effectIntensity;\n\n float finalAlpha = max(baseColor.a, popupColor.a);\n gl_FragColor = defaultLighting(vec4(finalColor, finalAlpha), uResolution, uRotate, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMouse;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform float uEffectSpeed;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n#include <utils/defaultLighting>\n\n#define S(a,b,t) smoothstep(a,b,t)\n\nmat2 Rot(float a) {\n float s = sin(a);\n float c = cos(a);\n return mat2(c, -s, s, c);\n}\n\nvec2 hash(vec2 p) {\n p = vec2(dot(p, vec2(2127.1, 81.17)), dot(p, vec2(1269.5, 283.37)));\n return fract(sin(p) * 43758.5453);\n}\n\nfloat noise(in vec2 p) {\n vec2 i = floor(p);\n vec2 f = fract(p);\n vec2 u = f * f * (3.0 - 2.0 * f);\n\n float n = mix(\n mix(\n dot(-1.0 + 2.0 * hash(i + vec2(0.0, 0.0)), f - vec2(0.0, 0.0)),\n dot(-1.0 + 2.0 * hash(i + vec2(1.0, 0.0)), f - vec2(1.0, 0.0)),\n u.x\n ),\n mix(\n dot(-1.0 + 2.0 * hash(i + vec2(0.0, 1.0)), f - vec2(0.0, 1.0)),\n dot(-1.0 + 2.0 * hash(i + vec2(1.0, 1.0)), f - vec2(1.0, 1.0)),\n u.x\n ),\n u.y\n );\n\n return 0.5 + 0.5 * n;\n}\n\nvoid main() {\n vec4 baseColor = texture2D(uLayer0, vUv);\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n float effectSpeed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;\n vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);\n vec4 popupColor = texture2D(uLayer1, vUv + popupOffset);\n float popupMix = smoothstep(0.35, 1.0, popupColor.a);\n vec3 layeredColor = mix(baseColor.rgb, popupColor.rgb, popupMix);\n\n vec2 uv = vUv;\n float ratio = uResolution.x / max(uResolution.y, 1.0);\n\n vec2 tuv = uv - 0.5;\n\n float effectTime = uTime * effectSpeed;\n float degree = noise(vec2(effectTime * 0.1, tuv.x * tuv.y));\n\n tuv.y *= 1.0 / ratio;\n tuv *= Rot(radians((degree - 0.5) * 720.0 + 180.0));\n tuv.y *= ratio;\n\n float frequency = 5.0;\n float amplitude = 30.0;\n float speed = effectTime * 2.0;\n tuv.x += sin(tuv.y * frequency + speed) / amplitude;\n tuv.y += sin(tuv.x * frequency * 1.5 + speed) / (amplitude * 0.5);\n\n vec3 colorYellow = vec3(0.957, 0.804, 0.623);\n vec3 colorDeepBlue = vec3(0.192, 0.384, 0.933);\n vec3 layer1 = mix(colorYellow, colorDeepBlue, S(-0.3, 0.2, (tuv * Rot(radians(-5.0))).x));\n\n vec3 colorRed = vec3(0.910, 0.510, 0.800);\n vec3 colorBlue = vec3(0.350, 0.710, 0.953);\n vec3 layer2 = mix(colorRed, colorBlue, S(-0.3, 0.2, (tuv * Rot(radians(-5.0))).x));\n\n vec3 waveComp = mix(layer1, layer2, S(0.5, -0.3, tuv.y));\n\n float luminance = dot(layeredColor, vec3(0.299, 0.587, 0.114));\n vec3 neutralBase = mix(layeredColor, vec3(luminance), 0.12);\n vec3 finalComp = mix(neutralBase, waveComp, 0.78 * effectIntensity);\n finalComp = mix(layeredColor, finalComp, 0.18 * effectIntensity);\n\n float vignette = smoothstep(1.25, 0.15, length((uv - 0.5) * vec2(ratio, 1.0)));\n finalComp = mix(finalComp * 0.75, finalComp, vignette);\n\n gl_FragColor = defaultLighting(vec4(finalComp, max(baseColor.a, popupColor.a)), uResolution, uRotate, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision highp float;\n#endif\n\n#define DRAG_MULT 0.048\n#define ITERATIONS_RAYMARCH 13\n#define ITERATIONS_NORMAL 48\n\nuniform vec2 uResolution;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform float uEffectSpeed;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\nconst vec2 DEFAULT_VIEW = vec2(0.0, 0.0);\n\nfloat effectTime() {\n float speed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;\n return uTime * speed;\n}\n\nvec2 wavedx(vec2 position, vec2 direction, float speed, float frequency, float timeshift) {\n float x = dot(direction, position) * frequency + timeshift * speed;\n float wave = exp(sin(x) - 1.0);\n float dx = wave * cos(x);\n return vec2(wave, -dx);\n}\n\nfloat getwaves(vec2 position, int iterations) {\n float iter = 0.0;\n float phase = 6.0;\n float speed = 0.4;\n float weight = 1.0;\n float w = 0.0;\n float ws = 0.0;\n for (int i = 0; i < iterations; i++) {\n vec2 p = vec2(sin(iter), cos(iter));\n vec2 res = wavedx(position, p, speed, phase, effectTime());\n position += p * res.y * weight * DRAG_MULT;\n w += res.x * weight;\n iter += 12.0;\n ws += weight;\n weight = mix(weight, 0.0, 0.2);\n phase *= 1.18;\n speed *= 1.07;\n }\n return w / ws;\n}\n\nfloat raymarchwater(vec3 camera, vec3 start, vec3 end, float depth) {\n vec3 pos = start;\n float h = 0.0;\n vec3 dir = normalize(end - start);\n float eps = 0.01;\n for (int i = 0; i < 318; i++) {\n h = getwaves(pos.xz * 0.1, ITERATIONS_RAYMARCH) * depth - depth;\n float dist_pos = distance(pos, camera);\n if (h + eps * dist_pos > pos.y) {\n return dist_pos;\n }\n pos += dir * (pos.y - h);\n }\n return -1.0;\n}\n\nvec3 normal(vec2 pos, float e, float depth) {\n vec2 ex = vec2(e, 0.0);\n float h = getwaves(pos * 0.1, ITERATIONS_NORMAL) * depth - depth;\n float hx = getwaves((pos + ex.xy) * 0.1, ITERATIONS_NORMAL) * depth - depth;\n float hy = getwaves((pos + ex.yx) * 0.1, ITERATIONS_NORMAL) * depth - depth;\n vec3 a = vec3(pos.x, h, pos.y);\n vec3 b = vec3(pos.x + e, hx, pos.y);\n vec3 c = vec3(pos.x, hy, pos.y + e);\n return normalize(cross(b - a, c - a));\n}\n\nmat3 rotmat(vec3 axis, float angle) {\n axis = normalize(axis);\n float s = sin(angle);\n float c = cos(angle);\n float oc = 1.0 - c;\n return mat3(\n oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s,\n oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s,\n oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c\n );\n}\n\nvec3 getRay(vec2 uv) {\n uv = (uv * 2.0 - 1.0) * vec2(uResolution.x / uResolution.y, 1.0);\n vec3 proj = normalize(vec3(uv.x, uv.y, 1.0) + vec3(uv.x, uv.y, -1.0) * pow(length(uv), 2.0) * 0.05);\n vec3 ray = rotmat(vec3(0.0, -1.0, 0.0), 3.0 * (DEFAULT_VIEW.x * 2.0 - 1.0) + uRotate.x * 0.06) *\n rotmat(vec3(1.0, 0.0, 0.0), 1.5 * (DEFAULT_VIEW.y * 2.0 - 1.0) + uRotate.y * 0.04) *\n proj;\n return ray;\n}\n\nfloat intersectPlane(vec3 origin, vec3 direction, vec3 point, vec3 normal) {\n return clamp(dot(point - origin, normal) / dot(direction, normal), -1.0, 9991999.0);\n}\n\nvec3 extra_cheap_atmosphere(vec3 raydir, vec3 sundir) {\n sundir.y = max(sundir.y, -0.07);\n float special_trick = 1.0 / (raydir.y * 1.0 + 0.1);\n float special_trick2 = 1.0 / (sundir.y * 11.0 + 1.0);\n float raysundt = pow(abs(dot(sundir, raydir)), 2.0);\n float sundt = pow(max(0.0, dot(sundir, raydir)), 8.0);\n float mymie = sundt * special_trick * 0.2;\n vec3 suncolor = mix(vec3(1.0), max(vec3(0.0), vec3(1.0) - vec3(5.5, 13.0, 22.4) / 22.4), special_trick2);\n vec3 bluesky = vec3(5.5, 13.0, 22.4) / 22.4 * suncolor;\n vec3 bluesky2 = max(vec3(0.0), bluesky - vec3(5.5, 13.0, 22.4) * 0.002 * (special_trick + -6.0 * sundir.y * sundir.y));\n bluesky2 *= special_trick * (0.24 + raysundt * 0.24);\n return bluesky2 * (1.0 + 1.0 * pow(1.0 - raydir.y, 3.0)) + mymie * suncolor;\n}\n\nvec3 getatm(vec3 ray) {\n return extra_cheap_atmosphere(ray, normalize(vec3(1.0))) * 0.5;\n}\n\nfloat sun(vec3 ray) {\n vec3 sd = normalize(vec3(1.0));\n return pow(max(0.0, dot(ray, sd)), 528.0) * 110.0;\n}\n\nvec3 aces_tonemap(vec3 color) {\n mat3 m1 = mat3(\n 0.59719, 0.07600, 0.02840,\n 0.35458, 0.90834, 0.13383,\n 0.04823, 0.01566, 0.83777\n );\n mat3 m2 = mat3(\n 1.60475, -0.10208, -0.00327,\n -0.53108, 1.10813, -0.07276,\n -0.07367, -0.00605, 1.07602\n );\n vec3 v = m1 * color;\n vec3 a = v * (v + 0.0245786) - 0.000090537;\n vec3 b = v * (0.983729 * v + 0.4329510) + 0.238081;\n return pow(clamp(m2 * (a / b), 0.0, 1.0), vec3(1.0 / 2.2));\n}\n\nvoid main() {\n vec2 uv = vUv;\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n float waterdepth = 2.1;\n vec3 wfloor = vec3(0.0, -waterdepth, 0.0);\n vec3 wceil = vec3(0.0, 0.0, 0.0);\n // vec3 orig = vec3(uMove.x * 0.12, 2.0 + uMove.y * 0.08, 0.0);\n vec3 orig = vec3(0.0, 2.0, 0.0);\n vec3 ray = getRay(uv);\n\n vec4 baseColor = texture2D(uLayer0, uv);\n // vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);\n vec2 popupOffset = vec2(0.0, 0.0);\n vec4 popupColor = texture2D(uLayer1, uv + popupOffset);\n float popupMix = smoothstep(0.35, 1.0, popupColor.a);\n vec3 layeredColor = mix(baseColor.rgb, popupColor.rgb, popupMix);\n vec3 tint = mix(layeredColor, vec3(dot(layeredColor, vec3(0.299, 0.587, 0.114))), 0.15);\n\n float hihit = intersectPlane(orig, ray, wceil, vec3(0.0, 1.0, 0.0));\n if (ray.y >= -0.01) {\n vec3 C = getatm(ray) * 2.0 + sun(ray);\n C = aces_tonemap(C);\n C = mix(C, tint, 0.38 * effectIntensity); // sky tint\n gl_FragColor = vec4(C, 1.0);\n return;\n }\n\n float lohit = intersectPlane(orig, ray, wfloor, vec3(0.0, 1.0, 0.0));\n vec3 hipos = orig + ray * hihit;\n vec3 lopos = orig + ray * lohit;\n float dist = raymarchwater(orig, hipos, lopos, waterdepth);\n vec3 pos = orig + ray * dist;\n\n vec3 N = normal(pos.xz, 0.001, waterdepth);\n vec2 velocity = N.xz * (1.0 - N.y);\n N = mix(vec3(0.0, 1.0, 0.0), N, 1.0 / (dist * dist * 0.01 + 1.0));\n vec3 R = reflect(ray, N);\n float fresnel = 0.04 + (1.0 - 0.04) * pow(1.0 - max(0.0, dot(-N, ray)), 5.0);\n\n vec3 C = fresnel * getatm(R) * 2.0 + fresnel * sun(R);\n C = mix(C, tint, 0.32 * effectIntensity); // water tint\n C += vec3(velocity.xyx) * 0.01;\n C = aces_tonemap(C);\n C = mix(C, layeredColor, 0.75 * effectIntensity); // final color mix\n\n gl_FragColor = vec4(C, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform float uEffectSpeed;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n#include <utils/defaultLighting>\n\nvec3 hsv2rgb(vec3 c) {\n vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n}\n\nvoid main() {\n vec4 baseColor = texture2D(uLayer0, vUv);\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n float effectSpeed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;\n vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);\n vec4 popupColor = texture2D(uLayer1, vUv + popupOffset);\n\n float popupMix = smoothstep(0.35, 1.0, popupColor.a);\n vec3 layeredColor = mix(baseColor.rgb, popupColor.rgb, popupMix);\n\n vec2 uv = vUv;\n float ratio = uResolution.x / max(uResolution.y, 1.0);\n vec2 centered = (uv - 0.5) * vec2(ratio, 1.0);\n\n float effectTime = uTime * effectSpeed;\n float hue = fract((uv.x + uv.y) * 0.25 + effectTime * 0.5);\n vec3 rainbow = hsv2rgb(vec3(hue, 0.6, 1.0));\n\n float flow = 0.5 + 0.5 * sin((centered.x + centered.y) * 7.0 + effectTime * 1.8);\n float stripe = 0.5 + 0.5 * sin((centered.x - centered.y) * 11.0 - effectTime * 1.2);\n float mask = smoothstep(0.15, 0.95, 0.35 * flow + 0.65 * stripe);\n float vignette = smoothstep(1.2, 0.15, length(centered));\n\n vec3 tint = mix(layeredColor, layeredColor * rainbow, 0.22);\n vec3 finalColor = mix(layeredColor, tint, mask * 0.65 * effectIntensity);\n finalColor = mix(finalColor * 0.85, finalColor, vignette);\n\n gl_FragColor = defaultLighting(vec4(finalColor, max(baseColor.a, popupColor.a)), uResolution, uRotate, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform float uEffectSpeed;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n#include <utils/defaultLighting>\n\n#define CENTER vec2(0.5, 0.5)\n#define PI 3.1415926\n\n#define force 0.04\n#define thickness 0.075\n#define feathering 0.05\n#define aberrationOffset 0.006\n#define flashIntensity 3.0\n#define waveSpeed 0.42\n\nvec2 centerScaleUV(vec2 uv, vec2 factor) {\n return (uv - vec2(0.5)) * factor + vec2(0.5);\n}\n\nfloat easeOutSine(float t) {\n return sin((t * PI) / 2.0);\n}\n\nvoid main() {\n vec4 baseColor = texture2D(uLayer0, vUv);\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n float effectSpeed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;\n vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);\n vec4 popupColor = texture2D(uLayer1, vUv + popupOffset);\n float popupMix = smoothstep(0.35, 1.0, popupColor.a);\n vec3 layeredColor = mix(baseColor.rgb, popupColor.rgb, popupMix);\n\n vec2 screenUV = vUv;\n float pos = easeOutSine(fract(uTime * waveSpeed * effectSpeed));\n\n float aspectRatio = uResolution.x / max(uResolution.y, 1.0);\n vec2 scalingFactor = vec2(aspectRatio, 1.0);\n scalingFactor *= 2.0;\n scalingFactor *= 1.0 - thickness - feathering;\n scalingFactor /= sqrt(pow(aspectRatio, 2.0) + 1.0);\n\n vec2 scaledUV = centerScaleUV(screenUV, scalingFactor);\n vec2 displacement = normalize(scaledUV - CENTER + vec2(1e-5)) * force * effectIntensity;\n float distanceFromCenter = distance(scaledUV, CENTER);\n\n float innerBound = smoothstep(\n pos - thickness - feathering,\n pos - thickness,\n distanceFromCenter\n );\n float outerBound = smoothstep(\n pos - feathering,\n pos,\n distanceFromCenter\n );\n float shapeMask = innerBound - outerBound;\n\n vec2 coords = vUv;\n\n vec2 texelOffset = displacement * shapeMask;\n vec2 chromaOffset = texelOffset * 0.5;\n\n vec3 background;\n background.r = texture2D(uLayer0, clamp(coords - (texelOffset - aberrationOffset * chromaOffset), vec2(0.0), vec2(1.0))).r;\n background.g = texture2D(uLayer0, clamp(coords - texelOffset, vec2(0.0), vec2(1.0))).g;\n background.b = texture2D(uLayer0, clamp(coords - (texelOffset + aberrationOffset * chromaOffset), vec2(0.0), vec2(1.0))).b;\n\n float flashOpacity = pow(1.0 - pos, 4.0);\n float flashMask = 1.0 - innerBound;\n background += flashIntensity * background * flashMask * flashOpacity * 0.12 * effectIntensity;\n\n vec3 finalColor = mix(background, layeredColor, 0.35);\n finalColor = mix(finalColor, layeredColor, popupMix * 0.25);\n\n gl_FragColor = defaultLighting(vec4(finalColor, max(baseColor.a, popupColor.a)), uResolution, uRotate, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform float uEffectIntensity;\nuniform float uEffectSpeed;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\n\nvarying vec2 vUv;\n\n#include <utils/defaultLighting>\n\nconst vec2 CENTER = vec2(0.5, 0.5);\nconst float EffectDuration = 2.0;\nconst float EffectFadeInTimeFactor = 0.5;\nconst float EffectWidth = 0.8;\nconst float EffectMaxTexelOffset = 0.01;\n\nvec2 getOffsetFromCenter(vec2 screenCoords, vec2 screenSize) {\n vec2 halfScreenSize = screenSize / 2.0;\n return (screenCoords - halfScreenSize) / min(halfScreenSize.x, halfScreenSize.y);\n}\n\nvec2 getDistortion(vec2 offsetDirection, float offsetDistance, float time) {\n float progress = mod(time, EffectDuration) / EffectDuration;\n\n float halfWidth = EffectWidth / 2.0;\n float lower = 1.0 - smoothstep(progress - halfWidth, progress, offsetDistance);\n float upper = smoothstep(progress, progress + halfWidth, offsetDistance);\n float band = 1.0 - (upper + lower);\n\n float strength = 1.0 - progress;\n float fadeStrength = smoothstep(0.0, EffectFadeInTimeFactor, progress);\n float distortion = band * strength * fadeStrength;\n\n return distortion * offsetDirection * EffectMaxTexelOffset;\n}\n\nvoid main() {\n vec4 baseColor = texture2D(uLayer0, vUv);\n float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;\n float effectSpeed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;\n vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);\n vec4 popupColor = texture2D(uLayer1, vUv + popupOffset);\n float popupMix = smoothstep(0.35, 1.0, popupColor.a);\n vec3 layeredColor = mix(baseColor.rgb, popupColor.rgb, popupMix);\n\n vec2 screenSize = max(uResolution, vec2(1.0));\n vec2 screenCoords = vUv * screenSize;\n vec2 offsetFromCenter = getOffsetFromCenter(screenCoords, screenSize);\n offsetFromCenter += uMove * 0.12 + uRotate * 0.04;\n\n float offsetDistance = length(offsetFromCenter);\n vec2 offsetDirection = normalize(-offsetFromCenter + vec2(1e-5));\n float effectTime = uTime * effectSpeed;\n vec2 offset = getDistortion(offsetDirection, offsetDistance, effectTime * 1.2);\n offset *= effectIntensity;\n\n vec2 warpedUv = clamp(vUv + offset, vec2(0.0), vec2(1.0));\n vec3 rippleColor = texture2D(uLayer0, warpedUv).rgb;\n\n float dist = length((vUv - CENTER) * vec2(screenSize.x / screenSize.y, 1.0));\n float ring = 1.0 - smoothstep(0.0, 0.55, abs(fract(effectTime * 0.8 - dist * 2.5) - 0.5));\n float rippleMix = smoothstep(0.15, 0.9, ring);\n\n vec3 finalColor = mix(layeredColor, rippleColor, rippleMix * 0.8 * effectIntensity);\n finalColor = mix(finalColor, layeredColor, 0.45);\n finalColor += layeredColor * rippleMix * 0.05;\n\n gl_FragColor = defaultLighting(vec4(finalColor, max(baseColor.a, popupColor.a)), uResolution, uRotate, 1.0);\n}\n`\n","import { glsl } from './utils/glsl'\n\nexport default glsl`\n#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform vec2 uResolution;\nuniform vec2 uMove;\nuniform vec2 uRotate;\nuniform float uTime;\nuniform sampler2D uLayer0;\nuniform sampler2D uLayer1;\nuniform int uLayerCount;\nuniform float uEffectIntensity;\nuniform float uEffectThreshold;\n\nvarying vec2 vUv;\n\n#include <utils/defaultLighting>\n\nvoid main() {\n vec4 baseColor = texture2D(uLayer0, vUv);\n vec4 topColor = texture2D(uLayer1, vUv);\n\n float intensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.8;\n float threshold = uEffectThreshold > 0.0 ? uEffectThreshold : 0.5;\n float tilt = clamp(abs(uRotate.x) * intensity, 0.0, 1.0);\n float blend = smoothstep(0.0, threshold, tilt);\n float baseWeight = 1.0 - blend;\n float topWeight = blend;\n\n vec3 finalColor = baseColor.rgb * baseWeight + topColor.rgb * topWeight;\n float alpha = baseColor.a * baseWeight + topColor.a * topWeight;\n\n gl_FragColor = defaultLighting(vec4(finalColor, alpha), uResolution, uRotate, 1.0);\n}\n`\n","export interface SpringOpts {\n stiffness?: number\n damping?: number\n precision?: number\n}\n\nexport interface SpringUpdateOpts {\n hard?: boolean\n soft?: number | boolean\n}\n\nexport interface Spring<T> {\n set(value: T, opts?: SpringUpdateOpts): Promise<void>\n get(): T\n stiffness: number\n damping: number\n precision: number\n}\n\n// Global animation loop shared across all springs\nconst tasks: Set<() => boolean> = new Set()\nlet rafId: number | null = null\n\nfunction runLoop() {\n if (tasks.size === 0) {\n rafId = null\n return\n }\n for (const task of tasks) {\n if (!task()) {\n tasks.delete(task)\n }\n }\n rafId = requestAnimationFrame(runLoop)\n}\n\nfunction scheduleTask(task: () => boolean) {\n tasks.add(task)\n if (rafId === null) {\n rafId = requestAnimationFrame(runLoop)\n }\n}\n\nfunction tickSpring(\n ctx: { val: number; lastVal: number; target: number; invMass: number },\n stiffness: number,\n damping: number,\n precision: number,\n): boolean {\n const delta = ctx.target - ctx.val\n const velocity = ctx.val - ctx.lastVal\n const springForce = stiffness * delta\n const damperForce = damping * velocity\n const acceleration = (springForce - damperForce) * ctx.invMass\n const d = velocity + acceleration\n\n if (Math.abs(d) < precision && Math.abs(delta) < precision) {\n ctx.val = ctx.target\n ctx.lastVal = ctx.target\n return false // settled\n }\n\n ctx.lastVal = ctx.val\n ctx.val += d\n return true // still moving\n}\n\nexport function spring(\n initialValue: number,\n onChange: (value: number) => void,\n opts: SpringOpts = {},\n): Spring<number> {\n const stiffness = opts.stiffness ?? 0.15\n const damping = opts.damping ?? 0.8\n const precision = opts.precision ?? 0.01\n\n const ctx = {\n val: initialValue,\n lastVal: initialValue,\n target: initialValue,\n invMass: 1,\n }\n let currentResolve: (() => void) | null = null\n let currentTask: (() => boolean) | null = null\n\n const s: Spring<number> = {\n stiffness,\n damping,\n precision,\n get() {\n return ctx.val\n },\n set(value: number, updateOpts?: SpringUpdateOpts) {\n ctx.target = value\n\n // Remove previous task to prevent duplicate ticking\n if (currentTask) {\n tasks.delete(currentTask)\n currentTask = null\n }\n\n if (updateOpts?.hard) {\n ctx.val = value\n ctx.lastVal = value\n onChange(value)\n currentResolve?.()\n currentResolve = null\n return Promise.resolve()\n }\n\n if (updateOpts?.soft) {\n const rate = typeof updateOpts.soft === 'number' ? updateOpts.soft : 0.5\n ctx.invMass = Math.min(ctx.invMass, rate)\n }\n\n return new Promise<void>((resolve) => {\n currentResolve = resolve\n const task = () => {\n const invMassTarget = 1\n ctx.invMass = Math.min(ctx.invMass + 0.02, invMassTarget)\n\n const moving = tickSpring(ctx, s.stiffness, s.damping, s.precision)\n onChange(ctx.val)\n\n if (!moving) {\n currentResolve?.()\n currentResolve = null\n currentTask = null\n }\n return moving\n }\n currentTask = task\n scheduleTask(task)\n })\n },\n }\n\n return s\n}\n\n// Convenience: spring for {x, y} objects\n// Uses batched onChange — ticks all components per frame, calls onChange once\nexport function springVec2(\n initial: { x: number; y: number },\n onChange: (value: { x: number; y: number }) => void,\n opts: SpringOpts = {},\n): Spring<{ x: number; y: number }> {\n const state = { x: initial.x, y: initial.y }\n let dirty = false\n\n const flush = () => {\n if (dirty) {\n dirty = false\n onChange({ ...state })\n }\n }\n\n const sx = spring(initial.x, (v) => {\n state.x = v\n dirty = true\n // Use microtask to batch x+y updates within the same frame\n queueMicrotask(flush)\n }, opts)\n\n const sy = spring(initial.y, (v) => {\n state.y = v\n dirty = true\n queueMicrotask(flush)\n }, opts)\n\n return {\n get stiffness() { return sx.stiffness },\n set stiffness(v) { sx.stiffness = v; sy.stiffness = v },\n get damping() { return sx.damping },\n set damping(v) { sx.damping = v; sy.damping = v },\n get precision() { return sx.precision },\n set precision(v) { sx.precision = v; sy.precision = v },\n get() {\n return { x: sx.get(), y: sy.get() }\n },\n async set(value, updateOpts) {\n await Promise.all([\n sx.set(value.x, updateOpts),\n sy.set(value.y, updateOpts),\n ])\n },\n }\n}\n\n// Convenience: spring for {x, y, o} (glare)\nexport function springVec3(\n initial: { x: number; y: number; o: number },\n onChange: (value: { x: number; y: number; o: number }) => void,\n opts: SpringOpts = {},\n): Spring<{ x: number; y: number; o: number }> {\n const state = { x: initial.x, y: initial.y, o: initial.o }\n let dirty = false\n\n const flush = () => {\n if (dirty) {\n dirty = false\n onChange({ ...state })\n }\n }\n\n const sx = spring(initial.x, (v) => {\n state.x = v\n dirty = true\n queueMicrotask(flush)\n }, opts)\n\n const sy = spring(initial.y, (v) => {\n state.y = v\n dirty = true\n queueMicrotask(flush)\n }, opts)\n\n const so = spring(initial.o, (v) => {\n state.o = v\n dirty = true\n queueMicrotask(flush)\n }, opts)\n\n return {\n get stiffness() { return sx.stiffness },\n set stiffness(v) { sx.stiffness = v; sy.stiffness = v; so.stiffness = v },\n get damping() { return sx.damping },\n set damping(v) { sx.damping = v; sy.damping = v; so.damping = v },\n get precision() { return sx.precision },\n set precision(v) { sx.precision = v; sy.precision = v; so.precision = v },\n get() {\n return { x: sx.get(), y: sy.get(), o: so.get() }\n },\n async set(value, updateOpts) {\n await Promise.all([\n sx.set(value.x, updateOpts),\n sy.set(value.y, updateOpts),\n so.set(value.o, updateOpts),\n ])\n },\n }\n}\n","export const round = (value: number, precision = 3): number =>\n parseFloat(value.toFixed(precision))\n\nexport const clamp = (value: number, min = 0, max = 100): number =>\n Math.min(Math.max(value, min), max)\n\nexport const adjust = (\n value: number,\n fromMin: number,\n fromMax: number,\n toMin: number,\n toMax: number,\n): number =>\n round(toMin + ((toMax - toMin) * (value - fromMin)) / (fromMax - fromMin))\n\nexport const distance = (x1: number, y1: number, x2: number, y2: number): number =>\n Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)\n","import { springVec2, springVec3, type Spring } from '../animation/spring';\nimport { clamp, distance, round } from '../utils/math';\n\nexport interface InteractionCallbacks {\n onRotate: (rotate: { x: number; y: number }) => void\n onGlare: (glare: { x: number; y: number; o: number }) => void\n onMousePos: (pos: { x: number; y: number }) => void\n onMoveDelta: (delta: { x: number; y: number }) => void\n onDistFromCenter: (dist: number) => void\n onFlip: (flipped: boolean) => void\n}\n\nexport interface InteractionOptions {\n interactive?: boolean\n preventTouchScroll?: boolean\n}\n\ninterface Rect {\n left: number\n top: number\n width: number\n height: number\n}\n\nconst SPRING_INTERACT = { stiffness: 0.095, damping: 0.5 }\nconst SPRING_FLIP = { stiffness: 0.03, damping: 0.25 }\nconst THROTTLE_MS = 1000 / 60\nconst DBLCLICK_MS = 200\n\nexport class InteractionHandler {\n private flipped = false\n private interacting = false\n private boundingRect: Rect = { left: 0, top: 0, width: 0, height: 0 }\n private interactionOrigin = { x: 0, y: 0 }\n\n private springRotate: Spring<{ x: number; y: number }>\n private springGlare: Spring<{ x: number; y: number; o: number }>\n\n private lastThrottleTime = 0\n private clickCount = 0\n private dblClickTimer: ReturnType<typeof setTimeout> | null = null\n private activePointerId: number | null = null\n\n private boundPointerDown: (e: PointerEvent) => void\n private boundPointerMove: (e: PointerEvent) => void\n private boundPointerUp: (e: PointerEvent) => void\n private boundClick: (e: MouseEvent) => void\n private boundTouchHandler: (e: TouchEvent) => void\n\n private _flipSpeed = 1\n private _flipId = 0\n\n constructor(\n private container: HTMLElement,\n private callbacks: InteractionCallbacks,\n private flippable: boolean,\n initialFlipped: boolean,\n private options: InteractionOptions = {},\n ) {\n this.flipped = initialFlipped\n\n // Spring rotate onChange: apply flip-aware sign to CSS rotation\n // Angular: { x: flipped ? 180 - v.x : -v.x, y: flipped ? -v.y : v.y }\n this.springRotate = springVec2({ x: 0, y: 0 }, (v) => {\n callbacks.onRotate(v)\n callbacks.onDistFromCenter(clamp(distance(v.x, v.y, 0, 0) / 50, 0, 1))\n }, SPRING_INTERACT)\n\n this.springGlare = springVec3({ x: 50, y: 50, o: 0 }, (v) => {\n callbacks.onGlare(v)\n }, SPRING_INTERACT)\n\n this.boundPointerDown = this.onPointerDown.bind(this)\n this.boundPointerMove = this.onPointerMove.bind(this)\n this.boundPointerUp = this.onPointerUp.bind(this)\n this.boundClick = this.onClick.bind(this)\n this.boundTouchHandler = (e: TouchEvent) => {\n e.preventDefault()\n e.stopPropagation()\n }\n\n if (this.options.interactive ?? true) {\n this.container.addEventListener('pointerdown', this.boundPointerDown)\n this.container.addEventListener('pointermove', this.boundPointerMove)\n this.container.addEventListener('pointerup', this.boundPointerUp)\n this.container.addEventListener('pointercancel', this.boundPointerUp)\n this.container.addEventListener('click', this.boundClick)\n }\n\n if (this.options.preventTouchScroll) {\n this.container.addEventListener('touchstart', this.boundTouchHandler, { passive: false })\n this.container.addEventListener('touchmove', this.boundTouchHandler, { passive: false })\n }\n }\n\n updateRect(rect: Rect): void {\n this.boundingRect = rect\n }\n\n private onPointerDown(e: PointerEvent): void {\n e.preventDefault()\n e.stopPropagation()\n this.interacting = true\n this.activePointerId = e.pointerId\n this.container.setPointerCapture(e.pointerId)\n\n const rect = this.container.getBoundingClientRect()\n this.boundingRect = { left: rect.left, top: rect.top, width: rect.width, height: rect.height }\n this.interactionOrigin = { x: e.clientX, y: e.clientY }\n this.doInteract(e.clientX, e.clientY)\n }\n\n private onPointerMove(e: PointerEvent): void {\n if (!this.interacting) return\n const now = performance.now()\n if (now - this.lastThrottleTime < THROTTLE_MS) return\n this.lastThrottleTime = now\n this.doInteract(e.clientX, e.clientY)\n }\n\n private onPointerUp(_e: PointerEvent): void {\n if (!this.interacting) return\n this.interacting = false\n if (this.activePointerId !== null) {\n try { this.container.releasePointerCapture(this.activePointerId) } catch {}\n this.activePointerId = null\n }\n this.endInteract()\n }\n\n private onClick(_e: MouseEvent): void {\n if (!this.flippable) return\n this.clickCount++\n if (this.dblClickTimer) clearTimeout(this.dblClickTimer)\n this.dblClickTimer = setTimeout(() => {\n if (this.clickCount >= 2) {\n this.flip()\n }\n this.clickCount = 0\n }, DBLCLICK_MS)\n }\n\n /**\n * Core interaction math — faithfully ported from Angular move.service.ts doInteract()\n */\n private doInteract(clientX: number, clientY: number): void {\n const rect = this.boundingRect\n if (rect.width === 0 || rect.height === 0) return\n\n const deltaX = clientX - this.interactionOrigin.x\n const deltaY = clientY - this.interactionOrigin.y\n\n // touchPosFromLT: absolute position within card (for glare)\n const touchPosFromLT = {\n x: clientX - rect.left,\n y: clientY - rect.top,\n }\n const touchPercentFromLT = {\n x: clamp(round((100 / rect.width) * touchPosFromLT.x)),\n y: clamp(round((100 / rect.height) * touchPosFromLT.y)),\n }\n\n // touchPosFromCenter: delta-based center offset (for rotation)\n const touchPosFromCenter = {\n x: rect.width / 2 + deltaX,\n y: rect.height / 2 + deltaY,\n }\n const touchPercentFromCenter = {\n x: clamp(round((100 / rect.width) * touchPosFromCenter.x)),\n y: clamp(round((100 / rect.height) * touchPosFromCenter.y)),\n }\n const touchPercentBasedCenter = {\n x: touchPercentFromCenter.x - 50,\n y: touchPercentFromCenter.y - 50,\n }\n\n // moveDelta: raw pixel delta (no DPR)\n this.callbacks.onMoveDelta({ x: deltaX, y: deltaY })\n\n // mousePos: absolute position in card, DPR-scaled, Y-flipped for WebGL\n const dpr = window.devicePixelRatio || 1\n this.callbacks.onMousePos({\n x: (clientX - rect.left) * dpr,\n y: (rect.height - (clientY - rect.top)) * dpr,\n })\n\n // Rotation: basedCenter / divisor\n const rotate = {\n x: round(touchPercentBasedCenter.x / 3.5),\n y: round(touchPercentBasedCenter.y / 2),\n }\n\n // Glare: absolute percentage from left-top\n const glare = {\n x: round(touchPercentFromLT.x),\n y: round(touchPercentFromLT.y),\n o: 1 as number,\n }\n\n this.updateSprings(glare, rotate)\n }\n\n /**\n * Apply spring targets with flip-aware rotation sign.\n * Angular: { x: flipped ? 180 - rotate.x : -rotate.x, y: flipped ? -rotate.y : rotate.y }\n */\n private updateSprings(\n glare: { x: number; y: number; o: number },\n rotate: { x: number; y: number },\n ): void {\n this.springGlare.stiffness = SPRING_INTERACT.stiffness\n this.springGlare.damping = SPRING_INTERACT.damping\n this.springGlare.set(glare)\n\n this.springRotate.stiffness = SPRING_INTERACT.stiffness\n this.springRotate.damping = SPRING_INTERACT.damping\n this.springRotate.set({\n x: this.flipped ? 180 - rotate.x : -rotate.x,\n y: this.flipped ? -rotate.y : rotate.y,\n })\n }\n\n private endInteract(): void {\n this.springRotate.set({ x: this.flipped ? 180 : 0, y: 0 })\n this.springGlare.set({ x: 50, y: 50, o: 0 })\n this.callbacks.onMoveDelta({ x: 0, y: 0 })\n\n const rect = this.boundingRect\n const dpr = window.devicePixelRatio || 1\n this.callbacks.onMousePos({\n x: (rect.width / 2) * dpr,\n y: (rect.height / 2) * dpr,\n })\n }\n\n set flipSpeed(speed: number) {\n this._flipSpeed = speed\n }\n\n flip(flipped?: boolean): boolean {\n this.flipped = flipped ?? !this.flipped\n const targetX = this.flipped ? 180 : 0\n\n // Snapshot current position and kill velocity\n const current = this.springRotate.get()\n this.springRotate.set({ x: current.x, y: current.y }, { hard: true })\n\n // Invalidate any previous flip's completion callback\n const flipId = ++this._flipId\n\n this.springRotate.stiffness = SPRING_FLIP.stiffness * this._flipSpeed\n this.springRotate.damping = SPRING_FLIP.damping\n this.springRotate.set({ x: targetX, y: 0 }).then(() => {\n // Only restore interact spring if this is still the latest flip\n if (this._flipId === flipId) {\n this.springRotate.stiffness = SPRING_INTERACT.stiffness\n this.springRotate.damping = SPRING_INTERACT.damping\n }\n })\n\n this.callbacks.onFlip(this.flipped)\n return this.flipped\n }\n\n /**\n * Wiggle support: start a synthetic interaction.\n * Matches Angular: startInteraction(0, 0, false)\n * Sets origin at (0,0) so wiggle coordinates become deltas directly.\n */\n startSyntheticInteraction(): void {\n const rect = this.container.getBoundingClientRect()\n this.boundingRect = { left: rect.left, top: rect.top, width: rect.width, height: rect.height }\n this.interactionOrigin = { x: 0, y: 0 }\n }\n\n /**\n * Feed raw clientX/Y directly to doInteract.\n * Used by wiggle where coordinates come from DefaultWiggler(0,0,100).\n */\n simulateInteractRaw(clientX: number, clientY: number): void {\n this.doInteract(clientX, clientY)\n }\n\n simulateEndInteract(): void {\n this.endInteract()\n }\n\n isInteracting(): boolean {\n return this.interacting\n }\n\n isFlipped(): boolean {\n return this.flipped\n }\n\n destroy(): void {\n if (this.activePointerId !== null) {\n try { this.container.releasePointerCapture(this.activePointerId) } catch {}\n }\n this.container.removeEventListener('pointerdown', this.boundPointerDown)\n this.container.removeEventListener('pointermove', this.boundPointerMove)\n this.container.removeEventListener('pointerup', this.boundPointerUp)\n this.container.removeEventListener('pointercancel', this.boundPointerUp)\n this.container.removeEventListener('click', this.boundClick)\n this.container.removeEventListener('touchstart', this.boundTouchHandler)\n this.container.removeEventListener('touchmove', this.boundTouchHandler)\n if (this.dblClickTimer) clearTimeout(this.dblClickTimer)\n }\n}\n","export type EasingFn = (t: number) => number\n\nexport const easeOut: EasingFn = (t) => 1 - (1 - t) ** 3\nexport const easeInOut: EasingFn = (t) =>\n t < 0.5 ? 4 * t * t * t : 1 - (-2 * t + 2) ** 3 / 2\nexport const easeIn: EasingFn = (t) => t * t * t\n\nexport interface TweenOpts {\n from: number\n to: number\n duration: number\n easing: EasingFn\n onUpdate: (value: number) => void\n}\n\nexport function tween(opts: TweenOpts): Promise<void> & { cancel: () => void } {\n let cancelled = false\n let rafId: number | null = null\n\n const promise = new Promise<void>((resolve) => {\n const start = performance.now()\n const range = opts.to - opts.from\n\n function tick(now: number) {\n if (cancelled) { resolve(); return }\n const elapsed = now - start\n const t = Math.min(elapsed / opts.duration, 1)\n const value = opts.from + range * opts.easing(t)\n opts.onUpdate(value)\n\n if (t < 1) {\n rafId = requestAnimationFrame(tick)\n } else {\n resolve()\n }\n }\n rafId = requestAnimationFrame(tick)\n })\n\n return Object.assign(promise, {\n cancel() {\n cancelled = true\n if (rafId !== null) cancelAnimationFrame(rafId)\n },\n })\n}\n","import { tween, easeOut, easeInOut, easeIn } from './tween'\n\nexport interface WiggleController {\n stop(): void\n}\n\nexport function wiggle(\n cx: number,\n cy: number,\n radius: number,\n onUpdate: (pos: { x: number; y: number }, done: boolean) => void,\n): WiggleController {\n let stopped = false\n const cancellers: (() => void)[] = []\n\n async function run() {\n let currentRadius = 0\n let theta = 0\n\n // Phase 1: Expand (0.5s)\n const expand = tween({\n from: 0, to: radius,\n duration: 500, easing: easeOut,\n onUpdate: (r) => {\n if (stopped) return\n currentRadius = r\n onUpdate({ x: cx + r, y: cy }, false)\n },\n })\n cancellers.push(expand.cancel)\n await expand\n if (stopped) return\n\n // Phase 2: Rotate (0.5s, 0 → π)\n const rotate = tween({\n from: 0, to: Math.PI,\n duration: 500, easing: easeInOut,\n onUpdate: (t) => {\n if (stopped) return\n theta = t\n onUpdate({\n x: cx + currentRadius * Math.cos(theta),\n y: cy + currentRadius * Math.sin(theta),\n }, false)\n },\n })\n cancellers.push(rotate.cancel)\n await rotate\n if (stopped) return\n\n // Phase 3: Shrink (0.3s)\n const shrink = tween({\n from: currentRadius, to: 0,\n duration: 300, easing: easeIn,\n onUpdate: (r) => {\n if (stopped) return\n currentRadius = r\n onUpdate({ x: cx + r * Math.cos(theta), y: cy }, false)\n },\n })\n cancellers.push(shrink.cancel)\n await shrink\n\n if (!stopped) {\n onUpdate({ x: cx, y: cy }, true)\n }\n }\n\n run()\n\n return {\n stop() {\n stopped = true\n cancellers.forEach((c) => c())\n },\n }\n}\n","import { EventEmitter } from './event-emitter'\nimport { Renderer, type RendererOptions } from './renderer'\nimport { InteractionHandler } from './interaction'\nimport { wiggle, type WiggleController } from './animation/wiggle'\nimport type { FaceOptions } from './types'\n\nexport interface PocaCardOptions {\n front: FaceOptions\n back?: FaceOptions\n flippable?: boolean\n initialFlipped?: boolean\n flipSpeed?: number\n interactive?: boolean\n preventTouchScroll?: boolean\n}\n\nexport class PocaCard extends EventEmitter {\n private renderer: Renderer\n private interaction: InteractionHandler\n private wiggleController: WiggleController | null = null\n\n constructor(container: HTMLElement, options: PocaCardOptions) {\n super()\n\n this.renderer = new Renderer(\n container,\n {\n front: options.front,\n back: options.back,\n preventTouchScroll: options.preventTouchScroll,\n },\n (error) => this.emit('error', error),\n () => this.emit('ready'),\n () => this.emit('firstFrame'),\n )\n\n this.interaction = new InteractionHandler(\n this.renderer.getRotatorEl(),\n {\n onRotate: (rotate) => this.renderer.updateUniforms({ rotate }),\n onGlare: () => {},\n onMousePos: (pos) => this.renderer.updateUniforms({ mouse: pos }),\n onMoveDelta: (delta) => this.renderer.updateUniforms({ move: delta }),\n onDistFromCenter: (_dist) => {},\n onFlip: (flipped) => {\n this.emit('flip', flipped)\n },\n },\n options.flippable ?? false,\n options.initialFlipped ?? false,\n {\n interactive: options.interactive,\n preventTouchScroll: options.preventTouchScroll,\n },\n )\n\n // Cancel wiggle when user starts interacting\n if (options.interactive ?? true) {\n this.renderer.getRotatorEl().addEventListener('pointerdown', () => {\n if (this.wiggleController) {\n this.wiggleController.stop()\n this.wiggleController = null\n }\n })\n }\n\n if (options.flipSpeed != null) {\n this.interaction.flipSpeed = options.flipSpeed\n }\n }\n\n getFrontContentEl(): HTMLDivElement {\n return this.renderer.getFrontContentEl()\n }\n\n getBackContentEl(): HTMLDivElement {\n return this.renderer.getBackContentEl()\n }\n\n flip(): void {\n this.interaction.flip()\n }\n\n wiggle(): void {\n // Don't wiggle while user is interacting\n if (this.interaction.isInteracting()) return\n\n this.wiggleController?.stop()\n this.interaction.startSyntheticInteraction()\n\n this.wiggleController = wiggle(0, 0, 100, (pos, done) => {\n if (done) {\n this.interaction.simulateEndInteract()\n this.wiggleController = null\n } else {\n this.interaction.simulateInteractRaw(pos.x, pos.y)\n }\n })\n }\n\n reset(): void {\n this.wiggleController?.stop()\n this.wiggleController = null\n this.interaction.simulateEndInteract()\n }\n\n updateOptions(options: Omit<Partial<PocaCardOptions>, 'front' | 'back'> & {\n front?: Partial<FaceOptions>\n back?: Partial<FaceOptions>\n }): void {\n if (options.flipSpeed != null) {\n this.interaction.flipSpeed = options.flipSpeed\n }\n if (options.front?.shader) {\n this.renderer.updateShader(options.front.shader)\n }\n if (options.back?.shader) {\n this.renderer.updateBackShader(options.back.shader)\n }\n if (options.front?.layers || options.back?.layers) {\n this.renderer.updateLayers(options.front?.layers, options.back?.layers)\n }\n if (options.front?.uniforms || options.back?.uniforms) {\n this.renderer.updateEffectUniforms(options.front?.uniforms, options.back?.uniforms)\n }\n if (options.front?.frame || options.back?.frame) {\n this.renderer.updateFrames(options.front?.frame, options.back?.frame)\n }\n }\n\n destroy(): void {\n this.wiggleController?.stop()\n this.interaction.destroy()\n this.renderer.destroy()\n this.removeAllListeners()\n }\n}\n","import glare from './glare.frag'\nimport glare3d from './glare-3d.frag'\nimport holo from './holo.frag'\nimport holo3d from './holo-3d.frag'\nimport snowfall from './snowfall.frag'\nimport snowfall3d from './snowfall-3d.frag'\nimport blur from './blur.frag'\nimport blur3d from './blur-3d.frag'\nimport brush from './brush.frag'\nimport brush3d from './brush-3d.frag'\nimport pulseLines from './pulse-lines.frag'\nimport gradientFlow from './gradient-flow.frag'\nimport proceduralOcean from './procedural-ocean.frag'\nimport rainbowFlow from './rainbow-flow.frag'\nimport shockWave from './shock-wave.frag'\nimport ripple from './ripple.frag'\nimport lenticular from './lenticular.frag'\n\nexport const builtinShaders: Record<string, string> = {\n glare,\n 'glare-3d': glare3d,\n holo,\n 'holo-3d': holo3d,\n snowfall,\n 'snowfall-3d': snowfall3d,\n blur,\n 'blur-3d': blur3d,\n brush,\n 'brush-3d': brush3d,\n 'pulse-lines': pulseLines,\n 'gradient-flow': gradientFlow,\n 'procedural-ocean': proceduralOcean,\n 'rainbow-flow': rainbowFlow,\n 'shock-wave': shockWave,\n 'ripple': ripple,\n lenticular,\n}\n"],"mappings":"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AAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAf,IAAO,2BAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAf,IAAO,qBAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAf,IAAO,wBAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAf,IAAO,oBAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAf,IAAO,uBAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAf,IAAO,oBAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAf,IAAO,uBAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAf,IAAO,2BAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAf,IAAO,6BAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAf,IAAO,gCAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAf,IAAO,4BAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAf,IAAO,0BAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAf,IAAO,sBAAQ;AAAA;AAAA;AA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","names":["THREE","THREE","D_default","D_default","THREE","rafId"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sangwonl/pocato-core",
3
- "version": "0.4.5",
3
+ "version": "0.4.7",
4
4
  "author": "Sangwon Lee <gamzabaw@gmail.com>",
5
5
  "license": "MIT",
6
6
  "repository": {