@basementstudio/shader-lab 0.1.0 → 1.0.2
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/src/easings.d.ts +3 -0
- package/dist/src/easings.js +3 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.js +4 -0
- package/dist/src/lib/editor/custom-shader/shared.d.ts +1 -0
- package/dist/src/lib/editor/custom-shader/shared.js +1 -0
- package/dist/src/renderer/ascii-atlas.d.ts +5 -0
- package/dist/src/renderer/ascii-atlas.js +61 -0
- package/dist/src/renderer/ascii-pass.d.ts +50 -0
- package/dist/src/renderer/ascii-pass.js +271 -0
- package/dist/src/renderer/asset-url.d.ts +1 -0
- package/dist/src/renderer/asset-url.js +3 -0
- package/dist/src/renderer/blend-modes.d.ts +4 -0
- package/dist/src/renderer/blend-modes.js +157 -0
- package/dist/src/renderer/contracts.d.ts +26 -0
- package/dist/src/renderer/contracts.js +13 -0
- package/dist/src/renderer/create-webgpu-renderer.d.ts +3 -0
- package/dist/src/renderer/create-webgpu-renderer.js +37 -0
- package/dist/src/renderer/crt-pass.d.ts +72 -0
- package/dist/src/renderer/crt-pass.js +536 -0
- package/dist/src/renderer/custom-shader-pass.d.ts +17 -0
- package/dist/src/renderer/custom-shader-pass.js +79 -0
- package/dist/src/renderer/custom-shader-runtime.d.ts +16 -0
- package/dist/src/renderer/custom-shader-runtime.js +169 -0
- package/dist/src/renderer/dither-textures.d.ts +8 -0
- package/dist/src/renderer/dither-textures.js +66 -0
- package/dist/src/renderer/dithering-pass.d.ts +45 -0
- package/dist/src/renderer/dithering-pass.js +229 -0
- package/dist/src/renderer/gradient-pass.d.ts +39 -0
- package/dist/src/renderer/gradient-pass.js +358 -0
- package/dist/src/renderer/halftone-pass.d.ts +65 -0
- package/dist/src/renderer/halftone-pass.js +530 -0
- package/dist/src/renderer/ink-pass.d.ts +84 -0
- package/dist/src/renderer/ink-pass.js +526 -0
- package/dist/src/renderer/live-pass.d.ts +31 -0
- package/dist/src/renderer/live-pass.js +136 -0
- package/dist/src/renderer/media-pass.d.ts +32 -0
- package/dist/src/renderer/media-pass.js +130 -0
- package/dist/src/renderer/media-texture.d.ts +8 -0
- package/dist/src/renderer/media-texture.js +41 -0
- package/dist/src/renderer/particle-grid-pass.d.ts +48 -0
- package/dist/src/renderer/particle-grid-pass.js +269 -0
- package/dist/src/renderer/pass-node.d.ts +36 -0
- package/dist/src/renderer/pass-node.js +120 -0
- package/dist/src/renderer/pattern-atlas.d.ts +8 -0
- package/dist/src/renderer/pattern-atlas.js +79 -0
- package/dist/src/renderer/pattern-pass.d.ts +58 -0
- package/dist/src/renderer/pattern-pass.js +316 -0
- package/dist/src/renderer/pipeline-manager.d.ts +39 -0
- package/dist/src/renderer/pipeline-manager.js +287 -0
- package/dist/src/renderer/pixel-sorting-pass.d.ts +33 -0
- package/dist/src/renderer/pixel-sorting-pass.js +179 -0
- package/dist/src/renderer/shaders/tsl/color/tonemapping.d.ts +9 -0
- package/dist/src/renderer/shaders/tsl/color/tonemapping.js +59 -0
- package/dist/src/renderer/shaders/tsl/cosine-palette.d.ts +4 -0
- package/{packages/shader-lab-react/src/renderer/shaders/tsl/cosine-palette.ts → dist/src/renderer/shaders/tsl/cosine-palette.js} +3 -4
- package/dist/src/renderer/shaders/tsl/noise/common.d.ts +5 -0
- package/dist/src/renderer/shaders/tsl/noise/common.js +24 -0
- package/dist/src/renderer/shaders/tsl/noise/curl-noise-3d.d.ts +1 -0
- package/dist/src/renderer/shaders/tsl/noise/curl-noise-3d.js +27 -0
- package/dist/src/renderer/shaders/tsl/noise/curl-noise-4d.d.ts +1 -0
- package/dist/src/renderer/shaders/tsl/noise/curl-noise-4d.js +27 -0
- package/dist/src/renderer/shaders/tsl/noise/fbm.d.ts +1 -0
- package/dist/src/renderer/shaders/tsl/noise/fbm.js +11 -0
- package/dist/src/renderer/shaders/tsl/noise/perlin-noise-3d.d.ts +5 -0
- package/dist/src/renderer/shaders/tsl/noise/perlin-noise-3d.js +66 -0
- package/dist/src/renderer/shaders/tsl/noise/ridge-noise.d.ts +1 -0
- package/dist/src/renderer/shaders/tsl/noise/ridge-noise.js +19 -0
- package/dist/src/renderer/shaders/tsl/noise/simplex-noise-3d.d.ts +1 -0
- package/dist/src/renderer/shaders/tsl/noise/simplex-noise-3d.js +44 -0
- package/dist/src/renderer/shaders/tsl/noise/simplex-noise-4d.d.ts +1 -0
- package/dist/src/renderer/shaders/tsl/noise/simplex-noise-4d.js +51 -0
- package/dist/src/renderer/shaders/tsl/noise/turbulence.d.ts +7 -0
- package/dist/src/renderer/shaders/tsl/noise/turbulence.js +34 -0
- package/dist/src/renderer/shaders/tsl/noise/value-noise-3d.d.ts +1 -0
- package/dist/src/renderer/shaders/tsl/noise/value-noise-3d.js +27 -0
- package/dist/src/renderer/shaders/tsl/noise/voronoi-noise-3d.d.ts +1 -0
- package/dist/src/renderer/shaders/tsl/noise/voronoi-noise-3d.js +45 -0
- package/dist/src/renderer/shaders/tsl/patterns/bloom-edge-pattern.d.ts +4 -0
- package/dist/src/renderer/shaders/tsl/patterns/bloom-edge-pattern.js +13 -0
- package/dist/src/renderer/shaders/tsl/patterns/bloom.d.ts +4 -0
- package/{packages/shader-lab-react/src/renderer/shaders/tsl/patterns/bloom.ts → dist/src/renderer/shaders/tsl/patterns/bloom.js} +4 -6
- package/dist/src/renderer/shaders/tsl/patterns/canvas-weave-pattern.d.ts +4 -0
- package/dist/src/renderer/shaders/tsl/patterns/canvas-weave-pattern.js +16 -0
- package/dist/src/renderer/shaders/tsl/patterns/grain-texture-pattern.d.ts +4 -0
- package/{packages/shader-lab-react/src/renderer/shaders/tsl/patterns/grain-texture-pattern.ts → dist/src/renderer/shaders/tsl/patterns/grain-texture-pattern.js} +3 -4
- package/dist/src/renderer/shaders/tsl/patterns/repeating-pattern.d.ts +4 -0
- package/{packages/shader-lab-react/src/renderer/shaders/tsl/patterns/repeating-pattern.ts → dist/src/renderer/shaders/tsl/patterns/repeating-pattern.js} +4 -6
- package/dist/src/renderer/shaders/tsl/utils/atan2.d.ts +1 -0
- package/dist/src/renderer/shaders/tsl/utils/atan2.js +7 -0
- package/dist/src/renderer/shaders/tsl/utils/complex-conj.d.ts +4 -0
- package/{packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-conj.ts → dist/src/renderer/shaders/tsl/utils/complex-conj.js} +3 -4
- package/dist/src/renderer/shaders/tsl/utils/complex-cos.d.ts +4 -0
- package/dist/src/renderer/shaders/tsl/utils/complex-cos.js +9 -0
- package/dist/src/renderer/shaders/tsl/utils/complex-div.d.ts +1 -0
- package/dist/src/renderer/shaders/tsl/utils/complex-div.js +6 -0
- package/dist/src/renderer/shaders/tsl/utils/complex-log.d.ts +1 -0
- package/dist/src/renderer/shaders/tsl/utils/complex-log.js +6 -0
- package/dist/src/renderer/shaders/tsl/utils/complex-mobius.d.ts +4 -0
- package/dist/src/renderer/shaders/tsl/utils/complex-mobius.js +10 -0
- package/dist/src/renderer/shaders/tsl/utils/complex-mul.d.ts +4 -0
- package/{packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-mul.ts → dist/src/renderer/shaders/tsl/utils/complex-mul.js} +3 -4
- package/dist/src/renderer/shaders/tsl/utils/complex-pow.d.ts +5 -0
- package/dist/src/renderer/shaders/tsl/utils/complex-pow.js +14 -0
- package/dist/src/renderer/shaders/tsl/utils/complex-sin.d.ts +4 -0
- package/dist/src/renderer/shaders/tsl/utils/complex-sin.js +9 -0
- package/dist/src/renderer/shaders/tsl/utils/complex-sqrt.d.ts +5 -0
- package/dist/src/renderer/shaders/tsl/utils/complex-sqrt.js +12 -0
- package/dist/src/renderer/shaders/tsl/utils/complex-tan.d.ts +4 -0
- package/dist/src/renderer/shaders/tsl/utils/complex-tan.js +11 -0
- package/dist/src/renderer/shaders/tsl/utils/complex-to-polar.d.ts +4 -0
- package/dist/src/renderer/shaders/tsl/utils/complex-to-polar.js +9 -0
- package/dist/src/renderer/shaders/tsl/utils/hyperbolic.d.ts +8 -0
- package/{packages/shader-lab-react/src/renderer/shaders/tsl/utils/hyperbolic.ts → dist/src/renderer/shaders/tsl/utils/hyperbolic.js} +7 -11
- package/dist/src/renderer/shaders/tsl/utils/index.d.ts +38 -0
- package/dist/src/renderer/shaders/tsl/utils/index.js +39 -0
- package/dist/src/renderer/shaders/tsl/utils/rotate.d.ts +2 -0
- package/dist/src/renderer/shaders/tsl/utils/rotate.js +7 -0
- package/dist/src/renderer/shaders/tsl/utils/screen-aspect-uv.d.ts +2 -0
- package/dist/src/renderer/shaders/tsl/utils/screen-aspect-uv.js +6 -0
- package/dist/src/renderer/shaders/tsl/utils/sd-box-2d.d.ts +1 -0
- package/dist/src/renderer/shaders/tsl/utils/sd-box-2d.js +5 -0
- package/dist/src/renderer/shaders/tsl/utils/sd-diamond.d.ts +1 -0
- package/dist/src/renderer/shaders/tsl/utils/sd-diamond.js +5 -0
- package/dist/src/renderer/shaders/tsl/utils/sd-rhombus.d.ts +1 -0
- package/dist/src/renderer/shaders/tsl/utils/sd-rhombus.js +14 -0
- package/dist/src/renderer/shaders/tsl/utils/sd-sphere.d.ts +1 -0
- package/dist/src/renderer/shaders/tsl/utils/sd-sphere.js +5 -0
- package/dist/src/renderer/shaders/tsl/utils/smax.d.ts +1 -0
- package/dist/src/renderer/shaders/tsl/utils/smax.js +6 -0
- package/dist/src/renderer/shaders/tsl/utils/smin.d.ts +1 -0
- package/dist/src/renderer/shaders/tsl/utils/smin.js +6 -0
- package/dist/src/renderer/text-pass.d.ts +23 -0
- package/dist/src/renderer/text-pass.js +129 -0
- package/dist/src/runtime-clock.d.ts +9 -0
- package/dist/src/runtime-clock.js +20 -0
- package/dist/src/runtime-frame.d.ts +11 -0
- package/dist/src/runtime-frame.js +12 -0
- package/dist/src/shader-lab-composition.d.ts +9 -0
- package/dist/src/shader-lab-composition.js +96 -0
- package/dist/src/timeline.d.ts +8 -0
- package/dist/src/timeline.js +179 -0
- package/dist/src/types/editor.d.ts +3 -0
- package/dist/src/types/editor.js +1 -0
- package/dist/src/types.d.ts +81 -0
- package/dist/src/types.js +1 -0
- package/package.json +28 -65
- package/.biome/plugins/README.md +0 -21
- package/.biome/plugins/no-anchor-element.grit +0 -12
- package/.biome/plugins/no-relative-parent-imports.grit +0 -10
- package/.biome/plugins/no-unnecessary-forwardref.grit +0 -9
- package/.changeset/README.md +0 -17
- package/.changeset/config.json +0 -11
- package/.editorconfig +0 -40
- package/.env.example +0 -81
- package/.gitattributes +0 -19
- package/.github/workflows/canary.yml +0 -80
- package/.github/workflows/ci.yml +0 -37
- package/.github/workflows/release.yml +0 -56
- package/.tldrignore +0 -84
- package/.vscode/extensions.json +0 -20
- package/.vscode/settings.json +0 -105
- package/biome.json +0 -249
- package/bun.lock +0 -1224
- package/next.config.ts +0 -131
- package/packages/shader-lab-react/CHANGELOG.md +0 -9
- package/packages/shader-lab-react/README.md +0 -119
- package/packages/shader-lab-react/package.json +0 -36
- package/packages/shader-lab-react/scripts/fix-esm-specifiers.mjs +0 -57
- package/packages/shader-lab-react/scripts/prepare-dist.mjs +0 -4
- package/packages/shader-lab-react/src/ambient/three-tsl.d.ts +0 -146
- package/packages/shader-lab-react/src/ambient/three-webgpu.d.ts +0 -51
- package/packages/shader-lab-react/src/easings.ts +0 -4
- package/packages/shader-lab-react/src/index.ts +0 -35
- package/packages/shader-lab-react/src/lib/editor/custom-shader/shared.ts +0 -2
- package/packages/shader-lab-react/src/renderer/ascii-atlas.ts +0 -83
- package/packages/shader-lab-react/src/renderer/ascii-pass.ts +0 -416
- package/packages/shader-lab-react/src/renderer/asset-url.ts +0 -3
- package/packages/shader-lab-react/src/renderer/blend-modes.ts +0 -229
- package/packages/shader-lab-react/src/renderer/contracts.ts +0 -54
- package/packages/shader-lab-react/src/renderer/create-webgpu-renderer.ts +0 -48
- package/packages/shader-lab-react/src/renderer/crt-pass.ts +0 -1040
- package/packages/shader-lab-react/src/renderer/custom-shader-pass.ts +0 -108
- package/packages/shader-lab-react/src/renderer/custom-shader-runtime.ts +0 -309
- package/packages/shader-lab-react/src/renderer/dither-textures.ts +0 -99
- package/packages/shader-lab-react/src/renderer/dithering-pass.ts +0 -322
- package/packages/shader-lab-react/src/renderer/gradient-pass.ts +0 -521
- package/packages/shader-lab-react/src/renderer/halftone-pass.ts +0 -932
- package/packages/shader-lab-react/src/renderer/ink-pass.ts +0 -802
- package/packages/shader-lab-react/src/renderer/live-pass.ts +0 -194
- package/packages/shader-lab-react/src/renderer/media-pass.ts +0 -187
- package/packages/shader-lab-react/src/renderer/media-texture.ts +0 -66
- package/packages/shader-lab-react/src/renderer/particle-grid-pass.ts +0 -389
- package/packages/shader-lab-react/src/renderer/pass-node.ts +0 -209
- package/packages/shader-lab-react/src/renderer/pattern-atlas.ts +0 -133
- package/packages/shader-lab-react/src/renderer/pattern-pass.ts +0 -552
- package/packages/shader-lab-react/src/renderer/pipeline-manager.ts +0 -369
- package/packages/shader-lab-react/src/renderer/pixel-sorting-pass.ts +0 -277
- package/packages/shader-lab-react/src/renderer/shaders/tsl/color/tonemapping.ts +0 -87
- package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/common.ts +0 -31
- package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/curl-noise-3d.ts +0 -36
- package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/curl-noise-4d.ts +0 -36
- package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/fbm.ts +0 -13
- package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/perlin-noise-3d.ts +0 -96
- package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/ridge-noise.ts +0 -24
- package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/simplex-noise-3d.ts +0 -79
- package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/simplex-noise-4d.ts +0 -89
- package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/turbulence.ts +0 -56
- package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/value-noise-3d.ts +0 -32
- package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/voronoi-noise-3d.ts +0 -60
- package/packages/shader-lab-react/src/renderer/shaders/tsl/patterns/bloom-edge-pattern.ts +0 -15
- package/packages/shader-lab-react/src/renderer/shaders/tsl/patterns/canvas-weave-pattern.ts +0 -24
- package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/atan2.ts +0 -9
- package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-cos.ts +0 -10
- package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-div.ts +0 -11
- package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-log.ts +0 -7
- package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-mobius.ts +0 -12
- package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-pow.ts +0 -16
- package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-sin.ts +0 -10
- package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-sqrt.ts +0 -18
- package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-tan.ts +0 -12
- package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-to-polar.ts +0 -10
- package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/index.ts +0 -48
- package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/rotate.ts +0 -15
- package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/screen-aspect-uv.ts +0 -15
- package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/sd-box-2d.ts +0 -6
- package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/sd-diamond.ts +0 -6
- package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/sd-rhombus.ts +0 -27
- package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/sd-sphere.ts +0 -6
- package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/smax.ts +0 -7
- package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/smin.ts +0 -7
- package/packages/shader-lab-react/src/renderer/text-pass.ts +0 -176
- package/packages/shader-lab-react/src/runtime-clock.ts +0 -42
- package/packages/shader-lab-react/src/runtime-frame.ts +0 -29
- package/packages/shader-lab-react/src/shader-lab-composition.tsx +0 -163
- package/packages/shader-lab-react/src/timeline.ts +0 -283
- package/packages/shader-lab-react/src/types/editor.ts +0 -5
- package/packages/shader-lab-react/src/types.ts +0 -141
- package/packages/shader-lab-react/tsconfig.build.json +0 -8
- package/packages/shader-lab-react/tsconfig.json +0 -21
- package/postcss.config.mjs +0 -5
- package/public/assets/fonts/msdf/geist-mono/GeistMono-Regular-msdf-atlas.png +0 -0
- package/public/assets/fonts/msdf/geist-mono/GeistMono-Regular-msdf.json +0 -1412
- package/public/assets/patterns/bars/1.svg +0 -3
- package/public/assets/patterns/bars/2.svg +0 -3
- package/public/assets/patterns/bars/3.svg +0 -3
- package/public/assets/patterns/bars/4.svg +0 -3
- package/public/assets/patterns/bars/5.svg +0 -3
- package/public/assets/patterns/bars/6.svg +0 -3
- package/public/assets/patterns/candles/1.svg +0 -3
- package/public/assets/patterns/candles/2.svg +0 -3
- package/public/assets/patterns/candles/3.svg +0 -3
- package/public/assets/patterns/candles/4.svg +0 -3
- package/public/assets/patterns/shapes/1.svg +0 -3
- package/public/assets/patterns/shapes/2.svg +0 -3
- package/public/assets/patterns/shapes/3.svg +0 -3
- package/public/assets/patterns/shapes/4.svg +0 -4
- package/public/assets/patterns/shapes/5.svg +0 -3
- package/public/assets/patterns/shapes/6.svg +0 -4
- package/public/fonts/geist/Geist-Mono.woff2 +0 -0
- package/public/textures/blue-noise.png +0 -0
- package/public/textures/crt-mask.png +0 -0
- package/src/app/design/page.tsx +0 -398
- package/src/app/favicon.ico +0 -0
- package/src/app/globals.css +0 -280
- package/src/app/layout.tsx +0 -89
- package/src/app/page.tsx +0 -20
- package/src/app/robots.ts +0 -13
- package/src/app/sitemap.ts +0 -13
- package/src/components/editor/editor-canvas-viewport.tsx +0 -116
- package/src/components/editor/editor-export-dialog.tsx +0 -1177
- package/src/components/editor/editor-timeline-overlay.tsx +0 -983
- package/src/components/editor/editor-topbar.tsx +0 -287
- package/src/components/editor/layer-sidebar.tsx +0 -738
- package/src/components/editor/properties-sidebar-content.tsx +0 -574
- package/src/components/editor/properties-sidebar-fields.tsx +0 -389
- package/src/components/editor/properties-sidebar-utils.ts +0 -178
- package/src/components/editor/properties-sidebar.tsx +0 -421
- package/src/components/ui/button/index.tsx +0 -57
- package/src/components/ui/color-picker/index.tsx +0 -358
- package/src/components/ui/glass-panel/index.tsx +0 -45
- package/src/components/ui/icon-button/index.tsx +0 -46
- package/src/components/ui/select/index.tsx +0 -136
- package/src/components/ui/slider/index.tsx +0 -192
- package/src/components/ui/toggle/index.tsx +0 -34
- package/src/components/ui/typography/index.tsx +0 -61
- package/src/components/ui/xy-pad/index.tsx +0 -160
- package/src/features/editor/components/editor-export-dialog.module.css +0 -271
- package/src/hooks/use-editor-renderer.ts +0 -182
- package/src/lib/app.ts +0 -6
- package/src/lib/cn.ts +0 -7
- package/src/lib/easings.ts +0 -240
- package/src/lib/editor/config/layer-registry.ts +0 -2434
- package/src/lib/editor/custom-shader/shared.ts +0 -28
- package/src/lib/editor/export.ts +0 -420
- package/src/lib/editor/history.ts +0 -71
- package/src/lib/editor/layers.ts +0 -76
- package/src/lib/editor/parameter-schema.ts +0 -75
- package/src/lib/editor/project-file.ts +0 -145
- package/src/lib/editor/shader-export-snippet.ts +0 -37
- package/src/lib/editor/shader-export.ts +0 -315
- package/src/lib/editor/timeline/evaluate.ts +0 -252
- package/src/lib/editor/view-transform.ts +0 -58
- package/src/lib/fonts.ts +0 -28
- package/src/renderer/ascii-atlas.ts +0 -83
- package/src/renderer/ascii-pass.ts +0 -416
- package/src/renderer/blend-modes.ts +0 -229
- package/src/renderer/contracts.ts +0 -161
- package/src/renderer/create-webgpu-renderer.ts +0 -48
- package/src/renderer/crt-pass.ts +0 -1040
- package/src/renderer/custom-shader-pass.ts +0 -117
- package/src/renderer/custom-shader-runtime.ts +0 -309
- package/src/renderer/dither-textures.ts +0 -99
- package/src/renderer/dithering-pass.ts +0 -322
- package/src/renderer/gradient-pass.ts +0 -520
- package/src/renderer/halftone-pass.ts +0 -932
- package/src/renderer/ink-pass.ts +0 -683
- package/src/renderer/live-pass.ts +0 -194
- package/src/renderer/media-pass.ts +0 -187
- package/src/renderer/media-texture.ts +0 -66
- package/src/renderer/particle-grid-pass.ts +0 -389
- package/src/renderer/pass-node-factory.ts +0 -33
- package/src/renderer/pass-node.ts +0 -209
- package/src/renderer/pattern-atlas.ts +0 -97
- package/src/renderer/pattern-pass.ts +0 -552
- package/src/renderer/pipeline-manager.ts +0 -343
- package/src/renderer/pixel-sorting-pass.ts +0 -277
- package/src/renderer/project-clock.ts +0 -57
- package/src/renderer/shaders/tsl/color/tonemapping.ts +0 -86
- package/src/renderer/shaders/tsl/cosine-palette.ts +0 -8
- package/src/renderer/shaders/tsl/noise/common.ts +0 -30
- package/src/renderer/shaders/tsl/noise/curl-noise-3d.ts +0 -35
- package/src/renderer/shaders/tsl/noise/curl-noise-4d.ts +0 -35
- package/src/renderer/shaders/tsl/noise/fbm.ts +0 -12
- package/src/renderer/shaders/tsl/noise/perlin-noise-3d.ts +0 -97
- package/src/renderer/shaders/tsl/noise/ridge-noise.ts +0 -23
- package/src/renderer/shaders/tsl/noise/simplex-noise-3d.ts +0 -78
- package/src/renderer/shaders/tsl/noise/simplex-noise-4d.ts +0 -88
- package/src/renderer/shaders/tsl/noise/turbulence.ts +0 -55
- package/src/renderer/shaders/tsl/noise/value-noise-3d.ts +0 -31
- package/src/renderer/shaders/tsl/noise/voronoi-noise-3d.ts +0 -59
- package/src/renderer/shaders/tsl/patterns/bloom-edge-pattern.ts +0 -14
- package/src/renderer/shaders/tsl/patterns/bloom.ts +0 -10
- package/src/renderer/shaders/tsl/patterns/canvas-weave-pattern.ts +0 -23
- package/src/renderer/shaders/tsl/patterns/grain-texture-pattern.ts +0 -8
- package/src/renderer/shaders/tsl/patterns/repeating-pattern.ts +0 -10
- package/src/renderer/shaders/tsl/utils/atan2.ts +0 -8
- package/src/renderer/shaders/tsl/utils/complex-conj.ts +0 -8
- package/src/renderer/shaders/tsl/utils/complex-cos.ts +0 -9
- package/src/renderer/shaders/tsl/utils/complex-div.ts +0 -10
- package/src/renderer/shaders/tsl/utils/complex-log.ts +0 -6
- package/src/renderer/shaders/tsl/utils/complex-mobius.ts +0 -11
- package/src/renderer/shaders/tsl/utils/complex-mul.ts +0 -8
- package/src/renderer/shaders/tsl/utils/complex-pow.ts +0 -15
- package/src/renderer/shaders/tsl/utils/complex-sin.ts +0 -9
- package/src/renderer/shaders/tsl/utils/complex-sqrt.ts +0 -17
- package/src/renderer/shaders/tsl/utils/complex-tan.ts +0 -11
- package/src/renderer/shaders/tsl/utils/complex-to-polar.ts +0 -9
- package/src/renderer/shaders/tsl/utils/hyperbolic.ts +0 -19
- package/src/renderer/shaders/tsl/utils/index.ts +0 -47
- package/src/renderer/shaders/tsl/utils/rotate.ts +0 -14
- package/src/renderer/shaders/tsl/utils/screen-aspect-uv.ts +0 -14
- package/src/renderer/shaders/tsl/utils/sd-box-2d.ts +0 -5
- package/src/renderer/shaders/tsl/utils/sd-diamond.ts +0 -5
- package/src/renderer/shaders/tsl/utils/sd-rhombus.ts +0 -26
- package/src/renderer/shaders/tsl/utils/sd-sphere.ts +0 -5
- package/src/renderer/shaders/tsl/utils/smax.ts +0 -7
- package/src/renderer/shaders/tsl/utils/smin.ts +0 -6
- package/src/renderer/text-pass.ts +0 -176
- package/src/store/asset-store.ts +0 -193
- package/src/store/editor-store.ts +0 -223
- package/src/store/history-store.ts +0 -172
- package/src/store/index.ts +0 -31
- package/src/store/layer-store.ts +0 -675
- package/src/store/timeline-store.ts +0 -572
- package/src/types/assets.d.ts +0 -6
- package/src/types/css.d.ts +0 -21
- package/src/types/editor.ts +0 -357
- package/src/types/react.d.ts +0 -15
- package/src/types/three-tsl.d.ts +0 -146
- package/src/types/three-webgpu.d.ts +0 -51
- package/tsconfig.json +0 -49
- /package/{packages/shader-lab-react/assets → assets}/patterns/bars/1.svg +0 -0
- /package/{packages/shader-lab-react/assets → assets}/patterns/bars/2.svg +0 -0
- /package/{packages/shader-lab-react/assets → assets}/patterns/bars/3.svg +0 -0
- /package/{packages/shader-lab-react/assets → assets}/patterns/bars/4.svg +0 -0
- /package/{packages/shader-lab-react/assets → assets}/patterns/bars/5.svg +0 -0
- /package/{packages/shader-lab-react/assets → assets}/patterns/bars/6.svg +0 -0
- /package/{packages/shader-lab-react/assets → assets}/patterns/candles/1.svg +0 -0
- /package/{packages/shader-lab-react/assets → assets}/patterns/candles/2.svg +0 -0
- /package/{packages/shader-lab-react/assets → assets}/patterns/candles/3.svg +0 -0
- /package/{packages/shader-lab-react/assets → assets}/patterns/candles/4.svg +0 -0
- /package/{packages/shader-lab-react/assets → assets}/patterns/shapes/1.svg +0 -0
- /package/{packages/shader-lab-react/assets → assets}/patterns/shapes/2.svg +0 -0
- /package/{packages/shader-lab-react/assets → assets}/patterns/shapes/3.svg +0 -0
- /package/{packages/shader-lab-react/assets → assets}/patterns/shapes/4.svg +0 -0
- /package/{packages/shader-lab-react/assets → assets}/patterns/shapes/5.svg +0 -0
- /package/{packages/shader-lab-react/assets → assets}/patterns/shapes/6.svg +0 -0
- /package/{packages/shader-lab-react/assets → assets}/textures/blue-noise.png +0 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { clamp, float, uniform, vec3, vec4 } from "three/tsl";
|
|
2
|
+
import { CUSTOM_SHADER_ENTRY_EXPORT } from "../lib/editor/custom-shader/shared.js";
|
|
3
|
+
import { compileCustomShaderModule } from "./custom-shader-runtime.js";
|
|
4
|
+
import { PassNode } from "./pass-node.js";
|
|
5
|
+
export class CustomShaderPass extends PassNode {
|
|
6
|
+
onRuntimeError;
|
|
7
|
+
compiledSketch = null;
|
|
8
|
+
compileRequestId = 0;
|
|
9
|
+
lastCompileSignature = "";
|
|
10
|
+
timeUniform;
|
|
11
|
+
constructor(layerId, onRuntimeError) {
|
|
12
|
+
super(layerId);
|
|
13
|
+
this.onRuntimeError = onRuntimeError;
|
|
14
|
+
this.timeUniform = uniform(0);
|
|
15
|
+
this.rebuildEffectNode();
|
|
16
|
+
}
|
|
17
|
+
needsContinuousRender() {
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
updateParams(params) {
|
|
21
|
+
const sourceCode = typeof params.sourceCode === "string" ? params.sourceCode : "";
|
|
22
|
+
const entryExport = typeof params.entryExport === "string" && params.entryExport.trim()
|
|
23
|
+
? params.entryExport.trim()
|
|
24
|
+
: CUSTOM_SHADER_ENTRY_EXPORT;
|
|
25
|
+
const sourceFileName = typeof params.sourceFileName === "string" ? params.sourceFileName : "";
|
|
26
|
+
const sourceRevision = typeof params.sourceRevision === "number" ? params.sourceRevision : 0;
|
|
27
|
+
const compileSignature = [
|
|
28
|
+
entryExport,
|
|
29
|
+
sourceCode,
|
|
30
|
+
sourceFileName,
|
|
31
|
+
sourceRevision,
|
|
32
|
+
].join("\n");
|
|
33
|
+
if (compileSignature === this.lastCompileSignature) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
this.lastCompileSignature = compileSignature;
|
|
37
|
+
this.compileRequestId += 1;
|
|
38
|
+
const requestId = this.compileRequestId;
|
|
39
|
+
void compileCustomShaderModule({
|
|
40
|
+
entryExport,
|
|
41
|
+
extraScope: {
|
|
42
|
+
time: this.timeUniform,
|
|
43
|
+
},
|
|
44
|
+
fileName: sourceFileName || "custom-shader.ts",
|
|
45
|
+
sourceCode,
|
|
46
|
+
})
|
|
47
|
+
.then((compiled) => {
|
|
48
|
+
if (requestId !== this.compileRequestId) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
this.compiledSketch = compiled.buildNode;
|
|
52
|
+
this.onRuntimeError?.(null);
|
|
53
|
+
this.rebuildEffectNode();
|
|
54
|
+
})
|
|
55
|
+
.catch((error) => {
|
|
56
|
+
if (requestId !== this.compileRequestId) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
this.compiledSketch = null;
|
|
60
|
+
this.onRuntimeError?.(error instanceof Error ? error.message : "Custom shader compilation failed.");
|
|
61
|
+
this.rebuildEffectNode();
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
beforeRender(time) {
|
|
65
|
+
this.timeUniform.value = time;
|
|
66
|
+
}
|
|
67
|
+
buildEffectNode() {
|
|
68
|
+
if (!this.compiledSketch) {
|
|
69
|
+
return vec4(vec3(float(0), float(0), float(0)), float(1));
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
return vec4(clamp(this.compiledSketch(), vec3(float(0), float(0), float(0)), vec3(float(1), float(1), float(1))), float(1));
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
this.onRuntimeError?.(error instanceof Error ? error.message : "Custom shader execution failed.");
|
|
76
|
+
return vec4(vec3(float(0), float(0), float(0)), float(1));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { TSLNode } from "three/tsl";
|
|
2
|
+
type CompiledShaderModule = {
|
|
3
|
+
buildNode: () => TSLNode;
|
|
4
|
+
};
|
|
5
|
+
export declare function formatCustomShaderSource({ fileName, sourceCode, }: {
|
|
6
|
+
fileName?: string;
|
|
7
|
+
sourceCode: string;
|
|
8
|
+
}): Promise<string>;
|
|
9
|
+
export declare function compileCustomShaderModule({ entryExport, extraScope, fileName, force, sourceCode, }: {
|
|
10
|
+
entryExport: string;
|
|
11
|
+
extraScope?: Record<string, unknown>;
|
|
12
|
+
fileName?: string;
|
|
13
|
+
force?: boolean;
|
|
14
|
+
sourceCode: string;
|
|
15
|
+
}): Promise<CompiledShaderModule>;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import * as tsl from "three/tsl";
|
|
2
|
+
import * as shaderUtils from "./shaders/tsl/utils/index.js";
|
|
3
|
+
const PRELUDE = {
|
|
4
|
+
...tsl,
|
|
5
|
+
...shaderUtils,
|
|
6
|
+
};
|
|
7
|
+
const TRANSPILED_CACHE = new Map();
|
|
8
|
+
let typescriptPromise = null;
|
|
9
|
+
function isNodeLike(value) {
|
|
10
|
+
return Boolean(value &&
|
|
11
|
+
typeof value === "object" &&
|
|
12
|
+
"mul" in value &&
|
|
13
|
+
"add" in value &&
|
|
14
|
+
"sub" in value);
|
|
15
|
+
}
|
|
16
|
+
function formatDiagnostics(compiler, diagnostics) {
|
|
17
|
+
if (!(diagnostics && diagnostics.length > 0)) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
return diagnostics
|
|
21
|
+
.map((diagnostic) => compiler.flattenDiagnosticMessageText(diagnostic.messageText, "\n"))
|
|
22
|
+
.join("\n\n");
|
|
23
|
+
}
|
|
24
|
+
function createSourceFile(compiler, fileName, sourceCode) {
|
|
25
|
+
return compiler.createSourceFile(fileName, sourceCode, compiler.ScriptTarget.ES2020, true, getScriptKind(compiler, fileName));
|
|
26
|
+
}
|
|
27
|
+
function getSourceFileDiagnostics(sourceFile) {
|
|
28
|
+
return sourceFile.parseDiagnostics;
|
|
29
|
+
}
|
|
30
|
+
function isDirectiveStatement(compiler, statement) {
|
|
31
|
+
return (compiler.isExpressionStatement(statement) &&
|
|
32
|
+
compiler.isStringLiteral(statement.expression) &&
|
|
33
|
+
(statement.expression.text === "use client" ||
|
|
34
|
+
statement.expression.text === "use server"));
|
|
35
|
+
}
|
|
36
|
+
function statementContainsJsx(compiler, statement) {
|
|
37
|
+
let containsJsx = false;
|
|
38
|
+
const visit = (node) => {
|
|
39
|
+
if (compiler.isJsxElement(node) ||
|
|
40
|
+
compiler.isJsxSelfClosingElement(node) ||
|
|
41
|
+
compiler.isJsxFragment(node)) {
|
|
42
|
+
containsJsx = true;
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
compiler.forEachChild(node, visit);
|
|
46
|
+
};
|
|
47
|
+
compiler.forEachChild(statement, visit);
|
|
48
|
+
return containsJsx;
|
|
49
|
+
}
|
|
50
|
+
async function sanitizeCustomShaderSource({ fileName, sourceCode, }) {
|
|
51
|
+
const compiler = await getTypeScript();
|
|
52
|
+
const sourceFile = createSourceFile(compiler, fileName, sourceCode);
|
|
53
|
+
const diagnosticsMessage = formatDiagnostics(compiler, getSourceFileDiagnostics(sourceFile));
|
|
54
|
+
if (diagnosticsMessage) {
|
|
55
|
+
throw new Error(diagnosticsMessage);
|
|
56
|
+
}
|
|
57
|
+
const statements = sourceFile.statements.filter((statement) => {
|
|
58
|
+
if (isDirectiveStatement(compiler, statement)) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
if (compiler.isImportDeclaration(statement) ||
|
|
62
|
+
compiler.isImportEqualsDeclaration(statement) ||
|
|
63
|
+
compiler.isExportAssignment(statement)) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
if (compiler.isExportDeclaration(statement) &&
|
|
67
|
+
statement.moduleSpecifier !== undefined) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
if (statementContainsJsx(compiler, statement)) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
return true;
|
|
74
|
+
});
|
|
75
|
+
const sanitizedFile = compiler.factory.updateSourceFile(sourceFile, statements);
|
|
76
|
+
const printer = compiler.createPrinter({
|
|
77
|
+
newLine: compiler.NewLineKind.LineFeed,
|
|
78
|
+
});
|
|
79
|
+
return `${printer.printFile(sanitizedFile).trim()}\n`;
|
|
80
|
+
}
|
|
81
|
+
function assertNoExplicitImports(sourceCode) {
|
|
82
|
+
if (/^\s*import[\s{*]/m.test(sourceCode)) {
|
|
83
|
+
throw new Error("Custom shader imports are resolved through the injected prelude. Remove the imports or paste the whole sketch file and let the custom shader layer strip them.");
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
async function getTypeScript() {
|
|
87
|
+
if (!typescriptPromise) {
|
|
88
|
+
typescriptPromise = import("typescript");
|
|
89
|
+
}
|
|
90
|
+
return typescriptPromise;
|
|
91
|
+
}
|
|
92
|
+
function getScriptKind(compiler, fileName) {
|
|
93
|
+
return fileName.endsWith(".tsx")
|
|
94
|
+
? compiler.ScriptKind.TSX
|
|
95
|
+
: compiler.ScriptKind.TS;
|
|
96
|
+
}
|
|
97
|
+
export async function formatCustomShaderSource({ fileName, sourceCode, }) {
|
|
98
|
+
const compiler = await getTypeScript();
|
|
99
|
+
const resolvedFileName = fileName ?? "custom-shader.ts";
|
|
100
|
+
const sourceFile = createSourceFile(compiler, resolvedFileName, sourceCode);
|
|
101
|
+
const diagnosticsMessage = formatDiagnostics(compiler, getSourceFileDiagnostics(sourceFile));
|
|
102
|
+
if (diagnosticsMessage) {
|
|
103
|
+
throw new Error(diagnosticsMessage);
|
|
104
|
+
}
|
|
105
|
+
const printer = compiler.createPrinter({
|
|
106
|
+
newLine: compiler.NewLineKind.LineFeed,
|
|
107
|
+
});
|
|
108
|
+
return `${printer.printFile(sourceFile).trim()}\n`;
|
|
109
|
+
}
|
|
110
|
+
export async function compileCustomShaderModule({ entryExport, extraScope, fileName, force = false, sourceCode, }) {
|
|
111
|
+
const resolvedFileName = fileName ?? "custom-shader.ts";
|
|
112
|
+
const sanitizedSourceCode = await sanitizeCustomShaderSource({
|
|
113
|
+
fileName: resolvedFileName,
|
|
114
|
+
sourceCode,
|
|
115
|
+
});
|
|
116
|
+
assertNoExplicitImports(sanitizedSourceCode);
|
|
117
|
+
const cacheKey = `${entryExport}\n${resolvedFileName}\n${sanitizedSourceCode}`;
|
|
118
|
+
let outputText = !force ? (TRANSPILED_CACHE.get(cacheKey) ?? null) : null;
|
|
119
|
+
const compiler = await getTypeScript();
|
|
120
|
+
if (!outputText) {
|
|
121
|
+
const transpiled = compiler.transpileModule(sanitizedSourceCode, {
|
|
122
|
+
compilerOptions: {
|
|
123
|
+
esModuleInterop: true,
|
|
124
|
+
jsx: compiler.JsxEmit.ReactJSX,
|
|
125
|
+
module: compiler.ModuleKind.CommonJS,
|
|
126
|
+
target: compiler.ScriptTarget.ES2020,
|
|
127
|
+
},
|
|
128
|
+
fileName: resolvedFileName,
|
|
129
|
+
reportDiagnostics: true,
|
|
130
|
+
});
|
|
131
|
+
const diagnosticsMessage = formatDiagnostics(compiler, transpiled.diagnostics);
|
|
132
|
+
if (diagnosticsMessage) {
|
|
133
|
+
throw new Error(diagnosticsMessage);
|
|
134
|
+
}
|
|
135
|
+
outputText = transpiled.outputText;
|
|
136
|
+
TRANSPILED_CACHE.set(cacheKey, outputText);
|
|
137
|
+
}
|
|
138
|
+
const runtimeScope = {
|
|
139
|
+
...PRELUDE,
|
|
140
|
+
...(extraScope ?? {}),
|
|
141
|
+
};
|
|
142
|
+
const scopeNames = Object.keys(runtimeScope);
|
|
143
|
+
const scopeValues = scopeNames.map((key) => runtimeScope[key]);
|
|
144
|
+
const module = { exports: {} };
|
|
145
|
+
const exportsObject = module.exports;
|
|
146
|
+
const evaluator = new Function("exports", "module", ...scopeNames, `${outputText}\nreturn module.exports;`);
|
|
147
|
+
let resolvedExports;
|
|
148
|
+
try {
|
|
149
|
+
resolvedExports = evaluator(exportsObject, module, ...scopeValues);
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
throw new Error(error instanceof Error
|
|
153
|
+
? error.message
|
|
154
|
+
: "Custom shader evaluation failed.");
|
|
155
|
+
}
|
|
156
|
+
const exported = resolvedExports[entryExport] ?? module.exports[entryExport];
|
|
157
|
+
if (typeof exported !== "function") {
|
|
158
|
+
throw new Error(`Expected a named export \`${entryExport}\` that resolves to a TSL sketch function.`);
|
|
159
|
+
}
|
|
160
|
+
return {
|
|
161
|
+
buildNode: () => {
|
|
162
|
+
const result = exported();
|
|
163
|
+
if (!isNodeLike(result)) {
|
|
164
|
+
throw new Error(`The export \`${entryExport}\` did not return a valid TSL node.`);
|
|
165
|
+
}
|
|
166
|
+
return result;
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import * as THREE from "three/webgpu";
|
|
2
|
+
const BAYER_2X2 = [0, 2, 3, 1];
|
|
3
|
+
const BAYER_4X4 = [
|
|
4
|
+
0, 8, 2, 10,
|
|
5
|
+
12, 4, 14, 6,
|
|
6
|
+
3, 11, 1, 9,
|
|
7
|
+
15, 7, 13, 5,
|
|
8
|
+
];
|
|
9
|
+
const BAYER_8X8 = [
|
|
10
|
+
0, 32, 8, 40, 2, 34, 10, 42,
|
|
11
|
+
48, 16, 56, 24, 50, 18, 58, 26,
|
|
12
|
+
12, 44, 4, 36, 14, 46, 6, 38,
|
|
13
|
+
60, 28, 52, 20, 62, 30, 54, 22,
|
|
14
|
+
3, 35, 11, 43, 1, 33, 9, 41,
|
|
15
|
+
51, 19, 59, 27, 49, 17, 57, 25,
|
|
16
|
+
15, 47, 7, 39, 13, 45, 5, 37,
|
|
17
|
+
63, 31, 55, 23, 61, 29, 53, 21,
|
|
18
|
+
];
|
|
19
|
+
function buildBayerTexture(values, size) {
|
|
20
|
+
const normalizer = size * size;
|
|
21
|
+
const data = new Uint8Array(size * size * 4);
|
|
22
|
+
for (let index = 0; index < size * size; index += 1) {
|
|
23
|
+
const channel = Math.round(((values[index] ?? 0) / normalizer) * 255);
|
|
24
|
+
const offset = index * 4;
|
|
25
|
+
data[offset] = channel;
|
|
26
|
+
data[offset + 1] = channel;
|
|
27
|
+
data[offset + 2] = channel;
|
|
28
|
+
data[offset + 3] = 255;
|
|
29
|
+
}
|
|
30
|
+
const texture = new THREE.DataTexture(data, size, size, THREE.RGBAFormat, THREE.UnsignedByteType);
|
|
31
|
+
texture.magFilter = THREE.NearestFilter;
|
|
32
|
+
texture.minFilter = THREE.NearestFilter;
|
|
33
|
+
texture.wrapS = THREE.RepeatWrapping;
|
|
34
|
+
texture.wrapT = THREE.RepeatWrapping;
|
|
35
|
+
texture.needsUpdate = true;
|
|
36
|
+
return texture;
|
|
37
|
+
}
|
|
38
|
+
function buildBlueNoiseTexture(size = 64) {
|
|
39
|
+
const data = new Uint8Array(size * size * 4);
|
|
40
|
+
const fract = (value) => value - Math.floor(value);
|
|
41
|
+
for (let y = 0; y < size; y += 1) {
|
|
42
|
+
for (let x = 0; x < size; x += 1) {
|
|
43
|
+
const noise = Math.round(fract(52.9829189 * fract(0.06711056 * x + 0.00583715 * y)) * 255);
|
|
44
|
+
const offset = (y * size + x) * 4;
|
|
45
|
+
data[offset] = noise;
|
|
46
|
+
data[offset + 1] = noise;
|
|
47
|
+
data[offset + 2] = noise;
|
|
48
|
+
data[offset + 3] = 255;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const texture = new THREE.DataTexture(data, size, size, THREE.RGBAFormat, THREE.UnsignedByteType);
|
|
52
|
+
texture.magFilter = THREE.NearestFilter;
|
|
53
|
+
texture.minFilter = THREE.NearestFilter;
|
|
54
|
+
texture.wrapS = THREE.RepeatWrapping;
|
|
55
|
+
texture.wrapT = THREE.RepeatWrapping;
|
|
56
|
+
texture.needsUpdate = true;
|
|
57
|
+
return texture;
|
|
58
|
+
}
|
|
59
|
+
export function buildDitherTextures() {
|
|
60
|
+
return {
|
|
61
|
+
bayer2: buildBayerTexture(BAYER_2X2, 2),
|
|
62
|
+
bayer4: buildBayerTexture(BAYER_4X4, 4),
|
|
63
|
+
bayer8: buildBayerTexture(BAYER_8X8, 8),
|
|
64
|
+
noise: buildBlueNoiseTexture(),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import * as THREE from "three/webgpu";
|
|
2
|
+
import { type TSLNode } from "three/tsl";
|
|
3
|
+
import { PassNode } from "./pass-node";
|
|
4
|
+
import type { LayerParameterValues } from "../types/editor";
|
|
5
|
+
type Node = TSLNode;
|
|
6
|
+
export declare class DitheringPass extends PassNode {
|
|
7
|
+
private colorMode;
|
|
8
|
+
private isAnimated;
|
|
9
|
+
private readonly colorBlueUniform;
|
|
10
|
+
private readonly colorGreenUniform;
|
|
11
|
+
private readonly colorRedUniform;
|
|
12
|
+
private readonly highlightBlueUniform;
|
|
13
|
+
private readonly highlightGreenUniform;
|
|
14
|
+
private readonly highlightRedUniform;
|
|
15
|
+
private readonly levelsUniform;
|
|
16
|
+
private readonly logicalHeightUniform;
|
|
17
|
+
private readonly logicalWidthUniform;
|
|
18
|
+
private readonly matrixSizeUniform;
|
|
19
|
+
private readonly pixelSizeUniform;
|
|
20
|
+
private readonly shadowBlueUniform;
|
|
21
|
+
private readonly shadowGreenUniform;
|
|
22
|
+
private readonly shadowRedUniform;
|
|
23
|
+
private readonly spreadUniform;
|
|
24
|
+
private readonly textures;
|
|
25
|
+
private readonly dotScaleUniform;
|
|
26
|
+
private readonly animateDitherUniform;
|
|
27
|
+
private readonly ditherSpeedUniform;
|
|
28
|
+
private readonly timeUniform;
|
|
29
|
+
private readonly chromaticSplitUniform;
|
|
30
|
+
private currentTexture;
|
|
31
|
+
private ditherNode;
|
|
32
|
+
private ditherNodeG;
|
|
33
|
+
private ditherNodeB;
|
|
34
|
+
private readonly placeholder;
|
|
35
|
+
private sourceTextureNode;
|
|
36
|
+
constructor(layerId: string);
|
|
37
|
+
render(renderer: THREE.WebGPURenderer, inputTexture: THREE.Texture, outputTarget: THREE.WebGLRenderTarget, time: number, delta: number): void;
|
|
38
|
+
protected beforeRender(time: number, _delta: number): void;
|
|
39
|
+
needsContinuousRender(): boolean;
|
|
40
|
+
updateParams(params: LayerParameterValues): void;
|
|
41
|
+
dispose(): void;
|
|
42
|
+
updateLogicalSize(width: number, height: number): void;
|
|
43
|
+
protected buildEffectNode(): Node;
|
|
44
|
+
}
|
|
45
|
+
export {};
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import * as THREE from "three/webgpu";
|
|
2
|
+
import { abs, clamp, float, floor, fract, max, mix, smoothstep, texture as tslTexture, uniform, uv, vec2, vec3, vec4, } from "three/tsl";
|
|
3
|
+
import { buildDitherTextures } from "./dither-textures.js";
|
|
4
|
+
import { PassNode } from "./pass-node.js";
|
|
5
|
+
function hexToRgb(hex) {
|
|
6
|
+
const normalized = hex.trim().replace("#", "");
|
|
7
|
+
const value = normalized.length === 3
|
|
8
|
+
? normalized
|
|
9
|
+
.split("")
|
|
10
|
+
.map((entry) => `${entry}${entry}`)
|
|
11
|
+
.join("")
|
|
12
|
+
: normalized.padEnd(6, "0").slice(0, 6);
|
|
13
|
+
return [
|
|
14
|
+
Number.parseInt(value.slice(0, 2), 16) / 255,
|
|
15
|
+
Number.parseInt(value.slice(2, 4), 16) / 255,
|
|
16
|
+
Number.parseInt(value.slice(4, 6), 16) / 255,
|
|
17
|
+
];
|
|
18
|
+
}
|
|
19
|
+
export class DitheringPass extends PassNode {
|
|
20
|
+
colorMode = "source";
|
|
21
|
+
isAnimated = false;
|
|
22
|
+
colorBlueUniform;
|
|
23
|
+
colorGreenUniform;
|
|
24
|
+
colorRedUniform;
|
|
25
|
+
highlightBlueUniform;
|
|
26
|
+
highlightGreenUniform;
|
|
27
|
+
highlightRedUniform;
|
|
28
|
+
levelsUniform;
|
|
29
|
+
logicalHeightUniform;
|
|
30
|
+
logicalWidthUniform;
|
|
31
|
+
matrixSizeUniform;
|
|
32
|
+
pixelSizeUniform;
|
|
33
|
+
shadowBlueUniform;
|
|
34
|
+
shadowGreenUniform;
|
|
35
|
+
shadowRedUniform;
|
|
36
|
+
spreadUniform;
|
|
37
|
+
textures;
|
|
38
|
+
// Effects uniforms
|
|
39
|
+
dotScaleUniform;
|
|
40
|
+
animateDitherUniform;
|
|
41
|
+
ditherSpeedUniform;
|
|
42
|
+
timeUniform;
|
|
43
|
+
chromaticSplitUniform;
|
|
44
|
+
currentTexture;
|
|
45
|
+
ditherNode = null;
|
|
46
|
+
ditherNodeG = null;
|
|
47
|
+
ditherNodeB = null;
|
|
48
|
+
placeholder;
|
|
49
|
+
sourceTextureNode = null;
|
|
50
|
+
constructor(layerId) {
|
|
51
|
+
super(layerId);
|
|
52
|
+
this.textures = buildDitherTextures();
|
|
53
|
+
this.placeholder = new THREE.Texture();
|
|
54
|
+
this.currentTexture = this.textures.bayer4;
|
|
55
|
+
this.levelsUniform = uniform(4);
|
|
56
|
+
this.logicalWidthUniform = uniform(1);
|
|
57
|
+
this.logicalHeightUniform = uniform(1);
|
|
58
|
+
this.matrixSizeUniform = uniform(4);
|
|
59
|
+
this.pixelSizeUniform = uniform(1);
|
|
60
|
+
this.spreadUniform = uniform(0.5);
|
|
61
|
+
this.colorRedUniform = uniform(0.96);
|
|
62
|
+
this.colorGreenUniform = uniform(0.96);
|
|
63
|
+
this.colorBlueUniform = uniform(0.94);
|
|
64
|
+
this.shadowRedUniform = uniform(0.06);
|
|
65
|
+
this.shadowGreenUniform = uniform(0.06);
|
|
66
|
+
this.shadowBlueUniform = uniform(0.06);
|
|
67
|
+
this.highlightRedUniform = uniform(0.96);
|
|
68
|
+
this.highlightGreenUniform = uniform(0.95);
|
|
69
|
+
this.highlightBlueUniform = uniform(0.91);
|
|
70
|
+
// Effects uniforms
|
|
71
|
+
this.dotScaleUniform = uniform(1.0);
|
|
72
|
+
this.animateDitherUniform = uniform(0.0);
|
|
73
|
+
this.ditherSpeedUniform = uniform(1.0);
|
|
74
|
+
this.timeUniform = uniform(0.0);
|
|
75
|
+
this.chromaticSplitUniform = uniform(0.0);
|
|
76
|
+
this.rebuildEffectNode();
|
|
77
|
+
}
|
|
78
|
+
render(renderer, inputTexture, outputTarget, time, delta) {
|
|
79
|
+
if (this.sourceTextureNode) {
|
|
80
|
+
this.sourceTextureNode.value = inputTexture;
|
|
81
|
+
}
|
|
82
|
+
if (this.ditherNode) {
|
|
83
|
+
this.ditherNode.value = this.currentTexture;
|
|
84
|
+
}
|
|
85
|
+
if (this.ditherNodeG) {
|
|
86
|
+
this.ditherNodeG.value = this.currentTexture;
|
|
87
|
+
}
|
|
88
|
+
if (this.ditherNodeB) {
|
|
89
|
+
this.ditherNodeB.value = this.currentTexture;
|
|
90
|
+
}
|
|
91
|
+
super.render(renderer, inputTexture, outputTarget, time, delta);
|
|
92
|
+
}
|
|
93
|
+
beforeRender(time, _delta) {
|
|
94
|
+
this.timeUniform.value = time;
|
|
95
|
+
}
|
|
96
|
+
needsContinuousRender() {
|
|
97
|
+
return this.isAnimated;
|
|
98
|
+
}
|
|
99
|
+
updateParams(params) {
|
|
100
|
+
const nextColorMode = params.colorMode === "monochrome" ||
|
|
101
|
+
params.colorMode === "duo-tone"
|
|
102
|
+
? params.colorMode
|
|
103
|
+
: "source";
|
|
104
|
+
const [red, green, blue] = hexToRgb(typeof params.monoColor === "string" ? params.monoColor : "#f5f5f0");
|
|
105
|
+
const [shadowRed, shadowGreen, shadowBlue] = hexToRgb(typeof params.shadowColor === "string" ? params.shadowColor : "#101010");
|
|
106
|
+
const [highlightRed, highlightGreen, highlightBlue] = hexToRgb(typeof params.highlightColor === "string" ? params.highlightColor : "#f5f2e8");
|
|
107
|
+
this.colorRedUniform.value = red;
|
|
108
|
+
this.colorGreenUniform.value = green;
|
|
109
|
+
this.colorBlueUniform.value = blue;
|
|
110
|
+
this.shadowRedUniform.value = shadowRed;
|
|
111
|
+
this.shadowGreenUniform.value = shadowGreen;
|
|
112
|
+
this.shadowBlueUniform.value = shadowBlue;
|
|
113
|
+
this.highlightRedUniform.value = highlightRed;
|
|
114
|
+
this.highlightGreenUniform.value = highlightGreen;
|
|
115
|
+
this.highlightBlueUniform.value = highlightBlue;
|
|
116
|
+
this.levelsUniform.value =
|
|
117
|
+
typeof params.levels === "number" ? Math.max(2, params.levels) : 4;
|
|
118
|
+
this.pixelSizeUniform.value =
|
|
119
|
+
typeof params.pixelSize === "number" ? Math.max(1, Math.round(params.pixelSize)) : 1;
|
|
120
|
+
this.spreadUniform.value =
|
|
121
|
+
typeof params.spread === "number"
|
|
122
|
+
? Math.max(0, Math.min(1, params.spread))
|
|
123
|
+
: 0.5;
|
|
124
|
+
switch (params.algorithm) {
|
|
125
|
+
case "bayer-2x2":
|
|
126
|
+
this.currentTexture = this.textures.bayer2;
|
|
127
|
+
this.matrixSizeUniform.value = 2;
|
|
128
|
+
break;
|
|
129
|
+
case "bayer-8x8":
|
|
130
|
+
this.currentTexture = this.textures.bayer8;
|
|
131
|
+
this.matrixSizeUniform.value = 8;
|
|
132
|
+
break;
|
|
133
|
+
case "noise":
|
|
134
|
+
this.currentTexture = this.textures.noise;
|
|
135
|
+
this.matrixSizeUniform.value = 64;
|
|
136
|
+
break;
|
|
137
|
+
default:
|
|
138
|
+
this.currentTexture = this.textures.bayer4;
|
|
139
|
+
this.matrixSizeUniform.value = 4;
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
// Effects params
|
|
143
|
+
this.dotScaleUniform.value =
|
|
144
|
+
typeof params.dotScale === "number" ? params.dotScale : 1.0;
|
|
145
|
+
this.isAnimated = params.animateDither === true;
|
|
146
|
+
this.animateDitherUniform.value = this.isAnimated ? 1.0 : 0.0;
|
|
147
|
+
this.ditherSpeedUniform.value =
|
|
148
|
+
typeof params.ditherSpeed === "number" ? params.ditherSpeed : 1.0;
|
|
149
|
+
this.chromaticSplitUniform.value = params.chromaticSplit === true ? 1.0 : 0.0;
|
|
150
|
+
if (nextColorMode !== this.colorMode) {
|
|
151
|
+
this.colorMode = nextColorMode;
|
|
152
|
+
this.rebuildEffectNode();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
dispose() {
|
|
156
|
+
this.placeholder.dispose();
|
|
157
|
+
this.textures.bayer2.dispose();
|
|
158
|
+
this.textures.bayer4.dispose();
|
|
159
|
+
this.textures.bayer8.dispose();
|
|
160
|
+
this.textures.noise.dispose();
|
|
161
|
+
super.dispose();
|
|
162
|
+
}
|
|
163
|
+
updateLogicalSize(width, height) {
|
|
164
|
+
this.logicalWidthUniform.value = Math.max(1, width);
|
|
165
|
+
this.logicalHeightUniform.value = Math.max(1, height);
|
|
166
|
+
}
|
|
167
|
+
buildEffectNode() {
|
|
168
|
+
if (!(this.levelsUniform && this.matrixSizeUniform)) {
|
|
169
|
+
return this.inputNode;
|
|
170
|
+
}
|
|
171
|
+
const pixelSize = max(this.pixelSizeUniform, float(1));
|
|
172
|
+
const renderTargetUv = vec2(uv().x, float(1).sub(uv().y));
|
|
173
|
+
const logicalWidth = max(this.logicalWidthUniform.div(pixelSize), float(1));
|
|
174
|
+
const logicalHeight = max(this.logicalHeightUniform.div(pixelSize), float(1));
|
|
175
|
+
const logicalDims = vec2(logicalWidth, logicalHeight);
|
|
176
|
+
// Cell grid
|
|
177
|
+
const cellCoordinates = vec2(floor(renderTargetUv.x.mul(logicalWidth)), floor(renderTargetUv.y.mul(logicalHeight)));
|
|
178
|
+
const snappedUv = vec2(cellCoordinates.x.add(0.5).div(logicalWidth), cellCoordinates.y.add(0.5).div(logicalHeight));
|
|
179
|
+
// Animated Dither: shift ditherUv by time * speed when animate is on
|
|
180
|
+
const timeOffset = this.timeUniform.mul(this.ditherSpeedUniform).mul(this.animateDitherUniform);
|
|
181
|
+
const ditherUv = cellCoordinates.div(this.matrixSizeUniform).add(timeOffset);
|
|
182
|
+
// Chromatic Split: sample dither at 3 offset UVs when enabled
|
|
183
|
+
const splitOffset = this.chromaticSplitUniform.div(this.matrixSizeUniform);
|
|
184
|
+
const ditherUvR = ditherUv;
|
|
185
|
+
const ditherUvG = ditherUv.add(vec2(splitOffset, float(0)));
|
|
186
|
+
const ditherUvB = ditherUv.add(vec2(float(0), splitOffset));
|
|
187
|
+
this.sourceTextureNode = tslTexture(this.placeholder, snappedUv);
|
|
188
|
+
this.ditherNode = tslTexture(this.currentTexture, ditherUvR);
|
|
189
|
+
this.ditherNodeG = tslTexture(this.currentTexture, ditherUvG);
|
|
190
|
+
this.ditherNodeB = tslTexture(this.currentTexture, ditherUvB);
|
|
191
|
+
const src = this.sourceTextureNode;
|
|
192
|
+
const thresholdR = float(this.ditherNode.r).sub(float(0.5));
|
|
193
|
+
const thresholdG = float(this.ditherNodeG.r).sub(float(0.5));
|
|
194
|
+
const thresholdB = float(this.ditherNodeB.r).sub(float(0.5));
|
|
195
|
+
const levelsMinusOne = max(this.levelsUniform.sub(float(1)), float(1));
|
|
196
|
+
// Per-channel quantization with independent thresholds
|
|
197
|
+
const adjustedR = float(src.r).add(thresholdR.mul(this.spreadUniform));
|
|
198
|
+
const adjustedG = float(src.g).add(thresholdG.mul(this.spreadUniform));
|
|
199
|
+
const adjustedB = float(src.b).add(thresholdB.mul(this.spreadUniform));
|
|
200
|
+
const quantizedColor = clamp(vec3(floor(adjustedR.mul(levelsMinusOne).add(0.5)).div(levelsMinusOne), floor(adjustedG.mul(levelsMinusOne).add(0.5)).div(levelsMinusOne), floor(adjustedB.mul(levelsMinusOne).add(0.5)).div(levelsMinusOne)), vec3(float(0), float(0), float(0)), vec3(float(1), float(1), float(1)));
|
|
201
|
+
// Color mode
|
|
202
|
+
const quantizedLuma = float(quantizedColor.x)
|
|
203
|
+
.mul(float(0.2126))
|
|
204
|
+
.add(float(quantizedColor.y).mul(float(0.7152)))
|
|
205
|
+
.add(float(quantizedColor.z).mul(float(0.0722)));
|
|
206
|
+
const monoTint = vec3(this.colorRedUniform, this.colorGreenUniform, this.colorBlueUniform);
|
|
207
|
+
const shadowTint = vec3(this.shadowRedUniform, this.shadowGreenUniform, this.shadowBlueUniform);
|
|
208
|
+
const highlightTint = vec3(this.highlightRedUniform, this.highlightGreenUniform, this.highlightBlueUniform);
|
|
209
|
+
let colorResult;
|
|
210
|
+
switch (this.colorMode) {
|
|
211
|
+
case "monochrome":
|
|
212
|
+
colorResult = vec3(quantizedLuma, quantizedLuma, quantizedLuma).mul(monoTint);
|
|
213
|
+
break;
|
|
214
|
+
case "duo-tone":
|
|
215
|
+
colorResult = mix(shadowTint, highlightTint, quantizedLuma);
|
|
216
|
+
break;
|
|
217
|
+
default:
|
|
218
|
+
colorResult = quantizedColor;
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
// Dot Scale: mask within each cell (square shape only)
|
|
222
|
+
const cellFrac = fract(renderTargetUv.mul(logicalDims));
|
|
223
|
+
const centered = cellFrac.sub(vec2(0.5, 0.5));
|
|
224
|
+
const dist = max(abs(centered.x), abs(centered.y));
|
|
225
|
+
const halfSize = float(0.5).mul(this.dotScaleUniform);
|
|
226
|
+
const mask = smoothstep(halfSize, halfSize.sub(float(0.01)), dist);
|
|
227
|
+
return vec4(vec3(colorResult).mul(mask), float(1));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type TSLNode } from "three/tsl";
|
|
2
|
+
import type { LayerParameterValues } from "../types/editor";
|
|
3
|
+
import { PassNode } from "./pass-node";
|
|
4
|
+
type Node = TSLNode;
|
|
5
|
+
export declare class GradientPass extends PassNode {
|
|
6
|
+
private readonly activePointsUniform;
|
|
7
|
+
private readonly animateUniform;
|
|
8
|
+
private readonly aspectUniform;
|
|
9
|
+
private readonly falloffUniform;
|
|
10
|
+
private readonly glowStrengthUniform;
|
|
11
|
+
private readonly glowThresholdUniform;
|
|
12
|
+
private readonly grainAmountUniform;
|
|
13
|
+
private readonly motionAmountUniform;
|
|
14
|
+
private readonly motionSpeedUniform;
|
|
15
|
+
private readonly pointColorUniforms;
|
|
16
|
+
private readonly pointPositionUniforms;
|
|
17
|
+
private readonly pointWeightUniforms;
|
|
18
|
+
private readonly timeUniform;
|
|
19
|
+
private readonly vignetteRadiusUniform;
|
|
20
|
+
private readonly vignetteSoftnessUniform;
|
|
21
|
+
private readonly vignetteStrengthUniform;
|
|
22
|
+
private noiseSeed;
|
|
23
|
+
private readonly vortexAmountUniform;
|
|
24
|
+
private readonly warpAmountUniform;
|
|
25
|
+
private readonly warpBiasUniform;
|
|
26
|
+
private readonly warpDecayUniform;
|
|
27
|
+
private readonly warpScaleUniform;
|
|
28
|
+
private isAnimated;
|
|
29
|
+
private noiseMode;
|
|
30
|
+
private tonemapMode;
|
|
31
|
+
private warpIterations;
|
|
32
|
+
constructor(layerId: string);
|
|
33
|
+
updateParams(params: LayerParameterValues): void;
|
|
34
|
+
resize(width: number, height: number): void;
|
|
35
|
+
needsContinuousRender(): boolean;
|
|
36
|
+
protected beforeRender(time: number): void;
|
|
37
|
+
protected buildEffectNode(): Node;
|
|
38
|
+
}
|
|
39
|
+
export {};
|