@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,287 @@
|
|
|
1
|
+
import { float, texture as tslTexture, uv, vec2 } from "three/tsl";
|
|
2
|
+
import * as THREE from "three/webgpu";
|
|
3
|
+
import { AsciiPass } from "./ascii-pass.js";
|
|
4
|
+
import { CrtPass } from "./crt-pass.js";
|
|
5
|
+
import { CustomShaderPass } from "./custom-shader-pass.js";
|
|
6
|
+
import { DitheringPass } from "./dithering-pass.js";
|
|
7
|
+
import { GradientPass } from "./gradient-pass.js";
|
|
8
|
+
import { HalftonePass } from "./halftone-pass.js";
|
|
9
|
+
import { InkPass } from "./ink-pass.js";
|
|
10
|
+
import { LivePass } from "./live-pass.js";
|
|
11
|
+
import { MediaPass } from "./media-pass.js";
|
|
12
|
+
import { ParticleGridPass } from "./particle-grid-pass.js";
|
|
13
|
+
import { PatternPass } from "./pattern-pass.js";
|
|
14
|
+
import { PixelSortingPass } from "./pixel-sorting-pass.js";
|
|
15
|
+
import { TextPass } from "./text-pass.js";
|
|
16
|
+
const RENDER_TARGET_OPTIONS = {
|
|
17
|
+
depthBuffer: false,
|
|
18
|
+
format: THREE.RGBAFormat,
|
|
19
|
+
generateMipmaps: false,
|
|
20
|
+
magFilter: THREE.NearestFilter,
|
|
21
|
+
minFilter: THREE.NearestFilter,
|
|
22
|
+
stencilBuffer: false,
|
|
23
|
+
type: THREE.HalfFloatType,
|
|
24
|
+
};
|
|
25
|
+
function clampUnit(value) {
|
|
26
|
+
return Math.max(0, Math.min(1, value));
|
|
27
|
+
}
|
|
28
|
+
function parameterValuesSignature(params) {
|
|
29
|
+
return JSON.stringify(Object.entries(params)
|
|
30
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
31
|
+
.map(([key, value]) => [key, value]));
|
|
32
|
+
}
|
|
33
|
+
function createLayerSignature(layer) {
|
|
34
|
+
if (layer.type === "custom-shader") {
|
|
35
|
+
return [
|
|
36
|
+
layer.id,
|
|
37
|
+
layer.kind,
|
|
38
|
+
layer.type,
|
|
39
|
+
layer.visible ? "1" : "0",
|
|
40
|
+
layer.opacity.toFixed(4),
|
|
41
|
+
layer.hue.toFixed(4),
|
|
42
|
+
layer.saturation.toFixed(4),
|
|
43
|
+
layer.blendMode,
|
|
44
|
+
layer.compositeMode,
|
|
45
|
+
typeof layer.params.sourceRevision === "number"
|
|
46
|
+
? String(layer.params.sourceRevision)
|
|
47
|
+
: "0",
|
|
48
|
+
typeof layer.params.sourceMode === "string" ? layer.params.sourceMode : "paste",
|
|
49
|
+
typeof layer.params.entryExport === "string" ? layer.params.entryExport : "sketch",
|
|
50
|
+
typeof layer.params.sourceFileName === "string" ? layer.params.sourceFileName : "",
|
|
51
|
+
].join("|");
|
|
52
|
+
}
|
|
53
|
+
return [
|
|
54
|
+
layer.id,
|
|
55
|
+
layer.kind,
|
|
56
|
+
layer.type,
|
|
57
|
+
layer.asset?.kind ?? "no-asset",
|
|
58
|
+
layer.asset?.src ?? "no-src",
|
|
59
|
+
layer.visible ? "1" : "0",
|
|
60
|
+
layer.opacity.toFixed(4),
|
|
61
|
+
layer.hue.toFixed(4),
|
|
62
|
+
layer.saturation.toFixed(4),
|
|
63
|
+
layer.blendMode,
|
|
64
|
+
layer.compositeMode,
|
|
65
|
+
parameterValuesSignature(layer.params),
|
|
66
|
+
].join("|");
|
|
67
|
+
}
|
|
68
|
+
export class PipelineManager {
|
|
69
|
+
renderer;
|
|
70
|
+
baseScene;
|
|
71
|
+
baseCamera;
|
|
72
|
+
blitScene;
|
|
73
|
+
blitCamera;
|
|
74
|
+
blitInputNode;
|
|
75
|
+
blitMaterial;
|
|
76
|
+
onRuntimeError;
|
|
77
|
+
passMap = new Map();
|
|
78
|
+
passes = [];
|
|
79
|
+
layerSignatures = new Map();
|
|
80
|
+
dirty = true;
|
|
81
|
+
width;
|
|
82
|
+
height;
|
|
83
|
+
logicalWidth;
|
|
84
|
+
logicalHeight;
|
|
85
|
+
rtA;
|
|
86
|
+
rtB;
|
|
87
|
+
constructor(renderer, size, onRuntimeError) {
|
|
88
|
+
this.renderer = renderer;
|
|
89
|
+
this.onRuntimeError = onRuntimeError;
|
|
90
|
+
this.width = Math.max(1, size.width);
|
|
91
|
+
this.height = Math.max(1, size.height);
|
|
92
|
+
this.logicalWidth = this.width;
|
|
93
|
+
this.logicalHeight = this.height;
|
|
94
|
+
this.baseScene = new THREE.Scene();
|
|
95
|
+
this.baseCamera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);
|
|
96
|
+
const baseMaterial = new THREE.MeshBasicMaterial({ color: "#080808" });
|
|
97
|
+
const baseMesh = new THREE.Mesh(new THREE.PlaneGeometry(2, 2), baseMaterial);
|
|
98
|
+
baseMesh.frustumCulled = false;
|
|
99
|
+
this.baseScene.add(baseMesh);
|
|
100
|
+
this.rtA = new THREE.WebGLRenderTarget(this.width, this.height, RENDER_TARGET_OPTIONS);
|
|
101
|
+
this.rtB = new THREE.WebGLRenderTarget(this.width, this.height, RENDER_TARGET_OPTIONS);
|
|
102
|
+
this.blitScene = new THREE.Scene();
|
|
103
|
+
this.blitCamera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);
|
|
104
|
+
const blitUv = vec2(uv().x, float(1).sub(uv().y));
|
|
105
|
+
this.blitInputNode = tslTexture(new THREE.Texture(), blitUv);
|
|
106
|
+
this.blitMaterial = new THREE.MeshBasicNodeMaterial();
|
|
107
|
+
this.blitMaterial.colorNode = this.blitInputNode;
|
|
108
|
+
const blitMesh = new THREE.Mesh(new THREE.PlaneGeometry(2, 2), this.blitMaterial);
|
|
109
|
+
blitMesh.frustumCulled = false;
|
|
110
|
+
this.blitScene.add(blitMesh);
|
|
111
|
+
}
|
|
112
|
+
syncLayers(layers) {
|
|
113
|
+
const incomingIds = new Set(layers.map((layer) => layer.id));
|
|
114
|
+
for (const [layerId, pass] of this.passMap) {
|
|
115
|
+
if (incomingIds.has(layerId)) {
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
pass.dispose();
|
|
119
|
+
this.passMap.delete(layerId);
|
|
120
|
+
this.layerSignatures.delete(layerId);
|
|
121
|
+
this.dirty = true;
|
|
122
|
+
}
|
|
123
|
+
const orderedPasses = [];
|
|
124
|
+
for (const layer of layers) {
|
|
125
|
+
const signature = createLayerSignature(layer);
|
|
126
|
+
let pass = this.passMap.get(layer.id);
|
|
127
|
+
if (!pass) {
|
|
128
|
+
pass = this.createPass(layer);
|
|
129
|
+
pass.resize(this.width, this.height);
|
|
130
|
+
pass.updateLogicalSize(this.logicalWidth, this.logicalHeight);
|
|
131
|
+
this.passMap.set(layer.id, pass);
|
|
132
|
+
this.dirty = true;
|
|
133
|
+
}
|
|
134
|
+
if (this.layerSignatures.get(layer.id) !== signature) {
|
|
135
|
+
this.layerSignatures.set(layer.id, signature);
|
|
136
|
+
this.applyLayerState(pass, layer);
|
|
137
|
+
this.dirty = true;
|
|
138
|
+
}
|
|
139
|
+
orderedPasses.push(pass);
|
|
140
|
+
}
|
|
141
|
+
if (orderedPasses.length !== this.passes.length ||
|
|
142
|
+
orderedPasses.some((pass, index) => this.passes[index] !== pass)) {
|
|
143
|
+
this.passes = orderedPasses;
|
|
144
|
+
this.dirty = true;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
render(time, delta) {
|
|
148
|
+
const activePasses = this.passes.filter((pass) => pass.enabled);
|
|
149
|
+
const needsContinuousRender = activePasses.some((pass) => pass.needsContinuousRender());
|
|
150
|
+
if (!(this.dirty || needsContinuousRender)) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
if (activePasses.length === 0) {
|
|
154
|
+
this.renderer.setRenderTarget(null);
|
|
155
|
+
this.renderer.render(this.baseScene, this.baseCamera);
|
|
156
|
+
this.dirty = false;
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
this.renderer.setRenderTarget(this.rtA);
|
|
160
|
+
this.renderer.render(this.baseScene, this.baseCamera);
|
|
161
|
+
let readTarget = this.rtA;
|
|
162
|
+
let writeTarget = this.rtB;
|
|
163
|
+
for (const pass of activePasses) {
|
|
164
|
+
pass.render(this.renderer, readTarget.texture, writeTarget, time, delta);
|
|
165
|
+
const previousRead = readTarget;
|
|
166
|
+
readTarget = writeTarget;
|
|
167
|
+
writeTarget = previousRead;
|
|
168
|
+
}
|
|
169
|
+
this.blitInputNode.value = readTarget.texture;
|
|
170
|
+
this.renderer.setRenderTarget(null);
|
|
171
|
+
this.renderer.render(this.blitScene, this.blitCamera);
|
|
172
|
+
this.dirty = false;
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
resize(size) {
|
|
176
|
+
this.width = Math.max(1, size.width);
|
|
177
|
+
this.height = Math.max(1, size.height);
|
|
178
|
+
this.rtA.setSize(this.width, this.height);
|
|
179
|
+
this.rtB.setSize(this.width, this.height);
|
|
180
|
+
for (const pass of this.passMap.values()) {
|
|
181
|
+
pass.resize(this.width, this.height);
|
|
182
|
+
}
|
|
183
|
+
this.dirty = true;
|
|
184
|
+
}
|
|
185
|
+
updateLogicalSize(size) {
|
|
186
|
+
const nextWidth = Math.max(1, size.width);
|
|
187
|
+
const nextHeight = Math.max(1, size.height);
|
|
188
|
+
if (nextWidth === this.logicalWidth && nextHeight === this.logicalHeight) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
this.logicalWidth = nextWidth;
|
|
192
|
+
this.logicalHeight = nextHeight;
|
|
193
|
+
for (const pass of this.passMap.values()) {
|
|
194
|
+
pass.updateLogicalSize(this.logicalWidth, this.logicalHeight);
|
|
195
|
+
}
|
|
196
|
+
this.dirty = true;
|
|
197
|
+
}
|
|
198
|
+
dispose() {
|
|
199
|
+
this.rtA.dispose();
|
|
200
|
+
this.rtB.dispose();
|
|
201
|
+
this.blitMaterial.dispose();
|
|
202
|
+
for (const pass of this.passMap.values()) {
|
|
203
|
+
pass.dispose();
|
|
204
|
+
}
|
|
205
|
+
this.passMap.clear();
|
|
206
|
+
this.passes = [];
|
|
207
|
+
this.layerSignatures.clear();
|
|
208
|
+
}
|
|
209
|
+
applyLayerState(pass, layer) {
|
|
210
|
+
pass.enabled = layer.visible;
|
|
211
|
+
pass.updateOpacity(clampUnit(layer.opacity));
|
|
212
|
+
pass.updateBlendMode(layer.blendMode);
|
|
213
|
+
const compositeMode = layer.compositeMode === "mask" ? "mask" : "filter";
|
|
214
|
+
pass.updateCompositeMode(compositeMode);
|
|
215
|
+
pass.updateLayerColorAdjustments(layer.hue, layer.saturation);
|
|
216
|
+
pass.updateParams(layer.params);
|
|
217
|
+
if (pass instanceof MediaPass) {
|
|
218
|
+
const asset = layer.asset;
|
|
219
|
+
if (asset?.kind === "image" || asset?.kind === "video") {
|
|
220
|
+
void pass
|
|
221
|
+
.setMedia(asset.src, asset.kind)
|
|
222
|
+
.then(() => {
|
|
223
|
+
this.dirty = true;
|
|
224
|
+
})
|
|
225
|
+
.catch((error) => {
|
|
226
|
+
this.onRuntimeError?.(error instanceof Error ? error.message : "Failed to load media asset.");
|
|
227
|
+
this.dirty = true;
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
pass.clearMedia();
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
if (pass instanceof LivePass) {
|
|
235
|
+
const facingMode = typeof layer.params.facingMode === "string" ? layer.params.facingMode : "user";
|
|
236
|
+
if (facingMode !== pass.getFacingMode() || !pass.needsContinuousRender()) {
|
|
237
|
+
void pass
|
|
238
|
+
.startCamera(facingMode)
|
|
239
|
+
.then(() => {
|
|
240
|
+
this.dirty = true;
|
|
241
|
+
})
|
|
242
|
+
.catch((error) => {
|
|
243
|
+
this.onRuntimeError?.(error instanceof Error ? error.message : "Failed to start live camera input.");
|
|
244
|
+
this.dirty = true;
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
createPass(layer) {
|
|
250
|
+
if (layer.kind === "effect") {
|
|
251
|
+
switch (layer.type) {
|
|
252
|
+
case "ascii":
|
|
253
|
+
return new AsciiPass(layer.id);
|
|
254
|
+
case "crt":
|
|
255
|
+
return new CrtPass(layer.id);
|
|
256
|
+
case "dithering":
|
|
257
|
+
return new DitheringPass(layer.id);
|
|
258
|
+
case "halftone":
|
|
259
|
+
return new HalftonePass(layer.id);
|
|
260
|
+
case "ink":
|
|
261
|
+
return new InkPass(layer.id);
|
|
262
|
+
case "particle-grid":
|
|
263
|
+
return new ParticleGridPass(layer.id);
|
|
264
|
+
case "pattern":
|
|
265
|
+
return new PatternPass(layer.id);
|
|
266
|
+
case "pixel-sorting":
|
|
267
|
+
return new PixelSortingPass(layer.id);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
if (layer.kind === "source" && (layer.type === "image" || layer.type === "video")) {
|
|
271
|
+
return new MediaPass(layer.id);
|
|
272
|
+
}
|
|
273
|
+
if (layer.kind === "source" && layer.type === "gradient") {
|
|
274
|
+
return new GradientPass(layer.id);
|
|
275
|
+
}
|
|
276
|
+
if (layer.kind === "source" && layer.type === "text") {
|
|
277
|
+
return new TextPass(layer.id);
|
|
278
|
+
}
|
|
279
|
+
if (layer.kind === "source" && layer.type === "custom-shader") {
|
|
280
|
+
return new CustomShaderPass(layer.id, this.onRuntimeError);
|
|
281
|
+
}
|
|
282
|
+
if (layer.kind === "source" && layer.type === "live") {
|
|
283
|
+
return new LivePass(layer.id);
|
|
284
|
+
}
|
|
285
|
+
throw new Error(`Layer "${layer.name}" of type "${layer.type}" is not supported by the package runtime yet.`);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
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 PixelSortingPass extends PassNode {
|
|
7
|
+
private readonly sortScene;
|
|
8
|
+
private readonly sortCamera;
|
|
9
|
+
private readonly sortMaterial;
|
|
10
|
+
private sortRtA;
|
|
11
|
+
private sortRtB;
|
|
12
|
+
private readonly blitInputNode;
|
|
13
|
+
private readonly sortTexNodeA;
|
|
14
|
+
private readonly sortTexNodeB;
|
|
15
|
+
private readonly passOffsetUniform;
|
|
16
|
+
private readonly widthUniform;
|
|
17
|
+
private readonly heightUniform;
|
|
18
|
+
private readonly thresholdUniform;
|
|
19
|
+
private readonly upperThresholdUniform;
|
|
20
|
+
private readonly directionUniform;
|
|
21
|
+
private readonly modeUniform;
|
|
22
|
+
private readonly reverseUniform;
|
|
23
|
+
private passCount;
|
|
24
|
+
private width;
|
|
25
|
+
private height;
|
|
26
|
+
constructor(layerId: string);
|
|
27
|
+
render(renderer: THREE.WebGPURenderer, inputTexture: THREE.Texture, outputTarget: THREE.WebGLRenderTarget, time: number, delta: number): void;
|
|
28
|
+
updateParams(params: LayerParameterValues): void;
|
|
29
|
+
resize(width: number, height: number): void;
|
|
30
|
+
dispose(): void;
|
|
31
|
+
protected buildEffectNode(): Node;
|
|
32
|
+
}
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import * as THREE from "three/webgpu";
|
|
2
|
+
import { dot, float, floor, max, min, mod, select, texture as tslTexture, uniform, uv, vec2, vec3, vec4, } from "three/tsl";
|
|
3
|
+
import { PassNode } from "./pass-node.js";
|
|
4
|
+
export class PixelSortingPass extends PassNode {
|
|
5
|
+
sortScene;
|
|
6
|
+
sortCamera;
|
|
7
|
+
sortMaterial;
|
|
8
|
+
sortRtA;
|
|
9
|
+
sortRtB;
|
|
10
|
+
blitInputNode;
|
|
11
|
+
sortTexNodeA;
|
|
12
|
+
sortTexNodeB;
|
|
13
|
+
passOffsetUniform;
|
|
14
|
+
widthUniform;
|
|
15
|
+
heightUniform;
|
|
16
|
+
thresholdUniform;
|
|
17
|
+
upperThresholdUniform;
|
|
18
|
+
directionUniform;
|
|
19
|
+
modeUniform;
|
|
20
|
+
reverseUniform;
|
|
21
|
+
passCount = 150;
|
|
22
|
+
width = 1;
|
|
23
|
+
height = 1;
|
|
24
|
+
constructor(layerId) {
|
|
25
|
+
super(layerId);
|
|
26
|
+
this.sortScene = new THREE.Scene();
|
|
27
|
+
this.sortCamera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);
|
|
28
|
+
this.passOffsetUniform = uniform(0);
|
|
29
|
+
this.widthUniform = uniform(1);
|
|
30
|
+
this.heightUniform = uniform(1);
|
|
31
|
+
this.thresholdUniform = uniform(0.25);
|
|
32
|
+
this.upperThresholdUniform = uniform(1);
|
|
33
|
+
this.directionUniform = uniform(0);
|
|
34
|
+
this.modeUniform = uniform(0);
|
|
35
|
+
this.reverseUniform = uniform(0);
|
|
36
|
+
const placeholder = new THREE.Texture();
|
|
37
|
+
// Compute pixel coordinates from flipped UVs
|
|
38
|
+
const texUv = vec2(uv().x, float(1).sub(uv().y));
|
|
39
|
+
const dims = vec2(this.widthUniform, this.heightUniform);
|
|
40
|
+
const pixelCoord = floor(texUv.mul(dims));
|
|
41
|
+
// Sort axis: horizontal (x) or vertical (y)
|
|
42
|
+
const isHorizontal = this.directionUniform.lessThan(float(0.5));
|
|
43
|
+
const sortIdx = select(isHorizontal, pixelCoord.x, pixelCoord.y);
|
|
44
|
+
const maxIdx = select(isHorizontal, this.widthUniform, this.heightUniform);
|
|
45
|
+
// Odd-even transposition: alternate pair groupings each pass
|
|
46
|
+
const pairMod = mod(sortIdx.add(this.passOffsetUniform), float(2));
|
|
47
|
+
const isLeft = pairMod.lessThan(float(1));
|
|
48
|
+
// Neighbor pixel coordinate
|
|
49
|
+
const neighborDir = select(isLeft, float(1), float(-1));
|
|
50
|
+
const neighborCoord = vec2(select(isHorizontal, pixelCoord.x.add(neighborDir), pixelCoord.x), select(isHorizontal, pixelCoord.y, pixelCoord.y.add(neighborDir)));
|
|
51
|
+
// Bounds check
|
|
52
|
+
const neighborIdx = select(isHorizontal, neighborCoord.x, neighborCoord.y);
|
|
53
|
+
const inBounds = neighborIdx
|
|
54
|
+
.greaterThanEqual(float(0))
|
|
55
|
+
.and(neighborIdx.lessThan(maxIdx));
|
|
56
|
+
// Sample both pixels (snapped to texel centers)
|
|
57
|
+
const mySnapUv = pixelCoord.add(0.5).div(dims);
|
|
58
|
+
const neighborSnapUv = neighborCoord.add(0.5).div(dims);
|
|
59
|
+
this.sortTexNodeA = tslTexture(placeholder, mySnapUv);
|
|
60
|
+
this.sortTexNodeB = tslTexture(placeholder, neighborSnapUv);
|
|
61
|
+
const myColor = this.sortTexNodeA;
|
|
62
|
+
const neighborColor = this.sortTexNodeB;
|
|
63
|
+
// Sort value: luminance
|
|
64
|
+
const lumaW = vec3(0.2126, 0.7152, 0.0722);
|
|
65
|
+
const myLuma = dot(vec3(myColor.r, myColor.g, myColor.b), lumaW);
|
|
66
|
+
const neighborLuma = dot(vec3(neighborColor.r, neighborColor.g, neighborColor.b), lumaW);
|
|
67
|
+
// Sort value: warmth (R-B, approximates hue/temperature)
|
|
68
|
+
const myWarmth = myColor.r.sub(myColor.b);
|
|
69
|
+
const neighborWarmth = neighborColor.r.sub(neighborColor.b);
|
|
70
|
+
// Sort value: saturation (HSV)
|
|
71
|
+
const myMax = max(max(myColor.r, myColor.g), myColor.b);
|
|
72
|
+
const myMin = min(min(myColor.r, myColor.g), myColor.b);
|
|
73
|
+
const mySat = select(myMax.greaterThan(float(0.001)), myMax.sub(myMin).div(myMax), float(0));
|
|
74
|
+
const nMax = max(max(neighborColor.r, neighborColor.g), neighborColor.b);
|
|
75
|
+
const nMin = min(min(neighborColor.r, neighborColor.g), neighborColor.b);
|
|
76
|
+
const nSat = select(nMax.greaterThan(float(0.001)), nMax.sub(nMin).div(nMax), float(0));
|
|
77
|
+
// Select sort value based on mode (0=luma, 1=hue/warmth, 2=saturation)
|
|
78
|
+
const isSatMode = this.modeUniform.greaterThan(float(1.5));
|
|
79
|
+
const isHueMode = this.modeUniform.greaterThan(float(0.5));
|
|
80
|
+
const myValue = select(isSatMode, mySat, select(isHueMode, myWarmth, myLuma));
|
|
81
|
+
const neighborValue = select(isSatMode, nSat, select(isHueMode, neighborWarmth, neighborLuma));
|
|
82
|
+
// Validation: both pixels must be within threshold band (luma-based)
|
|
83
|
+
const myInBand = myLuma
|
|
84
|
+
.greaterThan(this.thresholdUniform)
|
|
85
|
+
.and(myLuma.lessThan(this.upperThresholdUniform));
|
|
86
|
+
const neighborInBand = neighborLuma
|
|
87
|
+
.greaterThan(this.thresholdUniform)
|
|
88
|
+
.and(neighborLuma.lessThan(this.upperThresholdUniform));
|
|
89
|
+
const valid = myInBand.or(neighborInBand);
|
|
90
|
+
// Sort: swap if left > right (ascending) or left < right (descending/reverse)
|
|
91
|
+
const leftValue = select(isLeft, myValue, neighborValue);
|
|
92
|
+
const rightValue = select(isLeft, neighborValue, myValue);
|
|
93
|
+
const isReverse = this.reverseUniform.greaterThan(float(0.5));
|
|
94
|
+
const shouldSwap = select(isReverse, rightValue.greaterThan(leftValue), leftValue.greaterThan(rightValue));
|
|
95
|
+
const doSwap = inBounds.and(valid).and(shouldSwap);
|
|
96
|
+
const result = vec4(select(doSwap, neighborColor.r, myColor.r), select(doSwap, neighborColor.g, myColor.g), select(doSwap, neighborColor.b, myColor.b), float(1));
|
|
97
|
+
this.sortMaterial = new THREE.MeshBasicNodeMaterial();
|
|
98
|
+
this.sortMaterial.colorNode = result;
|
|
99
|
+
const sortMesh = new THREE.Mesh(new THREE.PlaneGeometry(2, 2), this.sortMaterial);
|
|
100
|
+
sortMesh.frustumCulled = false;
|
|
101
|
+
this.sortScene.add(sortMesh);
|
|
102
|
+
// Internal ping-pong render targets
|
|
103
|
+
const rtOptions = {
|
|
104
|
+
depthBuffer: false,
|
|
105
|
+
format: THREE.RGBAFormat,
|
|
106
|
+
generateMipmaps: false,
|
|
107
|
+
magFilter: THREE.NearestFilter,
|
|
108
|
+
minFilter: THREE.NearestFilter,
|
|
109
|
+
stencilBuffer: false,
|
|
110
|
+
type: THREE.HalfFloatType,
|
|
111
|
+
};
|
|
112
|
+
this.sortRtA = new THREE.WebGLRenderTarget(1, 1, rtOptions);
|
|
113
|
+
this.sortRtB = new THREE.WebGLRenderTarget(1, 1, rtOptions);
|
|
114
|
+
// Blit node for PassNode pipeline
|
|
115
|
+
const blitUv = vec2(uv().x, float(1).sub(uv().y));
|
|
116
|
+
this.blitInputNode = tslTexture(new THREE.Texture(), blitUv);
|
|
117
|
+
this.rebuildEffectNode();
|
|
118
|
+
}
|
|
119
|
+
render(renderer, inputTexture, outputTarget, time, delta) {
|
|
120
|
+
let readTexture = inputTexture;
|
|
121
|
+
let writeTarget = this.sortRtA;
|
|
122
|
+
for (let i = 0; i < this.passCount; i++) {
|
|
123
|
+
this.passOffsetUniform.value = i % 2;
|
|
124
|
+
this.sortTexNodeA.value = readTexture;
|
|
125
|
+
this.sortTexNodeB.value = readTexture;
|
|
126
|
+
renderer.setRenderTarget(writeTarget);
|
|
127
|
+
renderer.render(this.sortScene, this.sortCamera);
|
|
128
|
+
if (writeTarget === this.sortRtA) {
|
|
129
|
+
readTexture = this.sortRtA.texture;
|
|
130
|
+
writeTarget = this.sortRtB;
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
readTexture = this.sortRtB.texture;
|
|
134
|
+
writeTarget = this.sortRtA;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
this.blitInputNode.value = readTexture;
|
|
138
|
+
super.render(renderer, inputTexture, outputTarget, time, delta);
|
|
139
|
+
}
|
|
140
|
+
updateParams(params) {
|
|
141
|
+
this.thresholdUniform.value =
|
|
142
|
+
typeof params.threshold === "number" ? params.threshold : 0.25;
|
|
143
|
+
this.upperThresholdUniform.value =
|
|
144
|
+
typeof params.upperThreshold === "number" ? params.upperThreshold : 1;
|
|
145
|
+
this.directionUniform.value = params.direction === "vertical" ? 1 : 0;
|
|
146
|
+
this.reverseUniform.value = params.reverse === true ? 1 : 0;
|
|
147
|
+
if (params.mode === "hue") {
|
|
148
|
+
this.modeUniform.value = 1;
|
|
149
|
+
}
|
|
150
|
+
else if (params.mode === "saturation") {
|
|
151
|
+
this.modeUniform.value = 2;
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
this.modeUniform.value = 0;
|
|
155
|
+
}
|
|
156
|
+
const range = typeof params.range === "number" ? params.range : 0.3;
|
|
157
|
+
this.passCount = Math.max(1, Math.round(range * 300));
|
|
158
|
+
}
|
|
159
|
+
resize(width, height) {
|
|
160
|
+
this.width = Math.max(1, width);
|
|
161
|
+
this.height = Math.max(1, height);
|
|
162
|
+
this.widthUniform.value = this.width;
|
|
163
|
+
this.heightUniform.value = this.height;
|
|
164
|
+
this.sortRtA.setSize(this.width, this.height);
|
|
165
|
+
this.sortRtB.setSize(this.width, this.height);
|
|
166
|
+
}
|
|
167
|
+
dispose() {
|
|
168
|
+
this.sortRtA.dispose();
|
|
169
|
+
this.sortRtB.dispose();
|
|
170
|
+
this.sortMaterial.dispose();
|
|
171
|
+
super.dispose();
|
|
172
|
+
}
|
|
173
|
+
buildEffectNode() {
|
|
174
|
+
if (!this.blitInputNode) {
|
|
175
|
+
return this.inputNode;
|
|
176
|
+
}
|
|
177
|
+
return vec4(this.blitInputNode.r, this.blitInputNode.g, this.blitInputNode.b, float(1));
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const reinhardTonemap: (...args: unknown[]) => import("three/tsl").TSLNode;
|
|
2
|
+
export declare const totosTonemap: (...args: unknown[]) => import("three/tsl").TSLNode;
|
|
3
|
+
export declare const acesTonemap: (...args: unknown[]) => import("three/tsl").TSLNode;
|
|
4
|
+
export declare const crossProcessTonemap: (...args: unknown[]) => import("three/tsl").TSLNode;
|
|
5
|
+
export declare const bleachBypassTonemap: (...args: unknown[]) => import("three/tsl").TSLNode;
|
|
6
|
+
export declare const technicolorTonemap: (...args: unknown[]) => import("three/tsl").TSLNode;
|
|
7
|
+
export declare const cinematicTonemap: (...args: unknown[]) => import("three/tsl").TSLNode;
|
|
8
|
+
export declare const tanh: (...args: unknown[]) => import("three/tsl").TSLNode;
|
|
9
|
+
export declare const uncharted2Tonemap: (...args: unknown[]) => import("three/tsl").TSLNode;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import { Fn, dot, exp, mix, pow, smoothstep, vec3 } from "three/tsl";
|
|
3
|
+
export const reinhardTonemap = Fn(([color]) => {
|
|
4
|
+
return color.div(color.add(1.0));
|
|
5
|
+
});
|
|
6
|
+
export const totosTonemap = Fn(([color]) => {
|
|
7
|
+
const compressed = color
|
|
8
|
+
.mul(vec3(1.18, 1.04, 0.94))
|
|
9
|
+
.div(color.mul(vec3(0.82, 0.9, 0.98)).add(vec3(0.78, 0.68, 0.6)));
|
|
10
|
+
const lum = dot(compressed, vec3(0.2126, 0.7152, 0.0722));
|
|
11
|
+
const shadowLift = smoothstep(0.0, 0.38, lum);
|
|
12
|
+
const highlightRoll = smoothstep(0.42, 1.0, lum);
|
|
13
|
+
const toneMix = smoothstep(0.16, 0.82, lum);
|
|
14
|
+
const cool = vec3(compressed.x.mul(0.82), compressed.y.mul(0.98).add(shadowLift.mul(0.04)), compressed.z.mul(1.24).add(shadowLift.mul(0.08)));
|
|
15
|
+
const warm = vec3(compressed.x.mul(1.14).add(highlightRoll.mul(0.08)), compressed.y.mul(1.03).add(highlightRoll.mul(0.03)), compressed.z.mul(0.84));
|
|
16
|
+
const splitToned = mix(cool, warm, toneMix);
|
|
17
|
+
const curved = vec3(pow(splitToned.x, 0.86), pow(splitToned.y, 0.95), pow(splitToned.z, 1.12));
|
|
18
|
+
const bleach = mix(curved, vec3(lum), highlightRoll.mul(0.06));
|
|
19
|
+
return bleach.clamp(0.0, 1.0);
|
|
20
|
+
});
|
|
21
|
+
export const acesTonemap = Fn(([color]) => {
|
|
22
|
+
const a = 2.51;
|
|
23
|
+
const b = 0.03;
|
|
24
|
+
const c = 2.43;
|
|
25
|
+
const d = 0.59;
|
|
26
|
+
const e = 0.14;
|
|
27
|
+
return color
|
|
28
|
+
.mul(color.mul(a).add(b))
|
|
29
|
+
.div(color.mul(color.mul(c).add(d)).add(e))
|
|
30
|
+
.clamp(0.0, 1.0);
|
|
31
|
+
});
|
|
32
|
+
export const crossProcessTonemap = Fn(([color]) => {
|
|
33
|
+
const r = pow(color.x, 0.8);
|
|
34
|
+
const g = pow(color.y, 1.2);
|
|
35
|
+
const b = pow(color.z, 1.5);
|
|
36
|
+
return vec3(r, g, b).clamp(0.0, 1.0);
|
|
37
|
+
});
|
|
38
|
+
export const bleachBypassTonemap = Fn(([color]) => {
|
|
39
|
+
const lum = dot(color, vec3(0.2126, 0.7152, 0.0722));
|
|
40
|
+
const mixAmount = 0.7;
|
|
41
|
+
return mix(vec3(lum), color, mixAmount).mul(1.2).clamp(0.0, 1.0);
|
|
42
|
+
});
|
|
43
|
+
export const technicolorTonemap = Fn(([color]) => {
|
|
44
|
+
const r = color.x.mul(1.5);
|
|
45
|
+
const g = color.y.mul(1.2);
|
|
46
|
+
const b = color.z.mul(0.8).add(color.x.mul(0.2));
|
|
47
|
+
return vec3(r, g, b).clamp(0.0, 1.0);
|
|
48
|
+
});
|
|
49
|
+
export const cinematicTonemap = Fn(([color]) => {
|
|
50
|
+
const r = smoothstep(0.05, 0.95, color.x.mul(0.95).add(0.02));
|
|
51
|
+
const g = smoothstep(0.05, 0.95, color.y.mul(1.05));
|
|
52
|
+
const b = smoothstep(0.05, 0.95, color.z.mul(1.1));
|
|
53
|
+
return vec3(r, g, b).clamp(0.0, 1.0);
|
|
54
|
+
});
|
|
55
|
+
export const tanh = Fn(([x]) => {
|
|
56
|
+
const e2x = exp(x.mul(2.0));
|
|
57
|
+
return e2x.sub(1.0).div(e2x.add(1.0));
|
|
58
|
+
});
|
|
59
|
+
export const uncharted2Tonemap = totosTonemap;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
|
-
import { Fn, cos, float } from "three/tsl"
|
|
3
|
-
|
|
2
|
+
import { Fn, cos, float } from "three/tsl";
|
|
4
3
|
/**
|
|
5
4
|
* Generates a palette of colors using a cosine-based function.
|
|
6
5
|
*/
|
|
7
6
|
export const cosinePalette = Fn(([t, a, b, c, d, e = float(6.28318)]) => {
|
|
8
|
-
|
|
9
|
-
})
|
|
7
|
+
return a.add(b.mul(cos(e.mul(c.mul(t).add(d)))));
|
|
8
|
+
});
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const permute: (...args: unknown[]) => import("three/tsl").TSLNode;
|
|
2
|
+
export declare const taylorInvSqrt: (...args: unknown[]) => import("three/tsl").TSLNode;
|
|
3
|
+
export declare const mod289: (...args: unknown[]) => import("three/tsl").TSLNode;
|
|
4
|
+
export declare const fade: (...args: unknown[]) => import("three/tsl").TSLNode;
|
|
5
|
+
export declare const grad4: (...args: unknown[]) => import("three/tsl").TSLNode;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import { Fn, abs, add, dot, floor, fract, mod, mul, step, sub, vec3, vec4 } from "three/tsl";
|
|
3
|
+
export const permute = Fn(([x]) => {
|
|
4
|
+
return mod(mul(add(mul(x, 34.0), 10.0), x), 289.0);
|
|
5
|
+
});
|
|
6
|
+
export const taylorInvSqrt = Fn(([r]) => {
|
|
7
|
+
return sub(1.79284291400159, mul(0.85373472095314, r));
|
|
8
|
+
});
|
|
9
|
+
export const mod289 = Fn(([x]) => {
|
|
10
|
+
return mod(mul(add(mul(x, 34.0), 10.0), x), 289.0);
|
|
11
|
+
});
|
|
12
|
+
export const fade = Fn(([t]) => {
|
|
13
|
+
return t.mul(t).mul(t).mul(t.mul(t).mul(6.0).sub(t.mul(15.0)).add(10.0));
|
|
14
|
+
});
|
|
15
|
+
export const grad4 = Fn(([j, ip]) => {
|
|
16
|
+
const ones = vec4(1.0, 1.0, 1.0, -1.0);
|
|
17
|
+
const p = vec4().toVar();
|
|
18
|
+
const s = vec4().toVar();
|
|
19
|
+
p.xyz.assign(floor(fract(vec3(j).mul(ip.xyz)).mul(7.0)).mul(ip.z).sub(1.0));
|
|
20
|
+
p.w.assign(sub(1.5, dot(abs(p.xyz), ones.xyz)));
|
|
21
|
+
s.assign(step(p, vec4(0.0)));
|
|
22
|
+
p.xyz.assign(p.xyz.add(s.xyz.mul(2.0).sub(1.0).mul(s.www)));
|
|
23
|
+
return p;
|
|
24
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const curlNoise3d: (...args: unknown[]) => import("three/tsl").TSLNode;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import { EPSILON, Fn, cross, vec3 } from "three/tsl";
|
|
3
|
+
import { simplexNoise3d } from "./simplex-noise-3d.js";
|
|
4
|
+
export const curlNoise3d = Fn(([inputA]) => {
|
|
5
|
+
const aXPos = simplexNoise3d(inputA.add(vec3(EPSILON, 0, 0)));
|
|
6
|
+
const aXNeg = simplexNoise3d(inputA.sub(vec3(EPSILON, 0, 0)));
|
|
7
|
+
const aXAverage = aXPos.sub(aXNeg).div(EPSILON.mul(2));
|
|
8
|
+
const aYPos = simplexNoise3d(inputA.add(vec3(0, EPSILON, 0)));
|
|
9
|
+
const aYNeg = simplexNoise3d(inputA.sub(vec3(0, EPSILON, 0)));
|
|
10
|
+
const aYAverage = aYPos.sub(aYNeg).div(EPSILON.mul(2));
|
|
11
|
+
const aZPos = simplexNoise3d(inputA.add(vec3(0, 0, EPSILON)));
|
|
12
|
+
const aZNeg = simplexNoise3d(inputA.sub(vec3(0, 0, EPSILON)));
|
|
13
|
+
const aZAverage = aZPos.sub(aZNeg).div(EPSILON.mul(2));
|
|
14
|
+
const aGrabNoise = vec3(aXAverage, aYAverage, aZAverage).normalize();
|
|
15
|
+
const inputB = inputA.add(3.5);
|
|
16
|
+
const bXPos = simplexNoise3d(inputB.add(vec3(EPSILON, 0, 0)));
|
|
17
|
+
const bXNeg = simplexNoise3d(inputB.sub(vec3(EPSILON, 0, 0)));
|
|
18
|
+
const bXAverage = bXPos.sub(bXNeg).div(EPSILON.mul(2));
|
|
19
|
+
const bYPos = simplexNoise3d(inputB.add(vec3(0, EPSILON, 0)));
|
|
20
|
+
const bYNeg = simplexNoise3d(inputB.sub(vec3(0, EPSILON, 0)));
|
|
21
|
+
const bYAverage = bYPos.sub(bYNeg).div(EPSILON.mul(2));
|
|
22
|
+
const bZPos = simplexNoise3d(inputB.add(vec3(0, 0, EPSILON)));
|
|
23
|
+
const bZNeg = simplexNoise3d(inputB.sub(vec3(0, 0, EPSILON)));
|
|
24
|
+
const bZAverage = bZPos.sub(bZNeg).div(EPSILON.mul(2));
|
|
25
|
+
const bGrabNoise = vec3(bXAverage, bYAverage, bZAverage).normalize();
|
|
26
|
+
return cross(aGrabNoise, bGrabNoise).normalize();
|
|
27
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const curlNoise4d: (...args: unknown[]) => import("three/tsl").TSLNode;
|