@basementstudio/shader-lab 0.1.0

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 (261) hide show
  1. package/.biome/plugins/README.md +21 -0
  2. package/.biome/plugins/no-anchor-element.grit +12 -0
  3. package/.biome/plugins/no-relative-parent-imports.grit +10 -0
  4. package/.biome/plugins/no-unnecessary-forwardref.grit +9 -0
  5. package/.changeset/README.md +17 -0
  6. package/.changeset/config.json +11 -0
  7. package/.editorconfig +40 -0
  8. package/.env.example +81 -0
  9. package/.gitattributes +19 -0
  10. package/.github/workflows/canary.yml +80 -0
  11. package/.github/workflows/ci.yml +37 -0
  12. package/.github/workflows/release.yml +56 -0
  13. package/.tldrignore +84 -0
  14. package/.vscode/extensions.json +20 -0
  15. package/.vscode/settings.json +105 -0
  16. package/README.md +119 -0
  17. package/biome.json +249 -0
  18. package/bun.lock +1224 -0
  19. package/next.config.ts +131 -0
  20. package/package.json +73 -0
  21. package/packages/shader-lab-react/CHANGELOG.md +9 -0
  22. package/packages/shader-lab-react/README.md +119 -0
  23. package/packages/shader-lab-react/assets/patterns/bars/1.svg +3 -0
  24. package/packages/shader-lab-react/assets/patterns/bars/2.svg +3 -0
  25. package/packages/shader-lab-react/assets/patterns/bars/3.svg +3 -0
  26. package/packages/shader-lab-react/assets/patterns/bars/4.svg +3 -0
  27. package/packages/shader-lab-react/assets/patterns/bars/5.svg +3 -0
  28. package/packages/shader-lab-react/assets/patterns/bars/6.svg +3 -0
  29. package/packages/shader-lab-react/assets/patterns/candles/1.svg +3 -0
  30. package/packages/shader-lab-react/assets/patterns/candles/2.svg +3 -0
  31. package/packages/shader-lab-react/assets/patterns/candles/3.svg +3 -0
  32. package/packages/shader-lab-react/assets/patterns/candles/4.svg +3 -0
  33. package/packages/shader-lab-react/assets/patterns/shapes/1.svg +3 -0
  34. package/packages/shader-lab-react/assets/patterns/shapes/2.svg +3 -0
  35. package/packages/shader-lab-react/assets/patterns/shapes/3.svg +3 -0
  36. package/packages/shader-lab-react/assets/patterns/shapes/4.svg +4 -0
  37. package/packages/shader-lab-react/assets/patterns/shapes/5.svg +3 -0
  38. package/packages/shader-lab-react/assets/patterns/shapes/6.svg +4 -0
  39. package/packages/shader-lab-react/assets/textures/blue-noise.png +0 -0
  40. package/packages/shader-lab-react/package.json +36 -0
  41. package/packages/shader-lab-react/scripts/fix-esm-specifiers.mjs +57 -0
  42. package/packages/shader-lab-react/scripts/prepare-dist.mjs +4 -0
  43. package/packages/shader-lab-react/src/ambient/three-tsl.d.ts +146 -0
  44. package/packages/shader-lab-react/src/ambient/three-webgpu.d.ts +51 -0
  45. package/packages/shader-lab-react/src/easings.ts +4 -0
  46. package/packages/shader-lab-react/src/index.ts +35 -0
  47. package/packages/shader-lab-react/src/lib/editor/custom-shader/shared.ts +2 -0
  48. package/packages/shader-lab-react/src/renderer/ascii-atlas.ts +83 -0
  49. package/packages/shader-lab-react/src/renderer/ascii-pass.ts +416 -0
  50. package/packages/shader-lab-react/src/renderer/asset-url.ts +3 -0
  51. package/packages/shader-lab-react/src/renderer/blend-modes.ts +229 -0
  52. package/packages/shader-lab-react/src/renderer/contracts.ts +54 -0
  53. package/packages/shader-lab-react/src/renderer/create-webgpu-renderer.ts +48 -0
  54. package/packages/shader-lab-react/src/renderer/crt-pass.ts +1040 -0
  55. package/packages/shader-lab-react/src/renderer/custom-shader-pass.ts +108 -0
  56. package/packages/shader-lab-react/src/renderer/custom-shader-runtime.ts +309 -0
  57. package/packages/shader-lab-react/src/renderer/dither-textures.ts +99 -0
  58. package/packages/shader-lab-react/src/renderer/dithering-pass.ts +322 -0
  59. package/packages/shader-lab-react/src/renderer/gradient-pass.ts +521 -0
  60. package/packages/shader-lab-react/src/renderer/halftone-pass.ts +932 -0
  61. package/packages/shader-lab-react/src/renderer/ink-pass.ts +802 -0
  62. package/packages/shader-lab-react/src/renderer/live-pass.ts +194 -0
  63. package/packages/shader-lab-react/src/renderer/media-pass.ts +187 -0
  64. package/packages/shader-lab-react/src/renderer/media-texture.ts +66 -0
  65. package/packages/shader-lab-react/src/renderer/particle-grid-pass.ts +389 -0
  66. package/packages/shader-lab-react/src/renderer/pass-node.ts +209 -0
  67. package/packages/shader-lab-react/src/renderer/pattern-atlas.ts +133 -0
  68. package/packages/shader-lab-react/src/renderer/pattern-pass.ts +552 -0
  69. package/packages/shader-lab-react/src/renderer/pipeline-manager.ts +369 -0
  70. package/packages/shader-lab-react/src/renderer/pixel-sorting-pass.ts +277 -0
  71. package/packages/shader-lab-react/src/renderer/shaders/tsl/color/tonemapping.ts +87 -0
  72. package/packages/shader-lab-react/src/renderer/shaders/tsl/cosine-palette.ts +9 -0
  73. package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/common.ts +31 -0
  74. package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/curl-noise-3d.ts +36 -0
  75. package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/curl-noise-4d.ts +36 -0
  76. package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/fbm.ts +13 -0
  77. package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/perlin-noise-3d.ts +96 -0
  78. package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/ridge-noise.ts +24 -0
  79. package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/simplex-noise-3d.ts +79 -0
  80. package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/simplex-noise-4d.ts +89 -0
  81. package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/turbulence.ts +56 -0
  82. package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/value-noise-3d.ts +32 -0
  83. package/packages/shader-lab-react/src/renderer/shaders/tsl/noise/voronoi-noise-3d.ts +60 -0
  84. package/packages/shader-lab-react/src/renderer/shaders/tsl/patterns/bloom-edge-pattern.ts +15 -0
  85. package/packages/shader-lab-react/src/renderer/shaders/tsl/patterns/bloom.ts +11 -0
  86. package/packages/shader-lab-react/src/renderer/shaders/tsl/patterns/canvas-weave-pattern.ts +24 -0
  87. package/packages/shader-lab-react/src/renderer/shaders/tsl/patterns/grain-texture-pattern.ts +9 -0
  88. package/packages/shader-lab-react/src/renderer/shaders/tsl/patterns/repeating-pattern.ts +11 -0
  89. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/atan2.ts +9 -0
  90. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-conj.ts +9 -0
  91. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-cos.ts +10 -0
  92. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-div.ts +11 -0
  93. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-log.ts +7 -0
  94. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-mobius.ts +12 -0
  95. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-mul.ts +9 -0
  96. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-pow.ts +16 -0
  97. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-sin.ts +10 -0
  98. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-sqrt.ts +18 -0
  99. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-tan.ts +12 -0
  100. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/complex-to-polar.ts +10 -0
  101. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/hyperbolic.ts +20 -0
  102. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/index.ts +48 -0
  103. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/rotate.ts +15 -0
  104. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/screen-aspect-uv.ts +15 -0
  105. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/sd-box-2d.ts +6 -0
  106. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/sd-diamond.ts +6 -0
  107. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/sd-rhombus.ts +27 -0
  108. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/sd-sphere.ts +6 -0
  109. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/smax.ts +7 -0
  110. package/packages/shader-lab-react/src/renderer/shaders/tsl/utils/smin.ts +7 -0
  111. package/packages/shader-lab-react/src/renderer/text-pass.ts +176 -0
  112. package/packages/shader-lab-react/src/runtime-clock.ts +42 -0
  113. package/packages/shader-lab-react/src/runtime-frame.ts +29 -0
  114. package/packages/shader-lab-react/src/shader-lab-composition.tsx +163 -0
  115. package/packages/shader-lab-react/src/timeline.ts +283 -0
  116. package/packages/shader-lab-react/src/types/editor.ts +5 -0
  117. package/packages/shader-lab-react/src/types.ts +141 -0
  118. package/packages/shader-lab-react/tsconfig.build.json +8 -0
  119. package/packages/shader-lab-react/tsconfig.json +21 -0
  120. package/postcss.config.mjs +5 -0
  121. package/public/assets/fonts/msdf/geist-mono/GeistMono-Regular-msdf-atlas.png +0 -0
  122. package/public/assets/fonts/msdf/geist-mono/GeistMono-Regular-msdf.json +1412 -0
  123. package/public/assets/patterns/bars/1.svg +3 -0
  124. package/public/assets/patterns/bars/2.svg +3 -0
  125. package/public/assets/patterns/bars/3.svg +3 -0
  126. package/public/assets/patterns/bars/4.svg +3 -0
  127. package/public/assets/patterns/bars/5.svg +3 -0
  128. package/public/assets/patterns/bars/6.svg +3 -0
  129. package/public/assets/patterns/candles/1.svg +3 -0
  130. package/public/assets/patterns/candles/2.svg +3 -0
  131. package/public/assets/patterns/candles/3.svg +3 -0
  132. package/public/assets/patterns/candles/4.svg +3 -0
  133. package/public/assets/patterns/shapes/1.svg +3 -0
  134. package/public/assets/patterns/shapes/2.svg +3 -0
  135. package/public/assets/patterns/shapes/3.svg +3 -0
  136. package/public/assets/patterns/shapes/4.svg +4 -0
  137. package/public/assets/patterns/shapes/5.svg +3 -0
  138. package/public/assets/patterns/shapes/6.svg +4 -0
  139. package/public/fonts/geist/Geist-Mono.woff2 +0 -0
  140. package/public/textures/blue-noise.png +0 -0
  141. package/public/textures/crt-mask.png +0 -0
  142. package/src/app/design/page.tsx +398 -0
  143. package/src/app/favicon.ico +0 -0
  144. package/src/app/globals.css +280 -0
  145. package/src/app/layout.tsx +89 -0
  146. package/src/app/page.tsx +20 -0
  147. package/src/app/robots.ts +13 -0
  148. package/src/app/sitemap.ts +13 -0
  149. package/src/components/editor/editor-canvas-viewport.tsx +116 -0
  150. package/src/components/editor/editor-export-dialog.tsx +1177 -0
  151. package/src/components/editor/editor-timeline-overlay.tsx +983 -0
  152. package/src/components/editor/editor-topbar.tsx +287 -0
  153. package/src/components/editor/layer-sidebar.tsx +738 -0
  154. package/src/components/editor/properties-sidebar-content.tsx +574 -0
  155. package/src/components/editor/properties-sidebar-fields.tsx +389 -0
  156. package/src/components/editor/properties-sidebar-utils.ts +178 -0
  157. package/src/components/editor/properties-sidebar.tsx +421 -0
  158. package/src/components/ui/button/index.tsx +57 -0
  159. package/src/components/ui/color-picker/index.tsx +358 -0
  160. package/src/components/ui/glass-panel/index.tsx +45 -0
  161. package/src/components/ui/icon-button/index.tsx +46 -0
  162. package/src/components/ui/select/index.tsx +136 -0
  163. package/src/components/ui/slider/index.tsx +192 -0
  164. package/src/components/ui/toggle/index.tsx +34 -0
  165. package/src/components/ui/typography/index.tsx +61 -0
  166. package/src/components/ui/xy-pad/index.tsx +160 -0
  167. package/src/features/editor/components/editor-export-dialog.module.css +271 -0
  168. package/src/hooks/use-editor-renderer.ts +182 -0
  169. package/src/lib/app.ts +6 -0
  170. package/src/lib/cn.ts +7 -0
  171. package/src/lib/easings.ts +240 -0
  172. package/src/lib/editor/config/layer-registry.ts +2434 -0
  173. package/src/lib/editor/custom-shader/shared.ts +28 -0
  174. package/src/lib/editor/export.ts +420 -0
  175. package/src/lib/editor/history.ts +71 -0
  176. package/src/lib/editor/layers.ts +76 -0
  177. package/src/lib/editor/parameter-schema.ts +75 -0
  178. package/src/lib/editor/project-file.ts +145 -0
  179. package/src/lib/editor/shader-export-snippet.ts +37 -0
  180. package/src/lib/editor/shader-export.ts +315 -0
  181. package/src/lib/editor/timeline/evaluate.ts +252 -0
  182. package/src/lib/editor/view-transform.ts +58 -0
  183. package/src/lib/fonts.ts +28 -0
  184. package/src/renderer/ascii-atlas.ts +83 -0
  185. package/src/renderer/ascii-pass.ts +416 -0
  186. package/src/renderer/blend-modes.ts +229 -0
  187. package/src/renderer/contracts.ts +161 -0
  188. package/src/renderer/create-webgpu-renderer.ts +48 -0
  189. package/src/renderer/crt-pass.ts +1040 -0
  190. package/src/renderer/custom-shader-pass.ts +117 -0
  191. package/src/renderer/custom-shader-runtime.ts +309 -0
  192. package/src/renderer/dither-textures.ts +99 -0
  193. package/src/renderer/dithering-pass.ts +322 -0
  194. package/src/renderer/gradient-pass.ts +520 -0
  195. package/src/renderer/halftone-pass.ts +932 -0
  196. package/src/renderer/ink-pass.ts +683 -0
  197. package/src/renderer/live-pass.ts +194 -0
  198. package/src/renderer/media-pass.ts +187 -0
  199. package/src/renderer/media-texture.ts +66 -0
  200. package/src/renderer/particle-grid-pass.ts +389 -0
  201. package/src/renderer/pass-node-factory.ts +33 -0
  202. package/src/renderer/pass-node.ts +209 -0
  203. package/src/renderer/pattern-atlas.ts +97 -0
  204. package/src/renderer/pattern-pass.ts +552 -0
  205. package/src/renderer/pipeline-manager.ts +343 -0
  206. package/src/renderer/pixel-sorting-pass.ts +277 -0
  207. package/src/renderer/project-clock.ts +57 -0
  208. package/src/renderer/shaders/tsl/color/tonemapping.ts +86 -0
  209. package/src/renderer/shaders/tsl/cosine-palette.ts +8 -0
  210. package/src/renderer/shaders/tsl/noise/common.ts +30 -0
  211. package/src/renderer/shaders/tsl/noise/curl-noise-3d.ts +35 -0
  212. package/src/renderer/shaders/tsl/noise/curl-noise-4d.ts +35 -0
  213. package/src/renderer/shaders/tsl/noise/fbm.ts +12 -0
  214. package/src/renderer/shaders/tsl/noise/perlin-noise-3d.ts +97 -0
  215. package/src/renderer/shaders/tsl/noise/ridge-noise.ts +23 -0
  216. package/src/renderer/shaders/tsl/noise/simplex-noise-3d.ts +78 -0
  217. package/src/renderer/shaders/tsl/noise/simplex-noise-4d.ts +88 -0
  218. package/src/renderer/shaders/tsl/noise/turbulence.ts +55 -0
  219. package/src/renderer/shaders/tsl/noise/value-noise-3d.ts +31 -0
  220. package/src/renderer/shaders/tsl/noise/voronoi-noise-3d.ts +59 -0
  221. package/src/renderer/shaders/tsl/patterns/bloom-edge-pattern.ts +14 -0
  222. package/src/renderer/shaders/tsl/patterns/bloom.ts +10 -0
  223. package/src/renderer/shaders/tsl/patterns/canvas-weave-pattern.ts +23 -0
  224. package/src/renderer/shaders/tsl/patterns/grain-texture-pattern.ts +8 -0
  225. package/src/renderer/shaders/tsl/patterns/repeating-pattern.ts +10 -0
  226. package/src/renderer/shaders/tsl/utils/atan2.ts +8 -0
  227. package/src/renderer/shaders/tsl/utils/complex-conj.ts +8 -0
  228. package/src/renderer/shaders/tsl/utils/complex-cos.ts +9 -0
  229. package/src/renderer/shaders/tsl/utils/complex-div.ts +10 -0
  230. package/src/renderer/shaders/tsl/utils/complex-log.ts +6 -0
  231. package/src/renderer/shaders/tsl/utils/complex-mobius.ts +11 -0
  232. package/src/renderer/shaders/tsl/utils/complex-mul.ts +8 -0
  233. package/src/renderer/shaders/tsl/utils/complex-pow.ts +15 -0
  234. package/src/renderer/shaders/tsl/utils/complex-sin.ts +9 -0
  235. package/src/renderer/shaders/tsl/utils/complex-sqrt.ts +17 -0
  236. package/src/renderer/shaders/tsl/utils/complex-tan.ts +11 -0
  237. package/src/renderer/shaders/tsl/utils/complex-to-polar.ts +9 -0
  238. package/src/renderer/shaders/tsl/utils/hyperbolic.ts +19 -0
  239. package/src/renderer/shaders/tsl/utils/index.ts +47 -0
  240. package/src/renderer/shaders/tsl/utils/rotate.ts +14 -0
  241. package/src/renderer/shaders/tsl/utils/screen-aspect-uv.ts +14 -0
  242. package/src/renderer/shaders/tsl/utils/sd-box-2d.ts +5 -0
  243. package/src/renderer/shaders/tsl/utils/sd-diamond.ts +5 -0
  244. package/src/renderer/shaders/tsl/utils/sd-rhombus.ts +26 -0
  245. package/src/renderer/shaders/tsl/utils/sd-sphere.ts +5 -0
  246. package/src/renderer/shaders/tsl/utils/smax.ts +7 -0
  247. package/src/renderer/shaders/tsl/utils/smin.ts +6 -0
  248. package/src/renderer/text-pass.ts +176 -0
  249. package/src/store/asset-store.ts +193 -0
  250. package/src/store/editor-store.ts +223 -0
  251. package/src/store/history-store.ts +172 -0
  252. package/src/store/index.ts +31 -0
  253. package/src/store/layer-store.ts +675 -0
  254. package/src/store/timeline-store.ts +572 -0
  255. package/src/types/assets.d.ts +6 -0
  256. package/src/types/css.d.ts +21 -0
  257. package/src/types/editor.ts +357 -0
  258. package/src/types/react.d.ts +15 -0
  259. package/src/types/three-tsl.d.ts +146 -0
  260. package/src/types/three-webgpu.d.ts +51 -0
  261. package/tsconfig.json +49 -0
