@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.
Files changed (399) hide show
  1. package/dist/src/easings.d.ts +3 -0
  2. package/dist/src/easings.js +3 -0
  3. package/dist/src/index.d.ts +5 -0
  4. package/dist/src/index.js +4 -0
  5. package/dist/src/lib/editor/custom-shader/shared.d.ts +1 -0
  6. package/dist/src/lib/editor/custom-shader/shared.js +1 -0
  7. package/dist/src/renderer/ascii-atlas.d.ts +5 -0
  8. package/dist/src/renderer/ascii-atlas.js +61 -0
  9. package/dist/src/renderer/ascii-pass.d.ts +50 -0
  10. package/dist/src/renderer/ascii-pass.js +271 -0
  11. package/dist/src/renderer/asset-url.d.ts +1 -0
  12. package/dist/src/renderer/asset-url.js +3 -0
  13. package/dist/src/renderer/blend-modes.d.ts +4 -0
  14. package/dist/src/renderer/blend-modes.js +157 -0
  15. package/dist/src/renderer/contracts.d.ts +26 -0
  16. package/dist/src/renderer/contracts.js +13 -0
  17. package/dist/src/renderer/create-webgpu-renderer.d.ts +3 -0
  18. package/dist/src/renderer/create-webgpu-renderer.js +37 -0
  19. package/dist/src/renderer/crt-pass.d.ts +72 -0
  20. package/dist/src/renderer/crt-pass.js +536 -0
  21. package/dist/src/renderer/custom-shader-pass.d.ts +17 -0
  22. package/dist/src/renderer/custom-shader-pass.js +79 -0
  23. package/dist/src/renderer/custom-shader-runtime.d.ts +16 -0
  24. package/dist/src/renderer/custom-shader-runtime.js +169 -0
  25. package/dist/src/renderer/dither-textures.d.ts +8 -0
  26. package/dist/src/renderer/dither-textures.js +66 -0
  27. package/dist/src/renderer/dithering-pass.d.ts +45 -0
  28. package/dist/src/renderer/dithering-pass.js +229 -0
  29. package/dist/src/renderer/gradient-pass.d.ts +39 -0
  30. package/dist/src/renderer/gradient-pass.js +358 -0
  31. package/dist/src/renderer/halftone-pass.d.ts +65 -0
  32. package/dist/src/renderer/halftone-pass.js +530 -0
  33. package/dist/src/renderer/ink-pass.d.ts +84 -0
  34. package/dist/src/renderer/ink-pass.js +526 -0
  35. package/dist/src/renderer/live-pass.d.ts +31 -0
  36. package/dist/src/renderer/live-pass.js +136 -0
  37. package/dist/src/renderer/media-pass.d.ts +32 -0
  38. package/dist/src/renderer/media-pass.js +130 -0
  39. package/dist/src/renderer/media-texture.d.ts +8 -0
  40. package/dist/src/renderer/media-texture.js +41 -0
  41. package/dist/src/renderer/particle-grid-pass.d.ts +48 -0
  42. package/dist/src/renderer/particle-grid-pass.js +269 -0
  43. package/dist/src/renderer/pass-node.d.ts +36 -0
  44. package/dist/src/renderer/pass-node.js +120 -0
  45. package/dist/src/renderer/pattern-atlas.d.ts +8 -0
  46. package/dist/src/renderer/pattern-atlas.js +79 -0
  47. package/dist/src/renderer/pattern-pass.d.ts +58 -0
  48. package/dist/src/renderer/pattern-pass.js +316 -0
  49. package/dist/src/renderer/pipeline-manager.d.ts +39 -0
  50. package/dist/src/renderer/pipeline-manager.js +287 -0
  51. package/dist/src/renderer/pixel-sorting-pass.d.ts +33 -0
  52. package/dist/src/renderer/pixel-sorting-pass.js +179 -0
  53. package/dist/src/renderer/shaders/tsl/color/tonemapping.d.ts +9 -0
  54. package/dist/src/renderer/shaders/tsl/color/tonemapping.js +59 -0
  55. package/dist/src/renderer/shaders/tsl/cosine-palette.d.ts +4 -0
  56. package/{packages/shader-lab-react/src/renderer/shaders/tsl/cosine-palette.ts → dist/src/renderer/shaders/tsl/cosine-palette.js} +3 -4
  57. package/dist/src/renderer/shaders/tsl/noise/common.d.ts +5 -0
  58. package/dist/src/renderer/shaders/tsl/noise/common.js +24 -0
  59. package/dist/src/renderer/shaders/tsl/noise/curl-noise-3d.d.ts +1 -0
  60. package/dist/src/renderer/shaders/tsl/noise/curl-noise-3d.js +27 -0
  61. package/dist/src/renderer/shaders/tsl/noise/curl-noise-4d.d.ts +1 -0
  62. package/dist/src/renderer/shaders/tsl/noise/curl-noise-4d.js +27 -0
  63. package/dist/src/renderer/shaders/tsl/noise/fbm.d.ts +1 -0
  64. package/dist/src/renderer/shaders/tsl/noise/fbm.js +11 -0
  65. package/dist/src/renderer/shaders/tsl/noise/perlin-noise-3d.d.ts +5 -0
  66. package/dist/src/renderer/shaders/tsl/noise/perlin-noise-3d.js +66 -0
  67. package/dist/src/renderer/shaders/tsl/noise/ridge-noise.d.ts +1 -0
  68. package/dist/src/renderer/shaders/tsl/noise/ridge-noise.js +19 -0
  69. package/dist/src/renderer/shaders/tsl/noise/simplex-noise-3d.d.ts +1 -0
  70. package/dist/src/renderer/shaders/tsl/noise/simplex-noise-3d.js +44 -0
  71. package/dist/src/renderer/shaders/tsl/noise/simplex-noise-4d.d.ts +1 -0
  72. package/dist/src/renderer/shaders/tsl/noise/simplex-noise-4d.js +51 -0
  73. package/dist/src/renderer/shaders/tsl/noise/turbulence.d.ts +7 -0
  74. package/dist/src/renderer/shaders/tsl/noise/turbulence.js +34 -0
  75. package/dist/src/renderer/shaders/tsl/noise/value-noise-3d.d.ts +1 -0
  76. package/dist/src/renderer/shaders/tsl/noise/value-noise-3d.js +27 -0
  77. package/dist/src/renderer/shaders/tsl/noise/voronoi-noise-3d.d.ts +1 -0
  78. package/dist/src/renderer/shaders/tsl/noise/voronoi-noise-3d.js +45 -0
  79. package/dist/src/renderer/shaders/tsl/patterns/bloom-edge-pattern.d.ts +4 -0
  80. package/dist/src/renderer/shaders/tsl/patterns/bloom-edge-pattern.js +13 -0
  81. package/dist/src/renderer/shaders/tsl/patterns/bloom.d.ts +4 -0
  82. package/{packages/shader-lab-react/src/renderer/shaders/tsl/patterns/bloom.ts → dist/src/renderer/shaders/tsl/patterns/bloom.js} +4 -6
  83. package/dist/src/renderer/shaders/tsl/patterns/canvas-weave-pattern.d.ts +4 -0
  84. package/dist/src/renderer/shaders/tsl/patterns/canvas-weave-pattern.js +16 -0
  85. package/dist/src/renderer/shaders/tsl/patterns/grain-texture-pattern.d.ts +4 -0
  86. 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
  87. package/dist/src/renderer/shaders/tsl/patterns/repeating-pattern.d.ts +4 -0
  88. package/{packages/shader-lab-react/src/renderer/shaders/tsl/patterns/repeating-pattern.ts → dist/src/renderer/shaders/tsl/patterns/repeating-pattern.js} +4 -6
  89. package/dist/src/renderer/shaders/tsl/utils/atan2.d.ts +1 -0
  90. package/dist/src/renderer/shaders/tsl/utils/atan2.js +7 -0
  91. package/dist/src/renderer/shaders/tsl/utils/complex-conj.d.ts +4 -0
  92. package/{packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-conj.ts → dist/src/renderer/shaders/tsl/utils/complex-conj.js} +3 -4
  93. package/dist/src/renderer/shaders/tsl/utils/complex-cos.d.ts +4 -0
  94. package/dist/src/renderer/shaders/tsl/utils/complex-cos.js +9 -0
  95. package/dist/src/renderer/shaders/tsl/utils/complex-div.d.ts +1 -0
  96. package/dist/src/renderer/shaders/tsl/utils/complex-div.js +6 -0
  97. package/dist/src/renderer/shaders/tsl/utils/complex-log.d.ts +1 -0
  98. package/dist/src/renderer/shaders/tsl/utils/complex-log.js +6 -0
  99. package/dist/src/renderer/shaders/tsl/utils/complex-mobius.d.ts +4 -0
  100. package/dist/src/renderer/shaders/tsl/utils/complex-mobius.js +10 -0
  101. package/dist/src/renderer/shaders/tsl/utils/complex-mul.d.ts +4 -0
  102. package/{packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-mul.ts → dist/src/renderer/shaders/tsl/utils/complex-mul.js} +3 -4
  103. package/dist/src/renderer/shaders/tsl/utils/complex-pow.d.ts +5 -0
  104. package/dist/src/renderer/shaders/tsl/utils/complex-pow.js +14 -0
  105. package/dist/src/renderer/shaders/tsl/utils/complex-sin.d.ts +4 -0
  106. package/dist/src/renderer/shaders/tsl/utils/complex-sin.js +9 -0
  107. package/dist/src/renderer/shaders/tsl/utils/complex-sqrt.d.ts +5 -0
  108. package/dist/src/renderer/shaders/tsl/utils/complex-sqrt.js +12 -0
  109. package/dist/src/renderer/shaders/tsl/utils/complex-tan.d.ts +4 -0
  110. package/dist/src/renderer/shaders/tsl/utils/complex-tan.js +11 -0
  111. package/dist/src/renderer/shaders/tsl/utils/complex-to-polar.d.ts +4 -0
  112. package/dist/src/renderer/shaders/tsl/utils/complex-to-polar.js +9 -0
  113. package/dist/src/renderer/shaders/tsl/utils/hyperbolic.d.ts +8 -0
  114. package/{packages/shader-lab-react/src/renderer/shaders/tsl/utils/hyperbolic.ts → dist/src/renderer/shaders/tsl/utils/hyperbolic.js} +7 -11
  115. package/dist/src/renderer/shaders/tsl/utils/index.d.ts +38 -0
  116. package/dist/src/renderer/shaders/tsl/utils/index.js +39 -0
  117. package/dist/src/renderer/shaders/tsl/utils/rotate.d.ts +2 -0
  118. package/dist/src/renderer/shaders/tsl/utils/rotate.js +7 -0
  119. package/dist/src/renderer/shaders/tsl/utils/screen-aspect-uv.d.ts +2 -0
  120. package/dist/src/renderer/shaders/tsl/utils/screen-aspect-uv.js +6 -0
  121. package/dist/src/renderer/shaders/tsl/utils/sd-box-2d.d.ts +1 -0
  122. package/dist/src/renderer/shaders/tsl/utils/sd-box-2d.js +5 -0
  123. package/dist/src/renderer/shaders/tsl/utils/sd-diamond.d.ts +1 -0
  124. package/dist/src/renderer/shaders/tsl/utils/sd-diamond.js +5 -0
  125. package/dist/src/renderer/shaders/tsl/utils/sd-rhombus.d.ts +1 -0
  126. package/dist/src/renderer/shaders/tsl/utils/sd-rhombus.js +14 -0
  127. package/dist/src/renderer/shaders/tsl/utils/sd-sphere.d.ts +1 -0
  128. package/dist/src/renderer/shaders/tsl/utils/sd-sphere.js +5 -0
  129. package/dist/src/renderer/shaders/tsl/utils/smax.d.ts +1 -0
  130. package/dist/src/renderer/shaders/tsl/utils/smax.js +6 -0
  131. package/dist/src/renderer/shaders/tsl/utils/smin.d.ts +1 -0
  132. package/dist/src/renderer/shaders/tsl/utils/smin.js +6 -0
  133. package/dist/src/renderer/text-pass.d.ts +23 -0
  134. package/dist/src/renderer/text-pass.js +129 -0
  135. package/dist/src/runtime-clock.d.ts +9 -0
  136. package/dist/src/runtime-clock.js +20 -0
  137. package/dist/src/runtime-frame.d.ts +11 -0
  138. package/dist/src/runtime-frame.js +12 -0
  139. package/dist/src/shader-lab-composition.d.ts +9 -0
  140. package/dist/src/shader-lab-composition.js +96 -0
  141. package/dist/src/timeline.d.ts +8 -0
  142. package/dist/src/timeline.js +179 -0
  143. package/dist/src/types/editor.d.ts +3 -0
  144. package/dist/src/types/editor.js +1 -0
  145. package/dist/src/types.d.ts +81 -0
  146. package/dist/src/types.js +1 -0
  147. package/package.json +28 -65
  148. package/.biome/plugins/README.md +0 -21
  149. package/.biome/plugins/no-anchor-element.grit +0 -12
  150. package/.biome/plugins/no-relative-parent-imports.grit +0 -10
  151. package/.biome/plugins/no-unnecessary-forwardref.grit +0 -9
  152. package/.changeset/README.md +0 -17
  153. package/.changeset/config.json +0 -11
  154. package/.editorconfig +0 -40
  155. package/.env.example +0 -81
  156. package/.gitattributes +0 -19
  157. package/.github/workflows/canary.yml +0 -80
  158. package/.github/workflows/ci.yml +0 -37
  159. package/.github/workflows/release.yml +0 -56
  160. package/.tldrignore +0 -84
  161. package/.vscode/extensions.json +0 -20
  162. package/.vscode/settings.json +0 -105
  163. package/biome.json +0 -249
  164. package/bun.lock +0 -1224
  165. package/next.config.ts +0 -131
  166. package/packages/shader-lab-react/CHANGELOG.md +0 -9
  167. package/packages/shader-lab-react/README.md +0 -119
  168. package/packages/shader-lab-react/package.json +0 -36
  169. package/packages/shader-lab-react/scripts/fix-esm-specifiers.mjs +0 -57
  170. package/packages/shader-lab-react/scripts/prepare-dist.mjs +0 -4
  171. package/packages/shader-lab-react/src/ambient/three-tsl.d.ts +0 -146
  172. package/packages/shader-lab-react/src/ambient/three-webgpu.d.ts +0 -51
  173. package/packages/shader-lab-react/src/easings.ts +0 -4
  174. package/packages/shader-lab-react/src/index.ts +0 -35
  175. package/packages/shader-lab-react/src/lib/editor/custom-shader/shared.ts +0 -2
  176. package/packages/shader-lab-react/src/renderer/ascii-atlas.ts +0 -83
  177. package/packages/shader-lab-react/src/renderer/ascii-pass.ts +0 -416
  178. package/packages/shader-lab-react/src/renderer/asset-url.ts +0 -3
  179. package/packages/shader-lab-react/src/renderer/blend-modes.ts +0 -229
  180. package/packages/shader-lab-react/src/renderer/contracts.ts +0 -54
  181. package/packages/shader-lab-react/src/renderer/create-webgpu-renderer.ts +0 -48
  182. package/packages/shader-lab-react/src/renderer/crt-pass.ts +0 -1040
  183. package/packages/shader-lab-react/src/renderer/custom-shader-pass.ts +0 -108
  184. package/packages/shader-lab-react/src/renderer/custom-shader-runtime.ts +0 -309
  185. package/packages/shader-lab-react/src/renderer/dither-textures.ts +0 -99
  186. package/packages/shader-lab-react/src/renderer/dithering-pass.ts +0 -322
  187. package/packages/shader-lab-react/src/renderer/gradient-pass.ts +0 -521
  188. package/packages/shader-lab-react/src/renderer/halftone-pass.ts +0 -932
  189. package/packages/shader-lab-react/src/renderer/ink-pass.ts +0 -802
  190. package/packages/shader-lab-react/src/renderer/live-pass.ts +0 -194
  191. package/packages/shader-lab-react/src/renderer/media-pass.ts +0 -187
  192. package/packages/shader-lab-react/src/renderer/media-texture.ts +0 -66
  193. package/packages/shader-lab-react/src/renderer/particle-grid-pass.ts +0 -389
  194. package/packages/shader-lab-react/src/renderer/pass-node.ts +0 -209
  195. package/packages/shader-lab-react/src/renderer/pattern-atlas.ts +0 -133
  196. package/packages/shader-lab-react/src/renderer/pattern-pass.ts +0 -552
  197. package/packages/shader-lab-react/src/renderer/pipeline-manager.ts +0 -369
  198. package/packages/shader-lab-react/src/renderer/pixel-sorting-pass.ts +0 -277
  199. package/packages/shader-lab-react/src/renderer/shaders/tsl/color/tonemapping.ts +0 -87
  200. package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/common.ts +0 -31
  201. package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/curl-noise-3d.ts +0 -36
  202. package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/curl-noise-4d.ts +0 -36
  203. package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/fbm.ts +0 -13
  204. package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/perlin-noise-3d.ts +0 -96
  205. package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/ridge-noise.ts +0 -24
  206. package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/simplex-noise-3d.ts +0 -79
  207. package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/simplex-noise-4d.ts +0 -89
  208. package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/turbulence.ts +0 -56
  209. package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/value-noise-3d.ts +0 -32
  210. package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/voronoi-noise-3d.ts +0 -60
  211. package/packages/shader-lab-react/src/renderer/shaders/tsl/patterns/bloom-edge-pattern.ts +0 -15
  212. package/packages/shader-lab-react/src/renderer/shaders/tsl/patterns/canvas-weave-pattern.ts +0 -24
  213. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/atan2.ts +0 -9
  214. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-cos.ts +0 -10
  215. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-div.ts +0 -11
  216. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-log.ts +0 -7
  217. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-mobius.ts +0 -12
  218. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-pow.ts +0 -16
  219. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-sin.ts +0 -10
  220. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-sqrt.ts +0 -18
  221. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-tan.ts +0 -12
  222. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-to-polar.ts +0 -10
  223. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/index.ts +0 -48
  224. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/rotate.ts +0 -15
  225. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/screen-aspect-uv.ts +0 -15
  226. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/sd-box-2d.ts +0 -6
  227. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/sd-diamond.ts +0 -6
  228. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/sd-rhombus.ts +0 -27
  229. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/sd-sphere.ts +0 -6
  230. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/smax.ts +0 -7
  231. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/smin.ts +0 -7
  232. package/packages/shader-lab-react/src/renderer/text-pass.ts +0 -176
  233. package/packages/shader-lab-react/src/runtime-clock.ts +0 -42
  234. package/packages/shader-lab-react/src/runtime-frame.ts +0 -29
  235. package/packages/shader-lab-react/src/shader-lab-composition.tsx +0 -163
  236. package/packages/shader-lab-react/src/timeline.ts +0 -283
  237. package/packages/shader-lab-react/src/types/editor.ts +0 -5
  238. package/packages/shader-lab-react/src/types.ts +0 -141
  239. package/packages/shader-lab-react/tsconfig.build.json +0 -8
  240. package/packages/shader-lab-react/tsconfig.json +0 -21
  241. package/postcss.config.mjs +0 -5
  242. package/public/assets/fonts/msdf/geist-mono/GeistMono-Regular-msdf-atlas.png +0 -0
  243. package/public/assets/fonts/msdf/geist-mono/GeistMono-Regular-msdf.json +0 -1412
  244. package/public/assets/patterns/bars/1.svg +0 -3
  245. package/public/assets/patterns/bars/2.svg +0 -3
  246. package/public/assets/patterns/bars/3.svg +0 -3
  247. package/public/assets/patterns/bars/4.svg +0 -3
  248. package/public/assets/patterns/bars/5.svg +0 -3
  249. package/public/assets/patterns/bars/6.svg +0 -3
  250. package/public/assets/patterns/candles/1.svg +0 -3
  251. package/public/assets/patterns/candles/2.svg +0 -3
  252. package/public/assets/patterns/candles/3.svg +0 -3
  253. package/public/assets/patterns/candles/4.svg +0 -3
  254. package/public/assets/patterns/shapes/1.svg +0 -3
  255. package/public/assets/patterns/shapes/2.svg +0 -3
  256. package/public/assets/patterns/shapes/3.svg +0 -3
  257. package/public/assets/patterns/shapes/4.svg +0 -4
  258. package/public/assets/patterns/shapes/5.svg +0 -3
  259. package/public/assets/patterns/shapes/6.svg +0 -4
  260. package/public/fonts/geist/Geist-Mono.woff2 +0 -0
  261. package/public/textures/blue-noise.png +0 -0
  262. package/public/textures/crt-mask.png +0 -0
  263. package/src/app/design/page.tsx +0 -398
  264. package/src/app/favicon.ico +0 -0
  265. package/src/app/globals.css +0 -280
  266. package/src/app/layout.tsx +0 -89
  267. package/src/app/page.tsx +0 -20
  268. package/src/app/robots.ts +0 -13
  269. package/src/app/sitemap.ts +0 -13
  270. package/src/components/editor/editor-canvas-viewport.tsx +0 -116
  271. package/src/components/editor/editor-export-dialog.tsx +0 -1177
  272. package/src/components/editor/editor-timeline-overlay.tsx +0 -983
  273. package/src/components/editor/editor-topbar.tsx +0 -287
  274. package/src/components/editor/layer-sidebar.tsx +0 -738
  275. package/src/components/editor/properties-sidebar-content.tsx +0 -574
  276. package/src/components/editor/properties-sidebar-fields.tsx +0 -389
  277. package/src/components/editor/properties-sidebar-utils.ts +0 -178
  278. package/src/components/editor/properties-sidebar.tsx +0 -421
  279. package/src/components/ui/button/index.tsx +0 -57
  280. package/src/components/ui/color-picker/index.tsx +0 -358
  281. package/src/components/ui/glass-panel/index.tsx +0 -45
  282. package/src/components/ui/icon-button/index.tsx +0 -46
  283. package/src/components/ui/select/index.tsx +0 -136
  284. package/src/components/ui/slider/index.tsx +0 -192
  285. package/src/components/ui/toggle/index.tsx +0 -34
  286. package/src/components/ui/typography/index.tsx +0 -61
  287. package/src/components/ui/xy-pad/index.tsx +0 -160
  288. package/src/features/editor/components/editor-export-dialog.module.css +0 -271
  289. package/src/hooks/use-editor-renderer.ts +0 -182
  290. package/src/lib/app.ts +0 -6
  291. package/src/lib/cn.ts +0 -7
  292. package/src/lib/easings.ts +0 -240
  293. package/src/lib/editor/config/layer-registry.ts +0 -2434
  294. package/src/lib/editor/custom-shader/shared.ts +0 -28
  295. package/src/lib/editor/export.ts +0 -420
  296. package/src/lib/editor/history.ts +0 -71
  297. package/src/lib/editor/layers.ts +0 -76
  298. package/src/lib/editor/parameter-schema.ts +0 -75
  299. package/src/lib/editor/project-file.ts +0 -145
  300. package/src/lib/editor/shader-export-snippet.ts +0 -37
  301. package/src/lib/editor/shader-export.ts +0 -315
  302. package/src/lib/editor/timeline/evaluate.ts +0 -252
  303. package/src/lib/editor/view-transform.ts +0 -58
  304. package/src/lib/fonts.ts +0 -28
  305. package/src/renderer/ascii-atlas.ts +0 -83
  306. package/src/renderer/ascii-pass.ts +0 -416
  307. package/src/renderer/blend-modes.ts +0 -229
  308. package/src/renderer/contracts.ts +0 -161
  309. package/src/renderer/create-webgpu-renderer.ts +0 -48
  310. package/src/renderer/crt-pass.ts +0 -1040
  311. package/src/renderer/custom-shader-pass.ts +0 -117
  312. package/src/renderer/custom-shader-runtime.ts +0 -309
  313. package/src/renderer/dither-textures.ts +0 -99
  314. package/src/renderer/dithering-pass.ts +0 -322
  315. package/src/renderer/gradient-pass.ts +0 -520
  316. package/src/renderer/halftone-pass.ts +0 -932
  317. package/src/renderer/ink-pass.ts +0 -683
  318. package/src/renderer/live-pass.ts +0 -194
  319. package/src/renderer/media-pass.ts +0 -187
  320. package/src/renderer/media-texture.ts +0 -66
  321. package/src/renderer/particle-grid-pass.ts +0 -389
  322. package/src/renderer/pass-node-factory.ts +0 -33
  323. package/src/renderer/pass-node.ts +0 -209
  324. package/src/renderer/pattern-atlas.ts +0 -97
  325. package/src/renderer/pattern-pass.ts +0 -552
  326. package/src/renderer/pipeline-manager.ts +0 -343
  327. package/src/renderer/pixel-sorting-pass.ts +0 -277
  328. package/src/renderer/project-clock.ts +0 -57
  329. package/src/renderer/shaders/tsl/color/tonemapping.ts +0 -86
  330. package/src/renderer/shaders/tsl/cosine-palette.ts +0 -8
  331. package/src/renderer/shaders/tsl/noise/common.ts +0 -30
  332. package/src/renderer/shaders/tsl/noise/curl-noise-3d.ts +0 -35
  333. package/src/renderer/shaders/tsl/noise/curl-noise-4d.ts +0 -35
  334. package/src/renderer/shaders/tsl/noise/fbm.ts +0 -12
  335. package/src/renderer/shaders/tsl/noise/perlin-noise-3d.ts +0 -97
  336. package/src/renderer/shaders/tsl/noise/ridge-noise.ts +0 -23
  337. package/src/renderer/shaders/tsl/noise/simplex-noise-3d.ts +0 -78
  338. package/src/renderer/shaders/tsl/noise/simplex-noise-4d.ts +0 -88
  339. package/src/renderer/shaders/tsl/noise/turbulence.ts +0 -55
  340. package/src/renderer/shaders/tsl/noise/value-noise-3d.ts +0 -31
  341. package/src/renderer/shaders/tsl/noise/voronoi-noise-3d.ts +0 -59
  342. package/src/renderer/shaders/tsl/patterns/bloom-edge-pattern.ts +0 -14
  343. package/src/renderer/shaders/tsl/patterns/bloom.ts +0 -10
  344. package/src/renderer/shaders/tsl/patterns/canvas-weave-pattern.ts +0 -23
  345. package/src/renderer/shaders/tsl/patterns/grain-texture-pattern.ts +0 -8
  346. package/src/renderer/shaders/tsl/patterns/repeating-pattern.ts +0 -10
  347. package/src/renderer/shaders/tsl/utils/atan2.ts +0 -8
  348. package/src/renderer/shaders/tsl/utils/complex-conj.ts +0 -8
  349. package/src/renderer/shaders/tsl/utils/complex-cos.ts +0 -9
  350. package/src/renderer/shaders/tsl/utils/complex-div.ts +0 -10
  351. package/src/renderer/shaders/tsl/utils/complex-log.ts +0 -6
  352. package/src/renderer/shaders/tsl/utils/complex-mobius.ts +0 -11
  353. package/src/renderer/shaders/tsl/utils/complex-mul.ts +0 -8
  354. package/src/renderer/shaders/tsl/utils/complex-pow.ts +0 -15
  355. package/src/renderer/shaders/tsl/utils/complex-sin.ts +0 -9
  356. package/src/renderer/shaders/tsl/utils/complex-sqrt.ts +0 -17
  357. package/src/renderer/shaders/tsl/utils/complex-tan.ts +0 -11
  358. package/src/renderer/shaders/tsl/utils/complex-to-polar.ts +0 -9
  359. package/src/renderer/shaders/tsl/utils/hyperbolic.ts +0 -19
  360. package/src/renderer/shaders/tsl/utils/index.ts +0 -47
  361. package/src/renderer/shaders/tsl/utils/rotate.ts +0 -14
  362. package/src/renderer/shaders/tsl/utils/screen-aspect-uv.ts +0 -14
  363. package/src/renderer/shaders/tsl/utils/sd-box-2d.ts +0 -5
  364. package/src/renderer/shaders/tsl/utils/sd-diamond.ts +0 -5
  365. package/src/renderer/shaders/tsl/utils/sd-rhombus.ts +0 -26
  366. package/src/renderer/shaders/tsl/utils/sd-sphere.ts +0 -5
  367. package/src/renderer/shaders/tsl/utils/smax.ts +0 -7
  368. package/src/renderer/shaders/tsl/utils/smin.ts +0 -6
  369. package/src/renderer/text-pass.ts +0 -176
  370. package/src/store/asset-store.ts +0 -193
  371. package/src/store/editor-store.ts +0 -223
  372. package/src/store/history-store.ts +0 -172
  373. package/src/store/index.ts +0 -31
  374. package/src/store/layer-store.ts +0 -675
  375. package/src/store/timeline-store.ts +0 -572
  376. package/src/types/assets.d.ts +0 -6
  377. package/src/types/css.d.ts +0 -21
  378. package/src/types/editor.ts +0 -357
  379. package/src/types/react.d.ts +0 -15
  380. package/src/types/three-tsl.d.ts +0 -146
  381. package/src/types/three-webgpu.d.ts +0 -51
  382. package/tsconfig.json +0 -49
  383. /package/{packages/shader-lab-react/assets → assets}/patterns/bars/1.svg +0 -0
  384. /package/{packages/shader-lab-react/assets → assets}/patterns/bars/2.svg +0 -0
  385. /package/{packages/shader-lab-react/assets → assets}/patterns/bars/3.svg +0 -0
  386. /package/{packages/shader-lab-react/assets → assets}/patterns/bars/4.svg +0 -0
  387. /package/{packages/shader-lab-react/assets → assets}/patterns/bars/5.svg +0 -0
  388. /package/{packages/shader-lab-react/assets → assets}/patterns/bars/6.svg +0 -0
  389. /package/{packages/shader-lab-react/assets → assets}/patterns/candles/1.svg +0 -0
  390. /package/{packages/shader-lab-react/assets → assets}/patterns/candles/2.svg +0 -0
  391. /package/{packages/shader-lab-react/assets → assets}/patterns/candles/3.svg +0 -0
  392. /package/{packages/shader-lab-react/assets → assets}/patterns/candles/4.svg +0 -0
  393. /package/{packages/shader-lab-react/assets → assets}/patterns/shapes/1.svg +0 -0
  394. /package/{packages/shader-lab-react/assets → assets}/patterns/shapes/2.svg +0 -0
  395. /package/{packages/shader-lab-react/assets → assets}/patterns/shapes/3.svg +0 -0
  396. /package/{packages/shader-lab-react/assets → assets}/patterns/shapes/4.svg +0 -0
  397. /package/{packages/shader-lab-react/assets → assets}/patterns/shapes/5.svg +0 -0
  398. /package/{packages/shader-lab-react/assets → assets}/patterns/shapes/6.svg +0 -0
  399. /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 {};