@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,72 @@
|
|
|
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 CrtPass extends PassNode {
|
|
7
|
+
private bloomEnabled;
|
|
8
|
+
private bloomNode;
|
|
9
|
+
private readonly bloomIntensityUniform;
|
|
10
|
+
private readonly bloomRadiusUniform;
|
|
11
|
+
private readonly bloomSoftnessUniform;
|
|
12
|
+
private readonly bloomThresholdUniform;
|
|
13
|
+
private readonly crtModeUniform;
|
|
14
|
+
private readonly cellSizeUniform;
|
|
15
|
+
private readonly scanlineIntensityUniform;
|
|
16
|
+
private readonly maskIntensityUniform;
|
|
17
|
+
private readonly barrelDistortionUniform;
|
|
18
|
+
private readonly chromaticAberrationUniform;
|
|
19
|
+
private readonly beamFocusUniform;
|
|
20
|
+
private readonly brightnessUniform;
|
|
21
|
+
private readonly highlightDriveUniform;
|
|
22
|
+
private readonly highlightThresholdUniform;
|
|
23
|
+
private readonly shoulderUniform;
|
|
24
|
+
private readonly chromaRetentionUniform;
|
|
25
|
+
private readonly shadowLiftUniform;
|
|
26
|
+
private readonly persistenceUniform;
|
|
27
|
+
private readonly vignetteIntensityUniform;
|
|
28
|
+
private readonly flickerIntensityUniform;
|
|
29
|
+
private readonly glitchIntensityUniform;
|
|
30
|
+
private readonly glitchSpeedUniform;
|
|
31
|
+
private readonly signalArtifactsUniform;
|
|
32
|
+
private readonly widthUniform;
|
|
33
|
+
private readonly heightUniform;
|
|
34
|
+
private readonly timeUniform;
|
|
35
|
+
private readonly placeholder;
|
|
36
|
+
private historyReadTarget;
|
|
37
|
+
private historyWriteTarget;
|
|
38
|
+
private historyValid;
|
|
39
|
+
private sourceTextureNodes;
|
|
40
|
+
private historyTextureNodes;
|
|
41
|
+
private renderWidth;
|
|
42
|
+
private renderHeight;
|
|
43
|
+
constructor(layerId: string);
|
|
44
|
+
render(renderer: THREE.WebGPURenderer, inputTexture: THREE.Texture, outputTarget: THREE.WebGLRenderTarget, time: number, delta: number): void;
|
|
45
|
+
protected beforeRender(time: number, _delta: number): void;
|
|
46
|
+
needsContinuousRender(): boolean;
|
|
47
|
+
updateParams(params: LayerParameterValues): void;
|
|
48
|
+
resize(width: number, height: number): void;
|
|
49
|
+
updateLogicalSize(width: number, height: number): void;
|
|
50
|
+
dispose(): void;
|
|
51
|
+
protected buildEffectNode(): Node;
|
|
52
|
+
private buildBand;
|
|
53
|
+
private buildRoundedPhosphor;
|
|
54
|
+
private buildFeedResponse;
|
|
55
|
+
private renderPhosphorCell;
|
|
56
|
+
private buildTubeGlow;
|
|
57
|
+
private buildSpecularLift;
|
|
58
|
+
private buildScanlineEnvelope;
|
|
59
|
+
private luma;
|
|
60
|
+
private modeWeight;
|
|
61
|
+
private toNode;
|
|
62
|
+
private normalizeBloomRadius;
|
|
63
|
+
private normalizeBloomSoftness;
|
|
64
|
+
private disposeBloomNode;
|
|
65
|
+
private getBloomTextureNode;
|
|
66
|
+
private sampleBeamColor;
|
|
67
|
+
private sampleHalation;
|
|
68
|
+
private sampleSignalColor;
|
|
69
|
+
private trackHistoryTextureNode;
|
|
70
|
+
private trackSourceTextureNode;
|
|
71
|
+
}
|
|
72
|
+
export {};
|
|
@@ -0,0 +1,536 @@
|
|
|
1
|
+
import * as THREE from "three/webgpu";
|
|
2
|
+
import { bloom } from "three/examples/jsm/tsl/display/BloomNode.js";
|
|
3
|
+
import { abs, clamp, dot, float, floor, fract, max, min, mix, mod, pow, select, smoothstep, texture as tslTexture, uniform, uv, vec2, vec3, vec4, } from "three/tsl";
|
|
4
|
+
import { simplexNoise3d } from "./shaders/tsl/noise/simplex-noise-3d.js";
|
|
5
|
+
import { PassNode } from "./pass-node.js";
|
|
6
|
+
const CRT_MODE_SLOT_MASK = 0;
|
|
7
|
+
const CRT_MODE_APERTURE_GRILLE = 1;
|
|
8
|
+
const CRT_MODE_COMPOSITE_TV = 2;
|
|
9
|
+
const HISTORY_TARGET_OPTIONS = {
|
|
10
|
+
depthBuffer: false,
|
|
11
|
+
format: THREE.RGBAFormat,
|
|
12
|
+
generateMipmaps: false,
|
|
13
|
+
magFilter: THREE.LinearFilter,
|
|
14
|
+
minFilter: THREE.LinearFilter,
|
|
15
|
+
stencilBuffer: false,
|
|
16
|
+
type: THREE.HalfFloatType,
|
|
17
|
+
};
|
|
18
|
+
function clamp01(value) {
|
|
19
|
+
return Math.max(0, Math.min(1, value));
|
|
20
|
+
}
|
|
21
|
+
function toModeValue(value) {
|
|
22
|
+
switch (value) {
|
|
23
|
+
case "aperture-grille":
|
|
24
|
+
return CRT_MODE_APERTURE_GRILLE;
|
|
25
|
+
case "composite-tv":
|
|
26
|
+
return CRT_MODE_COMPOSITE_TV;
|
|
27
|
+
default:
|
|
28
|
+
return CRT_MODE_SLOT_MASK;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export class CrtPass extends PassNode {
|
|
32
|
+
bloomEnabled = true;
|
|
33
|
+
bloomNode = null;
|
|
34
|
+
bloomIntensityUniform;
|
|
35
|
+
bloomRadiusUniform;
|
|
36
|
+
bloomSoftnessUniform;
|
|
37
|
+
bloomThresholdUniform;
|
|
38
|
+
crtModeUniform;
|
|
39
|
+
cellSizeUniform;
|
|
40
|
+
scanlineIntensityUniform;
|
|
41
|
+
maskIntensityUniform;
|
|
42
|
+
barrelDistortionUniform;
|
|
43
|
+
chromaticAberrationUniform;
|
|
44
|
+
beamFocusUniform;
|
|
45
|
+
brightnessUniform;
|
|
46
|
+
highlightDriveUniform;
|
|
47
|
+
highlightThresholdUniform;
|
|
48
|
+
shoulderUniform;
|
|
49
|
+
chromaRetentionUniform;
|
|
50
|
+
shadowLiftUniform;
|
|
51
|
+
persistenceUniform;
|
|
52
|
+
vignetteIntensityUniform;
|
|
53
|
+
flickerIntensityUniform;
|
|
54
|
+
glitchIntensityUniform;
|
|
55
|
+
glitchSpeedUniform;
|
|
56
|
+
signalArtifactsUniform;
|
|
57
|
+
widthUniform;
|
|
58
|
+
heightUniform;
|
|
59
|
+
timeUniform;
|
|
60
|
+
placeholder;
|
|
61
|
+
historyReadTarget;
|
|
62
|
+
historyWriteTarget;
|
|
63
|
+
historyValid = false;
|
|
64
|
+
sourceTextureNodes = [];
|
|
65
|
+
historyTextureNodes = [];
|
|
66
|
+
renderWidth = 1;
|
|
67
|
+
renderHeight = 1;
|
|
68
|
+
constructor(layerId) {
|
|
69
|
+
super(layerId);
|
|
70
|
+
this.placeholder = new THREE.Texture();
|
|
71
|
+
this.historyReadTarget = new THREE.WebGLRenderTarget(1, 1, HISTORY_TARGET_OPTIONS);
|
|
72
|
+
this.historyWriteTarget = new THREE.WebGLRenderTarget(1, 1, HISTORY_TARGET_OPTIONS);
|
|
73
|
+
this.crtModeUniform = uniform(CRT_MODE_SLOT_MASK);
|
|
74
|
+
this.cellSizeUniform = uniform(3);
|
|
75
|
+
this.scanlineIntensityUniform = uniform(0.17);
|
|
76
|
+
this.maskIntensityUniform = uniform(1);
|
|
77
|
+
this.barrelDistortionUniform = uniform(0.15);
|
|
78
|
+
this.chromaticAberrationUniform = uniform(2);
|
|
79
|
+
this.beamFocusUniform = uniform(0.58);
|
|
80
|
+
this.brightnessUniform = uniform(1.8);
|
|
81
|
+
this.highlightDriveUniform = uniform(1);
|
|
82
|
+
this.highlightThresholdUniform = uniform(0.62);
|
|
83
|
+
this.shoulderUniform = uniform(0.25);
|
|
84
|
+
this.chromaRetentionUniform = uniform(1.15);
|
|
85
|
+
this.shadowLiftUniform = uniform(0.16);
|
|
86
|
+
this.persistenceUniform = uniform(0.18);
|
|
87
|
+
this.vignetteIntensityUniform = uniform(0.45);
|
|
88
|
+
this.flickerIntensityUniform = uniform(0.2);
|
|
89
|
+
this.glitchIntensityUniform = uniform(0.13);
|
|
90
|
+
this.glitchSpeedUniform = uniform(5);
|
|
91
|
+
this.signalArtifactsUniform = uniform(0.45);
|
|
92
|
+
this.widthUniform = uniform(1);
|
|
93
|
+
this.heightUniform = uniform(1);
|
|
94
|
+
this.timeUniform = uniform(0);
|
|
95
|
+
this.bloomIntensityUniform = uniform(1.93);
|
|
96
|
+
this.bloomRadiusUniform = uniform(8);
|
|
97
|
+
this.bloomSoftnessUniform = uniform(0.31);
|
|
98
|
+
this.bloomThresholdUniform = uniform(0);
|
|
99
|
+
this.rebuildEffectNode();
|
|
100
|
+
}
|
|
101
|
+
render(renderer, inputTexture, outputTarget, time, delta) {
|
|
102
|
+
this.inputNode.value = inputTexture;
|
|
103
|
+
for (const node of this.sourceTextureNodes) {
|
|
104
|
+
node.value = inputTexture;
|
|
105
|
+
}
|
|
106
|
+
const historyTexture = this.historyValid ? this.historyReadTarget.texture : this.placeholder;
|
|
107
|
+
for (const node of this.historyTextureNodes) {
|
|
108
|
+
node.value = historyTexture;
|
|
109
|
+
}
|
|
110
|
+
this.beforeRender(time, delta);
|
|
111
|
+
renderer.setRenderTarget(outputTarget);
|
|
112
|
+
renderer.render(this.scene, this.camera);
|
|
113
|
+
renderer.setRenderTarget(this.historyWriteTarget);
|
|
114
|
+
renderer.render(this.scene, this.camera);
|
|
115
|
+
const previousRead = this.historyReadTarget;
|
|
116
|
+
this.historyReadTarget = this.historyWriteTarget;
|
|
117
|
+
this.historyWriteTarget = previousRead;
|
|
118
|
+
this.historyValid = true;
|
|
119
|
+
}
|
|
120
|
+
beforeRender(time, _delta) {
|
|
121
|
+
this.timeUniform.value = time;
|
|
122
|
+
}
|
|
123
|
+
needsContinuousRender() {
|
|
124
|
+
const modeValue = this.crtModeUniform.value;
|
|
125
|
+
return (this.flickerIntensityUniform.value > 0 ||
|
|
126
|
+
this.glitchIntensityUniform.value > 0 ||
|
|
127
|
+
this.persistenceUniform.value > 0 ||
|
|
128
|
+
(modeValue === CRT_MODE_COMPOSITE_TV &&
|
|
129
|
+
this.signalArtifactsUniform.value > 0));
|
|
130
|
+
}
|
|
131
|
+
updateParams(params) {
|
|
132
|
+
this.crtModeUniform.value = toModeValue(params.crtMode);
|
|
133
|
+
this.cellSizeUniform.value =
|
|
134
|
+
typeof params.cellSize === "number" ? Math.max(2, params.cellSize) : 3;
|
|
135
|
+
this.scanlineIntensityUniform.value =
|
|
136
|
+
typeof params.scanlineIntensity === "number" ? clamp01(params.scanlineIntensity) : 0.17;
|
|
137
|
+
this.maskIntensityUniform.value =
|
|
138
|
+
typeof params.maskIntensity === "number" ? clamp01(params.maskIntensity) : 1;
|
|
139
|
+
this.barrelDistortionUniform.value =
|
|
140
|
+
typeof params.barrelDistortion === "number"
|
|
141
|
+
? Math.max(0, Math.min(0.3, params.barrelDistortion))
|
|
142
|
+
: 0.15;
|
|
143
|
+
this.chromaticAberrationUniform.value =
|
|
144
|
+
typeof params.chromaticAberration === "number"
|
|
145
|
+
? Math.max(0, Math.min(2, params.chromaticAberration))
|
|
146
|
+
: 2;
|
|
147
|
+
this.beamFocusUniform.value =
|
|
148
|
+
typeof params.beamFocus === "number" ? clamp01(params.beamFocus) : 0.58;
|
|
149
|
+
this.brightnessUniform.value =
|
|
150
|
+
typeof params.brightness === "number"
|
|
151
|
+
? Math.max(0.5, params.brightness)
|
|
152
|
+
: 1.8;
|
|
153
|
+
this.highlightDriveUniform.value =
|
|
154
|
+
typeof params.highlightDrive === "number"
|
|
155
|
+
? Math.max(1, params.highlightDrive)
|
|
156
|
+
: 1;
|
|
157
|
+
this.highlightThresholdUniform.value =
|
|
158
|
+
typeof params.highlightThreshold === "number"
|
|
159
|
+
? clamp01(params.highlightThreshold)
|
|
160
|
+
: 0.62;
|
|
161
|
+
this.shoulderUniform.value =
|
|
162
|
+
typeof params.shoulder === "number" ? Math.max(0, params.shoulder) : 0.25;
|
|
163
|
+
this.chromaRetentionUniform.value =
|
|
164
|
+
typeof params.chromaRetention === "number"
|
|
165
|
+
? Math.max(0, Math.min(2, params.chromaRetention))
|
|
166
|
+
: 1.15;
|
|
167
|
+
this.shadowLiftUniform.value =
|
|
168
|
+
typeof params.shadowLift === "number" ? clamp01(params.shadowLift) : 0.16;
|
|
169
|
+
this.persistenceUniform.value =
|
|
170
|
+
typeof params.persistence === "number" ? clamp01(params.persistence) : 0.18;
|
|
171
|
+
this.vignetteIntensityUniform.value =
|
|
172
|
+
typeof params.vignetteIntensity === "number" ? clamp01(params.vignetteIntensity) : 0.45;
|
|
173
|
+
this.flickerIntensityUniform.value =
|
|
174
|
+
typeof params.flickerIntensity === "number"
|
|
175
|
+
? Math.max(0, Math.min(0.2, params.flickerIntensity))
|
|
176
|
+
: 0.03;
|
|
177
|
+
this.glitchIntensityUniform.value =
|
|
178
|
+
typeof params.glitchIntensity === "number" ? clamp01(params.glitchIntensity) : 0;
|
|
179
|
+
this.glitchSpeedUniform.value =
|
|
180
|
+
typeof params.glitchSpeed === "number"
|
|
181
|
+
? Math.max(0.1, Math.min(5, params.glitchSpeed))
|
|
182
|
+
: 1;
|
|
183
|
+
this.signalArtifactsUniform.value =
|
|
184
|
+
typeof params.signalArtifacts === "number" ? clamp01(params.signalArtifacts) : 0.45;
|
|
185
|
+
const nextBloomEnabled = params.bloomEnabled !== false;
|
|
186
|
+
const nextBloomIntensity = typeof params.bloomIntensity === "number" ? Math.max(0, params.bloomIntensity) : 1.5;
|
|
187
|
+
const nextBloomThreshold = typeof params.bloomThreshold === "number" ? clamp01(params.bloomThreshold) : 0.4;
|
|
188
|
+
const nextBloomRadius = typeof params.bloomRadius === "number" ? Math.max(0, params.bloomRadius) : 8;
|
|
189
|
+
const nextBloomSoftness = typeof params.bloomSoftness === "number" ? clamp01(params.bloomSoftness) : 0.4;
|
|
190
|
+
this.bloomIntensityUniform.value = nextBloomIntensity;
|
|
191
|
+
this.bloomRadiusUniform.value = nextBloomRadius;
|
|
192
|
+
this.bloomSoftnessUniform.value = nextBloomSoftness;
|
|
193
|
+
this.bloomThresholdUniform.value = nextBloomThreshold;
|
|
194
|
+
if (nextBloomEnabled !== this.bloomEnabled) {
|
|
195
|
+
this.bloomEnabled = nextBloomEnabled;
|
|
196
|
+
this.rebuildEffectNode();
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
if (this.bloomNode) {
|
|
200
|
+
this.bloomNode.strength.value = nextBloomIntensity;
|
|
201
|
+
this.bloomNode.radius.value = this.normalizeBloomRadius(nextBloomRadius);
|
|
202
|
+
this.bloomNode.threshold.value = nextBloomThreshold;
|
|
203
|
+
this.bloomNode.smoothWidth.value = this.normalizeBloomSoftness(nextBloomSoftness);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
resize(width, height) {
|
|
207
|
+
this.renderWidth = Math.max(1, width);
|
|
208
|
+
this.renderHeight = Math.max(1, height);
|
|
209
|
+
this.widthUniform.value = this.renderWidth;
|
|
210
|
+
this.heightUniform.value = this.renderHeight;
|
|
211
|
+
this.historyReadTarget.setSize(this.renderWidth, this.renderHeight);
|
|
212
|
+
this.historyWriteTarget.setSize(this.renderWidth, this.renderHeight);
|
|
213
|
+
this.historyValid = false;
|
|
214
|
+
}
|
|
215
|
+
updateLogicalSize(width, height) {
|
|
216
|
+
this.widthUniform.value = Math.max(1, width);
|
|
217
|
+
this.heightUniform.value = Math.max(1, height);
|
|
218
|
+
}
|
|
219
|
+
dispose() {
|
|
220
|
+
this.disposeBloomNode();
|
|
221
|
+
this.placeholder.dispose();
|
|
222
|
+
this.historyReadTarget.dispose();
|
|
223
|
+
this.historyWriteTarget.dispose();
|
|
224
|
+
super.dispose();
|
|
225
|
+
}
|
|
226
|
+
buildEffectNode() {
|
|
227
|
+
if (!(this.cellSizeUniform && this.placeholder)) {
|
|
228
|
+
return this.inputNode;
|
|
229
|
+
}
|
|
230
|
+
this.disposeBloomNode();
|
|
231
|
+
this.bloomNode = null;
|
|
232
|
+
this.sourceTextureNodes = [];
|
|
233
|
+
this.historyTextureNodes = [];
|
|
234
|
+
const renderTargetUv = vec2(uv().x, float(1).sub(uv().y));
|
|
235
|
+
const dims = vec2(this.widthUniform, this.heightUniform);
|
|
236
|
+
const texel = vec2(float(1).div(max(this.widthUniform, float(1))), float(1).div(max(this.heightUniform, float(1))));
|
|
237
|
+
const centered = renderTargetUv.sub(vec2(0.5, 0.5));
|
|
238
|
+
const distSq = dot(centered, centered);
|
|
239
|
+
const slotWeight = this.modeWeight(CRT_MODE_SLOT_MASK);
|
|
240
|
+
const apertureWeight = this.modeWeight(CRT_MODE_APERTURE_GRILLE);
|
|
241
|
+
const compositeWeight = this.modeWeight(CRT_MODE_COMPOSITE_TV);
|
|
242
|
+
const distortionBias = slotWeight
|
|
243
|
+
.mul(1)
|
|
244
|
+
.add(apertureWeight.mul(0.72))
|
|
245
|
+
.add(compositeWeight.mul(1.16));
|
|
246
|
+
const distortedUv = renderTargetUv.add(centered.mul(distSq).mul(this.barrelDistortionUniform).mul(distortionBias));
|
|
247
|
+
const insideScreen = distortedUv.x
|
|
248
|
+
.greaterThanEqual(float(0))
|
|
249
|
+
.and(distortedUv.x.lessThanEqual(float(1)))
|
|
250
|
+
.and(distortedUv.y.greaterThanEqual(float(0)))
|
|
251
|
+
.and(distortedUv.y.lessThanEqual(float(1)));
|
|
252
|
+
const pitch = max(this.cellSizeUniform, float(2));
|
|
253
|
+
const screenPixel = renderTargetUv.mul(dims);
|
|
254
|
+
const cellCoord = floor(screenPixel.div(pitch));
|
|
255
|
+
const localCellUv = vec2(fract(screenPixel.x.div(pitch)), fract(screenPixel.y.div(pitch)));
|
|
256
|
+
const cellCenterUv = cellCoord.add(vec2(0.5, 0.5)).mul(pitch).div(dims);
|
|
257
|
+
const centeredCell = cellCenterUv.sub(vec2(0.5, 0.5));
|
|
258
|
+
const cellDistSq = dot(centeredCell, centeredCell);
|
|
259
|
+
const distortedCellUv = cellCenterUv.add(centeredCell.mul(cellDistSq).mul(this.barrelDistortionUniform).mul(distortionBias));
|
|
260
|
+
const row = cellCoord.y;
|
|
261
|
+
const timeDrift = this.timeUniform.mul(this.glitchSpeedUniform);
|
|
262
|
+
const drift = simplexNoise3d(vec3(float(0), row.mul(float(0.1)), timeDrift))
|
|
263
|
+
.mul(this.glitchIntensityUniform)
|
|
264
|
+
.mul(slotWeight.mul(0.003).add(compositeWeight.mul(0.007)).add(apertureWeight.mul(0.0025)));
|
|
265
|
+
const samplingUv = vec2(distortedCellUv.x.add(drift), distortedCellUv.y);
|
|
266
|
+
const clampedSamplingUv = clamp(samplingUv, vec2(0, 0), vec2(1, 1));
|
|
267
|
+
const baseSignal = this.sampleSignalColor(clampedSamplingUv, texel, compositeWeight);
|
|
268
|
+
const baseLuma = this.luma(baseSignal);
|
|
269
|
+
const brightnessSpread = mix(float(0.82), float(1.34), smoothstep(float(0.12), float(0.95), baseLuma));
|
|
270
|
+
const beamWidthX = mix(float(1.6), float(0.58), this.beamFocusUniform)
|
|
271
|
+
.mul(brightnessSpread.mul(float(0.15)).add(float(0.92)))
|
|
272
|
+
.mul(slotWeight.mul(1)
|
|
273
|
+
.add(apertureWeight.mul(0.72))
|
|
274
|
+
.add(compositeWeight.mul(1.4)));
|
|
275
|
+
const beamWidthY = mix(float(1.95), float(0.62), this.beamFocusUniform)
|
|
276
|
+
.mul(mix(float(1.12), float(0.46), this.scanlineIntensityUniform))
|
|
277
|
+
.mul(brightnessSpread)
|
|
278
|
+
.mul(slotWeight.mul(1)
|
|
279
|
+
.add(apertureWeight.mul(0.84))
|
|
280
|
+
.add(compositeWeight.mul(1.3)));
|
|
281
|
+
const edgeFactor = pow(clamp(centered.length().mul(float(1.82)), float(0), float(1)), float(2));
|
|
282
|
+
const convergenceShape = vec2(centered.x.mul(abs(centered.x).add(float(0.16))), centered.y.mul(abs(centered.y).add(float(0.08))));
|
|
283
|
+
const convergenceScale = this.chromaticAberrationUniform
|
|
284
|
+
.mul(edgeFactor)
|
|
285
|
+
.mul(slotWeight.mul(1).add(apertureWeight.mul(0.82)).add(compositeWeight.mul(1.18)))
|
|
286
|
+
.div(dims)
|
|
287
|
+
.mul(float(1.6));
|
|
288
|
+
const convergenceOffset = convergenceShape.mul(convergenceScale);
|
|
289
|
+
const greenOffset = vec2(float(0), convergenceScale.y.mul(float(-0.2)));
|
|
290
|
+
const redBeam = this.sampleBeamColor(clamp(clampedSamplingUv.add(convergenceOffset), vec2(0, 0), vec2(1, 1)), texel, beamWidthX, beamWidthY, compositeWeight);
|
|
291
|
+
const greenBeam = this.sampleBeamColor(clamp(clampedSamplingUv.add(greenOffset), vec2(0, 0), vec2(1, 1)), texel, beamWidthX, beamWidthY, compositeWeight);
|
|
292
|
+
const blueBeam = this.sampleBeamColor(clamp(clampedSamplingUv.sub(convergenceOffset), vec2(0, 0), vec2(1, 1)), texel, beamWidthX, beamWidthY, compositeWeight);
|
|
293
|
+
const beamEnergy = vec3(float(redBeam.r), float(greenBeam.g), float(blueBeam.b));
|
|
294
|
+
const feedResponse = this.buildFeedResponse(beamEnergy, cellCoord, slotWeight, apertureWeight, compositeWeight);
|
|
295
|
+
const scanlineEnvelope = this.buildScanlineEnvelope(screenPixel, baseLuma, compositeWeight);
|
|
296
|
+
const halationSignal = this.sampleHalation(clampedSamplingUv, texel, compositeWeight);
|
|
297
|
+
const halation = vec3(float(halationSignal.r), float(halationSignal.g), float(halationSignal.b)).mul(smoothstep(float(0.45), float(1), baseLuma).mul(slotWeight.mul(0.04).add(apertureWeight.mul(0.03)).add(compositeWeight.mul(0.07))));
|
|
298
|
+
let color = this.renderPhosphorCell(localCellUv, cellCoord, beamEnergy, baseLuma, feedResponse, slotWeight, apertureWeight, compositeWeight);
|
|
299
|
+
const tubeGlow = this.buildTubeGlow(localCellUv, baseSignal, baseLuma, slotWeight, apertureWeight, compositeWeight);
|
|
300
|
+
const specularLift = this.buildSpecularLift(localCellUv, baseSignal, baseLuma, slotWeight, apertureWeight, compositeWeight);
|
|
301
|
+
color = color.mul(mix(vec3(1, 1, 1), scanlineEnvelope, this.scanlineIntensityUniform));
|
|
302
|
+
color = color.add(halation).add(tubeGlow).add(specularLift);
|
|
303
|
+
const vignetteStrength = this.vignetteIntensityUniform.mul(slotWeight.mul(1).add(apertureWeight.mul(0.82)).add(compositeWeight.mul(1.1)));
|
|
304
|
+
const vignetteDistance = centered.length().mul(float(2));
|
|
305
|
+
const vignette = clamp(float(1).sub(vignetteDistance.mul(vignetteDistance).mul(vignetteStrength)), float(0), float(1));
|
|
306
|
+
color = color.mul(vignette);
|
|
307
|
+
const flickerNoise = simplexNoise3d(vec3(float(0), float(0), this.timeUniform.mul(float(8))));
|
|
308
|
+
const flicker = float(1).add(flickerNoise.mul(this.flickerIntensityUniform));
|
|
309
|
+
color = color.mul(flicker);
|
|
310
|
+
color = color.mul(select(insideScreen, float(1), float(0)));
|
|
311
|
+
const historySample = this.trackHistoryTextureNode(renderTargetUv);
|
|
312
|
+
const historyColor = vec3(float(historySample.r), float(historySample.g), float(historySample.b));
|
|
313
|
+
const historyDecay = historyColor.mul(vec3(mix(float(0.62), float(0.92), this.persistenceUniform), mix(float(0.68), float(0.96), this.persistenceUniform), mix(float(0.56), float(0.88), this.persistenceUniform)));
|
|
314
|
+
color = clamp(color.add(historyDecay.mul(this.persistenceUniform).mul(float(0.55))), vec3(0, 0, 0), vec3(1, 1, 1));
|
|
315
|
+
if (!this.bloomEnabled) {
|
|
316
|
+
return vec4(color, float(1));
|
|
317
|
+
}
|
|
318
|
+
const bloomInput = vec4(color, float(1));
|
|
319
|
+
this.bloomNode = bloom(bloomInput, this.bloomIntensityUniform.value, this.normalizeBloomRadius(this.bloomRadiusUniform.value), this.bloomThresholdUniform.value);
|
|
320
|
+
this.bloomNode.smoothWidth.value = this.normalizeBloomSoftness(this.bloomSoftnessUniform.value);
|
|
321
|
+
return vec4(clamp(color.add(this.getBloomTextureNode().rgb), vec3(float(0), float(0), float(0)), vec3(float(1), float(1), float(1))), float(1));
|
|
322
|
+
}
|
|
323
|
+
buildBand(position, center, halfWidth, softEdge) {
|
|
324
|
+
const bandCenter = this.toNode(center);
|
|
325
|
+
const halfWidthNode = this.toNode(halfWidth);
|
|
326
|
+
const softEdgeNode = this.toNode(softEdge);
|
|
327
|
+
const low = bandCenter.sub(halfWidthNode);
|
|
328
|
+
const high = bandCenter.add(halfWidthNode);
|
|
329
|
+
return smoothstep(low.sub(softEdgeNode), low, position).mul(float(1).sub(smoothstep(high, high.add(softEdgeNode), position)));
|
|
330
|
+
}
|
|
331
|
+
buildRoundedPhosphor(localX, localY, centerX, halfWidth, halfHeight, softEdge, taper) {
|
|
332
|
+
const halfHeightNode = this.toNode(halfHeight);
|
|
333
|
+
const softEdgeNode = this.toNode(softEdge);
|
|
334
|
+
const taperNode = this.toNode(taper);
|
|
335
|
+
const yDistance = abs(localY.sub(float(0.5)));
|
|
336
|
+
const widthTaper = mix(float(1), taperNode, smoothstep(halfHeightNode.mul(0.42), float(0.5), yDistance));
|
|
337
|
+
return this.buildBand(localX, centerX, this.toNode(halfWidth).mul(widthTaper), softEdgeNode).mul(this.buildBand(localY, 0.5, halfHeightNode, softEdgeNode));
|
|
338
|
+
}
|
|
339
|
+
buildFeedResponse(beamEnergy, cellCoord, slotWeight, apertureWeight, compositeWeight) {
|
|
340
|
+
const feedMax = max(float(beamEnergy.r), max(float(beamEnergy.g), float(beamEnergy.b)));
|
|
341
|
+
const safeFeedMax = max(feedMax, float(1e-4));
|
|
342
|
+
const channelSeparation = slotWeight.mul(0.86).add(apertureWeight.mul(0.78)).add(compositeWeight.mul(0.58));
|
|
343
|
+
const responseCurve = slotWeight.mul(0.92).add(apertureWeight.mul(0.88)).add(compositeWeight.mul(1.04));
|
|
344
|
+
const spill = compositeWeight.mul(0.12).add(slotWeight.mul(0.04)).add(apertureWeight.mul(0.03));
|
|
345
|
+
const rNoise = simplexNoise3d(vec3(cellCoord.x.add(float(0.19)), cellCoord.y, float(7.1)))
|
|
346
|
+
.mul(0.5)
|
|
347
|
+
.add(0.5);
|
|
348
|
+
const gNoise = simplexNoise3d(vec3(cellCoord.x.add(float(0.41)), cellCoord.y, float(13.7)))
|
|
349
|
+
.mul(0.5)
|
|
350
|
+
.add(0.5);
|
|
351
|
+
const bNoise = simplexNoise3d(vec3(cellCoord.x.add(float(0.73)), cellCoord.y, float(19.9)))
|
|
352
|
+
.mul(0.5)
|
|
353
|
+
.add(0.5);
|
|
354
|
+
const rResponse = mix(float(0.82), float(1.18), rNoise);
|
|
355
|
+
const gResponse = mix(float(0.84), float(1.16), gNoise);
|
|
356
|
+
const bResponse = mix(float(0.8), float(1.2), bNoise);
|
|
357
|
+
const rDominance = pow(clamp(float(beamEnergy.r).div(safeFeedMax), float(0), float(1)), float(0.82));
|
|
358
|
+
const gDominance = pow(clamp(float(beamEnergy.g).div(safeFeedMax), float(0), float(1)), float(0.82));
|
|
359
|
+
const bDominance = pow(clamp(float(beamEnergy.b).div(safeFeedMax), float(0), float(1)), float(0.82));
|
|
360
|
+
const rDrive = clamp(beamEnergy.r.mul(rResponse).mul(mix(float(1), rDominance, channelSeparation)).add(feedMax.mul(spill)), float(0), float(1));
|
|
361
|
+
const gDrive = clamp(beamEnergy.g.mul(gResponse).mul(mix(float(1), gDominance, channelSeparation)).add(feedMax.mul(spill)), float(0), float(1));
|
|
362
|
+
const bDrive = clamp(beamEnergy.b.mul(bResponse).mul(mix(float(1), bDominance, channelSeparation)).add(feedMax.mul(spill)), float(0), float(1));
|
|
363
|
+
return clamp(vec3(pow(rDrive, responseCurve), pow(gDrive, responseCurve), pow(bDrive, responseCurve)), vec3(0, 0, 0), vec3(1, 1, 1));
|
|
364
|
+
}
|
|
365
|
+
renderPhosphorCell(localCellUv, cellCoord, beamEnergy, baseLuma, feedResponse, slotWeight, apertureWeight, compositeWeight) {
|
|
366
|
+
const rowIndex = cellCoord.y;
|
|
367
|
+
const oddRow = mod(rowIndex, float(2)).greaterThan(float(0.5));
|
|
368
|
+
const slotX = fract(localCellUv.x.add(select(oddRow, float(0.5), float(0))));
|
|
369
|
+
const slotY = localCellUv.y;
|
|
370
|
+
const definition = mix(float(0.72), float(1.18), this.maskIntensityUniform);
|
|
371
|
+
const rowJitter = simplexNoise3d(vec3(float(0), rowIndex, float(3.7))).mul(0.5).add(0.5).sub(0.5);
|
|
372
|
+
const slotJitter = simplexNoise3d(vec3(cellCoord.x, cellCoord.y, float(9.3))).mul(0.5).add(0.5).sub(0.5);
|
|
373
|
+
const apertureJitter = simplexNoise3d(vec3(cellCoord.x, cellCoord.y, float(15.1)))
|
|
374
|
+
.mul(0.5)
|
|
375
|
+
.add(0.5)
|
|
376
|
+
.sub(0.5);
|
|
377
|
+
const tvJitter = simplexNoise3d(vec3(cellCoord.x, cellCoord.y, float(21.4))).mul(0.5).add(0.5).sub(0.5);
|
|
378
|
+
const slotShape = vec3(this.buildRoundedPhosphor(slotX, slotY, float(1 / 6).sub(rowJitter.mul(0.01)), float(0.12).mul(definition).add(slotJitter.mul(0.01)), float(0.38).add(abs(slotJitter).mul(0.03)), float(0.015), float(0.38)), this.buildRoundedPhosphor(slotX, slotY, float(0.5), float(0.115).mul(definition).add(slotJitter.mul(0.008)), float(0.38).add(abs(slotJitter).mul(0.03)), float(0.015), float(0.38)), this.buildRoundedPhosphor(slotX, slotY, float(5 / 6).add(rowJitter.mul(0.01)), float(0.12).mul(definition).add(slotJitter.mul(0.01)), float(0.38).add(abs(slotJitter).mul(0.03)), float(0.015), float(0.38)));
|
|
379
|
+
const apertureX = localCellUv.x;
|
|
380
|
+
const apertureSegment = this.buildBand(slotY, 0.5, float(0.41), float(0.06));
|
|
381
|
+
const apertureShape = vec3(this.buildRoundedPhosphor(apertureX, slotY, float(1 / 6).add(apertureJitter.mul(0.007)), float(0.14).mul(definition).add(apertureJitter.mul(0.008)), float(0.44), float(0.008), float(0.82)).mul(apertureSegment), this.buildRoundedPhosphor(apertureX, slotY, float(0.5), float(0.135).mul(definition).add(apertureJitter.mul(0.006)), float(0.44), float(0.008), float(0.82)).mul(apertureSegment), this.buildRoundedPhosphor(apertureX, slotY, float(5 / 6).sub(apertureJitter.mul(0.007)), float(0.14).mul(definition).add(apertureJitter.mul(0.008)), float(0.44), float(0.008), float(0.82)).mul(apertureSegment));
|
|
382
|
+
const tvX = fract(localCellUv.x.add(select(oddRow, float(0.25), float(0))));
|
|
383
|
+
const tvShape = vec3(this.buildRoundedPhosphor(tvX, slotY, float(1 / 6).add(tvJitter.mul(0.015)), float(0.11).mul(definition).add(tvJitter.mul(0.012)), float(0.34).add(abs(tvJitter).mul(0.04)), float(0.02), float(0.44)), this.buildRoundedPhosphor(tvX, slotY, float(0.5), float(0.105).mul(definition).add(tvJitter.mul(0.01)), float(0.34).add(abs(tvJitter).mul(0.04)), float(0.02), float(0.44)), this.buildRoundedPhosphor(tvX, slotY, float(5 / 6).sub(tvJitter.mul(0.015)), float(0.11).mul(definition).add(tvJitter.mul(0.012)), float(0.34).add(abs(tvJitter).mul(0.04)), float(0.02), float(0.44)));
|
|
384
|
+
const combinedShape = slotShape.mul(slotWeight)
|
|
385
|
+
.add(apertureShape.mul(apertureWeight))
|
|
386
|
+
.add(tvShape.mul(compositeWeight));
|
|
387
|
+
const channelResponse = vec3(beamEnergy.r.mul(feedResponse.r), beamEnergy.g.mul(feedResponse.g), beamEnergy.b.mul(feedResponse.b));
|
|
388
|
+
const responseLuma = this.luma(channelResponse);
|
|
389
|
+
const responseNeutral = vec3(responseLuma, responseLuma, responseLuma);
|
|
390
|
+
const responseChroma = channelResponse.sub(responseNeutral);
|
|
391
|
+
const highlightMask = smoothstep(this.highlightThresholdUniform, float(1), baseLuma);
|
|
392
|
+
const brightnessGain = mix(float(1), this.brightnessUniform, smoothstep(float(0.22), float(0.98), baseLuma));
|
|
393
|
+
const lumaDrive = brightnessGain.mul(mix(float(1), this.highlightDriveUniform, highlightMask));
|
|
394
|
+
const shadowGain = mix(float(1), this.shadowLiftUniform.mul(float(0.35)).add(float(1)), smoothstep(float(0.42), float(0.02), baseLuma));
|
|
395
|
+
const drivenLuma = responseLuma.mul(lumaDrive).mul(shadowGain);
|
|
396
|
+
const shoulderStrength = this.shoulderUniform.mul(highlightMask).mul(float(0.15));
|
|
397
|
+
const compressedLuma = drivenLuma.div(drivenLuma.mul(shoulderStrength).add(float(1)));
|
|
398
|
+
const shapedLuma = mix(drivenLuma, compressedLuma, smoothstep(float(0.05), float(1), highlightMask));
|
|
399
|
+
const chromaGain = mix(float(1), this.chromaRetentionUniform.mul(mix(float(1), lumaDrive, float(0.18))), smoothstep(float(0.18), float(0.95), baseLuma));
|
|
400
|
+
const boostedResponse = vec3(shapedLuma, shapedLuma, shapedLuma).add(responseChroma.mul(chromaGain));
|
|
401
|
+
const phosphorBrightness = slotWeight.mul(2.8).add(apertureWeight.mul(2.4)).add(compositeWeight.mul(2.6));
|
|
402
|
+
const baseEmission = vec3(combinedShape.r.mul(boostedResponse.r), combinedShape.g.mul(boostedResponse.g), combinedShape.b.mul(boostedResponse.b)).mul(phosphorBrightness);
|
|
403
|
+
const channelMin = min(boostedResponse.r, min(boostedResponse.g, boostedResponse.b));
|
|
404
|
+
const channelMax = max(boostedResponse.r, max(boostedResponse.g, boostedResponse.b));
|
|
405
|
+
const channelAvg = boostedResponse.r.add(boostedResponse.g).add(boostedResponse.b).div(3);
|
|
406
|
+
const sharedDrive = clamp(channelAvg.div(max(channelMax, float(1e-4))), float(0), float(1));
|
|
407
|
+
const neutrality = clamp(channelMin.div(max(channelMax, float(1e-4))), float(0), float(1));
|
|
408
|
+
const whiteHot = smoothstep(float(0.24), float(0.82), channelAvg).mul(smoothstep(float(0.55), float(0.96), neutrality)).mul(mix(float(0.03), float(0.18), pow(sharedDrive, float(0.72))));
|
|
409
|
+
const sharedCore = combinedShape.add(vec3(channelMin, channelMin, channelMin)).div(4);
|
|
410
|
+
const whiteCore = vec3(whiteHot, whiteHot, whiteHot).mul(sharedCore).mul(slotWeight.mul(0.34).add(apertureWeight.mul(0.28)).add(compositeWeight.mul(0.46))).mul(mix(float(1), lumaDrive, smoothstep(float(0.52), float(1), channelAvg)));
|
|
411
|
+
return clamp(baseEmission.add(whiteCore), vec3(0, 0, 0), vec3(1, 1, 1));
|
|
412
|
+
}
|
|
413
|
+
buildTubeGlow(localCellUv, baseSignal, baseLuma, slotWeight, apertureWeight, compositeWeight) {
|
|
414
|
+
const channelMax = max(baseSignal.r, max(baseSignal.g, baseSignal.b));
|
|
415
|
+
const channelMin = min(baseSignal.r, min(baseSignal.g, baseSignal.b));
|
|
416
|
+
const neutrality = clamp(channelMin.div(max(channelMax, float(1e-4))), float(0), float(1));
|
|
417
|
+
const highlightMix = smoothstep(float(0.58), float(0.98), channelMax);
|
|
418
|
+
const whiteness = smoothstep(float(0.55), float(0.94), baseLuma).mul(smoothstep(float(0.62), float(0.98), neutrality)).mul(mix(float(0.04), float(0.18), highlightMix));
|
|
419
|
+
const neutral = vec3(baseLuma, baseLuma, baseLuma);
|
|
420
|
+
const warmedNeutral = mix(neutral, vec3(baseLuma.mul(1.03), baseLuma.mul(0.99), baseLuma.mul(0.96)), slotWeight.mul(0.18).add(compositeWeight.mul(0.28)));
|
|
421
|
+
const neutralMix = whiteness.mul(mix(float(1), float(0.55), clamp(this.chromaRetentionUniform.sub(float(1)), float(0), float(1))));
|
|
422
|
+
const drivenSignal = mix(baseSignal, warmedNeutral, neutralMix);
|
|
423
|
+
const centerDistance = localCellUv.sub(vec2(0.5, 0.5)).length();
|
|
424
|
+
const spread = smoothstep(float(0.42), float(0.18), centerDistance);
|
|
425
|
+
const glowStrength = highlightMix.mul(baseLuma).mul(slotWeight.mul(0.04).add(apertureWeight.mul(0.03)).add(compositeWeight.mul(0.08)));
|
|
426
|
+
return drivenSignal.mul(spread).mul(glowStrength);
|
|
427
|
+
}
|
|
428
|
+
buildSpecularLift(localCellUv, baseSignal, baseLuma, slotWeight, apertureWeight, compositeWeight) {
|
|
429
|
+
const channelMax = max(baseSignal.r, max(baseSignal.g, baseSignal.b));
|
|
430
|
+
const channelMin = min(baseSignal.r, min(baseSignal.g, baseSignal.b));
|
|
431
|
+
const neutrality = clamp(channelMin.div(max(channelMax, float(1e-4))), float(0), float(1));
|
|
432
|
+
const highlightGate = smoothstep(float(0.62), float(0.98), channelMax)
|
|
433
|
+
.mul(smoothstep(float(0.42), float(0.92), baseLuma));
|
|
434
|
+
const coreDistance = localCellUv.sub(vec2(0.5, 0.5)).length();
|
|
435
|
+
const core = smoothstep(float(0.44), float(0.02), coreDistance);
|
|
436
|
+
const liftStrength = highlightGate.mul(mix(float(0.32), float(0.9), neutrality)).mul(slotWeight.mul(0.95).add(apertureWeight.mul(0.78)).add(compositeWeight.mul(1.08)));
|
|
437
|
+
const neutralLift = mix(baseSignal, vec3(channelMax, channelMax, channelMax), float(0.86));
|
|
438
|
+
return neutralLift.mul(core).mul(liftStrength);
|
|
439
|
+
}
|
|
440
|
+
buildScanlineEnvelope(screenPixel, luma, compositeWeight) {
|
|
441
|
+
const pitch = max(this.cellSizeUniform, float(2));
|
|
442
|
+
const localY = fract(screenPixel.y.div(pitch));
|
|
443
|
+
const halfWidth = mix(float(0.48), float(0.21), this.scanlineIntensityUniform)
|
|
444
|
+
.mul(mix(float(0.82), float(1.18), smoothstep(float(0.08), float(1), luma)))
|
|
445
|
+
.mul(mix(float(1), float(1.12), compositeWeight));
|
|
446
|
+
const envelope = this.buildBand(localY, 0.5, halfWidth, 0.12);
|
|
447
|
+
return vec3(envelope, envelope, envelope);
|
|
448
|
+
}
|
|
449
|
+
luma(color) {
|
|
450
|
+
return dot(color, vec3(0.2126, 0.7152, 0.0722));
|
|
451
|
+
}
|
|
452
|
+
modeWeight(targetMode) {
|
|
453
|
+
return select(this.crtModeUniform.equal(float(targetMode)), float(1), float(0));
|
|
454
|
+
}
|
|
455
|
+
toNode(value) {
|
|
456
|
+
return typeof value === "number" ? float(value) : value;
|
|
457
|
+
}
|
|
458
|
+
normalizeBloomRadius(value) {
|
|
459
|
+
return clamp01(value / 24);
|
|
460
|
+
}
|
|
461
|
+
normalizeBloomSoftness(value) {
|
|
462
|
+
return Math.max(0.001, value * 0.25);
|
|
463
|
+
}
|
|
464
|
+
disposeBloomNode() {
|
|
465
|
+
;
|
|
466
|
+
this.bloomNode?.dispose?.();
|
|
467
|
+
}
|
|
468
|
+
getBloomTextureNode() {
|
|
469
|
+
const bloomNode = this.bloomNode;
|
|
470
|
+
if (!bloomNode) {
|
|
471
|
+
throw new Error("Bloom node is not initialized");
|
|
472
|
+
}
|
|
473
|
+
if ("getTextureNode" in bloomNode && typeof bloomNode.getTextureNode === "function") {
|
|
474
|
+
return bloomNode.getTextureNode();
|
|
475
|
+
}
|
|
476
|
+
if ("getTexture" in bloomNode && typeof bloomNode.getTexture === "function") {
|
|
477
|
+
return bloomNode.getTexture();
|
|
478
|
+
}
|
|
479
|
+
throw new Error("Bloom node does not expose a texture getter");
|
|
480
|
+
}
|
|
481
|
+
sampleBeamColor(sampleUv, texel, beamWidthX, beamWidthY, compositeWeight) {
|
|
482
|
+
const xOffset = vec2(texel.x.mul(beamWidthX), float(0));
|
|
483
|
+
const yOffset = vec2(float(0), texel.y.mul(beamWidthY));
|
|
484
|
+
const center = this.sampleSignalColor(sampleUv, texel, compositeWeight);
|
|
485
|
+
const left = this.sampleSignalColor(clamp(sampleUv.sub(xOffset), vec2(0, 0), vec2(1, 1)), texel, compositeWeight);
|
|
486
|
+
const right = this.sampleSignalColor(clamp(sampleUv.add(xOffset), vec2(0, 0), vec2(1, 1)), texel, compositeWeight);
|
|
487
|
+
const up = this.sampleSignalColor(clamp(sampleUv.sub(yOffset), vec2(0, 0), vec2(1, 1)), texel, compositeWeight);
|
|
488
|
+
const down = this.sampleSignalColor(clamp(sampleUv.add(yOffset), vec2(0, 0), vec2(1, 1)), texel, compositeWeight);
|
|
489
|
+
return center.mul(0.42)
|
|
490
|
+
.add(left.add(right).mul(0.2))
|
|
491
|
+
.add(up.add(down).mul(0.09));
|
|
492
|
+
}
|
|
493
|
+
sampleHalation(sampleUv, texel, compositeWeight) {
|
|
494
|
+
const haloX = vec2(texel.x.mul(2.2), float(0));
|
|
495
|
+
const haloY = vec2(float(0), texel.y.mul(1.6));
|
|
496
|
+
const left = this.sampleSignalColor(clamp(sampleUv.sub(haloX), vec2(0, 0), vec2(1, 1)), texel, compositeWeight);
|
|
497
|
+
const right = this.sampleSignalColor(clamp(sampleUv.add(haloX), vec2(0, 0), vec2(1, 1)), texel, compositeWeight);
|
|
498
|
+
const up = this.sampleSignalColor(clamp(sampleUv.sub(haloY), vec2(0, 0), vec2(1, 1)), texel, compositeWeight);
|
|
499
|
+
const down = this.sampleSignalColor(clamp(sampleUv.add(haloY), vec2(0, 0), vec2(1, 1)), texel, compositeWeight);
|
|
500
|
+
return left.add(right).add(up).add(down).mul(0.25);
|
|
501
|
+
}
|
|
502
|
+
sampleSignalColor(sampleUv, texel, compositeWeight) {
|
|
503
|
+
const sampleOffset = vec2(texel.x.mul(1.35), float(0));
|
|
504
|
+
const center = this.trackSourceTextureNode(sampleUv);
|
|
505
|
+
const left = this.trackSourceTextureNode(clamp(sampleUv.sub(sampleOffset), vec2(0, 0), vec2(1, 1)));
|
|
506
|
+
const right = this.trackSourceTextureNode(clamp(sampleUv.add(sampleOffset), vec2(0, 0), vec2(1, 1)));
|
|
507
|
+
const centerColor = vec3(float(center.r), float(center.g), float(center.b));
|
|
508
|
+
const leftColor = vec3(float(left.r), float(left.g), float(left.b));
|
|
509
|
+
const rightColor = vec3(float(right.r), float(right.g), float(right.b));
|
|
510
|
+
const avgColor = centerColor.mul(2).add(leftColor).add(rightColor).div(4);
|
|
511
|
+
const lumaCenter = this.luma(centerColor);
|
|
512
|
+
const lumaAvg = this.luma(avgColor);
|
|
513
|
+
const chromaBlur = avgColor.sub(vec3(lumaAvg, lumaAvg, lumaAvg));
|
|
514
|
+
const lumaSignal = vec3(mix(lumaCenter, lumaAvg, this.signalArtifactsUniform.mul(0.28)), mix(lumaCenter, lumaAvg, this.signalArtifactsUniform.mul(0.28)), mix(lumaCenter, lumaAvg, this.signalArtifactsUniform.mul(0.28)));
|
|
515
|
+
const ringing = centerColor.sub(avgColor).mul(this.signalArtifactsUniform.mul(0.3));
|
|
516
|
+
const compositeColor = clamp(lumaSignal.add(chromaBlur.mul(0.92)).add(ringing), vec3(0, 0, 0), vec3(1, 1, 1));
|
|
517
|
+
const signalColor = mix(centerColor, compositeColor, compositeWeight.mul(this.signalArtifactsUniform));
|
|
518
|
+
const signalLuma = this.luma(signalColor);
|
|
519
|
+
const neutralSignal = vec3(signalLuma, signalLuma, signalLuma);
|
|
520
|
+
const signalChroma = signalColor.sub(neutralSignal);
|
|
521
|
+
const liftedLuma = signalLuma.add(smoothstep(float(0.38), float(0.02), signalLuma)
|
|
522
|
+
.mul(this.shadowLiftUniform)
|
|
523
|
+
.mul(float(0.08)));
|
|
524
|
+
return clamp(vec3(liftedLuma, liftedLuma, liftedLuma).add(signalChroma), vec3(0, 0, 0), vec3(1, 1, 1));
|
|
525
|
+
}
|
|
526
|
+
trackHistoryTextureNode(uvNode) {
|
|
527
|
+
const historyTextureNode = tslTexture(this.placeholder, uvNode);
|
|
528
|
+
this.historyTextureNodes.push(historyTextureNode);
|
|
529
|
+
return historyTextureNode;
|
|
530
|
+
}
|
|
531
|
+
trackSourceTextureNode(uvNode) {
|
|
532
|
+
const sourceTextureNode = tslTexture(this.placeholder, uvNode);
|
|
533
|
+
this.sourceTextureNodes.push(sourceTextureNode);
|
|
534
|
+
return sourceTextureNode;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type TSLNode } from "three/tsl";
|
|
2
|
+
import { PassNode } from "./pass-node";
|
|
3
|
+
import type { LayerParameterValues } from "../types/editor";
|
|
4
|
+
type Node = TSLNode;
|
|
5
|
+
export declare class CustomShaderPass extends PassNode {
|
|
6
|
+
private readonly onRuntimeError;
|
|
7
|
+
private compiledSketch;
|
|
8
|
+
private compileRequestId;
|
|
9
|
+
private lastCompileSignature;
|
|
10
|
+
private readonly timeUniform;
|
|
11
|
+
constructor(layerId: string, onRuntimeError?: (message: string | null) => void);
|
|
12
|
+
needsContinuousRender(): boolean;
|
|
13
|
+
updateParams(params: LayerParameterValues): void;
|
|
14
|
+
protected beforeRender(time: number): void;
|
|
15
|
+
protected buildEffectNode(): Node;
|
|
16
|
+
}
|
|
17
|
+
export {};
|