@triforge/shader-core 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 (297) hide show
  1. package/README.md +90 -0
  2. package/dist/bundle.js +5578 -0
  3. package/dist/core/CompileContext.d.ts +60 -0
  4. package/dist/core/CompileContext.d.ts.map +1 -0
  5. package/dist/core/CompileContext.js +276 -0
  6. package/dist/core/InputNode.d.ts +11 -0
  7. package/dist/core/InputNode.d.ts.map +1 -0
  8. package/dist/core/InputNode.js +13 -0
  9. package/dist/core/InputSocket.d.ts +21 -0
  10. package/dist/core/InputSocket.d.ts.map +1 -0
  11. package/dist/core/InputSocket.js +23 -0
  12. package/dist/core/OutputNode.d.ts +30 -0
  13. package/dist/core/OutputNode.d.ts.map +1 -0
  14. package/dist/core/OutputNode.js +60 -0
  15. package/dist/core/OutputSocket.d.ts +18 -0
  16. package/dist/core/OutputSocket.d.ts.map +1 -0
  17. package/dist/core/OutputSocket.js +16 -0
  18. package/dist/core/ProcessNode.d.ts +8 -0
  19. package/dist/core/ProcessNode.d.ts.map +1 -0
  20. package/dist/core/ProcessNode.js +7 -0
  21. package/dist/core/ShaderConfig.d.ts +13 -0
  22. package/dist/core/ShaderConfig.d.ts.map +1 -0
  23. package/dist/core/ShaderConfig.js +11 -0
  24. package/dist/core/ShaderNode.d.ts +114 -0
  25. package/dist/core/ShaderNode.d.ts.map +1 -0
  26. package/dist/core/ShaderNode.js +156 -0
  27. package/dist/core/ShaderNodeError.d.ts +32 -0
  28. package/dist/core/ShaderNodeError.d.ts.map +1 -0
  29. package/dist/core/ShaderNodeError.js +61 -0
  30. package/dist/core/SocketType.d.ts +12 -0
  31. package/dist/core/SocketType.d.ts.map +1 -0
  32. package/dist/core/SocketType.js +7 -0
  33. package/dist/index.d.ts +164 -0
  34. package/dist/index.d.ts.map +1 -0
  35. package/dist/index.js +108 -0
  36. package/dist/nodes/input/Attribute.d.ts +45 -0
  37. package/dist/nodes/input/Attribute.d.ts.map +1 -0
  38. package/dist/nodes/input/Attribute.js +58 -0
  39. package/dist/nodes/input/CameraData.d.ts +21 -0
  40. package/dist/nodes/input/CameraData.d.ts.map +1 -0
  41. package/dist/nodes/input/CameraData.js +33 -0
  42. package/dist/nodes/input/ColorAttribute.d.ts +28 -0
  43. package/dist/nodes/input/ColorAttribute.d.ts.map +1 -0
  44. package/dist/nodes/input/ColorAttribute.js +32 -0
  45. package/dist/nodes/input/Geometry.d.ts +23 -0
  46. package/dist/nodes/input/Geometry.d.ts.map +1 -0
  47. package/dist/nodes/input/Geometry.js +38 -0
  48. package/dist/nodes/input/HairInfo.d.ts +38 -0
  49. package/dist/nodes/input/HairInfo.d.ts.map +1 -0
  50. package/dist/nodes/input/HairInfo.js +50 -0
  51. package/dist/nodes/input/LayerWeight.d.ts +26 -0
  52. package/dist/nodes/input/LayerWeight.d.ts.map +1 -0
  53. package/dist/nodes/input/LayerWeight.js +35 -0
  54. package/dist/nodes/input/LightPath.d.ts +60 -0
  55. package/dist/nodes/input/LightPath.d.ts.map +1 -0
  56. package/dist/nodes/input/LightPath.js +112 -0
  57. package/dist/nodes/input/ObjectInfo.d.ts +22 -0
  58. package/dist/nodes/input/ObjectInfo.d.ts.map +1 -0
  59. package/dist/nodes/input/ObjectInfo.js +41 -0
  60. package/dist/nodes/input/OceanAttribute.d.ts +32 -0
  61. package/dist/nodes/input/OceanAttribute.d.ts.map +1 -0
  62. package/dist/nodes/input/OceanAttribute.js +38 -0
  63. package/dist/nodes/input/ParticleInfo.d.ts +31 -0
  64. package/dist/nodes/input/ParticleInfo.d.ts.map +1 -0
  65. package/dist/nodes/input/ParticleInfo.js +44 -0
  66. package/dist/nodes/input/RGB.d.ts +19 -0
  67. package/dist/nodes/input/RGB.d.ts.map +1 -0
  68. package/dist/nodes/input/RGB.js +23 -0
  69. package/dist/nodes/input/ScreenCamera.d.ts +37 -0
  70. package/dist/nodes/input/ScreenCamera.d.ts.map +1 -0
  71. package/dist/nodes/input/ScreenCamera.js +59 -0
  72. package/dist/nodes/input/Tangent.d.ts +21 -0
  73. package/dist/nodes/input/Tangent.d.ts.map +1 -0
  74. package/dist/nodes/input/Tangent.js +30 -0
  75. package/dist/nodes/input/TextureCoordinate.d.ts +17 -0
  76. package/dist/nodes/input/TextureCoordinate.d.ts.map +1 -0
  77. package/dist/nodes/input/TextureCoordinate.js +24 -0
  78. package/dist/nodes/input/UVMap.d.ts +20 -0
  79. package/dist/nodes/input/UVMap.d.ts.map +1 -0
  80. package/dist/nodes/input/UVMap.js +23 -0
  81. package/dist/nodes/input/Value.d.ts +19 -0
  82. package/dist/nodes/input/Value.d.ts.map +1 -0
  83. package/dist/nodes/input/Value.js +22 -0
  84. package/dist/nodes/input/Wireframe.d.ts +25 -0
  85. package/dist/nodes/input/Wireframe.d.ts.map +1 -0
  86. package/dist/nodes/input/Wireframe.js +30 -0
  87. package/dist/nodes/output/Displacement.d.ts +28 -0
  88. package/dist/nodes/output/Displacement.d.ts.map +1 -0
  89. package/dist/nodes/output/Displacement.js +34 -0
  90. package/dist/nodes/output/MaterialOutput.d.ts +43 -0
  91. package/dist/nodes/output/MaterialOutput.d.ts.map +1 -0
  92. package/dist/nodes/output/MaterialOutput.js +118 -0
  93. package/dist/nodes/output/ScreenOutput.d.ts +38 -0
  94. package/dist/nodes/output/ScreenOutput.d.ts.map +1 -0
  95. package/dist/nodes/output/ScreenOutput.js +88 -0
  96. package/dist/nodes/process/AddShader.d.ts +30 -0
  97. package/dist/nodes/process/AddShader.d.ts.map +1 -0
  98. package/dist/nodes/process/AddShader.js +36 -0
  99. package/dist/nodes/process/AnimatedNoiseTexture.d.ts +39 -0
  100. package/dist/nodes/process/AnimatedNoiseTexture.d.ts.map +1 -0
  101. package/dist/nodes/process/AnimatedNoiseTexture.js +93 -0
  102. package/dist/nodes/process/Blackbody.d.ts +29 -0
  103. package/dist/nodes/process/Blackbody.d.ts.map +1 -0
  104. package/dist/nodes/process/Blackbody.js +50 -0
  105. package/dist/nodes/process/BrickTexture.d.ts +36 -0
  106. package/dist/nodes/process/BrickTexture.d.ts.map +1 -0
  107. package/dist/nodes/process/BrickTexture.js +71 -0
  108. package/dist/nodes/process/BrightContrast.d.ts +30 -0
  109. package/dist/nodes/process/BrightContrast.d.ts.map +1 -0
  110. package/dist/nodes/process/BrightContrast.js +41 -0
  111. package/dist/nodes/process/Bump.d.ts +31 -0
  112. package/dist/nodes/process/Bump.d.ts.map +1 -0
  113. package/dist/nodes/process/Bump.js +65 -0
  114. package/dist/nodes/process/CheckerTexture.d.ts +30 -0
  115. package/dist/nodes/process/CheckerTexture.d.ts.map +1 -0
  116. package/dist/nodes/process/CheckerTexture.js +48 -0
  117. package/dist/nodes/process/Clamp.d.ts +32 -0
  118. package/dist/nodes/process/Clamp.d.ts.map +1 -0
  119. package/dist/nodes/process/Clamp.js +37 -0
  120. package/dist/nodes/process/ColorRamp.d.ts +28 -0
  121. package/dist/nodes/process/ColorRamp.d.ts.map +1 -0
  122. package/dist/nodes/process/ColorRamp.js +49 -0
  123. package/dist/nodes/process/CombineColor.d.ts +34 -0
  124. package/dist/nodes/process/CombineColor.d.ts.map +1 -0
  125. package/dist/nodes/process/CombineColor.js +69 -0
  126. package/dist/nodes/process/CombineRGB.d.ts +29 -0
  127. package/dist/nodes/process/CombineRGB.d.ts.map +1 -0
  128. package/dist/nodes/process/CombineRGB.js +33 -0
  129. package/dist/nodes/process/CombineXYZ.d.ts +29 -0
  130. package/dist/nodes/process/CombineXYZ.d.ts.map +1 -0
  131. package/dist/nodes/process/CombineXYZ.js +33 -0
  132. package/dist/nodes/process/DiffuseBSDF.d.ts +30 -0
  133. package/dist/nodes/process/DiffuseBSDF.d.ts.map +1 -0
  134. package/dist/nodes/process/DiffuseBSDF.js +43 -0
  135. package/dist/nodes/process/Emission.d.ts +30 -0
  136. package/dist/nodes/process/Emission.d.ts.map +1 -0
  137. package/dist/nodes/process/Emission.js +36 -0
  138. package/dist/nodes/process/EnvironmentTexture.d.ts +41 -0
  139. package/dist/nodes/process/EnvironmentTexture.d.ts.map +1 -0
  140. package/dist/nodes/process/EnvironmentTexture.js +65 -0
  141. package/dist/nodes/process/FloatCurve.d.ts +34 -0
  142. package/dist/nodes/process/FloatCurve.d.ts.map +1 -0
  143. package/dist/nodes/process/FloatCurve.js +46 -0
  144. package/dist/nodes/process/Fresnel.d.ts +36 -0
  145. package/dist/nodes/process/Fresnel.d.ts.map +1 -0
  146. package/dist/nodes/process/Fresnel.js +53 -0
  147. package/dist/nodes/process/Gamma.d.ts +29 -0
  148. package/dist/nodes/process/Gamma.d.ts.map +1 -0
  149. package/dist/nodes/process/Gamma.js +35 -0
  150. package/dist/nodes/process/GlassBSDF.d.ts +31 -0
  151. package/dist/nodes/process/GlassBSDF.d.ts.map +1 -0
  152. package/dist/nodes/process/GlassBSDF.js +51 -0
  153. package/dist/nodes/process/GlossyBSDF.d.ts +30 -0
  154. package/dist/nodes/process/GlossyBSDF.d.ts.map +1 -0
  155. package/dist/nodes/process/GlossyBSDF.js +50 -0
  156. package/dist/nodes/process/GradientTexture.d.ts +31 -0
  157. package/dist/nodes/process/GradientTexture.d.ts.map +1 -0
  158. package/dist/nodes/process/GradientTexture.js +49 -0
  159. package/dist/nodes/process/HashValue.d.ts +30 -0
  160. package/dist/nodes/process/HashValue.d.ts.map +1 -0
  161. package/dist/nodes/process/HashValue.js +34 -0
  162. package/dist/nodes/process/HueSaturationValue.d.ts +32 -0
  163. package/dist/nodes/process/HueSaturationValue.d.ts.map +1 -0
  164. package/dist/nodes/process/HueSaturationValue.js +58 -0
  165. package/dist/nodes/process/ImageTexture.d.ts +34 -0
  166. package/dist/nodes/process/ImageTexture.d.ts.map +1 -0
  167. package/dist/nodes/process/ImageTexture.js +53 -0
  168. package/dist/nodes/process/InvertColor.d.ts +29 -0
  169. package/dist/nodes/process/InvertColor.d.ts.map +1 -0
  170. package/dist/nodes/process/InvertColor.js +35 -0
  171. package/dist/nodes/process/MagicTexture.d.ts +30 -0
  172. package/dist/nodes/process/MagicTexture.d.ts.map +1 -0
  173. package/dist/nodes/process/MagicTexture.js +54 -0
  174. package/dist/nodes/process/MapRange.d.ts +38 -0
  175. package/dist/nodes/process/MapRange.d.ts.map +1 -0
  176. package/dist/nodes/process/MapRange.js +52 -0
  177. package/dist/nodes/process/Mapping.d.ts +37 -0
  178. package/dist/nodes/process/Mapping.d.ts.map +1 -0
  179. package/dist/nodes/process/Mapping.js +57 -0
  180. package/dist/nodes/process/Math.d.ts +40 -0
  181. package/dist/nodes/process/Math.d.ts.map +1 -0
  182. package/dist/nodes/process/Math.js +100 -0
  183. package/dist/nodes/process/MixRGB.d.ts +35 -0
  184. package/dist/nodes/process/MixRGB.d.ts.map +1 -0
  185. package/dist/nodes/process/MixRGB.js +63 -0
  186. package/dist/nodes/process/MixShader.d.ts +35 -0
  187. package/dist/nodes/process/MixShader.d.ts.map +1 -0
  188. package/dist/nodes/process/MixShader.js +47 -0
  189. package/dist/nodes/process/MusgraveTexture.d.ts +36 -0
  190. package/dist/nodes/process/MusgraveTexture.d.ts.map +1 -0
  191. package/dist/nodes/process/MusgraveTexture.js +70 -0
  192. package/dist/nodes/process/NoiseTexture.d.ts +31 -0
  193. package/dist/nodes/process/NoiseTexture.d.ts.map +1 -0
  194. package/dist/nodes/process/NoiseTexture.js +78 -0
  195. package/dist/nodes/process/Normal.d.ts +30 -0
  196. package/dist/nodes/process/Normal.d.ts.map +1 -0
  197. package/dist/nodes/process/Normal.js +38 -0
  198. package/dist/nodes/process/NormalMap.d.ts +34 -0
  199. package/dist/nodes/process/NormalMap.d.ts.map +1 -0
  200. package/dist/nodes/process/NormalMap.js +54 -0
  201. package/dist/nodes/process/PrincipledBSDF.d.ts +32 -0
  202. package/dist/nodes/process/PrincipledBSDF.d.ts.map +1 -0
  203. package/dist/nodes/process/PrincipledBSDF.js +75 -0
  204. package/dist/nodes/process/PrincipledHair.d.ts +63 -0
  205. package/dist/nodes/process/PrincipledHair.d.ts.map +1 -0
  206. package/dist/nodes/process/PrincipledHair.js +137 -0
  207. package/dist/nodes/process/PrincipledVolume.d.ts +37 -0
  208. package/dist/nodes/process/PrincipledVolume.d.ts.map +1 -0
  209. package/dist/nodes/process/PrincipledVolume.js +67 -0
  210. package/dist/nodes/process/RGBCurves.d.ts +45 -0
  211. package/dist/nodes/process/RGBCurves.d.ts.map +1 -0
  212. package/dist/nodes/process/RGBCurves.js +81 -0
  213. package/dist/nodes/process/RGBtoBW.d.ts +28 -0
  214. package/dist/nodes/process/RGBtoBW.d.ts.map +1 -0
  215. package/dist/nodes/process/RGBtoBW.js +31 -0
  216. package/dist/nodes/process/RefractionBSDF.d.ts +32 -0
  217. package/dist/nodes/process/RefractionBSDF.d.ts.map +1 -0
  218. package/dist/nodes/process/RefractionBSDF.js +46 -0
  219. package/dist/nodes/process/SchwarzschildMarch.d.ts +56 -0
  220. package/dist/nodes/process/SchwarzschildMarch.d.ts.map +1 -0
  221. package/dist/nodes/process/SchwarzschildMarch.js +306 -0
  222. package/dist/nodes/process/SeparateColor.d.ts +33 -0
  223. package/dist/nodes/process/SeparateColor.d.ts.map +1 -0
  224. package/dist/nodes/process/SeparateColor.js +79 -0
  225. package/dist/nodes/process/SeparateRGB.d.ts +27 -0
  226. package/dist/nodes/process/SeparateRGB.d.ts.map +1 -0
  227. package/dist/nodes/process/SeparateRGB.js +31 -0
  228. package/dist/nodes/process/SeparateXYZ.d.ts +27 -0
  229. package/dist/nodes/process/SeparateXYZ.d.ts.map +1 -0
  230. package/dist/nodes/process/SeparateXYZ.js +31 -0
  231. package/dist/nodes/process/ShaderScript.d.ts +95 -0
  232. package/dist/nodes/process/ShaderScript.d.ts.map +1 -0
  233. package/dist/nodes/process/ShaderScript.js +119 -0
  234. package/dist/nodes/process/ShaderToRGB.d.ts +28 -0
  235. package/dist/nodes/process/ShaderToRGB.d.ts.map +1 -0
  236. package/dist/nodes/process/ShaderToRGB.js +33 -0
  237. package/dist/nodes/process/SheenBSDF.d.ts +31 -0
  238. package/dist/nodes/process/SheenBSDF.d.ts.map +1 -0
  239. package/dist/nodes/process/SheenBSDF.js +49 -0
  240. package/dist/nodes/process/SpecularBSDF.d.ts +32 -0
  241. package/dist/nodes/process/SpecularBSDF.d.ts.map +1 -0
  242. package/dist/nodes/process/SpecularBSDF.js +54 -0
  243. package/dist/nodes/process/SubsurfaceScattering.d.ts +33 -0
  244. package/dist/nodes/process/SubsurfaceScattering.d.ts.map +1 -0
  245. package/dist/nodes/process/SubsurfaceScattering.js +46 -0
  246. package/dist/nodes/process/ToonBSDF.d.ts +31 -0
  247. package/dist/nodes/process/ToonBSDF.d.ts.map +1 -0
  248. package/dist/nodes/process/ToonBSDF.js +44 -0
  249. package/dist/nodes/process/TranslucentBSDF.d.ts +29 -0
  250. package/dist/nodes/process/TranslucentBSDF.d.ts.map +1 -0
  251. package/dist/nodes/process/TranslucentBSDF.js +39 -0
  252. package/dist/nodes/process/VectorCurves.d.ts +42 -0
  253. package/dist/nodes/process/VectorCurves.d.ts.map +1 -0
  254. package/dist/nodes/process/VectorCurves.js +71 -0
  255. package/dist/nodes/process/VectorMath.d.ts +38 -0
  256. package/dist/nodes/process/VectorMath.d.ts.map +1 -0
  257. package/dist/nodes/process/VectorMath.js +105 -0
  258. package/dist/nodes/process/VectorRotate.d.ts +34 -0
  259. package/dist/nodes/process/VectorRotate.d.ts.map +1 -0
  260. package/dist/nodes/process/VectorRotate.js +52 -0
  261. package/dist/nodes/process/VectorTransform.d.ts +36 -0
  262. package/dist/nodes/process/VectorTransform.d.ts.map +1 -0
  263. package/dist/nodes/process/VectorTransform.js +48 -0
  264. package/dist/nodes/process/VolumeAbsorption.d.ts +30 -0
  265. package/dist/nodes/process/VolumeAbsorption.d.ts.map +1 -0
  266. package/dist/nodes/process/VolumeAbsorption.js +36 -0
  267. package/dist/nodes/process/VolumeScatter.d.ts +31 -0
  268. package/dist/nodes/process/VolumeScatter.d.ts.map +1 -0
  269. package/dist/nodes/process/VolumeScatter.js +42 -0
  270. package/dist/nodes/process/VoronoiTexture.d.ts +38 -0
  271. package/dist/nodes/process/VoronoiTexture.d.ts.map +1 -0
  272. package/dist/nodes/process/VoronoiTexture.js +123 -0
  273. package/dist/nodes/process/WaveTexture.d.ts +39 -0
  274. package/dist/nodes/process/WaveTexture.d.ts.map +1 -0
  275. package/dist/nodes/process/WaveTexture.js +77 -0
  276. package/dist/nodes/process/Wavelength.d.ts +28 -0
  277. package/dist/nodes/process/Wavelength.d.ts.map +1 -0
  278. package/dist/nodes/process/Wavelength.js +43 -0
  279. package/dist/nodes/process/WhiteNoise.d.ts +27 -0
  280. package/dist/nodes/process/WhiteNoise.d.ts.map +1 -0
  281. package/dist/nodes/process/WhiteNoise.js +44 -0
  282. package/dist/nodes/shader/AmbientOcclusion.d.ts +47 -0
  283. package/dist/nodes/shader/AmbientOcclusion.d.ts.map +1 -0
  284. package/dist/nodes/shader/AmbientOcclusion.js +128 -0
  285. package/dist/nodes/shader/RayPortal.d.ts +57 -0
  286. package/dist/nodes/shader/RayPortal.d.ts.map +1 -0
  287. package/dist/nodes/shader/RayPortal.js +56 -0
  288. package/dist/shaders/color.d.ts +12 -0
  289. package/dist/shaders/color.d.ts.map +1 -0
  290. package/dist/shaders/color.js +42 -0
  291. package/dist/shaders/noise.d.ts +12 -0
  292. package/dist/shaders/noise.d.ts.map +1 -0
  293. package/dist/shaders/noise.js +70 -0
  294. package/dist/types/shader.d.ts +17 -0
  295. package/dist/types/shader.d.ts.map +1 -0
  296. package/dist/types/shader.js +1 -0
  297. package/package.json +44 -0
