@zephyr3d/scene 0.9.24 → 0.9.26

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 (264) hide show
  1. package/dist/animation/hair/gpu_hair_simulation.js +1090 -0
  2. package/dist/animation/hair/gpu_hair_simulation.js.map +1 -0
  3. package/dist/animation/joint_dynamics/controller.js +7 -5
  4. package/dist/animation/joint_dynamics/controller.js.map +1 -1
  5. package/dist/animation/joint_dynamics/joint_dynamics_system.js +81 -5
  6. package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
  7. package/dist/animation/morphtrack.js +3 -4
  8. package/dist/animation/morphtrack.js.map +1 -1
  9. package/dist/animation/skeleton.js +58 -24
  10. package/dist/animation/skeleton.js.map +1 -1
  11. package/dist/animation/spring/multi_chain_spring_system.js +577 -179
  12. package/dist/animation/spring/multi_chain_spring_system.js.map +1 -1
  13. package/dist/animation/spring/spring_collider.js +4 -3
  14. package/dist/animation/spring/spring_collider.js.map +1 -1
  15. package/dist/animation/spring/spring_node_pose_tracker.js +40 -0
  16. package/dist/animation/spring/spring_node_pose_tracker.js.map +1 -0
  17. package/dist/animation/spring/spring_particle.js +2 -0
  18. package/dist/animation/spring/spring_particle.js.map +1 -1
  19. package/dist/animation/spring/spring_system.js +11 -3
  20. package/dist/animation/spring/spring_system.js.map +1 -1
  21. package/dist/animation/spring_modifier.js +10 -0
  22. package/dist/animation/spring_modifier.js.map +1 -1
  23. package/dist/app/engine.js +53 -43
  24. package/dist/app/engine.js.map +1 -1
  25. package/dist/app/scriptingsystem.js +119 -6
  26. package/dist/app/scriptingsystem.js.map +1 -1
  27. package/dist/app/scriptregistry.js +3 -2
  28. package/dist/app/scriptregistry.js.map +1 -1
  29. package/dist/asset/assetmanager.js +284 -67
  30. package/dist/asset/assetmanager.js.map +1 -1
  31. package/dist/asset/loaders/zhair/zhair_format.js +288 -0
  32. package/dist/asset/loaders/zhair/zhair_format.js.map +1 -0
  33. package/dist/asset/loaders/zhair/zhair_loader.js +221 -0
  34. package/dist/asset/loaders/zhair/zhair_loader.js.map +1 -0
  35. package/dist/asset/model.js +178 -67
  36. package/dist/asset/model.js.map +1 -1
  37. package/dist/camera/camera.js +193 -21
  38. package/dist/camera/camera.js.map +1 -1
  39. package/dist/camera/perspectivecamera.js +3 -1
  40. package/dist/camera/perspectivecamera.js.map +1 -1
  41. package/dist/index.d.ts +4040 -1290
  42. package/dist/index.js +16 -6
  43. package/dist/index.js.map +1 -1
  44. package/dist/material/eye.js +932 -0
  45. package/dist/material/eye.js.map +1 -0
  46. package/dist/material/hair.js +917 -0
  47. package/dist/material/hair.js.map +1 -0
  48. package/dist/material/hairstrand.js +842 -0
  49. package/dist/material/hairstrand.js.map +1 -0
  50. package/dist/material/hairstrand_data.js +162 -0
  51. package/dist/material/hairstrand_data.js.map +1 -0
  52. package/dist/material/lambert.js +5 -2
  53. package/dist/material/lambert.js.map +1 -1
  54. package/dist/material/material.js +338 -300
  55. package/dist/material/material.js.map +1 -1
  56. package/dist/material/meshmaterial.js +120 -19
  57. package/dist/material/meshmaterial.js.map +1 -1
  58. package/dist/material/mixins/albedocolor.js +1 -1
  59. package/dist/material/mixins/albedocolor.js.map +1 -1
  60. package/dist/material/mixins/lightmodel/blinnphong.js +5 -3
  61. package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
  62. package/dist/material/mixins/lightmodel/lambert.js +5 -4
  63. package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
  64. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +3 -3
  65. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
  66. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +5 -5
  67. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  68. package/dist/material/mixins/lightmodel/pbrspecularglossness.js +3 -3
  69. package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
  70. package/dist/material/mixins/lit.js +73 -18
  71. package/dist/material/mixins/lit.js.map +1 -1
  72. package/dist/material/mixins/pbr/common.js +4 -4
  73. package/dist/material/mixins/pbr/common.js.map +1 -1
  74. package/dist/material/mixins/texture.js +48 -11
  75. package/dist/material/mixins/texture.js.map +1 -1
  76. package/dist/material/mtoon.js +6 -5
  77. package/dist/material/mtoon.js.map +1 -1
  78. package/dist/material/pbrblueprint.js +146 -28
  79. package/dist/material/pbrblueprint.js.map +1 -1
  80. package/dist/material/pbrblueprint_instance.js +501 -0
  81. package/dist/material/pbrblueprint_instance.js.map +1 -0
  82. package/dist/material/pbrmr.js +15 -16
  83. package/dist/material/pbrmr.js.map +1 -1
  84. package/dist/material/shader/helper.js +766 -456
  85. package/dist/material/shader/helper.js.map +1 -1
  86. package/dist/material/shader/terrain_blend.js +55 -0
  87. package/dist/material/shader/terrain_blend.js.map +1 -0
  88. package/dist/material/skin.js +192 -32
  89. package/dist/material/skin.js.map +1 -1
  90. package/dist/material/spriteblueprint.js +16 -1
  91. package/dist/material/spriteblueprint.js.map +1 -1
  92. package/dist/material/subsurfaceprofile.js +86 -23
  93. package/dist/material/subsurfaceprofile.js.map +1 -1
  94. package/dist/material/water.js +3 -1
  95. package/dist/material/water.js.map +1 -1
  96. package/dist/posteffect/bloom.js +167 -7
  97. package/dist/posteffect/bloom.js.map +1 -1
  98. package/dist/posteffect/coloradjust.js +2 -1
  99. package/dist/posteffect/coloradjust.js.map +1 -1
  100. package/dist/posteffect/compositor.js.map +1 -1
  101. package/dist/posteffect/fxaa.js +2 -1
  102. package/dist/posteffect/fxaa.js.map +1 -1
  103. package/dist/posteffect/grayscale.js +3 -1
  104. package/dist/posteffect/grayscale.js.map +1 -1
  105. package/dist/posteffect/motionblur.js +4 -1
  106. package/dist/posteffect/motionblur.js.map +1 -1
  107. package/dist/posteffect/posteffect.js.map +1 -1
  108. package/dist/posteffect/skinsss.js +368 -69
  109. package/dist/posteffect/skinsss.js.map +1 -1
  110. package/dist/posteffect/ssgi.js +16 -9
  111. package/dist/posteffect/ssgi.js.map +1 -1
  112. package/dist/posteffect/ssr.js +3 -0
  113. package/dist/posteffect/ssr.js.map +1 -1
  114. package/dist/posteffect/sss.js +91 -34
  115. package/dist/posteffect/sss.js.map +1 -1
  116. package/dist/posteffect/taa.js.map +1 -1
  117. package/dist/posteffect/tonemap.js +44 -1
  118. package/dist/posteffect/tonemap.js.map +1 -1
  119. package/dist/render/abuffer_oit.js +45 -39
  120. package/dist/render/abuffer_oit.js.map +1 -1
  121. package/dist/render/cluster_light.js +4 -4
  122. package/dist/render/cluster_light.js.map +1 -1
  123. package/dist/render/cull_visitor.js +19 -0
  124. package/dist/render/cull_visitor.js.map +1 -1
  125. package/dist/render/depthpass.js +36 -2
  126. package/dist/render/depthpass.js.map +1 -1
  127. package/dist/render/drawable_mixin.js +26 -1
  128. package/dist/render/drawable_mixin.js.map +1 -1
  129. package/dist/render/dualdepthpeeling_oit.js +52 -51
  130. package/dist/render/dualdepthpeeling_oit.js.map +1 -1
  131. package/dist/render/envlight.js +1 -1
  132. package/dist/render/envlight.js.map +1 -1
  133. package/dist/render/fbm_wavegenerator.js +3 -0
  134. package/dist/render/fbm_wavegenerator.js.map +1 -1
  135. package/dist/render/gerstner_wavegenerator.js +3 -0
  136. package/dist/render/gerstner_wavegenerator.js.map +1 -1
  137. package/dist/render/globalbindgroup_allocator.js +3 -0
  138. package/dist/render/globalbindgroup_allocator.js.map +1 -1
  139. package/dist/render/oit.js +29 -0
  140. package/dist/render/oit.js.map +1 -0
  141. package/dist/render/render_queue.js +3 -0
  142. package/dist/render/render_queue.js.map +1 -1
  143. package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
  144. package/dist/render/rendergraph/executor.js +2 -0
  145. package/dist/render/rendergraph/executor.js.map +1 -1
  146. package/dist/render/rendergraph/forward_plus_builder.js +61 -1
  147. package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
  148. package/dist/render/rendergraph/rendergraph.js.map +1 -1
  149. package/dist/render/rendergraph/texture_affinity_cache.js +1 -1
  150. package/dist/render/rendergraph/texture_affinity_cache.js.map +1 -1
  151. package/dist/render/rendergraph/types.js.map +1 -1
  152. package/dist/render/shadow_mask_pass.js +73 -8
  153. package/dist/render/shadow_mask_pass.js.map +1 -1
  154. package/dist/render/sky.js +166 -126
  155. package/dist/render/sky.js.map +1 -1
  156. package/dist/render/weightedblended_oit.js +36 -35
  157. package/dist/render/weightedblended_oit.js.map +1 -1
  158. package/dist/scene/basesprite.js +8 -0
  159. package/dist/scene/basesprite.js.map +1 -1
  160. package/dist/scene/batchgroup.js +3 -0
  161. package/dist/scene/batchgroup.js.map +1 -1
  162. package/dist/scene/environment.js +4 -1
  163. package/dist/scene/environment.js.map +1 -1
  164. package/dist/scene/hair.js +963 -0
  165. package/dist/scene/hair.js.map +1 -0
  166. package/dist/scene/light.js +5 -1
  167. package/dist/scene/light.js.map +1 -1
  168. package/dist/scene/mesh.js +481 -47
  169. package/dist/scene/mesh.js.map +1 -1
  170. package/dist/scene/meshdrawable.js +6 -0
  171. package/dist/scene/meshdrawable.js.map +1 -1
  172. package/dist/scene/msdftext.js +3 -0
  173. package/dist/scene/msdftext.js.map +1 -1
  174. package/dist/scene/msdftextsprite.js +3 -0
  175. package/dist/scene/msdftextsprite.js.map +1 -1
  176. package/dist/scene/particlesys.js +6 -0
  177. package/dist/scene/particlesys.js.map +1 -1
  178. package/dist/scene/scene.js +3 -0
  179. package/dist/scene/scene.js.map +1 -1
  180. package/dist/scene/scene_node.js +6 -1
  181. package/dist/scene/scene_node.js.map +1 -1
  182. package/dist/scene/terrain-cm/grass.js +273 -249
  183. package/dist/scene/terrain-cm/grass.js.map +1 -1
  184. package/dist/scene/terrain-cm/grassmaterial.js +3 -0
  185. package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
  186. package/dist/scene/terrain-cm/terrain-cm.js +6 -0
  187. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  188. package/dist/scene/terrain-cm/texture_cache.js +309 -0
  189. package/dist/scene/terrain-cm/texture_cache.js.map +1 -0
  190. package/dist/scene/water.js +6 -0
  191. package/dist/scene/water.js.map +1 -1
  192. package/dist/shaders/atmosphere.js.map +1 -1
  193. package/dist/shaders/diffusion.js +54 -0
  194. package/dist/shaders/diffusion.js.map +1 -0
  195. package/dist/shaders/shadow.js +33 -21
  196. package/dist/shaders/shadow.js.map +1 -1
  197. package/dist/shaders/temporal.js +71 -33
  198. package/dist/shaders/temporal.js.map +1 -1
  199. package/dist/shadow/dom.js +546 -0
  200. package/dist/shadow/dom.js.map +1 -0
  201. package/dist/shadow/pcf_opt.js +3 -5
  202. package/dist/shadow/pcf_opt.js.map +1 -1
  203. package/dist/shadow/pcf_pd.js +1 -1
  204. package/dist/shadow/pcf_pd.js.map +1 -1
  205. package/dist/shadow/receiver_bias.js +41 -0
  206. package/dist/shadow/receiver_bias.js.map +1 -0
  207. package/dist/shadow/shader.js +20 -60
  208. package/dist/shadow/shader.js.map +1 -1
  209. package/dist/shadow/shadow_impl.js +89 -0
  210. package/dist/shadow/shadow_impl.js.map +1 -1
  211. package/dist/shadow/shadow_region.js +50 -50
  212. package/dist/shadow/shadow_region.js.map +1 -1
  213. package/dist/shadow/shadowmapper.js +150 -37
  214. package/dist/shadow/shadowmapper.js.map +1 -1
  215. package/dist/shapes/shape.js +11 -2
  216. package/dist/shapes/shape.js.map +1 -1
  217. package/dist/shapes/sphere.js +50 -9
  218. package/dist/shapes/sphere.js.map +1 -1
  219. package/dist/utility/blueprint/common/constants.js +112 -2
  220. package/dist/utility/blueprint/common/constants.js.map +1 -1
  221. package/dist/utility/blueprint/material/func.js +142 -49
  222. package/dist/utility/blueprint/material/func.js.map +1 -1
  223. package/dist/utility/blueprint/material/ir.js +490 -25
  224. package/dist/utility/blueprint/material/ir.js.map +1 -1
  225. package/dist/utility/blueprint/material/texture.js +898 -4
  226. package/dist/utility/blueprint/material/texture.js.map +1 -1
  227. package/dist/utility/serialization/manager.js +431 -100
  228. package/dist/utility/serialization/manager.js.map +1 -1
  229. package/dist/utility/serialization/scene/animation.js +370 -3
  230. package/dist/utility/serialization/scene/animation.js.map +1 -1
  231. package/dist/utility/serialization/scene/batch.js +4 -0
  232. package/dist/utility/serialization/scene/batch.js.map +1 -1
  233. package/dist/utility/serialization/scene/camera.js +133 -1
  234. package/dist/utility/serialization/scene/camera.js.map +1 -1
  235. package/dist/utility/serialization/scene/common.js +26 -5
  236. package/dist/utility/serialization/scene/common.js.map +1 -1
  237. package/dist/utility/serialization/scene/hair.js +1141 -0
  238. package/dist/utility/serialization/scene/hair.js.map +1 -0
  239. package/dist/utility/serialization/scene/light.js +84 -4
  240. package/dist/utility/serialization/scene/light.js.map +1 -1
  241. package/dist/utility/serialization/scene/material.js +1867 -166
  242. package/dist/utility/serialization/scene/material.js.map +1 -1
  243. package/dist/utility/serialization/scene/mesh.js +231 -14
  244. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  245. package/dist/utility/serialization/scene/node.js +141 -7
  246. package/dist/utility/serialization/scene/node.js.map +1 -1
  247. package/dist/utility/serialization/scene/particle.js +4 -0
  248. package/dist/utility/serialization/scene/particle.js.map +1 -1
  249. package/dist/utility/serialization/scene/primitive.js +18 -0
  250. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  251. package/dist/utility/serialization/scene/sprite.js +4 -0
  252. package/dist/utility/serialization/scene/sprite.js.map +1 -1
  253. package/dist/utility/serialization/scene/terrain.js +92 -69
  254. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  255. package/dist/utility/serialization/scene/text.js +4 -0
  256. package/dist/utility/serialization/scene/text.js.map +1 -1
  257. package/dist/utility/serialization/scene/water.js +4 -0
  258. package/dist/utility/serialization/scene/water.js.map +1 -1
  259. package/dist/utility/serialization/types.js.map +1 -1
  260. package/dist/utility/shprojector.js +96 -95
  261. package/dist/utility/shprojector.js.map +1 -1
  262. package/dist/values.js +105 -58
  263. package/dist/values.js.map +1 -1
  264. package/package.json +3 -3
