@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,46 @@
1
+ import { ProcessNode } from '../../core/ProcessNode.js';
2
+ /**
3
+ * Refraction BSDF — Blender "Refraction BSDF" node equivalent.
4
+ * Simulates light bending through a transparent medium.
5
+ * Approximated in real-time using a tinted transmission colour.
6
+ *
7
+ * Inputs: color, roughness, ior, normal
8
+ * Outputs: BSDF (shader)
9
+ */
10
+ export class RefractionBSDF extends ProcessNode {
11
+ get nodeType() { return 'RefractionBSDF'; }
12
+ get metadata() {
13
+ return { label: 'Refraction BSDF', category: 'Shader', color: '#336699', cost: 'medium' };
14
+ }
15
+ constructor(inputs = {}) {
16
+ super('RefractionBSDF');
17
+ this._inputs = this.createInputs(inputs, {
18
+ color: ['color', '#ffffff'],
19
+ roughness: ['float', inputs.roughness ?? 0.0],
20
+ ior: ['float', inputs.ior ?? 1.45],
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 RefractionBSDF.glslFunction; }
28
+ compileCall(ctx) {
29
+ const color = ctx.resolveInput(this._inputs.color);
30
+ const roughness = ctx.resolveInput(this._inputs.roughness);
31
+ const ior = ctx.resolveInput(this._inputs.ior);
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_refractionBSDF(${color}, ${roughness}, ${ior}, ${normal});`;
36
+ }
37
+ }
38
+ RefractionBSDF.instanceSpecificDef = false;
39
+ RefractionBSDF.glslFunction = `
40
+ vec3 _st_refractionBSDF(vec3 color, float roughness, float ior, vec3 N) {
41
+ vec3 V = normalize(cameraPosition - vPosition);
42
+ vec3 refDir = refract(-V, N, 1.0 / ior);
43
+ float fresnel = pow(1.0 - max(dot(V, N), 0.0), 5.0);
44
+ vec3 refColor = color * (1.0 - fresnel) * (1.0 - roughness * 0.5);
45
+ return refColor;
46
+ }`;
@@ -0,0 +1,56 @@
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 SchwarzschildMarchInputs {
6
+ rayPos?: OutputSocket;
7
+ rayDir?: OutputSocket;
8
+ Rs?: number | OutputSocket;
9
+ diskInn?: number | OutputSocket;
10
+ diskOut?: number | OutputSocket;
11
+ diskThk?: number | OutputSocket;
12
+ doppler?: number | OutputSocket;
13
+ rotSpd?: number | OutputSocket;
14
+ psBright?: number | OutputSocket;
15
+ psWidth?: number | OutputSocket;
16
+ psFresnel?: number | OutputSocket;
17
+ steps?: number | OutputSocket;
18
+ stepSz?: number | OutputSocket;
19
+ time?: number | OutputSocket;
20
+ exposure?: number | OutputSocket;
21
+ rFreq?: number | OutputSocket;
22
+ rDist?: number | OutputSocket;
23
+ rDet?: number | OutputSocket;
24
+ rContr?: number | OutputSocket;
25
+ n1Scale?: number | OutputSocket;
26
+ n1Det?: number | OutputSocket;
27
+ n1Rough?: number | OutputSocket;
28
+ nScale?: number | OutputSocket;
29
+ nDet?: number | OutputSocket;
30
+ nRough?: number | OutputSocket;
31
+ sBlend?: number | OutputSocket;
32
+ ringStr?: number | OutputSocket;
33
+ surfStr?: number | OutputSocket;
34
+ warpSc?: number | OutputSocket;
35
+ warpStr?: number | OutputSocket;
36
+ cDark?: string | [number, number, number] | OutputSocket;
37
+ cMid?: string | [number, number, number] | OutputSocket;
38
+ cBright?: string | [number, number, number] | OutputSocket;
39
+ cMidPt?: number | OutputSocket;
40
+ cLow?: number | OutputSocket;
41
+ cHigh?: number | OutputSocket;
42
+ bright?: number | OutputSocket;
43
+ }
44
+ export declare class SchwarzschildMarch extends ProcessNode {
45
+ get nodeType(): string;
46
+ static instanceSpecificDef: boolean;
47
+ get metadata(): NodeMetadata;
48
+ private readonly _inputs;
49
+ private readonly _outputs;
50
+ constructor(inputs?: SchwarzschildMarchInputs);
51
+ getInputSockets(): Record<string, import("../../core/InputSocket.js").InputSocket<unknown>>;
52
+ getOutputSockets(): Record<string, OutputSocket>;
53
+ compileDefs(): string;
54
+ compileCall(ctx: CompileContext): string;
55
+ }
56
+ //# sourceMappingURL=SchwarzschildMarch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SchwarzschildMarch.d.ts","sourceRoot":"","sources":["../../../src/nodes/process/SchwarzschildMarch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,306 @@
1
+ import { ProcessNode } from '../../core/ProcessNode.js';
2
+ export class SchwarzschildMarch extends ProcessNode {
3
+ get nodeType() { return 'SchwarzschildMarch'; }
4
+ get metadata() {
5
+ return {
6
+ label: 'Schwarzschild March',
7
+ category: 'Raymarcher',
8
+ color: '#223344',
9
+ cost: 'high',
10
+ costNote: 'Full geodesic integration — GPU heavy at high step counts.',
11
+ };
12
+ }
13
+ constructor(inputs = {}) {
14
+ super('SchwarzschildMarch');
15
+ this._inputs = this.createInputs(inputs, {
16
+ rayPos: ['color', null],
17
+ rayDir: ['color', null],
18
+ Rs: ['float', inputs.Rs ?? 0.2],
19
+ diskInn: ['float', inputs.diskInn ?? 0.55],
20
+ diskOut: ['float', inputs.diskOut ?? 2.0],
21
+ diskThk: ['float', inputs.diskThk ?? 0.01],
22
+ doppler: ['float', inputs.doppler ?? 1.0],
23
+ rotSpd: ['float', inputs.rotSpd ?? 0.05],
24
+ psBright: ['float', inputs.psBright ?? 0.5],
25
+ psWidth: ['float', inputs.psWidth ?? 0.01],
26
+ psFresnel: ['float', inputs.psFresnel ?? 10.0],
27
+ steps: ['float', inputs.steps ?? 500.0],
28
+ stepSz: ['float', inputs.stepSz ?? 0.015],
29
+ time: ['float', inputs.time ?? 0.0],
30
+ exposure: ['float', inputs.exposure ?? 3.0],
31
+ // Ring / stripe
32
+ rFreq: ['float', inputs.rFreq ?? 40.75],
33
+ rDist: ['float', inputs.rDist ?? 8.0],
34
+ rDet: ['float', inputs.rDet ?? 8.0],
35
+ rContr: ['float', inputs.rContr ?? 1.0],
36
+ // Surface noise
37
+ n1Scale: ['float', inputs.n1Scale ?? 30.0],
38
+ n1Det: ['float', inputs.n1Det ?? 1.0],
39
+ n1Rough: ['float', inputs.n1Rough ?? 0.25],
40
+ nScale: ['float', inputs.nScale ?? 40.0],
41
+ nDet: ['float', inputs.nDet ?? 8.0],
42
+ nRough: ['float', inputs.nRough ?? 1.0],
43
+ sBlend: ['float', inputs.sBlend ?? 0.25],
44
+ // Combine
45
+ ringStr: ['float', inputs.ringStr ?? 0.5],
46
+ surfStr: ['float', inputs.surfStr ?? 1.0],
47
+ warpSc: ['float', inputs.warpSc ?? 10.0],
48
+ warpStr: ['float', inputs.warpStr ?? 0.05],
49
+ // Color mapping (color type → live vec3 uniforms)
50
+ cDark: ['color', inputs.cDark ?? '#000000'],
51
+ cMid: ['color', inputs.cMid ?? '#926649'],
52
+ cBright: ['color', inputs.cBright ?? '#ff8800'],
53
+ cMidPt: ['float', inputs.cMidPt ?? 0.25],
54
+ cLow: ['float', inputs.cLow ?? 0.15],
55
+ cHigh: ['float', inputs.cHigh ?? 1.0],
56
+ bright: ['float', inputs.bright ?? 5.0],
57
+ });
58
+ this._outputs = this.createOutputs({ Color: 'color' });
59
+ }
60
+ getInputSockets() { return this._inputs; }
61
+ getOutputSockets() { return this._outputs; }
62
+ compileDefs() {
63
+ const p = `_sm${this.id}`;
64
+ return `
65
+ float ${p}H2(vec2 q){return fract(sin(dot(q,vec2(127.1,311.7)))*43758.5453);}
66
+ float ${p}H3(vec3 q){return fract(sin(dot(q,vec3(127.1,311.7,74.7)))*43758.5453);}
67
+ float ${p}SN(vec2 q){
68
+ vec2 i=floor(q),f=fract(q);f=f*f*(3.0-2.0*f);
69
+ return mix(mix(${p}H2(i),${p}H2(i+vec2(1,0)),f.x),
70
+ mix(${p}H2(i+vec2(0,1)),${p}H2(i+vec2(1,1)),f.x),f.y);
71
+ }
72
+
73
+ // Geodesic acceleration — inward bending (correct sign for lensing)
74
+ vec3 ${p}Accel(vec3 pos,vec3 vel,float M){
75
+ float r=max(length(pos),M*1.04);float r3=r*r*r;
76
+ vec3 rh=pos/r;float vr=dot(vel,rh);float v2=dot(vel,vel);
77
+ return (M/r3)*(2.0*vr*vel-(v2-3.0*vr*vr)*rh);
78
+ }
79
+ void ${p}RK4(inout vec3 pos,inout vec3 vel,float h,float M){
80
+ vec3 k1v=${p}Accel(pos,vel,M);vec3 k1p=vel;
81
+ vec3 k2v=${p}Accel(pos+.5*h*k1p,vel+.5*h*k1v,M);vec3 k2p=vel+.5*h*k1v;
82
+ vec3 k3v=${p}Accel(pos+.5*h*k2p,vel+.5*h*k2v,M);vec3 k3p=vel+.5*h*k2v;
83
+ vec3 k4v=${p}Accel(pos+h*k3p,vel+h*k3v,M);vec3 k4p=vel+h*k3v;
84
+ pos+=(h/6.0)*(k1p+2.0*k2p+2.0*k3p+k4p);
85
+ vel+=(h/6.0)*(k1v+2.0*k2v+2.0*k3v+k4v);
86
+ vel=normalize(vel);
87
+ }
88
+
89
+ // ── Disk colour — Texture Maker recipe: Ring + (Noise1 × Noise2) ────────────
90
+ // All the ring/surface/color parameters come in as uniforms, identical to the
91
+ // sliders in example-texture-maker.html, so what you design there is what you see here.
92
+ vec3 ${p}DiskCol(vec3 hit, float hitCnt,
93
+ float dInn, float dOut,
94
+ float dopp, float rSpd, float t,
95
+ float rFreq, float rDist, float rDet, float rContr,
96
+ float n1Scale, float n1Det, float n1Rough,
97
+ float nScale, float nDet, float nRough,
98
+ float sBlend, float ringStr, float surfStr,
99
+ float warpSc, float warpStr,
100
+ vec3 cDark, vec3 cMid, vec3 cBright,
101
+ float cMidPt, float cLow, float cHigh, float texBri) {
102
+
103
+ float r = length(hit.xz);
104
+ float fac = clamp((r - dInn) / max(dOut - dInn, 0.001), 0.0, 1.0);
105
+
106
+ // Smooth radial mask — outer 25% fades gracefully, inner 5% ramps up
107
+ float radialMask = smoothstep(1.0, 0.75, fac) * smoothstep(0.0, 0.05, fac);
108
+
109
+ // Angular position — used ONLY for Doppler (sin(ang) is continuous at ±π seam)
110
+ // NOT used for noise UV lookups — atan2 has a ±π discontinuity at the left
111
+ // of the disk that creates a visible cut line. Cartesian (hit.x, hit.z) are
112
+ // continuous everywhere and completely eliminate the seam.
113
+ float ang = atan(hit.z, hit.x) + t * rSpd;
114
+
115
+ // ── ① Ring / stripe layer ─────────────────────────────────────────────────
116
+ // Exact match of the Texture Maker's ring computation:
117
+ // VectorMath(LENGTH, pos) → warp noise → WaveTexture(scale=rFreq, SINE)
118
+ // Scale applied directly (no extra multiplier) so slider values are identical.
119
+ // Warp sampled in Cartesian — no ±π seam.
120
+ float wN = ${p}SN(vec2(hit.x * warpSc + t * 0.04, hit.z * warpSc));
121
+ float wR = r + wN * warpStr;
122
+
123
+ // WaveTexture SINE: phase = input * scale * 2π (texture maker uses 2π, not π)
124
+ float phase = wR * rFreq * 6.28318;
125
+ float rings = sin(phase + rDist * ${p}SN(vec2(hit.x * 1.8, hit.z * 1.8))) * 0.5 + 0.5;
126
+ float rA = 0.5;
127
+ for (int ri = 0; ri < 8; ri++) {
128
+ if (float(ri) >= rDet) break;
129
+ float sc = pow(2.1, float(ri+1));
130
+ rings += rA * (sin(phase * pow(2.0, float(ri+1))
131
+ + rDist * ${p}SN(vec2(hit.x * sc, hit.z * sc))) * 0.5 + 0.5);
132
+ rA *= 0.5;
133
+ }
134
+ rings /= max(2.0 - rA, 0.001);
135
+ rings = pow(clamp(rings, 0.0, 1.0), rContr);
136
+
137
+ // ── ② Surface texture (Noise 1 × Noise 2) ────────────────────────────────
138
+ // Scale applied directly — matches NoiseTexture(scale=n1Scale) in texture maker.
139
+ // No arbitrary multipliers: n1Scale=30 here = n1Scale=30 in texture maker.
140
+ // Cartesian UVs throughout — zero seam.
141
+ vec2 n1uv = vec2(hit.x * n1Scale + t * rSpd * 0.4, hit.z * n1Scale + t * rSpd * 0.2);
142
+ float n1 = ${p}SN(n1uv) * 0.5;
143
+ float n1a = 0.5;
144
+ for (int n1i = 0; n1i < 8; n1i++) {
145
+ if (float(n1i) >= n1Det) break;
146
+ n1 += n1a * ${p}SN(n1uv * pow(2.07, float(n1i+1)));
147
+ n1a *= n1Rough;
148
+ }
149
+ n1 = clamp(n1, 0.0, 1.0);
150
+
151
+ vec2 n2uv = vec2(hit.x * nScale + t * rSpd * 0.7 + 3.7, hit.z * nScale + t * rSpd * 0.5 + 1.3);
152
+ float n2 = ${p}SN(n2uv) * 0.5;
153
+ float n2a = 0.5;
154
+ for (int n2i = 0; n2i < 8; n2i++) {
155
+ if (float(n2i) >= nDet) break;
156
+ n2 += n2a * ${p}SN(n2uv * pow(2.07, float(n2i+1)));
157
+ n2a *= nRough;
158
+ }
159
+ n2 = clamp(n2, 0.0, 1.0);
160
+
161
+ // Blend: multiply first (dark voids + bright peaks), then fade toward N2 at sBlend
162
+ float surf = mix(clamp(n1 * n2 * 2.0, 0.0, 1.0), n2, sBlend);
163
+
164
+ // ── ③ Combine: (rings × surface) × radial mask ───────────────────────────
165
+ float combined = rings * ringStr * surf * surfStr * radialMask;
166
+ combined = clamp(combined, 0.0, 1.0);
167
+
168
+ // ── ④ Color mapping — 3-stop gradient (dark → mid → bright) ──────────────
169
+ float s1 = clamp((combined - cLow) / max(cHigh * cMidPt - cLow, 0.001), 0.0, 1.0);
170
+ vec3 col = mix(cDark, cMid, s1);
171
+ float s2 = clamp((combined - cHigh * cMidPt) / max(cHigh * (1.0 - cMidPt), 0.001), 0.0, 1.0);
172
+ col = mix(col, cBright, s2);
173
+
174
+ // ── ⑤ Brightness + relativistic Doppler beaming ──────────────────────────
175
+ float bri = texBri;
176
+ float M = dInn * 0.15;
177
+ float beta = sqrt(clamp(M / max(r, 0.001), 0.0, 0.9));
178
+ float dop = (1.0 + dopp * beta * sin(ang)) / sqrt(max(1.0 - beta * beta, 0.001));
179
+ bri *= clamp(dop, 0.1, 5.0);
180
+ bri *= pow(0.35, hitCnt); // each lensed image dimmer
181
+
182
+ return col * bri;
183
+ }
184
+
185
+ // Procedural star field
186
+ vec3 ${p}Stars(vec3 dir){
187
+ dir=normalize(dir); vec3 col=vec3(0.0);
188
+ vec3 s1=dir*130.0; float h1=${p}H3(floor(s1));
189
+ if(h1>0.972){float s=pow(max(0.0,1.0-length(fract(s1)-0.5)*9.0),2.0);
190
+ col+=s*0.5*mix(vec3(0.7,0.8,1.0),vec3(1.0,0.9,0.7),h1);}
191
+ vec3 s2=dir*55.0; float h2=${p}H3(floor(s2)+77.7);
192
+ if(h2>0.989){float s=pow(max(0.0,1.0-length(fract(s2)-0.5)*9.0),2.0);
193
+ col+=s*1.4*mix(vec3(1.0,0.95,0.8),vec3(0.7,0.85,1.0),h2);}
194
+ return col;
195
+ }
196
+
197
+ // ACES filmic tonemapping + gamma
198
+ vec3 ${p}Aces(vec3 x){
199
+ return pow(clamp((x*(2.51*x+0.03))/(x*(2.43*x+0.59)+0.14),0.0,1.0),vec3(1.0/2.2));
200
+ }`.trim();
201
+ }
202
+ compileCall(ctx) {
203
+ const p = `_sm${this.id}`;
204
+ const rp = ctx.resolveInput(this._inputs.rayPos);
205
+ const rd = ctx.resolveInput(this._inputs.rayDir);
206
+ const Rs = ctx.resolveInput(this._inputs.Rs);
207
+ const dInn = ctx.resolveInput(this._inputs.diskInn);
208
+ const dOut = ctx.resolveInput(this._inputs.diskOut);
209
+ const dThk = ctx.resolveInput(this._inputs.diskThk);
210
+ const dopp = ctx.resolveInput(this._inputs.doppler);
211
+ const rSpd = ctx.resolveInput(this._inputs.rotSpd);
212
+ const psBri = ctx.resolveInput(this._inputs.psBright);
213
+ const psW = ctx.resolveInput(this._inputs.psWidth);
214
+ const psF = ctx.resolveInput(this._inputs.psFresnel);
215
+ const steps = ctx.resolveInput(this._inputs.steps);
216
+ const stepSz = ctx.resolveInput(this._inputs.stepSz);
217
+ const time = ctx.resolveInput(this._inputs.time);
218
+ const expo = ctx.resolveInput(this._inputs.exposure);
219
+ // Ring
220
+ const rFreq = ctx.resolveInput(this._inputs.rFreq);
221
+ const rDist = ctx.resolveInput(this._inputs.rDist);
222
+ const rDet = ctx.resolveInput(this._inputs.rDet);
223
+ const rContr = ctx.resolveInput(this._inputs.rContr);
224
+ // Surface
225
+ const n1Scale = ctx.resolveInput(this._inputs.n1Scale);
226
+ const n1Det = ctx.resolveInput(this._inputs.n1Det);
227
+ const n1Rough = ctx.resolveInput(this._inputs.n1Rough);
228
+ const nScale = ctx.resolveInput(this._inputs.nScale);
229
+ const nDet = ctx.resolveInput(this._inputs.nDet);
230
+ const nRough = ctx.resolveInput(this._inputs.nRough);
231
+ const sBlend = ctx.resolveInput(this._inputs.sBlend);
232
+ // Combine
233
+ const ringStr = ctx.resolveInput(this._inputs.ringStr);
234
+ const surfStr = ctx.resolveInput(this._inputs.surfStr);
235
+ const warpSc = ctx.resolveInput(this._inputs.warpSc);
236
+ const warpStr = ctx.resolveInput(this._inputs.warpStr);
237
+ // Color
238
+ const cDark = ctx.resolveInput(this._inputs.cDark);
239
+ const cMid = ctx.resolveInput(this._inputs.cMid);
240
+ const cBright = ctx.resolveInput(this._inputs.cBright);
241
+ const cMidPt = ctx.resolveInput(this._inputs.cMidPt);
242
+ const cLow = ctx.resolveInput(this._inputs.cLow);
243
+ const cHigh = ctx.resolveInput(this._inputs.cHigh);
244
+ const texBri = ctx.resolveInput(this._inputs.bright);
245
+ const colorOut = ctx.outputVar(this, 'Color');
246
+ return `
247
+ vec3 ${p}_pos = ${rp};
248
+ vec3 ${p}_vel = ${rd};
249
+ vec3 ${p}_prev = ${p}_pos;
250
+ vec3 ${p}_col = vec3(0.0);
251
+ float ${p}_hits = 0.0;
252
+ float ${p}_minR = 1e6;
253
+ bool ${p}_abs = false;
254
+ bool ${p}_esc = false;
255
+ float ${p}_M = ${Rs} * 0.5;
256
+ int ${p}_max = int(clamp(${steps}, 50.0, 500.0));
257
+
258
+ for (int ${p}_i = 0; ${p}_i < 500; ${p}_i++) {
259
+ if (${p}_i >= ${p}_max) break;
260
+ float ${p}_r = length(${p}_pos);
261
+ ${p}_minR = min(${p}_minR, ${p}_r);
262
+ float ${p}_rn = ${p}_r / ${Rs};
263
+ float ${p}_dt = ${stepSz} * clamp((${p}_rn - 1.0) * 0.4, 0.015, 1.5);
264
+
265
+ if (${p}_r < ${Rs} * 0.55) { ${p}_abs = true; break; }
266
+
267
+ if (${p}_prev.y * ${p}_pos.y < 0.0) {
268
+ float ${p}_a = ${p}_prev.y / (${p}_prev.y - ${p}_pos.y);
269
+ vec3 ${p}_hit = mix(${p}_prev, ${p}_pos, ${p}_a);
270
+ float ${p}_hr = length(${p}_hit.xz);
271
+ if (${p}_hr > ${dInn} && ${p}_hr < ${dOut} && abs(${p}_hit.y) < ${dThk}) {
272
+ ${p}_col += ${p}DiskCol(${p}_hit, ${p}_hits,
273
+ ${dInn}, ${dOut}, ${dopp}, ${rSpd}, ${time},
274
+ ${rFreq}, ${rDist}, ${rDet}, ${rContr},
275
+ ${n1Scale}, ${n1Det}, ${n1Rough},
276
+ ${nScale}, ${nDet}, ${nRough},
277
+ ${sBlend}, ${ringStr}, ${surfStr},
278
+ ${warpSc}, ${warpStr},
279
+ ${cDark}, ${cMid}, ${cBright},
280
+ ${cMidPt}, ${cLow}, ${cHigh}, ${texBri});
281
+ ${p}_hits += 1.0;
282
+ }
283
+ }
284
+
285
+ if (${p}_r > 60.0) { ${p}_col += ${p}Stars(${p}_vel); ${p}_esc = true; break; }
286
+
287
+ ${p}_prev = ${p}_pos;
288
+ ${p}RK4(${p}_pos, ${p}_vel, ${p}_dt, ${p}_M);
289
+ }
290
+
291
+ if (!${p}_abs && !${p}_esc) ${p}_col += ${p}Stars(${p}_vel);
292
+
293
+ if (!${p}_abs) {
294
+ float ${p}_psR = ${Rs} * 1.5;
295
+ float ${p}_psDt = abs(${p}_minR - ${p}_psR) / (${Rs} * ${psW});
296
+ float ${p}_psMk = exp(-${p}_hits * ${psF});
297
+ ${p}_col += exp(-${p}_psDt * ${p}_psDt) * ${psBri} * ${p}_psMk * vec3(0.88, 0.94, 1.0);
298
+ }
299
+
300
+ if (${p}_abs) ${p}_col = vec3(0.0);
301
+
302
+ vec3 ${colorOut} = ${p}Aces(${p}_col * ${expo});
303
+ `.trim();
304
+ }
305
+ }
306
+ SchwarzschildMarch.instanceSpecificDef = true;
@@ -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 type SeparateColorMode = 'RGB' | 'HSV' | 'HSL';
6
+ export interface SeparateColorInputs {
7
+ color?: OutputSocket | string;
8
+ mode?: SeparateColorMode;
9
+ }
10
+ /**
11
+ * Separate Color — Blender 3.4+ "Separate Color" node equivalent.
12
+ * Separates a color into three float channels using RGB, HSV, or HSL mode.
13
+ * Replaces the older SeparateRGB node and adds HSV/HSL support.
14
+ *
15
+ * Inputs: color
16
+ * Outputs: Red (float), Green (float), Blue (float)
17
+ * — semantics depend on mode: R/G/B in RGB, H/S/V in HSV, H/S/L in HSL
18
+ */
19
+ export declare class SeparateColor extends ProcessNode {
20
+ get nodeType(): string;
21
+ static instanceSpecificDef: boolean;
22
+ get metadata(): NodeMetadata;
23
+ static glslFunction: string;
24
+ private readonly mode;
25
+ private readonly _inputs;
26
+ private readonly _outputs;
27
+ constructor(inputs?: SeparateColorInputs);
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=SeparateColor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SeparateColor.d.ts","sourceRoot":"","sources":["../../../src/nodes/process/SeparateColor.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,MAAM,iBAAiB,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAA;AAErD,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,YAAY,GAAG,MAAM,CAAA;IAC7B,IAAI,CAAC,EAAG,iBAAiB,CAAA;CAC1B;AAED;;;;;;;;GAQG;AACH,qBAAa,aAAc,SAAQ,WAAW;IAC5C,IAAI,QAAQ,WAA6B;IACzC,MAAM,CAAC,mBAAmB,UAAQ;IAElC,IAAI,QAAQ,IAAI,YAAY,CAE3B;IAED,MAAM,CAAC,YAAY,SAqBnB;IAEA,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAsB;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2E;IACnG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmE;gBAEhF,MAAM,GAAE,mBAAwB;IAa5C,eAAe;IACf,gBAAgB;IAChB,WAAW;IAEX,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM;CAqBzC"}
@@ -0,0 +1,79 @@
1
+ import { ProcessNode } from '../../core/ProcessNode.js';
2
+ /**
3
+ * Separate Color — Blender 3.4+ "Separate Color" node equivalent.
4
+ * Separates a color into three float channels using RGB, HSV, or HSL mode.
5
+ * Replaces the older SeparateRGB node and adds HSV/HSL support.
6
+ *
7
+ * Inputs: color
8
+ * Outputs: Red (float), Green (float), Blue (float)
9
+ * — semantics depend on mode: R/G/B in RGB, H/S/V in HSV, H/S/L in HSL
10
+ */
11
+ export class SeparateColor extends ProcessNode {
12
+ get nodeType() { return 'SeparateColor'; }
13
+ get metadata() {
14
+ return { label: 'Separate Color', category: 'Converter', color: '#633060', cost: 'low' };
15
+ }
16
+ constructor(inputs = {}) {
17
+ super('SeparateColor');
18
+ this.mode = inputs.mode ?? 'RGB';
19
+ this._inputs = this.createInputs(inputs, {
20
+ color: ['color', '#ffffff'],
21
+ });
22
+ this._outputs = this.createOutputs({
23
+ Red: 'float',
24
+ Green: 'float',
25
+ Blue: 'float',
26
+ });
27
+ }
28
+ getInputSockets() { return this._inputs; }
29
+ getOutputSockets() { return this._outputs; }
30
+ compileDefs() { return SeparateColor.glslFunction; }
31
+ compileCall(ctx) {
32
+ const cv = ctx.resolveInput(this._inputs.color);
33
+ const tmp = `_sc_${this.id}`;
34
+ const rv = ctx.outputVar(this, 'Red');
35
+ const gv = ctx.outputVar(this, 'Green');
36
+ const bv = ctx.outputVar(this, 'Blue');
37
+ let convert;
38
+ switch (this.mode) {
39
+ case 'HSV':
40
+ convert = `vec3 ${tmp} = _st_rgbToHsv(${cv});`;
41
+ break;
42
+ case 'HSL':
43
+ convert = `vec3 ${tmp} = _st_rgbToHsl(${cv});`;
44
+ break;
45
+ default:
46
+ convert = `vec3 ${tmp} = ${cv};`;
47
+ break;
48
+ }
49
+ return [
50
+ convert,
51
+ `float ${rv} = ${tmp}.x;`,
52
+ `float ${gv} = ${tmp}.y;`,
53
+ `float ${bv} = ${tmp}.z;`,
54
+ ].join('\n ');
55
+ }
56
+ }
57
+ SeparateColor.instanceSpecificDef = false;
58
+ SeparateColor.glslFunction = `
59
+ vec3 _st_rgbToHsv(vec3 c) {
60
+ vec4 K = vec4(0.0, -1.0/3.0, 2.0/3.0, -1.0);
61
+ vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
62
+ vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
63
+ float d = q.x - min(q.w, q.y), e = 1.0e-10;
64
+ return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
65
+ }
66
+ vec3 _st_rgbToHsl(vec3 c) {
67
+ float maxC = max(c.r, max(c.g, c.b));
68
+ float minC = min(c.r, min(c.g, c.b));
69
+ float l = (maxC + minC) * 0.5;
70
+ float d = maxC - minC;
71
+ float s = (d < 0.0001) ? 0.0 : d / (1.0 - abs(2.0 * l - 1.0));
72
+ float h = 0.0;
73
+ if (d > 0.0001) {
74
+ if (maxC == c.r) h = mod((c.g - c.b) / d, 6.0) / 6.0;
75
+ else if (maxC == c.g) h = ((c.b - c.r) / d + 2.0) / 6.0;
76
+ else h = ((c.r - c.g) / d + 4.0) / 6.0;
77
+ }
78
+ return vec3(h, s, l);
79
+ }`;
@@ -0,0 +1,27 @@
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 SeparateRGBInputs {
6
+ color?: OutputSocket | string;
7
+ }
8
+ /**
9
+ * Separate RGB — Blender "Separate Color" node equivalent.
10
+ * Splits a colour into its R, G, B float channels.
11
+ *
12
+ * Inputs: color (color)
13
+ * Outputs: R (float), G (float), B (float)
14
+ */
15
+ export declare class SeparateRGB extends ProcessNode {
16
+ get nodeType(): string;
17
+ static instanceSpecificDef: boolean;
18
+ get metadata(): NodeMetadata;
19
+ private readonly _inputs;
20
+ private readonly _outputs;
21
+ constructor(inputs?: SeparateRGBInputs);
22
+ getInputSockets(): Record<string, import("../../core/InputSocket.js").InputSocket<unknown>>;
23
+ getOutputSockets(): Record<string, OutputSocket>;
24
+ compileDefs(): string;
25
+ compileCall(ctx: CompileContext): string;
26
+ }
27
+ //# sourceMappingURL=SeparateRGB.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SeparateRGB.d.ts","sourceRoot":"","sources":["../../../src/nodes/process/SeparateRGB.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,KAAK,CAAC,EAAE,YAAY,GAAG,MAAM,CAAA;CAC9B;AAED;;;;;;GAMG;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;CAQzC"}
@@ -0,0 +1,31 @@
1
+ import { ProcessNode } from '../../core/ProcessNode.js';
2
+ /**
3
+ * Separate RGB — Blender "Separate Color" node equivalent.
4
+ * Splits a colour into its R, G, B float channels.
5
+ *
6
+ * Inputs: color (color)
7
+ * Outputs: R (float), G (float), B (float)
8
+ */
9
+ export class SeparateRGB extends ProcessNode {
10
+ get nodeType() { return 'SeparateRGB'; }
11
+ get metadata() {
12
+ return { label: 'Separate RGB', category: 'Converter', color: '#4a3a6a', cost: 'low' };
13
+ }
14
+ constructor(inputs = {}) {
15
+ super('SeparateRGB');
16
+ this._inputs = this.createInputs(inputs, { color: ['color', '#ffffff'] });
17
+ this._outputs = this.createOutputs({ R: 'float', G: 'float', B: 'float' });
18
+ }
19
+ getInputSockets() { return this._inputs; }
20
+ getOutputSockets() { return this._outputs; }
21
+ compileDefs() { return ''; }
22
+ compileCall(ctx) {
23
+ const col = ctx.resolveInput(this._inputs.color);
24
+ return [
25
+ `float ${ctx.outputVar(this, 'R')} = (${col}).r;`,
26
+ `float ${ctx.outputVar(this, 'G')} = (${col}).g;`,
27
+ `float ${ctx.outputVar(this, 'B')} = (${col}).b;`,
28
+ ].join('\n ');
29
+ }
30
+ }
31
+ SeparateRGB.instanceSpecificDef = false;
@@ -0,0 +1,27 @@
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 SeparateXYZInputs {
6
+ vector?: OutputSocket;
7
+ }
8
+ /**
9
+ * Separate XYZ — Blender "Separate XYZ" node equivalent.
10
+ * Splits a vector into X, Y, Z float components.
11
+ *
12
+ * Inputs: vector (vector/color)
13
+ * Outputs: X (float), Y (float), Z (float)
14
+ */
15
+ export declare class SeparateXYZ extends ProcessNode {
16
+ get nodeType(): string;
17
+ static instanceSpecificDef: boolean;
18
+ get metadata(): NodeMetadata;
19
+ private readonly _inputs;
20
+ private readonly _outputs;
21
+ constructor(inputs?: SeparateXYZInputs);
22
+ getInputSockets(): Record<string, import("../../core/InputSocket.js").InputSocket<unknown>>;
23
+ getOutputSockets(): Record<string, OutputSocket>;
24
+ compileDefs(): string;
25
+ compileCall(ctx: CompileContext): string;
26
+ }
27
+ //# sourceMappingURL=SeparateXYZ.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SeparateXYZ.d.ts","sourceRoot":"","sources":["../../../src/nodes/process/SeparateXYZ.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;;;;;;GAMG;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;CAQzC"}
@@ -0,0 +1,31 @@
1
+ import { ProcessNode } from '../../core/ProcessNode.js';
2
+ /**
3
+ * Separate XYZ — Blender "Separate XYZ" node equivalent.
4
+ * Splits a vector into X, Y, Z float components.
5
+ *
6
+ * Inputs: vector (vector/color)
7
+ * Outputs: X (float), Y (float), Z (float)
8
+ */
9
+ export class SeparateXYZ extends ProcessNode {
10
+ get nodeType() { return 'SeparateXYZ'; }
11
+ get metadata() {
12
+ return { label: 'Separate XYZ', category: 'Converter', color: '#4a3a6a', cost: 'low' };
13
+ }
14
+ constructor(inputs = {}) {
15
+ super('SeparateXYZ');
16
+ this._inputs = this.createInputs(inputs, { vector: ['color', null] });
17
+ this._outputs = this.createOutputs({ X: 'float', Y: 'float', Z: 'float' });
18
+ }
19
+ getInputSockets() { return this._inputs; }
20
+ getOutputSockets() { return this._outputs; }
21
+ compileDefs() { return ''; }
22
+ compileCall(ctx) {
23
+ const v = ctx.resolveInput(this._inputs.vector);
24
+ return [
25
+ `float ${ctx.outputVar(this, 'X')} = (${v}).x;`,
26
+ `float ${ctx.outputVar(this, 'Y')} = (${v}).y;`,
27
+ `float ${ctx.outputVar(this, 'Z')} = (${v}).z;`,
28
+ ].join('\n ');
29
+ }
30
+ }
31
+ SeparateXYZ.instanceSpecificDef = false;