@@ -0,0 +1,95 @@
1
+ import { ProcessNode } from '../../core/ProcessNode.js';
2
+ import type { NodeMetadata } from '../../core/ShaderNode.js';
3
+ import type { CompileContext } from '../../core/CompileContext.js';
4
+ import type { OutputSocket } from '../../core/OutputSocket.js';
5
+ /**
6
+ * Declare an input socket: [glslType, defaultValue]
7
+ * 'float' → float (uniform or literal)
8
+ * 'color' → vec3 (uniform or literal hex / [r,g,b])
9
+ * 'vector' → vec2 (UV coordinates)
10
+ * 'shader' → vec3 (BSDF connection)
11
+ */
12
+ export type ScriptInputDecl = ['float' | 'color' | 'vector' | 'shader', unknown];
13
+ /** Output socket type map: socketName → glslType */
14
+ export type ScriptOutputDecl = Record<string, 'float' | 'color' | 'vector' | 'shader'>;
15
+ export interface ShaderScriptConfig {
16
+ /**
17
+ * Input sockets. Each entry is either:
18
+ * ['float'|'color'|'vector', defaultValue] — static or connectable socket
19
+ * OutputSocket — already-connected socket
20
+ */
21
+ inputs?: Record<string, ScriptInputDecl | OutputSocket>;
22
+ /** Output socket names and their types. */
23
+ outputs?: ScriptOutputDecl;
24
+ /**
25
+ * GLSL body. Input names are available as local variables.
26
+ * Output names must be assigned before the block ends.
27
+ *
28
+ * @example
29
+ * glsl: `
30
+ * result = sin(myScale * 6.28318) * 0.5 + 0.5;
31
+ * outColor = mix(colorA, colorB, result);
32
+ * `
33
+ */
34
+ glsl: string;
35
+ /**
36
+ * Optional GLSL helper functions emitted once above main().
37
+ * Use this for custom math utilities, noise functions, etc.
38
+ */
39
+ defs?: string;
40
+ /** Display name shown in error messages and metadata. */
41
+ label?: string;
42
+ }
43
+ /**
44
+ * ShaderScript — Blender "Script Node (OSL)" equivalent for st-shader-core.
45
+ *
46
+ * Wraps a block of custom GLSL as a first-class node in the shader graph.
47
+ * Input and output sockets connect to all other nodes normally.
48
+ *
49
+ * Inside the GLSL body:
50
+ * • Input sockets are available as local variables with the exact name you declared.
51
+ * • Output sockets must be assigned by name before the block ends.
52
+ * • GLSL types: 'float' → float, 'color'/'shader' → vec3, 'vector' → vec2
53
+ *
54
+ * @example
55
+ * const ripple = new ShaderScript({
56
+ * inputs: {
57
+ * uv: textureCoord.output('UV'), // connected vec2
58
+ * speed: ['float', 1.0], // animatable float uniform
59
+ * color: ['color', '#0055ff'], // live vec3 uniform
60
+ * },
61
+ * outputs: { result: 'float', tinted: 'color' },
62
+ * glsl: `
63
+ * float wave = sin(uv.x * 12.566 - speed * uTime) * 0.5 + 0.5;
64
+ * result = wave;
65
+ * tinted = color * wave;
66
+ * `,
67
+ * })
68
+ */
69
+ export declare class ShaderScript extends ProcessNode {
70
+ get nodeType(): string;
71
+ static instanceSpecificDef: boolean;
72
+ get metadata(): NodeMetadata;
73
+ private readonly _glsl;
74
+ private readonly _defs;
75
+ private readonly _label;
76
+ private readonly _outputDecl;
77
+ private readonly _inputs;
78
+ private readonly _outputs;
79
+ constructor(config: ShaderScriptConfig);
80
+ getInputSockets(): Record<string, import("../../core/InputSocket.js").InputSocket<unknown>>;
81
+ getOutputSockets(): Record<string, OutputSocket>;
82
+ /** Emit any helper functions the user declared. */
83
+ compileDefs(): string;
84
+ /**
85
+ * Emit the script body as a GLSL block:
86
+ * 1. Declare each input as a local variable (resolved from graph).
87
+ * 2. Declare each output as a local variable.
88
+ * 3. Execute the user's GLSL body in a scoped block.
89
+ * 4. Copy local output vars → canonical output variable names.
90
+ */
91
+ compileCall(ctx: CompileContext): string;
92
+ private _socketGlslType;
93
+ private _declGlslType;
94
+ }
95
+ //# sourceMappingURL=ShaderScript.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShaderScript.d.ts","sourceRoot":"","sources":["../../../src/nodes/process/ShaderScript.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAK9D;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,EAAE,OAAO,CAAC,CAAA;AAEhF,oDAAoD;AACpD,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC,CAAA;AAEtF,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,MAAM,CAAC,EAAG,MAAM,CAAC,MAAM,EAAE,eAAe,GAAG,YAAY,CAAC,CAAA;IAExD,2CAA2C;IAC3C,OAAO,CAAC,EAAE,gBAAgB,CAAA;IAE1B;;;;;;;;;OASG;IACH,IAAI,EAAE,MAAM,CAAA;IAEZ;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IAEb,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAID;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qBAAa,YAAa,SAAQ,WAAW;IAC3C,IAAI,QAAQ,WAA4B;IACxC,MAAM,CAAC,mBAAmB,UAAO;IAEjC,IAAI,QAAQ,IAAI,YAAY,CAQ3B;IAED,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IACrC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmB;IAC/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA+E;IACvG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkC;gBAE/C,MAAM,EAAE,kBAAkB;IA8BtC,eAAe;IACf,gBAAgB;IAEhB,mDAAmD;IACnD,WAAW,IAAI,MAAM;IAErB;;;;;;OAMG;IACH,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM;IAkCxC,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,aAAa;CAKtB"}
@@ -0,0 +1,119 @@
1
+ import { ProcessNode } from '../../core/ProcessNode.js';
2
+ // ── ShaderScript node ─────────────────────────────────────────────────────────
3
+ /**
4
+ * ShaderScript — Blender "Script Node (OSL)" equivalent for st-shader-core.
5
+ *
6
+ * Wraps a block of custom GLSL as a first-class node in the shader graph.
7
+ * Input and output sockets connect to all other nodes normally.
8
+ *
9
+ * Inside the GLSL body:
10
+ * • Input sockets are available as local variables with the exact name you declared.
11
+ * • Output sockets must be assigned by name before the block ends.
12
+ * • GLSL types: 'float' → float, 'color'/'shader' → vec3, 'vector' → vec2
13
+ *
14
+ * @example
15
+ * const ripple = new ShaderScript({
16
+ * inputs: {
17
+ * uv: textureCoord.output('UV'), // connected vec2
18
+ * speed: ['float', 1.0], // animatable float uniform
19
+ * color: ['color', '#0055ff'], // live vec3 uniform
20
+ * },
21
+ * outputs: { result: 'float', tinted: 'color' },
22
+ * glsl: `
23
+ * float wave = sin(uv.x * 12.566 - speed * uTime) * 0.5 + 0.5;
24
+ * result = wave;
25
+ * tinted = color * wave;
26
+ * `,
27
+ * })
28
+ */
29
+ export class ShaderScript extends ProcessNode {
30
+ get nodeType() { return 'ShaderScript'; }
31
+ get metadata() {
32
+ return {
33
+ label: this._label,
34
+ category: 'Script',
35
+ color: '#336655',
36
+ cost: 'high',
37
+ costNote: 'Custom GLSL — performance depends on script content.',
38
+ };
39
+ }
40
+ constructor(config) {
41
+ super('ShaderScript');
42
+ this._glsl = config.glsl ?? '';
43
+ this._defs = config.defs ?? '';
44
+ this._label = config.label ?? 'Shader Script';
45
+ this._outputDecl = config.outputs ?? {};
46
+ // ── Build input defs + supplied maps ────────────────────────────────────
47
+ const defs = {};
48
+ const supplied = {};
49
+ for (const [name, spec] of Object.entries(config.inputs ?? {})) {
50
+ if (Array.isArray(spec)) {
51
+ // ['float'|'color'|'vector'|'shader', defaultValue]
52
+ const [type, defaultVal] = spec;
53
+ defs[name] = [type, defaultVal];
54
+ // Leave supplied[name] undefined → createInputs uses defs default
55
+ }
56
+ else {
57
+ // It's an OutputSocket (already connected)
58
+ const sock = spec;
59
+ defs[name] = [sock.type, null];
60
+ supplied[name] = sock;
61
+ }
62
+ }
63
+ this._inputs = this.createInputs(supplied, defs);
64
+ this._outputs = this.createOutputs(this._outputDecl);
65
+ }
66
+ getInputSockets() { return this._inputs; }
67
+ getOutputSockets() { return this._outputs; }
68
+ /** Emit any helper functions the user declared. */
69
+ compileDefs() { return this._defs.trim(); }
70
+ /**
71
+ * Emit the script body as a GLSL block:
72
+ * 1. Declare each input as a local variable (resolved from graph).
73
+ * 2. Declare each output as a local variable.
74
+ * 3. Execute the user's GLSL body in a scoped block.
75
+ * 4. Copy local output vars → canonical output variable names.
76
+ */
77
+ compileCall(ctx) {
78
+ const lines = [];
79
+ // ── 1. Inputs as local variables ─────────────────────────────────────────
80
+ for (const [name, socket] of Object.entries(this._inputs)) {
81
+ const glslType = this._socketGlslType(socket.type);
82
+ const resolved = ctx.resolveInput(socket);
83
+ lines.push(`${glslType} ${name} = ${resolved};`);
84
+ }
85
+ // ── 2. Output local variables ─────────────────────────────────────────────
86
+ for (const [name, type] of Object.entries(this._outputDecl)) {
87
+ const glslType = this._declGlslType(type);
88
+ lines.push(`${glslType} ${name};`);
89
+ }
90
+ // ── 3. User script body in a scoped block ─────────────────────────────────
91
+ lines.push('{');
92
+ for (const line of this._glsl.trim().split('\n')) {
93
+ lines.push(` ${line}`);
94
+ }
95
+ lines.push('}');
96
+ // ── 4. Copy locals → canonical output var names ───────────────────────────
97
+ for (const [name, type] of Object.entries(this._outputDecl)) {
98
+ const glslType = this._declGlslType(type);
99
+ lines.push(`${glslType} ${ctx.outputVar(this, name)} = ${name};`);
100
+ }
101
+ return lines.join('\n ');
102
+ }
103
+ // ── Helpers ──────────────────────────────────────────────────────────────────
104
+ _socketGlslType(type) {
105
+ if (type === 'float')
106
+ return 'float';
107
+ if (type === 'vector')
108
+ return 'vec2';
109
+ return 'vec3'; // 'color' | 'shader'
110
+ }
111
+ _declGlslType(type) {
112
+ if (type === 'float')
113
+ return 'float';
114
+ if (type === 'vector')
115
+ return 'vec2';
116
+ return 'vec3'; // 'color' | 'shader'
117
+ }
118
+ }
119
+ ShaderScript.instanceSpecificDef = true; // every script is unique — no dedup
@@ -0,0 +1,28 @@
1
+ import { ProcessNode } from '../../core/ProcessNode.js';
2
+ import type { NodeMetadata } from '../../core/ShaderNode.js';
3
+ import type { CompileContext } from '../../core/CompileContext.js';
4
+ import type { OutputSocket } from '../../core/OutputSocket.js';
5
+ export interface ShaderToRGBInputs {
6
+ shader?: OutputSocket;
7
+ }
8
+ /**
9
+ * Shader to RGB — Blender "Shader to RGB" converter node equivalent.
10
+ * Converts a BSDF shader output back into a colour for further processing.
11
+ * Useful for cel shading and NPR (non-photorealistic) rendering.
12
+ *
13
+ * Inputs: shader (BSDF)
14
+ * Outputs: Color (color), Alpha (float)
15
+ */
16
+ export declare class ShaderToRGB extends ProcessNode {
17
+ get nodeType(): string;
18
+ static instanceSpecificDef: boolean;
19
+ get metadata(): NodeMetadata;
20
+ private readonly _inputs;
21
+ private readonly _outputs;
22
+ constructor(inputs?: ShaderToRGBInputs);
23
+ getInputSockets(): Record<string, import("../../core/InputSocket.js").InputSocket<unknown>>;
24
+ getOutputSockets(): Record<string, OutputSocket>;
25
+ compileDefs(): string;
26
+ compileCall(ctx: CompileContext): string;
27
+ }
28
+ //# sourceMappingURL=ShaderToRGB.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShaderToRGB.d.ts","sourceRoot":"","sources":["../../../src/nodes/process/ShaderToRGB.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAE9D,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,YAAY,CAAA;CACtB;AAED;;;;;;;GAOG;AACH,qBAAa,WAAY,SAAQ,WAAW;IAC1C,IAAI,QAAQ,WAA2B;IACvC,MAAM,CAAC,mBAAmB,UAAQ;IAElC,IAAI,QAAQ,IAAI,YAAY,CAE3B;IAED,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2E;IACnG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmE;gBAEhF,MAAM,GAAE,iBAAsB;IAM1C,eAAe;IACf,gBAAgB;IAChB,WAAW;IAEX,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM;CASzC"}
@@ -0,0 +1,33 @@
1
+ import { ProcessNode } from '../../core/ProcessNode.js';
2
+ /**
3
+ * Shader to RGB — Blender "Shader to RGB" converter node equivalent.
4
+ * Converts a BSDF shader output back into a colour for further processing.
5
+ * Useful for cel shading and NPR (non-photorealistic) rendering.
6
+ *
7
+ * Inputs: shader (BSDF)
8
+ * Outputs: Color (color), Alpha (float)
9
+ */
10
+ export class ShaderToRGB extends ProcessNode {
11
+ get nodeType() { return 'ShaderToRGB'; }
12
+ get metadata() {
13
+ return { label: 'Shader to RGB', category: 'Converter', color: '#4a3a6a', cost: 'low' };
14
+ }
15
+ constructor(inputs = {}) {
16
+ super('ShaderToRGB');
17
+ this._inputs = this.createInputs(inputs, { shader: ['shader', null] });
18
+ this._outputs = this.createOutputs({ Color: 'color', Alpha: 'float' });
19
+ }
20
+ getInputSockets() { return this._inputs; }
21
+ getOutputSockets() { return this._outputs; }
22
+ compileDefs() { return ''; }
23
+ compileCall(ctx) {
24
+ const shader = ctx.resolveInput(this._inputs.shader);
25
+ const cv = ctx.outputVar(this, 'Color');
26
+ const av = ctx.outputVar(this, 'Alpha');
27
+ return [
28
+ `vec3 ${cv} = ${shader};`,
29
+ `float ${av} = 1.0;`,
30
+ ].join('\n ');
31
+ }
32
+ }
33
+ ShaderToRGB.instanceSpecificDef = false;
@@ -0,0 +1,31 @@
1
+ import { ProcessNode } from '../../core/ProcessNode.js';
2
+ import type { NodeMetadata } from '../../core/ShaderNode.js';
3
+ import type { CompileContext } from '../../core/CompileContext.js';
4
+ import type { OutputSocket } from '../../core/OutputSocket.js';
5
+ export interface SheenBSDFInputs {
6
+ color?: OutputSocket | string;
7
+ roughness?: OutputSocket | number;
8
+ normal?: OutputSocket;
9
+ }
10
+ /**
11
+ * Sheen BSDF — Blender "Sheen BSDF" node equivalent.
12
+ * Simulates fuzzy micro-fibre cloth surfaces — velvet, satin, felt.
13
+ * Uses Ashikhmin sheen model approximation.
14
+ *
15
+ * Inputs: color, roughness, normal
16
+ * Outputs: BSDF (shader)
17
+ */
18
+ export declare class SheenBSDF extends ProcessNode {
19
+ get nodeType(): string;
20
+ static instanceSpecificDef: boolean;
21
+ get metadata(): NodeMetadata;
22
+ static glslFunction: string;
23
+ private readonly _inputs;
24
+ private readonly _outputs;
25
+ constructor(inputs?: SheenBSDFInputs);
26
+ getInputSockets(): Record<string, import("../../core/InputSocket.js").InputSocket<unknown>>;
27
+ getOutputSockets(): Record<string, OutputSocket>;
28
+ compileDefs(): string;
29
+ compileCall(ctx: CompileContext): string;
30
+ }
31
+ //# sourceMappingURL=SheenBSDF.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SheenBSDF.d.ts","sourceRoot":"","sources":["../../../src/nodes/process/SheenBSDF.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAE9D,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAM,YAAY,GAAG,MAAM,CAAA;IACjC,SAAS,CAAC,EAAE,YAAY,GAAG,MAAM,CAAA;IACjC,MAAM,CAAC,EAAK,YAAY,CAAA;CACzB;AAED;;;;;;;GAOG;AACH,qBAAa,SAAU,SAAQ,WAAW;IACxC,IAAI,QAAQ,WAAyB;IACrC,MAAM,CAAC,mBAAmB,UAAQ;IAElC,IAAI,QAAQ,IAAI,YAAY,CAE3B;IAED,MAAM,CAAC,YAAY,SAYnB;IAEA,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2E;IACnG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmE;gBAEhF,MAAM,GAAE,eAAoB;IAUxC,eAAe;IACf,gBAAgB;IAChB,WAAW;IAEX,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM;CAQzC"}
@@ -0,0 +1,49 @@
1
+ import { ProcessNode } from '../../core/ProcessNode.js';
2
+ /**
3
+ * Sheen BSDF — Blender "Sheen BSDF" node equivalent.
4
+ * Simulates fuzzy micro-fibre cloth surfaces — velvet, satin, felt.
5
+ * Uses Ashikhmin sheen model approximation.
6
+ *
7
+ * Inputs: color, roughness, normal
8
+ * Outputs: BSDF (shader)
9
+ */
10
+ export class SheenBSDF extends ProcessNode {
11
+ get nodeType() { return 'SheenBSDF'; }
12
+ get metadata() {
13
+ return { label: 'Sheen BSDF', category: 'Shader', color: '#336699', cost: 'medium' };
14
+ }
15
+ constructor(inputs = {}) {
16
+ super('SheenBSDF');
17
+ this._inputs = this.createInputs(inputs, {
18
+ color: ['color', '#ffffff'],
19
+ roughness: ['float', inputs.roughness ?? 0.5],
20
+ normal: ['color', null],
21
+ });
22
+ this._outputs = this.createOutputs({ BSDF: 'shader' });
23
+ }
24
+ getInputSockets() { return this._inputs; }
25
+ getOutputSockets() { return this._outputs; }
26
+ compileDefs() { return SheenBSDF.glslFunction; }
27
+ compileCall(ctx) {
28
+ const color = ctx.resolveInput(this._inputs.color);
29
+ const roughness = ctx.resolveInput(this._inputs.roughness);
30
+ const normal = this._inputs.normal.isConnected()
31
+ ? ctx.outputVar(this._inputs.normal.connection.node, this._inputs.normal.connection.name)
32
+ : 'normalize(vNormal)';
33
+ return `vec3 ${ctx.outputVar(this, 'BSDF')} = _st_sheenBSDF(${color}, ${roughness}, ${normal});`;
34
+ }
35
+ }
36
+ SheenBSDF.instanceSpecificDef = false;
37
+ SheenBSDF.glslFunction = `
38
+ vec3 _st_sheenBSDF(vec3 color, float roughness, vec3 N) {
39
+ vec3 V = normalize(cameraPosition - vPosition);
40
+ vec3 L = normalize(vec3(1.0, 2.0, 1.0));
41
+ vec3 H = normalize(L + V);
42
+ float NdotL = max(dot(N, L), 0.0);
43
+ float NdotV = max(dot(N, V), 0.0001);
44
+ float NdotH = max(dot(N, H), 0.0);
45
+ float sinThetaH = sqrt(max(1.0 - NdotH * NdotH, 0.0));
46
+ float r2 = roughness * roughness;
47
+ float sheen = (2.0 + 1.0 / r2) * pow(sinThetaH, 1.0 / r2) / (2.0 * 3.14159);
48
+ return color * sheen * NdotL / max(NdotL + NdotV - NdotL * NdotV, 0.0001) + color * 0.03;
49
+ }`;
@@ -0,0 +1,32 @@
1
+ import { ProcessNode } from '../../core/ProcessNode.js';
2
+ import type { NodeMetadata } from '../../core/ShaderNode.js';
3
+ import type { CompileContext } from '../../core/CompileContext.js';
4
+ import type { OutputSocket } from '../../core/OutputSocket.js';
5
+ export interface SpecularBSDFInputs {
6
+ baseColor?: OutputSocket | string;
7
+ specular?: OutputSocket | string;
8
+ roughness?: OutputSocket | number;
9
+ normal?: OutputSocket;
10
+ }
11
+ /**
12
+ * Specular BSDF — Blender "Specular BSDF" node equivalent.
13
+ * Specular workflow alternative to metalness-roughness PBR.
14
+ * Uses explicit specular colour rather than metallic factor.
15
+ *
16
+ * Inputs: baseColor, specular (color), roughness, normal
17
+ * Outputs: BSDF (shader)
18
+ */
19
+ export declare class SpecularBSDF extends ProcessNode {
20
+ get nodeType(): string;
21
+ static instanceSpecificDef: boolean;
22
+ get metadata(): NodeMetadata;
23
+ static glslFunction: string;
24
+ private readonly _inputs;
25
+ private readonly _outputs;
26
+ constructor(inputs?: SpecularBSDFInputs);
27
+ getInputSockets(): Record<string, import("../../core/InputSocket.js").InputSocket<unknown>>;
28
+ getOutputSockets(): Record<string, OutputSocket>;
29
+ compileDefs(): string;
30
+ compileCall(ctx: CompileContext): string;
31
+ }
32
+ //# sourceMappingURL=SpecularBSDF.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SpecularBSDF.d.ts","sourceRoot":"","sources":["../../../src/nodes/process/SpecularBSDF.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAE9D,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAI,YAAY,GAAG,MAAM,CAAA;IACnC,QAAQ,CAAC,EAAK,YAAY,GAAG,MAAM,CAAA;IACnC,SAAS,CAAC,EAAI,YAAY,GAAG,MAAM,CAAA;IACnC,MAAM,CAAC,EAAO,YAAY,CAAA;CAC3B;AAED;;;;;;;GAOG;AACH,qBAAa,YAAa,SAAQ,WAAW;IAC3C,IAAI,QAAQ,WAA4B;IACxC,MAAM,CAAC,mBAAmB,UAAQ;IAElC,IAAI,QAAQ,IAAI,YAAY,CAE3B;IAED,MAAM,CAAC,YAAY,SAenB;IAEA,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2E;IACnG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmE;gBAEhF,MAAM,GAAE,kBAAuB;IAW3C,eAAe;IACf,gBAAgB;IAChB,WAAW;IAEX,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM;CASzC"}
@@ -0,0 +1,54 @@
1
+ import { ProcessNode } from '../../core/ProcessNode.js';
2
+ /**
3
+ * Specular BSDF — Blender "Specular BSDF" node equivalent.
4
+ * Specular workflow alternative to metalness-roughness PBR.
5
+ * Uses explicit specular colour rather than metallic factor.
6
+ *
7
+ * Inputs: baseColor, specular (color), roughness, normal
8
+ * Outputs: BSDF (shader)
9
+ */
10
+ export class SpecularBSDF extends ProcessNode {
11
+ get nodeType() { return 'SpecularBSDF'; }
12
+ get metadata() {
13
+ return { label: 'Specular BSDF', category: 'Shader', color: '#336699', cost: 'medium' };
14
+ }
15
+ constructor(inputs = {}) {
16
+ super('SpecularBSDF');
17
+ this._inputs = this.createInputs(inputs, {
18
+ baseColor: ['color', '#ffffff'],
19
+ specular: ['color', '#888888'],
20
+ roughness: ['float', inputs.roughness ?? 0.5],
21
+ normal: ['color', null],
22
+ });
23
+ this._outputs = this.createOutputs({ BSDF: 'shader' });
24
+ }
25
+ getInputSockets() { return this._inputs; }
26
+ getOutputSockets() { return this._outputs; }
27
+ compileDefs() { return SpecularBSDF.glslFunction; }
28
+ compileCall(ctx) {
29
+ const base = ctx.resolveInput(this._inputs.baseColor);
30
+ const spec = ctx.resolveInput(this._inputs.specular);
31
+ const roughness = ctx.resolveInput(this._inputs.roughness);
32
+ const normal = this._inputs.normal.isConnected()
33
+ ? ctx.outputVar(this._inputs.normal.connection.node, this._inputs.normal.connection.name)
34
+ : 'normalize(vNormal)';
35
+ return `vec3 ${ctx.outputVar(this, 'BSDF')} = _st_specularBSDF(${base}, ${spec}, ${roughness}, ${normal});`;
36
+ }
37
+ }
38
+ SpecularBSDF.instanceSpecificDef = false;
39
+ SpecularBSDF.glslFunction = `
40
+ vec3 _st_specularBSDF(vec3 base, vec3 spec, float roughness, vec3 N) {
41
+ vec3 L = normalize(vec3(1.0, 2.0, 1.0));
42
+ vec3 V = normalize(cameraPosition - vPosition);
43
+ vec3 H = normalize(L + V);
44
+ float NdotL = max(dot(N, L), 0.0);
45
+ float NdotH = max(dot(N, H), 0.0);
46
+ float NdotV = max(dot(N, V), 0.0001);
47
+ float a2 = pow(roughness, 4.0);
48
+ float D = a2 / max(3.14159 * pow(NdotH * NdotH * (a2 - 1.0) + 1.0, 2.0), 0.0001);
49
+ float k = (roughness + 1.0) * (roughness + 1.0) / 8.0;
50
+ float G = (NdotL / (NdotL * (1.0 - k) + k)) * (NdotV / (NdotV * (1.0 - k) + k));
51
+ vec3 F = spec + (1.0 - spec) * pow(1.0 - max(dot(H, V), 0.0), 5.0);
52
+ vec3 specColor = D * G * F / max(4.0 * NdotL * NdotV, 0.0001);
53
+ return (base / 3.14159 + specColor) * NdotL + base * 0.04;
54
+ }`;
@@ -0,0 +1,33 @@
1
+ import { ProcessNode } from '../../core/ProcessNode.js';
2
+ import type { NodeMetadata } from '../../core/ShaderNode.js';
3
+ import type { CompileContext } from '../../core/CompileContext.js';
4
+ import type { OutputSocket } from '../../core/OutputSocket.js';
5
+ export interface SubsurfaceScatteringInputs {
6
+ color?: OutputSocket | string;
7
+ scale?: OutputSocket | number;
8
+ radius?: [number, number, number];
9
+ normal?: OutputSocket;
10
+ }
11
+ /**
12
+ * Subsurface Scattering — Blender "Subsurface Scattering" node equivalent.
13
+ * Simulates light bleeding beneath thin surfaces — skin, marble, wax, candles.
14
+ * Real-time approximation using wrap lighting and translucency.
15
+ *
16
+ * Inputs: color, scale [0-1], radius (RGB scatter distances), normal
17
+ * Outputs: BSDF (shader)
18
+ */
19
+ export declare class SubsurfaceScattering extends ProcessNode {
20
+ get nodeType(): string;
21
+ static instanceSpecificDef: boolean;
22
+ get metadata(): NodeMetadata;
23
+ static glslFunction: string;
24
+ private readonly radius;
25
+ private readonly _inputs;
26
+ private readonly _outputs;
27
+ constructor(inputs?: SubsurfaceScatteringInputs);
28
+ getInputSockets(): Record<string, import("../../core/InputSocket.js").InputSocket<unknown>>;
29
+ getOutputSockets(): Record<string, OutputSocket>;
30
+ compileDefs(): string;
31
+ compileCall(ctx: CompileContext): string;
32
+ }
33
+ //# sourceMappingURL=SubsurfaceScattering.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SubsurfaceScattering.d.ts","sourceRoot":"","sources":["../../../src/nodes/process/SubsurfaceScattering.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAE9D,MAAM,WAAW,0BAA0B;IACzC,KAAK,CAAC,EAAK,YAAY,GAAG,MAAM,CAAA;IAChC,KAAK,CAAC,EAAK,YAAY,GAAG,MAAM,CAAA;IAChC,MAAM,CAAC,EAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC,MAAM,CAAC,EAAI,YAAY,CAAA;CACxB;AAED;;;;;;;GAOG;AACH,qBAAa,oBAAqB,SAAQ,WAAW;IACnD,IAAI,QAAQ,WAAoC;IAChD,MAAM,CAAC,mBAAmB,UAAQ;IAElC,IAAI,QAAQ,IAAI,YAAY,CAE3B;IAED,MAAM,CAAC,YAAY,SAOnB;IAEA,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;IACjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2E;IACnG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmE;gBAEhF,MAAM,GAAE,0BAA+B;IAWnD,eAAe;IACf,gBAAgB;IAChB,WAAW;IAEX,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM;CASzC"}
@@ -0,0 +1,46 @@
1
+ import { ProcessNode } from '../../core/ProcessNode.js';
2
+ /**
3
+ * Subsurface Scattering — Blender "Subsurface Scattering" node equivalent.
4
+ * Simulates light bleeding beneath thin surfaces — skin, marble, wax, candles.
5
+ * Real-time approximation using wrap lighting and translucency.
6
+ *
7
+ * Inputs: color, scale [0-1], radius (RGB scatter distances), normal
8
+ * Outputs: BSDF (shader)
9
+ */
10
+ export class SubsurfaceScattering extends ProcessNode {
11
+ get nodeType() { return 'SubsurfaceScattering'; }
12
+ get metadata() {
13
+ return { label: 'Subsurface Scattering', category: 'Shader', color: '#336699', cost: 'medium', costNote: 'Real-time approximation — not physically exact.' };
14
+ }
15
+ constructor(inputs = {}) {
16
+ super('SubsurfaceScattering');
17
+ this.radius = inputs.radius ?? [1.0, 0.2, 0.1];
18
+ this._inputs = this.createInputs(inputs, {
19
+ color: ['color', '#ffffff'],
20
+ scale: ['float', inputs.scale ?? 0.05],
21
+ normal: ['color', null],
22
+ });
23
+ this._outputs = this.createOutputs({ BSDF: 'shader' });
24
+ }
25
+ getInputSockets() { return this._inputs; }
26
+ getOutputSockets() { return this._outputs; }
27
+ compileDefs() { return SubsurfaceScattering.glslFunction; }
28
+ compileCall(ctx) {
29
+ const color = ctx.resolveInput(this._inputs.color);
30
+ const scale = ctx.resolveInput(this._inputs.scale);
31
+ const [r, g, b] = this.radius;
32
+ const normal = this._inputs.normal.isConnected()
33
+ ? ctx.outputVar(this._inputs.normal.connection.node, this._inputs.normal.connection.name)
34
+ : 'normalize(vNormal)';
35
+ return `vec3 ${ctx.outputVar(this, 'BSDF')} = _st_sss(${color}, ${scale}, vec3(${r.toFixed(4)}, ${g.toFixed(4)}, ${b.toFixed(4)}), ${normal});`;
36
+ }
37
+ }
38
+ SubsurfaceScattering.instanceSpecificDef = false;
39
+ SubsurfaceScattering.glslFunction = `
40
+ vec3 _st_sss(vec3 color, float scale, vec3 radius, vec3 N) {
41
+ vec3 L = normalize(vec3(1.0, 2.0, 1.0));
42
+ float wrap = max(dot(N, L) * 0.5 + 0.5, 0.0);
43
+ vec3 scatter = color * radius * wrap * scale;
44
+ float back = max(-dot(N, L), 0.0) * scale * 0.3;
45
+ return color * (0.04 + wrap * 0.5) + scatter + color * back;
46
+ }`;
@@ -0,0 +1,31 @@
1
+ import { ProcessNode } from '../../core/ProcessNode.js';
2
+ import type { NodeMetadata } from '../../core/ShaderNode.js';
3
+ import type { CompileContext } from '../../core/CompileContext.js';
4
+ import type { OutputSocket } from '../../core/OutputSocket.js';
5
+ export interface ToonBSDFInputs {
6
+ color?: OutputSocket | string;
7
+ size?: OutputSocket | number;
8
+ smooth?: OutputSocket | number;
9
+ normal?: OutputSocket;
10
+ }
11
+ /**
12
+ * Toon BSDF — Blender "Toon BSDF" node equivalent.
13
+ * Hard cel-shading bands — cartoon and anime aesthetics.
14
+ *
15
+ * Inputs: color, size [0-1], smooth [0-1], normal
16
+ * Outputs: BSDF (shader)
17
+ */
18
+ export declare class ToonBSDF extends ProcessNode {
19
+ get nodeType(): string;
20
+ static instanceSpecificDef: boolean;
21
+ get metadata(): NodeMetadata;
22
+ static glslFunction: string;
23
+ private readonly _inputs;
24
+ private readonly _outputs;
25
+ constructor(inputs?: ToonBSDFInputs);
26
+ getInputSockets(): Record<string, import("../../core/InputSocket.js").InputSocket<unknown>>;
27
+ getOutputSockets(): Record<string, OutputSocket>;
28
+ compileDefs(): string;
29
+ compileCall(ctx: CompileContext): string;
30
+ }
31
+ //# sourceMappingURL=ToonBSDF.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToonBSDF.d.ts","sourceRoot":"","sources":["../../../src/nodes/process/ToonBSDF.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAE9D,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAI,YAAY,GAAG,MAAM,CAAA;IAC/B,IAAI,CAAC,EAAK,YAAY,GAAG,MAAM,CAAA;IAC/B,MAAM,CAAC,EAAG,YAAY,GAAG,MAAM,CAAA;IAC/B,MAAM,CAAC,EAAG,YAAY,CAAA;CACvB;AAED;;;;;;GAMG;AACH,qBAAa,QAAS,SAAQ,WAAW;IACvC,IAAI,QAAQ,WAAwB;IACpC,MAAM,CAAC,mBAAmB,UAAQ;IAElC,IAAI,QAAQ,IAAI,YAAY,CAE3B;IAED,MAAM,CAAC,YAAY,SAMnB;IAEA,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2E;IACnG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmE;gBAEhF,MAAM,GAAE,cAAmB;IAWvC,eAAe;IACf,gBAAgB;IAChB,WAAW;IAEX,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM;CASzC"}
@@ -0,0 +1,44 @@
1
+ import { ProcessNode } from '../../core/ProcessNode.js';
2
+ /**
3
+ * Toon BSDF — Blender "Toon BSDF" node equivalent.
4
+ * Hard cel-shading bands — cartoon and anime aesthetics.
5
+ *
6
+ * Inputs: color, size [0-1], smooth [0-1], normal
7
+ * Outputs: BSDF (shader)
8
+ */
9
+ export class ToonBSDF extends ProcessNode {
10
+ get nodeType() { return 'ToonBSDF'; }
11
+ get metadata() {
12
+ return { label: 'Toon BSDF', category: 'Shader', color: '#336699', cost: 'low' };
13
+ }
14
+ constructor(inputs = {}) {
15
+ super('ToonBSDF');
16
+ this._inputs = this.createInputs(inputs, {
17
+ color: ['color', '#ffffff'],
18
+ size: ['float', inputs.size ?? 0.5],
19
+ smooth: ['float', inputs.smooth ?? 0.0],
20
+ normal: ['color', null],
21
+ });
22
+ this._outputs = this.createOutputs({ BSDF: 'shader' });
23
+ }
24
+ getInputSockets() { return this._inputs; }
25
+ getOutputSockets() { return this._outputs; }
26
+ compileDefs() { return ToonBSDF.glslFunction; }
27
+ compileCall(ctx) {
28
+ const color = ctx.resolveInput(this._inputs.color);
29
+ const size = ctx.resolveInput(this._inputs.size);
30
+ const smoothWidth = ctx.resolveInput(this._inputs.smooth);
31
+ const normal = this._inputs.normal.isConnected()
32
+ ? ctx.outputVar(this._inputs.normal.connection.node, this._inputs.normal.connection.name)
33
+ : 'normalize(vNormal)';
34
+ return `vec3 ${ctx.outputVar(this, 'BSDF')} = _st_toonBSDF(${color}, ${size}, ${smoothWidth}, ${normal});`;
35
+ }
36
+ }
37
+ ToonBSDF.instanceSpecificDef = false;
38
+ ToonBSDF.glslFunction = `
39
+ vec3 _st_toonBSDF(vec3 color, float size, float smoothWidth, vec3 N) {
40
+ vec3 L = normalize(vec3(1.0, 2.0, 1.0));
41
+ float NdotL = dot(N, L) * 0.5 + 0.5;
42
+ float band = smoothstep(size - smoothWidth, size + smoothWidth, NdotL);
43
+ return color * band + color * 0.1;
44
+ }`;