@@ -25,7 +25,7 @@ import { defineProps } from '../../serialization/types.js';
25
25
  *
26
26
  * @returns A 1x1 white Texture2D instance
27
27
  *
28
- * @internal
28
+ * @public
29
29
  */ function getDefaultTexture2D() {
30
30
  if (!defaultTexture2D.get()) {
31
31
  const defaultTex = getDevice().createTexture2D('rgba8unorm', 1, 1, {
@@ -50,7 +50,7 @@ import { defineProps } from '../../serialization/types.js';
50
50
  *
51
51
  * @returns A 1x1x1 white Texture2DArray instance
52
52
  *
53
- * @internal
53
+ * @public
54
54
  */ function getDefaultTexture2DArray() {
55
55
  if (!defaultTexture2DArray.get()) {
56
56
  const defaultTex = getDevice().createTexture2DArray('rgba8unorm', 1, 1, 1, {
@@ -75,7 +75,7 @@ import { defineProps } from '../../serialization/types.js';
75
75
  *
76
76
  * @returns A 1x1 white TextureCube instance
77
77
  *
78
- * @internal
78
+ * @public
79
79
  */ function getDefaultTextureCube() {
80
80
  if (!defaultTextureCube.get()) {
81
81
  const defaultTex = getDevice().createCubeTexture('rgba8unorm', 1, {
@@ -126,6 +126,23 @@ import { defineProps } from '../../serialization/types.js';
126
126
  }
127
127
  }
128
128
  },
129
+ {
130
+ name: 'Expose',
131
+ type: 'bool',
132
+ default: true,
133
+ options: {
134
+ label: 'Expose'
135
+ },
136
+ get (value) {
137
+ value.bool[0] = this.expose;
138
+ },
139
+ set (value) {
140
+ this.expose = value.bool[0];
141
+ },
142
+ isHidden () {
143
+ return this instanceof TextureSampleNode && !!this.inputs[0]?.inputNode;
144
+ }
145
+ },
129
146
  {
130
147
  name: 'sRGB',
131
148
  type: 'bool',
@@ -306,6 +323,7 @@ import { defineProps } from '../../serialization/types.js';
306
323
  * @public
307
324
  */ class BaseTextureNode extends BaseGraphNode {
308
325
  /** The shader parameter name for this texture uniform */ _paramName;
326
+ /** Whether this texture uniform should be exposed to material instances */ _expose;
309
327
  /** Whether this texture should be loaded in sRGB color space */ sRGB;
310
328
  /** Horizontal texture coordinate wrapping mode */ addressU;
311
329
  /** Vertical texture coordinate wrapping mode */ addressV;
@@ -326,6 +344,7 @@ import { defineProps } from '../../serialization/types.js';
326
344
  */ constructor(){
327
345
  super();
328
346
  this._paramName = getParamName();
347
+ this._expose = true;
329
348
  this.sRGB = true;
330
349
  this.addressU = 'clamp';
331
350
  this.addressV = 'clamp';
@@ -348,6 +367,17 @@ import { defineProps } from '../../serialization/types.js';
348
367
  }
349
368
  }
350
369
  /**
370
+ * Whether this texture parameter should be exposed to material instances.
371
+ */ get expose() {
372
+ return this._expose;
373
+ }
374
+ set expose(val) {
375
+ if (this._expose !== val) {
376
+ this._expose = val;
377
+ this.dispatchEvent('changed');
378
+ }
379
+ }
380
+ /**
351
381
  * Indicates this node represents a shader uniform
352
382
  *
353
383
  * @returns Always true for texture nodes
@@ -968,6 +998,7 @@ import { defineProps } from '../../serialization/types.js';
968
998
  */ class TextureSampleNode extends BaseGraphNode {
969
999
  /** The type of sampling (Color or Normal) */ samplerType;
970
1000
  /** The shader parameter name for fallback texture uniform */ _paramName;
1001
+ /** Whether fallback texture parameter should be exposed to material instances */ _expose;
971
1002
  /** Asset ID for fallback texture (used when texture input is not connected) */ textureId;
972
1003
  /** Whether fallback texture should be loaded in sRGB color space */ sRGB;
973
1004
  /** Horizontal texture coordinate wrapping mode for fallback texture */ addressU;
@@ -987,6 +1018,7 @@ import { defineProps } from '../../serialization/types.js';
987
1018
  super();
988
1019
  this.samplerType = 'Color';
989
1020
  this._paramName = getParamName();
1021
+ this._expose = true;
990
1022
  this.textureId = '';
991
1023
  this.sRGB = true;
992
1024
  this.addressU = 'clamp';
@@ -1064,6 +1096,20 @@ import { defineProps } from '../../serialization/types.js';
1064
1096
  }
1065
1097
  }
1066
1098
  /**
1099
+ * Whether fallback texture parameter should be exposed to material instances.
1100
+ *
1101
+ * @remarks
1102
+ * Only meaningful when the texture input is not connected.
1103
+ */ get expose() {
1104
+ return this._expose;
1105
+ }
1106
+ set expose(val) {
1107
+ if (this._expose !== val) {
1108
+ this._expose = val;
1109
+ this.dispatchEvent('changed');
1110
+ }
1111
+ }
1112
+ /**
1067
1113
  * Gets the serialization descriptor for this node type
1068
1114
  *
1069
1115
  * @returns Serialization class descriptor
@@ -1194,6 +1240,854 @@ import { defineProps } from '../../serialization/types.js';
1194
1240
  }
1195
1241
  }
1196
1242
  }
1243
+ /**
1244
+ * Texture property query node
1245
+ *
1246
+ * @remarks
1247
+ * Queries metadata derived from a texture object, similar to Unreal Engine's
1248
+ * `TextureProperty` material expression.
1249
+ *
1250
+ * Supported properties:
1251
+ * - `TextureSize`: returns the texture dimensions as a vec2
1252
+ * - `TexelSize`: returns `1 / textureDimensions` as a vec2
1253
+ *
1254
+ * Inputs:
1255
+ * - Input 1: Texture sampler (tex2D, tex2DArray, or texCube)
1256
+ *
1257
+ * Outputs:
1258
+ * - Output 1: Full property value (vec2)
1259
+ * - Output 2: X component (float)
1260
+ * - Output 3: Y component (float)
1261
+ *
1262
+ * @public
1263
+ */ class TexturePropertyNode extends BaseGraphNode {
1264
+ /** The queried texture property */ property;
1265
+ /**
1266
+ * Creates a new texture property node
1267
+ *
1268
+ * @remarks
1269
+ * Initializes with:
1270
+ * - One required texture input
1271
+ * - One vec2 output and two scalar swizzled outputs
1272
+ * - `TexelSize` as default property
1273
+ */ constructor(){
1274
+ super();
1275
+ this.property = 'TexelSize';
1276
+ this._outputs = [
1277
+ {
1278
+ id: 1,
1279
+ name: ''
1280
+ },
1281
+ {
1282
+ id: 2,
1283
+ name: 'x',
1284
+ swizzle: 'x'
1285
+ },
1286
+ {
1287
+ id: 3,
1288
+ name: 'y',
1289
+ swizzle: 'y'
1290
+ }
1291
+ ];
1292
+ this._inputs = [
1293
+ {
1294
+ id: 1,
1295
+ name: 'texture',
1296
+ type: [
1297
+ 'tex2D',
1298
+ 'tex2DArray',
1299
+ 'texCube'
1300
+ ],
1301
+ required: true
1302
+ }
1303
+ ];
1304
+ }
1305
+ /**
1306
+ * Gets the serialization descriptor for this node type
1307
+ *
1308
+ * @returns Serialization class descriptor
1309
+ */ static getSerializationCls() {
1310
+ return {
1311
+ ctor: TexturePropertyNode,
1312
+ name: 'TexturePropertyNode',
1313
+ getProps () {
1314
+ return defineProps([
1315
+ {
1316
+ name: 'Property',
1317
+ type: 'string',
1318
+ options: {
1319
+ enum: {
1320
+ labels: [
1321
+ 'TextureSize',
1322
+ 'TexelSize'
1323
+ ],
1324
+ values: [
1325
+ 'TextureSize',
1326
+ 'TexelSize'
1327
+ ]
1328
+ }
1329
+ },
1330
+ get (value) {
1331
+ value.str[0] = this.property;
1332
+ },
1333
+ set (value) {
1334
+ this.property = value.str[0];
1335
+ }
1336
+ }
1337
+ ]);
1338
+ }
1339
+ };
1340
+ }
1341
+ /**
1342
+ * Generates a string representation of this node
1343
+ *
1344
+ * @returns `textureProperty`
1345
+ */ toString() {
1346
+ return 'textureProperty';
1347
+ }
1348
+ /**
1349
+ * Validates the node state and input type compatibility
1350
+ *
1351
+ * @returns Error message if invalid, empty string if valid
1352
+ */ validate() {
1353
+ const err = super.validate();
1354
+ if (err) {
1355
+ return err;
1356
+ }
1357
+ const textureInput = this._inputs[0];
1358
+ const textureType = textureInput.inputNode?.getOutputType(textureInput.inputId);
1359
+ if (!textureType) {
1360
+ return `Cannot determine type of argument \`${textureInput.name}\``;
1361
+ }
1362
+ if (!textureInput.type.includes(textureType)) {
1363
+ return `Invalid input type of argument \`${textureInput.name}\`: ${textureType}`;
1364
+ }
1365
+ return '';
1366
+ }
1367
+ /**
1368
+ * Gets the output type
1369
+ */ getType(id) {
1370
+ const err = this.validate();
1371
+ if (err) {
1372
+ return '';
1373
+ }
1374
+ return id === 1 ? 'vec2' : 'float';
1375
+ }
1376
+ }
1377
+ /**
1378
+ * Channel SDF mask evaluation node
1379
+ *
1380
+ * @remarks
1381
+ * Samples a channel-packed SDF texture and reconstructs a feathered mask
1382
+ * by decoding the stored value back into signed distance space.
1383
+ *
1384
+ * Inputs:
1385
+ * - `texture`: source SDF texture
1386
+ * - `coord`: UV coordinates, defaults to vertex UV when disconnected
1387
+ * - `sizeOffset`: positive expands, negative shrinks, in SDF distance units
1388
+ * - `feather`: transition width around the boundary, in SDF distance units
1389
+ * - `spread`: encode range used when baking the SDF texture
1390
+ * - `edgeCurve`: edge response curve, `1` keeps linear behavior, `>1` softens, `<1` hardens
1391
+ * - `channelMask`: channel selector mask, defaults to R
1392
+ *
1393
+ * Output:
1394
+ * - `Result`: scalar mask in `[0, 1]`
1395
+ *
1396
+ * @public
1397
+ */ class ChannelSDFMaskNode extends BaseGraphNode {
1398
+ _paramName;
1399
+ _expose;
1400
+ textureId;
1401
+ sRGB;
1402
+ addressU;
1403
+ addressV;
1404
+ filterMin;
1405
+ filterMag;
1406
+ filterMip;
1407
+ constructor(){
1408
+ super();
1409
+ this._paramName = getParamName();
1410
+ this._expose = true;
1411
+ this.textureId = '';
1412
+ this.sRGB = true;
1413
+ this.addressU = 'clamp';
1414
+ this.addressV = 'clamp';
1415
+ this.filterMin = 'linear';
1416
+ this.filterMag = 'linear';
1417
+ this.filterMip = 'nearest';
1418
+ this._inputs = [
1419
+ {
1420
+ id: 1,
1421
+ name: 'texture',
1422
+ type: [
1423
+ 'tex2D'
1424
+ ],
1425
+ required: false
1426
+ },
1427
+ {
1428
+ id: 2,
1429
+ name: 'coord',
1430
+ type: [
1431
+ 'vec2'
1432
+ ],
1433
+ required: false
1434
+ },
1435
+ {
1436
+ id: 3,
1437
+ name: 'sizeOffset',
1438
+ type: [
1439
+ 'float'
1440
+ ],
1441
+ required: false,
1442
+ defaultValue: [
1443
+ 0
1444
+ ]
1445
+ },
1446
+ {
1447
+ id: 4,
1448
+ name: 'feather',
1449
+ type: [
1450
+ 'float'
1451
+ ],
1452
+ required: false,
1453
+ defaultValue: [
1454
+ 0
1455
+ ]
1456
+ },
1457
+ {
1458
+ id: 5,
1459
+ name: 'spread',
1460
+ type: [
1461
+ 'float'
1462
+ ],
1463
+ required: false,
1464
+ defaultValue: [
1465
+ 16
1466
+ ]
1467
+ },
1468
+ {
1469
+ id: 6,
1470
+ name: 'edgeCurve',
1471
+ type: [
1472
+ 'float'
1473
+ ],
1474
+ required: false,
1475
+ defaultValue: [
1476
+ 1
1477
+ ]
1478
+ },
1479
+ {
1480
+ id: 7,
1481
+ name: 'channelMask',
1482
+ type: [
1483
+ 'vec4'
1484
+ ],
1485
+ required: false,
1486
+ defaultValue: [
1487
+ 1,
1488
+ 0,
1489
+ 0,
1490
+ 0
1491
+ ]
1492
+ }
1493
+ ];
1494
+ this._outputs = [
1495
+ {
1496
+ id: 1,
1497
+ name: 'Result'
1498
+ }
1499
+ ];
1500
+ }
1501
+ get isUniform() {
1502
+ return !this._inputs[0].inputNode;
1503
+ }
1504
+ get paramName() {
1505
+ return this._paramName;
1506
+ }
1507
+ set paramName(val) {
1508
+ if (this._paramName !== val) {
1509
+ this._paramName = val;
1510
+ this.dispatchEvent('changed');
1511
+ }
1512
+ }
1513
+ get expose() {
1514
+ return this._expose;
1515
+ }
1516
+ set expose(val) {
1517
+ if (this._expose !== val) {
1518
+ this._expose = val;
1519
+ this.dispatchEvent('changed');
1520
+ }
1521
+ }
1522
+ get sizeOffset() {
1523
+ return this._inputs[2].defaultValue?.[0] ?? 0;
1524
+ }
1525
+ set sizeOffset(val) {
1526
+ if (this.sizeOffset !== val) {
1527
+ this._inputs[2].defaultValue = [
1528
+ val
1529
+ ];
1530
+ this.dispatchEvent('changed');
1531
+ }
1532
+ }
1533
+ get feather() {
1534
+ return this._inputs[3].defaultValue?.[0] ?? 0;
1535
+ }
1536
+ set feather(val) {
1537
+ if (this.feather !== val) {
1538
+ this._inputs[3].defaultValue = [
1539
+ val
1540
+ ];
1541
+ this.dispatchEvent('changed');
1542
+ }
1543
+ }
1544
+ get spread() {
1545
+ return this._inputs[4].defaultValue?.[0] ?? 16;
1546
+ }
1547
+ set spread(val) {
1548
+ if (this.spread !== val) {
1549
+ this._inputs[4].defaultValue = [
1550
+ val
1551
+ ];
1552
+ this.dispatchEvent('changed');
1553
+ }
1554
+ }
1555
+ get edgeCurve() {
1556
+ return this._inputs[5].defaultValue?.[0] ?? 1;
1557
+ }
1558
+ set edgeCurve(val) {
1559
+ if (this.edgeCurve !== val) {
1560
+ this._inputs[5].defaultValue = [
1561
+ val
1562
+ ];
1563
+ this.dispatchEvent('changed');
1564
+ }
1565
+ }
1566
+ get channelMask() {
1567
+ return [
1568
+ ...this._inputs[6].defaultValue ?? [
1569
+ 1,
1570
+ 0,
1571
+ 0,
1572
+ 0
1573
+ ]
1574
+ ];
1575
+ }
1576
+ set channelMask(val) {
1577
+ const next = [
1578
+ val[0] ?? 0,
1579
+ val[1] ?? 0,
1580
+ val[2] ?? 0,
1581
+ val[3] ?? 0
1582
+ ];
1583
+ const prev = this.channelMask;
1584
+ if (prev.some((v, i)=>v !== next[i])) {
1585
+ this._inputs[6].defaultValue = next;
1586
+ this.dispatchEvent('changed');
1587
+ }
1588
+ }
1589
+ static getSerializationCls() {
1590
+ return {
1591
+ ctor: ChannelSDFMaskNode,
1592
+ name: 'ChannelSDFMaskNode',
1593
+ getProps () {
1594
+ return defineProps([
1595
+ ...textureNodeProps,
1596
+ {
1597
+ name: 'Texture',
1598
+ type: 'object',
1599
+ default: null,
1600
+ options: {
1601
+ mimeTypes: [
1602
+ 'image/jpeg',
1603
+ 'image/png',
1604
+ 'image/tga',
1605
+ 'image/vnd.radiance',
1606
+ 'image/x-dds',
1607
+ 'image/webp'
1608
+ ]
1609
+ },
1610
+ isNullable () {
1611
+ return true;
1612
+ },
1613
+ get (value) {
1614
+ value.str[0] = this.textureId;
1615
+ },
1616
+ async set (value) {
1617
+ const path = value?.str?.[0];
1618
+ this.textureId = typeof path === 'string' ? path : '';
1619
+ }
1620
+ },
1621
+ {
1622
+ name: 'SizeOffset',
1623
+ type: 'float',
1624
+ description: 'Used when the sizeOffset pin is not connected.',
1625
+ get (value) {
1626
+ value.num[0] = this.sizeOffset;
1627
+ },
1628
+ set (value) {
1629
+ this.sizeOffset = value.num[0];
1630
+ }
1631
+ },
1632
+ {
1633
+ name: 'Feather',
1634
+ type: 'float',
1635
+ description: 'Used when the feather pin is not connected.',
1636
+ get (value) {
1637
+ value.num[0] = this.feather;
1638
+ },
1639
+ set (value) {
1640
+ this.feather = value.num[0];
1641
+ }
1642
+ },
1643
+ {
1644
+ name: 'Spread',
1645
+ type: 'float',
1646
+ description: 'Used when the spread pin is not connected.',
1647
+ get (value) {
1648
+ value.num[0] = this.spread;
1649
+ },
1650
+ set (value) {
1651
+ this.spread = value.num[0];
1652
+ }
1653
+ },
1654
+ {
1655
+ name: 'EdgeCurve',
1656
+ type: 'float',
1657
+ description: 'Used when the edgeCurve pin is not connected.',
1658
+ get (value) {
1659
+ value.num[0] = this.edgeCurve;
1660
+ },
1661
+ set (value) {
1662
+ this.edgeCurve = value.num[0];
1663
+ }
1664
+ },
1665
+ {
1666
+ name: 'ChannelMaskR',
1667
+ type: 'float',
1668
+ description: 'Used when the channelMask pin is not connected.',
1669
+ get (value) {
1670
+ value.num[0] = this.channelMask[0];
1671
+ },
1672
+ set (value) {
1673
+ const next = this.channelMask;
1674
+ next[0] = value.num[0];
1675
+ this.channelMask = next;
1676
+ }
1677
+ },
1678
+ {
1679
+ name: 'ChannelMaskG',
1680
+ type: 'float',
1681
+ description: 'Used when the channelMask pin is not connected.',
1682
+ get (value) {
1683
+ value.num[0] = this.channelMask[1];
1684
+ },
1685
+ set (value) {
1686
+ const next = this.channelMask;
1687
+ next[1] = value.num[0];
1688
+ this.channelMask = next;
1689
+ }
1690
+ },
1691
+ {
1692
+ name: 'ChannelMaskB',
1693
+ type: 'float',
1694
+ description: 'Used when the channelMask pin is not connected.',
1695
+ get (value) {
1696
+ value.num[0] = this.channelMask[2];
1697
+ },
1698
+ set (value) {
1699
+ const next = this.channelMask;
1700
+ next[2] = value.num[0];
1701
+ this.channelMask = next;
1702
+ }
1703
+ },
1704
+ {
1705
+ name: 'ChannelMaskA',
1706
+ type: 'float',
1707
+ description: 'Used when the channelMask pin is not connected.',
1708
+ get (value) {
1709
+ value.num[0] = this.channelMask[3];
1710
+ },
1711
+ set (value) {
1712
+ const next = this.channelMask;
1713
+ next[3] = value.num[0];
1714
+ this.channelMask = next;
1715
+ }
1716
+ }
1717
+ ]);
1718
+ }
1719
+ };
1720
+ }
1721
+ toString() {
1722
+ return 'ChannelSDFMask';
1723
+ }
1724
+ validate() {
1725
+ const err = super.validate();
1726
+ if (err) {
1727
+ return err;
1728
+ }
1729
+ const textureInput = this._inputs[0];
1730
+ const textureType = textureInput.inputNode ? textureInput.inputNode.getOutputType(textureInput.inputId) : 'tex2D';
1731
+ if (textureInput.inputNode) {
1732
+ if (!textureType) {
1733
+ return `Cannot determine type of argument \`${textureInput.name}\``;
1734
+ }
1735
+ if (textureType !== 'tex2D') {
1736
+ return 'Texture input must be tex2D';
1737
+ }
1738
+ } else if (!this.textureId) {
1739
+ return 'Texture not specified';
1740
+ }
1741
+ const coordType = this._inputs[1].inputNode?.getOutputType(this._inputs[1].inputId);
1742
+ if (coordType && coordType !== 'vec2') {
1743
+ return 'Texture coordinate type should be vec2';
1744
+ }
1745
+ const sizeType = this._inputs[2].inputNode?.getOutputType(this._inputs[2].inputId);
1746
+ if (sizeType && sizeType !== 'float') {
1747
+ return 'Size offset type should be float';
1748
+ }
1749
+ const featherType = this._inputs[3].inputNode?.getOutputType(this._inputs[3].inputId);
1750
+ if (featherType && featherType !== 'float') {
1751
+ return 'Feather type should be float';
1752
+ }
1753
+ const spreadType = this._inputs[4].inputNode?.getOutputType(this._inputs[4].inputId);
1754
+ if (spreadType && spreadType !== 'float') {
1755
+ return 'Spread type should be float';
1756
+ }
1757
+ const edgeCurveType = this._inputs[5].inputNode?.getOutputType(this._inputs[5].inputId);
1758
+ if (edgeCurveType && edgeCurveType !== 'float') {
1759
+ return 'Edge curve type should be float';
1760
+ }
1761
+ const maskType = this._inputs[6].inputNode?.getOutputType(this._inputs[6].inputId);
1762
+ if (maskType && maskType !== 'vec4') {
1763
+ return 'Channel mask type should be vec4';
1764
+ }
1765
+ return '';
1766
+ }
1767
+ getType() {
1768
+ return this.validate() ? '' : 'float';
1769
+ }
1770
+ }
1771
+ /**
1772
+ * Morph + blur node
1773
+ *
1774
+ * @remarks
1775
+ * Applies channel morphology and Gaussian blur in a single node. The node
1776
+ * short-circuits internally so that when one radius is zero it falls back to
1777
+ * the corresponding single-stage path instead of always paying for the full
1778
+ * combined cost.
1779
+ *
1780
+ * Inputs:
1781
+ * - `texture`: source mask texture
1782
+ * - `coord`: UV coordinates, defaults to vertex UV when disconnected
1783
+ * - `morphRadius`: positive expands, negative shrinks, zero disables morph
1784
+ * - `blurRadius`: blur radius in texel units, zero disables blur
1785
+ * - `channelMask`: channel selector mask, defaults to R
1786
+ *
1787
+ * Output:
1788
+ * - `Result`: scalar sampled value
1789
+ *
1790
+ * @public
1791
+ */ class MorphBlurNode extends BaseGraphNode {
1792
+ _paramName;
1793
+ _expose;
1794
+ textureId;
1795
+ sRGB;
1796
+ addressU;
1797
+ addressV;
1798
+ filterMin;
1799
+ filterMag;
1800
+ filterMip;
1801
+ constructor(){
1802
+ super();
1803
+ this._paramName = getParamName();
1804
+ this._expose = true;
1805
+ this.textureId = '';
1806
+ this.sRGB = true;
1807
+ this.addressU = 'clamp';
1808
+ this.addressV = 'clamp';
1809
+ this.filterMin = 'linear';
1810
+ this.filterMag = 'linear';
1811
+ this.filterMip = 'nearest';
1812
+ this._inputs = [
1813
+ {
1814
+ id: 1,
1815
+ name: 'texture',
1816
+ type: [
1817
+ 'tex2D'
1818
+ ],
1819
+ required: false
1820
+ },
1821
+ {
1822
+ id: 2,
1823
+ name: 'coord',
1824
+ type: [
1825
+ 'vec2'
1826
+ ],
1827
+ required: false
1828
+ },
1829
+ {
1830
+ id: 3,
1831
+ name: 'morphRadius',
1832
+ type: [
1833
+ 'float'
1834
+ ],
1835
+ required: false,
1836
+ defaultValue: [
1837
+ 0
1838
+ ]
1839
+ },
1840
+ {
1841
+ id: 4,
1842
+ name: 'blurRadius',
1843
+ type: [
1844
+ 'float'
1845
+ ],
1846
+ required: false,
1847
+ defaultValue: [
1848
+ 0
1849
+ ]
1850
+ },
1851
+ {
1852
+ id: 5,
1853
+ name: 'channelMask',
1854
+ type: [
1855
+ 'vec4'
1856
+ ],
1857
+ required: false,
1858
+ defaultValue: [
1859
+ 1,
1860
+ 0,
1861
+ 0,
1862
+ 0
1863
+ ]
1864
+ }
1865
+ ];
1866
+ this._outputs = [
1867
+ {
1868
+ id: 1,
1869
+ name: 'Result'
1870
+ }
1871
+ ];
1872
+ }
1873
+ get isUniform() {
1874
+ return !this._inputs[0].inputNode;
1875
+ }
1876
+ get paramName() {
1877
+ return this._paramName;
1878
+ }
1879
+ set paramName(val) {
1880
+ if (this._paramName !== val) {
1881
+ this._paramName = val;
1882
+ this.dispatchEvent('changed');
1883
+ }
1884
+ }
1885
+ get expose() {
1886
+ return this._expose;
1887
+ }
1888
+ set expose(val) {
1889
+ if (this._expose !== val) {
1890
+ this._expose = val;
1891
+ this.dispatchEvent('changed');
1892
+ }
1893
+ }
1894
+ get morphRadius() {
1895
+ return this._inputs[2].defaultValue?.[0] ?? 0;
1896
+ }
1897
+ set morphRadius(val) {
1898
+ if (this.morphRadius !== val) {
1899
+ this._inputs[2].defaultValue = [
1900
+ val
1901
+ ];
1902
+ this.dispatchEvent('changed');
1903
+ }
1904
+ }
1905
+ get blurRadius() {
1906
+ return this._inputs[3].defaultValue?.[0] ?? 0;
1907
+ }
1908
+ set blurRadius(val) {
1909
+ if (this.blurRadius !== val) {
1910
+ this._inputs[3].defaultValue = [
1911
+ val
1912
+ ];
1913
+ this.dispatchEvent('changed');
1914
+ }
1915
+ }
1916
+ get channelMask() {
1917
+ return [
1918
+ ...this._inputs[4].defaultValue ?? [
1919
+ 1,
1920
+ 0,
1921
+ 0,
1922
+ 0
1923
+ ]
1924
+ ];
1925
+ }
1926
+ set channelMask(val) {
1927
+ const next = [
1928
+ val[0] ?? 0,
1929
+ val[1] ?? 0,
1930
+ val[2] ?? 0,
1931
+ val[3] ?? 0
1932
+ ];
1933
+ const prev = this.channelMask;
1934
+ if (prev.some((v, i)=>v !== next[i])) {
1935
+ this._inputs[4].defaultValue = next;
1936
+ this.dispatchEvent('changed');
1937
+ }
1938
+ }
1939
+ static getSerializationCls() {
1940
+ return {
1941
+ ctor: MorphBlurNode,
1942
+ name: 'MorphBlurNode',
1943
+ getProps () {
1944
+ return defineProps([
1945
+ ...textureNodeProps,
1946
+ {
1947
+ name: 'Texture',
1948
+ type: 'object',
1949
+ default: null,
1950
+ options: {
1951
+ mimeTypes: [
1952
+ 'image/jpeg',
1953
+ 'image/png',
1954
+ 'image/tga',
1955
+ 'image/vnd.radiance',
1956
+ 'image/x-dds',
1957
+ 'image/webp'
1958
+ ]
1959
+ },
1960
+ isNullable () {
1961
+ return true;
1962
+ },
1963
+ get (value) {
1964
+ value.str[0] = this.textureId;
1965
+ },
1966
+ async set (value) {
1967
+ const path = value?.str?.[0];
1968
+ this.textureId = typeof path === 'string' ? path : '';
1969
+ }
1970
+ },
1971
+ {
1972
+ name: 'MorphRadius',
1973
+ type: 'float',
1974
+ description: 'Used when the morphRadius pin is not connected.',
1975
+ get (value) {
1976
+ value.num[0] = this.morphRadius;
1977
+ },
1978
+ set (value) {
1979
+ this.morphRadius = value.num[0];
1980
+ }
1981
+ },
1982
+ {
1983
+ name: 'BlurRadius',
1984
+ type: 'float',
1985
+ description: 'Used when the blurRadius pin is not connected.',
1986
+ get (value) {
1987
+ value.num[0] = this.blurRadius;
1988
+ },
1989
+ set (value) {
1990
+ this.blurRadius = value.num[0];
1991
+ }
1992
+ },
1993
+ {
1994
+ name: 'ChannelMaskR',
1995
+ type: 'float',
1996
+ description: 'Used when the channelMask pin is not connected.',
1997
+ get (value) {
1998
+ value.num[0] = this.channelMask[0];
1999
+ },
2000
+ set (value) {
2001
+ const next = this.channelMask;
2002
+ next[0] = value.num[0];
2003
+ this.channelMask = next;
2004
+ }
2005
+ },
2006
+ {
2007
+ name: 'ChannelMaskG',
2008
+ type: 'float',
2009
+ description: 'Used when the channelMask pin is not connected.',
2010
+ get (value) {
2011
+ value.num[0] = this.channelMask[1];
2012
+ },
2013
+ set (value) {
2014
+ const next = this.channelMask;
2015
+ next[1] = value.num[0];
2016
+ this.channelMask = next;
2017
+ }
2018
+ },
2019
+ {
2020
+ name: 'ChannelMaskB',
2021
+ type: 'float',
2022
+ description: 'Used when the channelMask pin is not connected.',
2023
+ get (value) {
2024
+ value.num[0] = this.channelMask[2];
2025
+ },
2026
+ set (value) {
2027
+ const next = this.channelMask;
2028
+ next[2] = value.num[0];
2029
+ this.channelMask = next;
2030
+ }
2031
+ },
2032
+ {
2033
+ name: 'ChannelMaskA',
2034
+ type: 'float',
2035
+ description: 'Used when the channelMask pin is not connected.',
2036
+ get (value) {
2037
+ value.num[0] = this.channelMask[3];
2038
+ },
2039
+ set (value) {
2040
+ const next = this.channelMask;
2041
+ next[3] = value.num[0];
2042
+ this.channelMask = next;
2043
+ }
2044
+ }
2045
+ ]);
2046
+ }
2047
+ };
2048
+ }
2049
+ toString() {
2050
+ return 'MorphBlur';
2051
+ }
2052
+ validate() {
2053
+ const err = super.validate();
2054
+ if (err) {
2055
+ return err;
2056
+ }
2057
+ const textureInput = this._inputs[0];
2058
+ const textureType = textureInput.inputNode ? textureInput.inputNode.getOutputType(textureInput.inputId) : 'tex2D';
2059
+ if (textureInput.inputNode) {
2060
+ if (!textureType) {
2061
+ return `Cannot determine type of argument \`${textureInput.name}\``;
2062
+ }
2063
+ if (textureType !== 'tex2D') {
2064
+ return 'Texture input must be tex2D';
2065
+ }
2066
+ } else if (!this.textureId) {
2067
+ return 'Texture not specified';
2068
+ }
2069
+ const coordType = this._inputs[1].inputNode?.getOutputType(this._inputs[1].inputId);
2070
+ if (coordType && coordType !== 'vec2') {
2071
+ return 'Texture coordinate type should be vec2';
2072
+ }
2073
+ const morphType = this._inputs[2].inputNode?.getOutputType(this._inputs[2].inputId);
2074
+ if (morphType && morphType !== 'float') {
2075
+ return 'Morph radius type should be float';
2076
+ }
2077
+ const blurType = this._inputs[3].inputNode?.getOutputType(this._inputs[3].inputId);
2078
+ if (blurType && blurType !== 'float') {
2079
+ return 'Blur radius type should be float';
2080
+ }
2081
+ const maskType = this._inputs[4].inputNode?.getOutputType(this._inputs[4].inputId);
2082
+ if (maskType && maskType !== 'vec4') {
2083
+ return 'Channel mask type should be vec4';
2084
+ }
2085
+ return '';
2086
+ }
2087
+ getType() {
2088
+ return this.validate() ? '' : 'float';
2089
+ }
2090
+ }
1197
2091
  /**
1198
2092
  * Texture sampling with explicit gradients node
1199
2093
  *
@@ -1350,5 +2244,5 @@ import { defineProps } from '../../serialization/types.js';
1350
2244
  }
1351
2245
  }
1352
2246
 
1353
- export { BaseTextureNode, ConstantTexture2DArrayNode, ConstantTexture2DNode, ConstantTextureCubeNode, PannerNode, TextureSampleGrad, TextureSampleNode, getDefaultTexture2D, getDefaultTexture2DArray, getDefaultTextureCube };
2247
+ export { BaseTextureNode, ChannelSDFMaskNode, ConstantTexture2DArrayNode, ConstantTexture2DNode, ConstantTextureCubeNode, MorphBlurNode, PannerNode, TexturePropertyNode, TextureSampleGrad, TextureSampleNode, getDefaultTexture2D, getDefaultTexture2DArray, getDefaultTextureCube };
1354
2248
  //# sourceMappingURL=texture.js.map