@@ -0,0 +1,229 @@
1
+ import {
2
+ abs,
3
+ clamp,
4
+ dot,
5
+ float,
6
+ max,
7
+ min,
8
+ mix,
9
+ select,
10
+ sqrt,
11
+ type TSLNode,
12
+ vec3,
13
+ vec4,
14
+ } from "three/tsl"
15
+
16
+ type Node = TSLNode
17
+
18
+ function normal(_base: Node, blend: Node): Node {
19
+ return blend
20
+ }
21
+
22
+ function multiply(base: Node, blend: Node): Node {
23
+ return base.mul(blend)
24
+ }
25
+
26
+ function screen(base: Node, blend: Node): Node {
27
+ return float(1).sub(float(1).sub(base).mul(float(1).sub(blend)))
28
+ }
29
+
30
+ function overlay(base: Node, blend: Node): Node {
31
+ const dark = float(2).mul(base).mul(blend)
32
+ const light = float(1).sub(
33
+ float(2).mul(float(1).sub(base)).mul(float(1).sub(blend)),
34
+ )
35
+
36
+ return select(base.lessThan(float(0.5)), dark, light)
37
+ }
38
+
39
+ function darken(base: Node, blend: Node): Node {
40
+ return min(base, blend)
41
+ }
42
+
43
+ function lighten(base: Node, blend: Node): Node {
44
+ return max(base, blend)
45
+ }
46
+
47
+ function colorDodge(base: Node, blend: Node): Node {
48
+ return clamp(base.div(max(float(1).sub(blend), float(1e-6))), vec3(0), vec3(1))
49
+ }
50
+
51
+ function colorBurn(base: Node, blend: Node): Node {
52
+ return clamp(
53
+ float(1).sub(float(1).sub(base).div(max(blend, float(1e-6)))),
54
+ vec3(0),
55
+ vec3(1),
56
+ )
57
+ }
58
+
59
+ function hardLight(base: Node, blend: Node): Node {
60
+ return overlay(blend, base)
61
+ }
62
+
63
+ function softLight(base: Node, blend: Node): Node {
64
+ const darkResult = base.sub(
65
+ float(1).sub(float(2).mul(blend)).mul(base).mul(float(1).sub(base)),
66
+ )
67
+ const twoBlendMinusOne = float(2).mul(blend).sub(float(1))
68
+ const dLow = float(16).mul(base).sub(float(12)).mul(base).add(float(4)).mul(base)
69
+ const dHigh = sqrt(base)
70
+ const d = select(base.lessThanEqual(float(0.25)), dLow, dHigh)
71
+ const lightResult = base.add(twoBlendMinusOne.mul(d.sub(base)))
72
+
73
+ return select(blend.lessThanEqual(float(0.5)), darkResult, lightResult)
74
+ }
75
+
76
+ function difference(base: Node, blend: Node): Node {
77
+ return abs(base.sub(blend))
78
+ }
79
+
80
+ function exclusion(base: Node, blend: Node): Node {
81
+ return base.add(blend).sub(float(2).mul(base).mul(blend))
82
+ }
83
+
84
+ function lum(color: Node): Node {
85
+ return dot(color, vec3(0.2126, 0.7152, 0.0722))
86
+ }
87
+
88
+ function clipColor(color: Node): Node {
89
+ const luma = lum(color)
90
+ const colorMin = min(color.x, min(color.y, color.z))
91
+ const lowClipped = color
92
+ .sub(luma)
93
+ .mul(luma.div(max(luma.sub(colorMin), float(1e-6))))
94
+ .add(luma)
95
+ const lowAdjusted = select(colorMin.lessThan(float(0)), lowClipped, color)
96
+ const maxAfterLow = max(lowAdjusted.x, max(lowAdjusted.y, lowAdjusted.z))
97
+ const excess = maxAfterLow.sub(float(1))
98
+ const highClipped = lowAdjusted
99
+ .sub(luma)
100
+ .mul(float(1).sub(luma).div(max(excess, float(1e-6))))
101
+ .add(luma)
102
+
103
+ return select(maxAfterLow.greaterThan(float(1)), highClipped, lowAdjusted)
104
+ }
105
+
106
+ function setLum(color: Node, nextLum: Node): Node {
107
+ return clipColor(color.add(nextLum.sub(lum(color))))
108
+ }
109
+
110
+ function sat(color: Node): Node {
111
+ return max(color.x, max(color.y, color.z)).sub(min(color.x, min(color.y, color.z)))
112
+ }
113
+
114
+ function setSat(color: Node, nextSat: Node): Node {
115
+ const red = color.x
116
+ const green = color.y
117
+ const blue = color.z
118
+ const colorMin = min(red, min(green, blue))
119
+ const colorMax = max(red, max(green, blue))
120
+ const delta = colorMax.sub(colorMin)
121
+ const scale = select(delta.greaterThan(float(0)), nextSat.div(delta), float(0))
122
+ const redOut = select(
123
+ red.lessThanEqual(colorMin),
124
+ float(0),
125
+ select(red.greaterThanEqual(colorMax), nextSat, red.sub(colorMin).mul(scale)),
126
+ )
127
+ const greenOut = select(
128
+ green.lessThanEqual(colorMin),
129
+ float(0),
130
+ select(green.greaterThanEqual(colorMax), nextSat, green.sub(colorMin).mul(scale)),
131
+ )
132
+ const blueOut = select(
133
+ blue.lessThanEqual(colorMin),
134
+ float(0),
135
+ select(blue.greaterThanEqual(colorMax), nextSat, blue.sub(colorMin).mul(scale)),
136
+ )
137
+
138
+ return vec3(redOut, greenOut, blueOut)
139
+ }
140
+
141
+ function hue(base: Node, blend: Node): Node {
142
+ return setLum(setSat(blend, sat(base)), lum(base))
143
+ }
144
+
145
+ function saturation(base: Node, blend: Node): Node {
146
+ return setLum(setSat(base, sat(blend)), lum(base))
147
+ }
148
+
149
+ function color(base: Node, blend: Node): Node {
150
+ return setLum(blend, lum(base))
151
+ }
152
+
153
+ function luminosity(base: Node, blend: Node): Node {
154
+ return setLum(base, lum(blend))
155
+ }
156
+
157
+ export function buildBlendNode(
158
+ mode: string,
159
+ base: Node,
160
+ blend: Node,
161
+ opacity: Node,
162
+ compositeMode: "filter" | "mask" = "filter",
163
+ ): Node {
164
+ const baseRgb = base.rgb
165
+ const blendRgb = blend.rgb
166
+ const normalizedOpacity = float(clamp(opacity, float(0), float(1)))
167
+
168
+ let composited: Node
169
+
170
+ switch (mode) {
171
+ case "multiply":
172
+ composited = multiply(baseRgb, blendRgb)
173
+ break
174
+ case "screen":
175
+ composited = screen(baseRgb, blendRgb)
176
+ break
177
+ case "overlay":
178
+ composited = overlay(baseRgb, blendRgb)
179
+ break
180
+ case "darken":
181
+ composited = darken(baseRgb, blendRgb)
182
+ break
183
+ case "lighten":
184
+ composited = lighten(baseRgb, blendRgb)
185
+ break
186
+ case "color-dodge":
187
+ composited = colorDodge(baseRgb, blendRgb)
188
+ break
189
+ case "color-burn":
190
+ composited = colorBurn(baseRgb, blendRgb)
191
+ break
192
+ case "hard-light":
193
+ composited = hardLight(baseRgb, blendRgb)
194
+ break
195
+ case "soft-light":
196
+ composited = softLight(baseRgb, blendRgb)
197
+ break
198
+ case "difference":
199
+ composited = difference(baseRgb, blendRgb)
200
+ break
201
+ case "exclusion":
202
+ composited = exclusion(baseRgb, blendRgb)
203
+ break
204
+ case "hue":
205
+ composited = hue(baseRgb, blendRgb)
206
+ break
207
+ case "saturation":
208
+ composited = saturation(baseRgb, blendRgb)
209
+ break
210
+ case "color":
211
+ composited = color(baseRgb, blendRgb)
212
+ break
213
+ case "luminosity":
214
+ composited = luminosity(baseRgb, blendRgb)
215
+ break
216
+ default:
217
+ composited = normal(baseRgb, blendRgb)
218
+ break
219
+ }
220
+
221
+ if (compositeMode === "filter") {
222
+ return vec4(mix(baseRgb, composited, normalizedOpacity), float(1))
223
+ }
224
+
225
+ const maskLuma = float(dot(blendRgb, vec3(0.2126, 0.7152, 0.0722)))
226
+ const maskStrength = mix(float(1), clamp(maskLuma, float(0), float(1)), normalizedOpacity)
227
+
228
+ return vec4(baseRgb.mul(maskStrength), float(1))
229
+ }
@@ -0,0 +1,54 @@
1
+ import { createRuntimeClock } from "../runtime-clock"
2
+ import { resolveEvaluatedLayers } from "../timeline"
3
+ import type { ShaderLabConfig, ShaderLabLayerConfig } from "../types"
4
+
5
+ export interface RendererSize {
6
+ height: number
7
+ width: number
8
+ }
9
+
10
+ export interface ProjectClock {
11
+ delta: number
12
+ duration: number
13
+ loop: boolean
14
+ time: number
15
+ }
16
+
17
+ export interface RendererFrame {
18
+ clock: ProjectClock
19
+ layers: ShaderLabLayerConfig[]
20
+ logicalSize: ShaderLabConfig["composition"]
21
+ outputSize: RendererSize
22
+ pixelRatio: number
23
+ viewportSize: RendererSize
24
+ }
25
+
26
+ export interface RuntimeRenderer {
27
+ dispose(): void
28
+ initialize(): Promise<void>
29
+ render(frame: RendererFrame): boolean
30
+ resize(size: RendererSize, pixelRatio: number): void
31
+ }
32
+
33
+ export function buildRendererFrame(
34
+ config: ShaderLabConfig,
35
+ time: number,
36
+ delta: number,
37
+ pixelRatio: number,
38
+ viewportSize: RendererSize
39
+ ): RendererFrame {
40
+ const layers = resolveEvaluatedLayers(
41
+ config.layers,
42
+ config.timeline.tracks,
43
+ time
44
+ ).filter((layer) => layer.visible)
45
+
46
+ return {
47
+ clock: createRuntimeClock(config.timeline, time, delta),
48
+ layers,
49
+ logicalSize: viewportSize,
50
+ outputSize: viewportSize,
51
+ pixelRatio,
52
+ viewportSize,
53
+ }
54
+ }
@@ -0,0 +1,48 @@
1
+ import * as THREE from "three/webgpu"
2
+ import { PipelineManager } from "./pipeline-manager"
3
+ import type { RendererFrame, RuntimeRenderer } from "./contracts"
4
+
5
+ export function browserSupportsWebGPU(): boolean {
6
+ return typeof navigator !== "undefined" && "gpu" in navigator
7
+ }
8
+
9
+ export async function createWebGPURenderer(
10
+ canvas: HTMLCanvasElement,
11
+ onRuntimeError?: (message: string | null) => void,
12
+ ): Promise<RuntimeRenderer> {
13
+ const renderer = new THREE.WebGPURenderer({
14
+ alpha: false,
15
+ antialias: true,
16
+ canvas,
17
+ })
18
+ let pipeline: PipelineManager | null = null
19
+
20
+ return {
21
+ async initialize() {
22
+ await renderer.init()
23
+ renderer.setClearColor("#0a0d10", 1)
24
+ },
25
+
26
+ resize(size, pixelRatio) {
27
+ renderer.setPixelRatio(pixelRatio)
28
+ renderer.setSize(size.width, size.height, false)
29
+ pipeline?.resize(size)
30
+ },
31
+
32
+ render(frame: RendererFrame) {
33
+ if (!pipeline) {
34
+ pipeline = new PipelineManager(renderer, frame.viewportSize, onRuntimeError)
35
+ }
36
+
37
+ pipeline.updateLogicalSize(frame.logicalSize)
38
+ pipeline.syncLayers([...frame.layers].reverse())
39
+ return pipeline.render(frame.clock.time, frame.clock.delta)
40
+ },
41
+
42
+ dispose() {
43
+ renderer.setAnimationLoop(null)
44
+ pipeline?.dispose()
45
+ renderer.dispose()
46
+ },
47
+ }
48
+ }