@zephyr3d/scene 0.7.0 → 0.8.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 (368) hide show
  1. package/dist/animation/animation.js +4 -33
  2. package/dist/animation/animation.js.map +1 -1
  3. package/dist/animation/animationset.js +24 -11
  4. package/dist/animation/animationset.js.map +1 -1
  5. package/dist/animation/animationtrack.js +1 -0
  6. package/dist/animation/animationtrack.js.map +1 -1
  7. package/dist/animation/eulerrotationtrack.js +0 -1
  8. package/dist/animation/eulerrotationtrack.js.map +1 -1
  9. package/dist/animation/ik/ccd_solver.js +372 -0
  10. package/dist/animation/ik/ccd_solver.js.map +1 -0
  11. package/dist/animation/ik/fabrik_solver.js +399 -0
  12. package/dist/animation/ik/fabrik_solver.js.map +1 -0
  13. package/dist/animation/ik/ik_angle_constraint.js +181 -0
  14. package/dist/animation/ik/ik_angle_constraint.js.map +1 -0
  15. package/dist/animation/ik/ik_chain.js +163 -0
  16. package/dist/animation/ik/ik_chain.js.map +1 -0
  17. package/dist/animation/ik/ik_chain_builder.js +68 -0
  18. package/dist/animation/ik/ik_chain_builder.js.map +1 -0
  19. package/dist/animation/ik/ik_constraint.js +25 -0
  20. package/dist/animation/ik/ik_constraint.js.map +1 -0
  21. package/dist/animation/ik/ik_pole_constraint.js +123 -0
  22. package/dist/animation/ik/ik_pole_constraint.js.map +1 -0
  23. package/dist/animation/ik/ik_solver.js +48 -0
  24. package/dist/animation/ik/ik_solver.js.map +1 -0
  25. package/dist/animation/ik/ik_track.js +96 -0
  26. package/dist/animation/ik/ik_track.js.map +1 -0
  27. package/dist/animation/ik/ik_utils.js +270 -0
  28. package/dist/animation/ik/ik_utils.js.map +1 -0
  29. package/dist/animation/ik/two_bone_ik_solver.js +332 -0
  30. package/dist/animation/ik/two_bone_ik_solver.js.map +1 -0
  31. package/dist/animation/ik_modifier.js +61 -0
  32. package/dist/animation/ik_modifier.js.map +1 -0
  33. package/dist/animation/ik_postprocessor.js +71 -0
  34. package/dist/animation/ik_postprocessor.js.map +1 -0
  35. package/dist/animation/manual_transform_processor.js +156 -0
  36. package/dist/animation/manual_transform_processor.js.map +1 -0
  37. package/dist/animation/morphtarget.js +7 -1
  38. package/dist/animation/morphtarget.js.map +1 -1
  39. package/dist/animation/morphtrack.js +3 -3
  40. package/dist/animation/morphtrack.js.map +1 -1
  41. package/dist/animation/proptrack.js +37 -41
  42. package/dist/animation/proptrack.js.map +1 -1
  43. package/dist/animation/rotationtrack.js +0 -1
  44. package/dist/animation/rotationtrack.js.map +1 -1
  45. package/dist/animation/scaletrack.js +0 -1
  46. package/dist/animation/scaletrack.js.map +1 -1
  47. package/dist/animation/skeleton.js +57 -60
  48. package/dist/animation/skeleton.js.map +1 -1
  49. package/dist/animation/skeleton_modifier.js +38 -0
  50. package/dist/animation/skeleton_modifier.js.map +1 -0
  51. package/dist/animation/skeleton_postprocessor.js +50 -0
  52. package/dist/animation/skeleton_postprocessor.js.map +1 -0
  53. package/dist/animation/spring/multi_chain_spring_system.js +503 -0
  54. package/dist/animation/spring/multi_chain_spring_system.js.map +1 -0
  55. package/dist/animation/spring/spring_chain.js +103 -0
  56. package/dist/animation/spring/spring_chain.js.map +1 -0
  57. package/dist/animation/spring/spring_collider.js +247 -0
  58. package/dist/animation/spring/spring_collider.js.map +1 -0
  59. package/dist/animation/spring/spring_constraint.js +21 -0
  60. package/dist/animation/spring/spring_constraint.js.map +1 -0
  61. package/dist/animation/spring/spring_particle.js +20 -0
  62. package/dist/animation/spring/spring_particle.js.map +1 -0
  63. package/dist/animation/spring/spring_system.js +526 -0
  64. package/dist/animation/spring/spring_system.js.map +1 -0
  65. package/dist/animation/spring_modifier.js +45 -0
  66. package/dist/animation/spring_modifier.js.map +1 -0
  67. package/dist/animation/spring_postprocessor.js +54 -0
  68. package/dist/animation/spring_postprocessor.js.map +1 -0
  69. package/dist/animation/translationtrack.js +0 -1
  70. package/dist/animation/translationtrack.js.map +1 -1
  71. package/dist/app/api.js +13 -4
  72. package/dist/app/api.js.map +1 -1
  73. package/dist/app/app.js +13 -1
  74. package/dist/app/app.js.map +1 -1
  75. package/dist/app/engine.js +33 -45
  76. package/dist/app/engine.js.map +1 -1
  77. package/dist/app/inputmgr.js.map +1 -1
  78. package/dist/app/runtimescript.js.map +1 -1
  79. package/dist/app/screen.js +318 -0
  80. package/dist/app/screen.js.map +1 -0
  81. package/dist/app/scriptingsystem.js +10 -6
  82. package/dist/app/scriptingsystem.js.map +1 -1
  83. package/dist/app/scriptregistry.js +11 -22
  84. package/dist/app/scriptregistry.js.map +1 -1
  85. package/dist/asset/assetmanager.js +79 -58
  86. package/dist/asset/assetmanager.js.map +1 -1
  87. package/dist/asset/builtin.js +5 -5
  88. package/dist/asset/builtin.js.map +1 -1
  89. package/dist/asset/loaders/dds/dds.js +6 -2
  90. package/dist/asset/loaders/dds/dds.js.map +1 -1
  91. package/dist/asset/loaders/dds/dds_loader.js +1 -1
  92. package/dist/asset/loaders/dds/dds_loader.js.map +1 -1
  93. package/dist/asset/loaders/gltf/gltf_loader.js +14 -6
  94. package/dist/asset/loaders/gltf/gltf_loader.js.map +1 -1
  95. package/dist/asset/loaders/gltf/helpers.js +6 -2
  96. package/dist/asset/loaders/gltf/helpers.js.map +1 -1
  97. package/dist/asset/loaders/hdr/hdr.js +22 -15
  98. package/dist/asset/loaders/hdr/hdr.js.map +1 -1
  99. package/dist/asset/loaders/image/tga_Loader.js +2 -1
  100. package/dist/asset/loaders/image/tga_Loader.js.map +1 -1
  101. package/dist/asset/loaders/image/webimage_loader.js.map +1 -1
  102. package/dist/asset/loaders/loader.js +2 -2
  103. package/dist/asset/loaders/loader.js.map +1 -1
  104. package/dist/asset/model.js +9 -5
  105. package/dist/asset/model.js.map +1 -1
  106. package/dist/blitter/bilateralblur.js.map +1 -1
  107. package/dist/blitter/blitter.js +9 -11
  108. package/dist/blitter/blitter.js.map +1 -1
  109. package/dist/blitter/box.js +0 -1
  110. package/dist/blitter/box.js.map +1 -1
  111. package/dist/blitter/copy.js.map +1 -1
  112. package/dist/blitter/gaussianblur.js.map +1 -1
  113. package/dist/camera/base.js +1 -3
  114. package/dist/camera/base.js.map +1 -1
  115. package/dist/camera/camera.js +121 -37
  116. package/dist/camera/camera.js.map +1 -1
  117. package/dist/camera/fps.js +19 -17
  118. package/dist/camera/fps.js.map +1 -1
  119. package/dist/camera/orbit.js +45 -43
  120. package/dist/camera/orbit.js.map +1 -1
  121. package/dist/camera/orthocamera.js +27 -21
  122. package/dist/camera/orthocamera.js.map +1 -1
  123. package/dist/camera/perspectivecamera.js +28 -19
  124. package/dist/camera/perspectivecamera.js.map +1 -1
  125. package/dist/index.d.ts +15802 -15577
  126. package/dist/index.js +33 -11
  127. package/dist/index.js.map +1 -1
  128. package/dist/material/blinn.js.map +1 -1
  129. package/dist/material/grassmaterial.js.map +1 -1
  130. package/dist/material/lambert.js.map +1 -1
  131. package/dist/material/material.js +11 -5
  132. package/dist/material/material.js.map +1 -1
  133. package/dist/material/meshmaterial.js +10 -9
  134. package/dist/material/meshmaterial.js.map +1 -1
  135. package/dist/material/mixins/albedocolor.js.map +1 -1
  136. package/dist/material/mixins/foliage.js.map +1 -1
  137. package/dist/material/mixins/lightmodel/blinnphong.js +66 -4
  138. package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
  139. package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
  140. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +7 -0
  141. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
  142. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  143. package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
  144. package/dist/material/mixins/lit.js +3 -3
  145. package/dist/material/mixins/lit.js.map +1 -1
  146. package/dist/material/mixins/pbr/brdf.js.map +1 -1
  147. package/dist/material/mixins/pbr/common.js.map +1 -1
  148. package/dist/material/mixins/texture.js +3 -0
  149. package/dist/material/mixins/texture.js.map +1 -1
  150. package/dist/material/mixins/vertexcolor.js.map +1 -1
  151. package/dist/material/particle.js.map +1 -1
  152. package/dist/material/pbrblueprint.js +180 -22
  153. package/dist/material/pbrblueprint.js.map +1 -1
  154. package/dist/material/pbrmr.js.map +1 -1
  155. package/dist/material/pbrsg.js.map +1 -1
  156. package/dist/material/shader/helper.js +41 -56
  157. package/dist/material/shader/helper.js.map +1 -1
  158. package/dist/material/sprite.js +301 -0
  159. package/dist/material/sprite.js.map +1 -0
  160. package/dist/material/sprite3d.js +301 -0
  161. package/dist/material/sprite3d.js.map +1 -0
  162. package/dist/material/sprite3d_std.js +116 -0
  163. package/dist/material/sprite3d_std.js.map +1 -0
  164. package/dist/material/sprite3dblueprint.js +235 -0
  165. package/dist/material/sprite3dblueprint.js.map +1 -0
  166. package/dist/material/sprite_std.js +116 -0
  167. package/dist/material/sprite_std.js.map +1 -0
  168. package/dist/material/spriteblueprint.js +235 -0
  169. package/dist/material/spriteblueprint.js.map +1 -0
  170. package/dist/material/terrain-cm.js +0 -1
  171. package/dist/material/terrain-cm.js.map +1 -1
  172. package/dist/material/unlit.js.map +1 -1
  173. package/dist/material/water.js.map +1 -1
  174. package/dist/posteffect/bloom.js.map +1 -1
  175. package/dist/posteffect/compositor.js.map +1 -1
  176. package/dist/posteffect/fxaa.js.map +1 -1
  177. package/dist/posteffect/grayscale.js.map +1 -1
  178. package/dist/posteffect/motionblur.js.map +1 -1
  179. package/dist/posteffect/posteffect.js.map +1 -1
  180. package/dist/posteffect/sao.js.map +1 -1
  181. package/dist/posteffect/ssr.js +7 -5
  182. package/dist/posteffect/ssr.js.map +1 -1
  183. package/dist/posteffect/taa.js.map +1 -1
  184. package/dist/posteffect/tonemap.js.map +1 -1
  185. package/dist/render/abuffer_oit.js +8 -6
  186. package/dist/render/abuffer_oit.js.map +1 -1
  187. package/dist/render/clipmap.js +0 -10
  188. package/dist/render/clipmap.js.map +1 -1
  189. package/dist/render/cluster_light.js +4 -4
  190. package/dist/render/cluster_light.js.map +1 -1
  191. package/dist/render/cull_visitor.js +15 -17
  192. package/dist/render/cull_visitor.js.map +1 -1
  193. package/dist/render/depthpass.js +3 -4
  194. package/dist/render/depthpass.js.map +1 -1
  195. package/dist/render/drawable.js +15 -0
  196. package/dist/render/drawable.js.map +1 -0
  197. package/dist/render/drawable_mixin.js +8 -4
  198. package/dist/render/drawable_mixin.js.map +1 -1
  199. package/dist/render/envlight.js.map +1 -1
  200. package/dist/render/fbm_wavegenerator.js +3 -1
  201. package/dist/render/fbm_wavegenerator.js.map +1 -1
  202. package/dist/render/fft_wavegenerator.js +67 -64
  203. package/dist/render/fft_wavegenerator.js.map +1 -1
  204. package/dist/render/fullscreenquad.js.map +1 -1
  205. package/dist/render/gerstner_wavegenerator.js +3 -1
  206. package/dist/render/gerstner_wavegenerator.js.map +1 -1
  207. package/dist/render/globalbindgroup_allocator.js +3 -1
  208. package/dist/render/globalbindgroup_allocator.js.map +1 -1
  209. package/dist/render/hzb.js +1 -2
  210. package/dist/render/hzb.js.map +1 -1
  211. package/dist/render/lightpass.js +13 -13
  212. package/dist/render/lightpass.js.map +1 -1
  213. package/dist/render/objectcolorpass.js +4 -7
  214. package/dist/render/objectcolorpass.js.map +1 -1
  215. package/dist/render/primitive.js +4 -5
  216. package/dist/render/primitive.js.map +1 -1
  217. package/dist/render/render_queue.js +10 -5
  218. package/dist/render/render_queue.js.map +1 -1
  219. package/dist/render/renderer.js +16 -22
  220. package/dist/render/renderer.js.map +1 -1
  221. package/dist/render/renderpass.js +27 -52
  222. package/dist/render/renderpass.js.map +1 -1
  223. package/dist/render/rendertarget.js +5 -0
  224. package/dist/render/rendertarget.js.map +1 -0
  225. package/dist/render/screenrendertarget.js +56 -0
  226. package/dist/render/screenrendertarget.js.map +1 -0
  227. package/dist/render/shadowmap_pass.js +4 -5
  228. package/dist/render/shadowmap_pass.js.map +1 -1
  229. package/dist/render/sky.js +16 -14
  230. package/dist/render/sky.js.map +1 -1
  231. package/dist/render/weightedblended_oit.js.map +1 -1
  232. package/dist/scene/basesprite.js +296 -0
  233. package/dist/scene/basesprite.js.map +1 -0
  234. package/dist/scene/batchgroup.js +4 -2
  235. package/dist/scene/batchgroup.js.map +1 -1
  236. package/dist/scene/environment.js +9 -10
  237. package/dist/scene/environment.js.map +1 -1
  238. package/dist/scene/graph_node.js.map +1 -1
  239. package/dist/scene/light.js +22 -4
  240. package/dist/scene/light.js.map +1 -1
  241. package/dist/scene/mesh.js +96 -26
  242. package/dist/scene/mesh.js.map +1 -1
  243. package/dist/scene/octree.js.map +1 -1
  244. package/dist/scene/particlesys.js +25 -22
  245. package/dist/scene/particlesys.js.map +1 -1
  246. package/dist/scene/raycast_visitor.js +0 -16
  247. package/dist/scene/raycast_visitor.js.map +1 -1
  248. package/dist/scene/scene.js +7 -4
  249. package/dist/scene/scene.js.map +1 -1
  250. package/dist/scene/scene_node.js +20 -35
  251. package/dist/scene/scene_node.js.map +1 -1
  252. package/dist/scene/sprite.js +18 -0
  253. package/dist/scene/sprite.js.map +1 -0
  254. package/dist/scene/sprite3d.js +18 -0
  255. package/dist/scene/sprite3d.js.map +1 -0
  256. package/dist/scene/terrain-cm/grass.js +5 -4
  257. package/dist/scene/terrain-cm/grass.js.map +1 -1
  258. package/dist/scene/terrain-cm/grassmaterial.js +3 -1
  259. package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
  260. package/dist/scene/terrain-cm/terrain-cm.js +65 -48
  261. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  262. package/dist/scene/water.js +35 -30
  263. package/dist/scene/water.js.map +1 -1
  264. package/dist/shaders/atmosphere.js +17 -29
  265. package/dist/shaders/atmosphere.js.map +1 -1
  266. package/dist/shaders/fog.js.map +1 -1
  267. package/dist/shaders/misc.js.map +1 -1
  268. package/dist/shaders/noise.js.map +1 -1
  269. package/dist/shaders/pbr.js.map +1 -1
  270. package/dist/shaders/shadow.js.map +1 -1
  271. package/dist/shaders/ssr.js.map +1 -1
  272. package/dist/shaders/temporal.js.map +1 -1
  273. package/dist/shaders/water.js.map +1 -1
  274. package/dist/shadow/esm.js +1 -1
  275. package/dist/shadow/esm.js.map +1 -1
  276. package/dist/shadow/pcf_opt.js.map +1 -1
  277. package/dist/shadow/pcf_pd.js.map +1 -1
  278. package/dist/shadow/shader.js +3 -1
  279. package/dist/shadow/shader.js.map +1 -1
  280. package/dist/shadow/shadow_impl.js.map +1 -1
  281. package/dist/shadow/shadowmapper.js +6 -18
  282. package/dist/shadow/shadowmapper.js.map +1 -1
  283. package/dist/shadow/ssm.js.map +1 -1
  284. package/dist/shadow/vsm.js.map +1 -1
  285. package/dist/shapes/box.js +9 -3
  286. package/dist/shapes/box.js.map +1 -1
  287. package/dist/shapes/cylinder.js +2 -2
  288. package/dist/shapes/cylinder.js.map +1 -1
  289. package/dist/shapes/plane.js +2 -2
  290. package/dist/shapes/plane.js.map +1 -1
  291. package/dist/shapes/shape.js +2 -1
  292. package/dist/shapes/shape.js.map +1 -1
  293. package/dist/shapes/sphere.js +2 -2
  294. package/dist/shapes/sphere.js.map +1 -1
  295. package/dist/shapes/tetrahedron.js +5 -6
  296. package/dist/shapes/tetrahedron.js.map +1 -1
  297. package/dist/shapes/torus.js +2 -2
  298. package/dist/shapes/torus.js.map +1 -1
  299. package/dist/utility/aabbtree.js +1 -1
  300. package/dist/utility/aabbtree.js.map +1 -1
  301. package/dist/utility/blueprint/common/constants.js +578 -104
  302. package/dist/utility/blueprint/common/constants.js.map +1 -1
  303. package/dist/utility/blueprint/common/math.js +471 -9
  304. package/dist/utility/blueprint/common/math.js.map +1 -1
  305. package/dist/utility/blueprint/common.js +1 -1
  306. package/dist/utility/blueprint/common.js.map +1 -1
  307. package/dist/utility/blueprint/material/func.js +9 -5
  308. package/dist/utility/blueprint/material/func.js.map +1 -1
  309. package/dist/utility/blueprint/material/inputs.js.map +1 -1
  310. package/dist/utility/blueprint/material/ir.js +288 -80
  311. package/dist/utility/blueprint/material/ir.js.map +1 -1
  312. package/dist/utility/blueprint/material/pbr.js +92 -4
  313. package/dist/utility/blueprint/material/pbr.js.map +1 -1
  314. package/dist/utility/blueprint/material/texture.js +62 -45
  315. package/dist/utility/blueprint/material/texture.js.map +1 -1
  316. package/dist/utility/blueprint/node.js +28 -1
  317. package/dist/utility/blueprint/node.js.map +1 -1
  318. package/dist/utility/bounding_volume.js.map +1 -1
  319. package/dist/utility/debug.js.map +1 -1
  320. package/dist/utility/draco/decoder.js.map +1 -1
  321. package/dist/utility/misc.js +1 -1
  322. package/dist/utility/misc.js.map +1 -1
  323. package/dist/utility/panorama.js.map +1 -1
  324. package/dist/utility/pmrem.js.map +1 -1
  325. package/dist/utility/rendermipmap.js.map +1 -1
  326. package/dist/utility/serialization/json.js +19 -15
  327. package/dist/utility/serialization/json.js.map +1 -1
  328. package/dist/utility/serialization/manager.js +89 -22
  329. package/dist/utility/serialization/manager.js.map +1 -1
  330. package/dist/utility/serialization/scene/animation.js +44 -41
  331. package/dist/utility/serialization/scene/animation.js.map +1 -1
  332. package/dist/utility/serialization/scene/batch.js +4 -3
  333. package/dist/utility/serialization/scene/batch.js.map +1 -1
  334. package/dist/utility/serialization/scene/camera.js +97 -9
  335. package/dist/utility/serialization/scene/camera.js.map +1 -1
  336. package/dist/utility/serialization/scene/common.js +102 -28
  337. package/dist/utility/serialization/scene/common.js.map +1 -1
  338. package/dist/utility/serialization/scene/light.js +14 -12
  339. package/dist/utility/serialization/scene/light.js.map +1 -1
  340. package/dist/utility/serialization/scene/material.js +216 -26
  341. package/dist/utility/serialization/scene/material.js.map +1 -1
  342. package/dist/utility/serialization/scene/mesh.js +71 -100
  343. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  344. package/dist/utility/serialization/scene/misc.js +3 -2
  345. package/dist/utility/serialization/scene/misc.js.map +1 -1
  346. package/dist/utility/serialization/scene/node.js +42 -9
  347. package/dist/utility/serialization/scene/node.js.map +1 -1
  348. package/dist/utility/serialization/scene/particle.js +7 -5
  349. package/dist/utility/serialization/scene/particle.js.map +1 -1
  350. package/dist/utility/serialization/scene/primitive.js +18 -15
  351. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  352. package/dist/utility/serialization/scene/scene.js +3 -2
  353. package/dist/utility/serialization/scene/scene.js.map +1 -1
  354. package/dist/utility/serialization/scene/sprite.js +164 -0
  355. package/dist/utility/serialization/scene/sprite.js.map +1 -0
  356. package/dist/utility/serialization/scene/terrain.js +8 -6
  357. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  358. package/dist/utility/serialization/scene/water.js +11 -9
  359. package/dist/utility/serialization/scene/water.js.map +1 -1
  360. package/dist/utility/serialization/types.js +6 -0
  361. package/dist/utility/serialization/types.js.map +1 -0
  362. package/dist/utility/shprojector.js.map +1 -1
  363. package/dist/utility/textures/ggxlut.js.map +1 -1
  364. package/dist/utility/textures/gradientnoise.js.map +1 -1
  365. package/dist/utility/textures/randomnoise.js.map +1 -1
  366. package/dist/values.js +14 -14
  367. package/dist/values.js.map +1 -1
  368. package/package.json +80 -80
@@ -0,0 +1,301 @@
1
+ import { MeshMaterial } from './meshmaterial.js';
2
+ import { ShaderHelper } from './shader/helper.js';
3
+ import { MaterialVaryingFlags } from '../values.js';
4
+ import { Vector4 } from '@zephyr3d/base';
5
+
6
+ /**
7
+ * Sprite material base class.
8
+ *
9
+ * @remarks
10
+ * This material renders a camera-facing quad (billboard) in 3D space,
11
+ * using UV information and an anchor point to control how the sprite
12
+ * is positioned and textured.
13
+ *
14
+ * Derived classes can override {@link internalSetupUniforms},
15
+ * {@link internalApplyUniforms} and
16
+ * {@link calcFragmentColor} to provide custom
17
+ * uniforms and shading logic (e.g. sampling a texture).
18
+ *
19
+ * @public
20
+ */ class SpriteMaterial extends MeshMaterial {
21
+ static UVINFO = this.defineInstanceUniform('uvinfo', 'vec4');
22
+ static ANCHOR_ROTATION = this.defineInstanceUniform('anchorRotation', 'vec4');
23
+ _uvinfo;
24
+ _anchorRotation;
25
+ /**
26
+ * Creates a new {@link SpriteMaterial} instance.
27
+ *
28
+ * @remarks
29
+ * - Default UV rectangle is the full texture [0, 0, 1, 1].
30
+ * - Default anchor is the center [0.5, 0.5].
31
+ * - Face culling is disabled (`cullMode = 'none'`) so the sprite
32
+ * is visible from both sides.
33
+ */ constructor(){
34
+ super();
35
+ this._uvinfo = new Vector4(0, 0, 1, 1);
36
+ this._anchorRotation = new Vector4(0.5, 0.5, 0, 0);
37
+ this.cullMode = 'none';
38
+ }
39
+ /**
40
+ * Gets the UV rectangle of the sprite in the texture.
41
+ *
42
+ * @returns A Vector4 storing \([u0, v0, u1, v1]\).
43
+ */ get uvinfo() {
44
+ return this._uvinfo;
45
+ }
46
+ set uvinfo(value) {
47
+ if (!value.equalsTo(this.uvinfo)) {
48
+ this._uvinfo.set(value);
49
+ this.uniformChanged();
50
+ }
51
+ }
52
+ /**
53
+ * Convenience method to set the UV rectangle via individual components.
54
+ *
55
+ * @param uvx0 - Left (U) coordinate.
56
+ * @param uvy0 - Bottom (V) coordinate.
57
+ * @param uvx1 - Right (U) coordinate.
58
+ * @param uvy1 - Top (V) coordinate.
59
+ */ setUVInfo(uvx0, uvy0, uvx1, uvy1) {
60
+ this.uvinfo = new Vector4(uvx0, uvy0, uvx1, uvy1);
61
+ }
62
+ /**
63
+ * Gets the sprite anchor-rotation.
64
+ *
65
+ * @returns The current anchor-rotation.
66
+ */ get anchorRotation() {
67
+ return this._anchorRotation;
68
+ }
69
+ set anchorRotation(value) {
70
+ if (!value.equalsTo(this._anchorRotation)) {
71
+ this._anchorRotation.set(value);
72
+ this.uniformChanged();
73
+ }
74
+ }
75
+ /**
76
+ * Gets the sprite anchor point in normalized quad space.
77
+ *
78
+ * @returns The current anchor as a Vector2.
79
+ */ get anchor() {
80
+ return this._anchorRotation.xy();
81
+ }
82
+ set anchor(value) {
83
+ if (value.x !== this._anchorRotation.x || value.y !== this._anchorRotation.y) {
84
+ this.anchorRotation = new Vector4(value.x, value.y, this._anchorRotation.z, this._anchorRotation.w);
85
+ }
86
+ }
87
+ /**
88
+ * Gets the sprite rotation around the Z axis.
89
+ *
90
+ * @returns The sprite rotation.
91
+ */ get rotation() {
92
+ return this._anchorRotation.z;
93
+ }
94
+ set rotation(value) {
95
+ if (value !== this._anchorRotation.z) {
96
+ this.anchorRotation = new Vector4(this._anchorRotation.x, this._anchorRotation.y, value, this._anchorRotation.w);
97
+ }
98
+ }
99
+ /**
100
+ * Gets the X component of the sprite anchor.
101
+ */ get anchorX() {
102
+ return this._anchorRotation.x;
103
+ }
104
+ set anchorX(value) {
105
+ if (this._anchorRotation.x !== value) {
106
+ this.anchorRotation = new Vector4(value, this._anchorRotation.y, this._anchorRotation.z, this._anchorRotation.w);
107
+ }
108
+ }
109
+ /**
110
+ * Gets the Y component of the sprite anchor.
111
+ */ get anchorY() {
112
+ return this._anchorRotation.y;
113
+ }
114
+ set anchorY(value) {
115
+ if (this._anchorRotation.y !== value) {
116
+ this.anchorRotation = new Vector4(this._anchorRotation.x, value, this._anchorRotation.z, this._anchorRotation.w);
117
+ }
118
+ }
119
+ /**
120
+ * Convenience method to set both anchor components at once.
121
+ *
122
+ * @param anchorX - X coordinate of the anchor.
123
+ * @param anchorY - Y coordinate of the anchor.
124
+ */ setAnchor(anchorX, anchorY) {
125
+ if (this._anchorRotation.x !== anchorX || this._anchorRotation.y !== anchorY) {
126
+ this.anchorRotation = new Vector4(anchorX, anchorY, this._anchorRotation.z, this._anchorRotation.w);
127
+ }
128
+ }
129
+ /**
130
+ * Creates a deep copy of this material.
131
+ *
132
+ * @returns A new {@link SpriteMaterial} instance with the same properties.
133
+ */ clone() {
134
+ const other = new SpriteMaterial();
135
+ other.copyFrom(this);
136
+ return other;
137
+ }
138
+ /**
139
+ * Copies all relevant state from another {@link SpriteMaterial}.
140
+ *
141
+ * @param other - The source material to copy from.
142
+ */ copyFrom(other) {
143
+ super.copyFrom(other);
144
+ this.uvinfo = other.uvinfo;
145
+ this.anchorRotation = other.anchorRotation;
146
+ }
147
+ /**
148
+ * Builds the vertex shader for this material.
149
+ *
150
+ * @remarks
151
+ * This method:
152
+ * - Calls the base implementation.
153
+ * - Computes per-vertex positions for a camera-facing quad (billboard)
154
+ * based on the sprite's world transform, size, and anchor.
155
+ * - Selects the correct UV coordinates for each quad corner using
156
+ * the `vertexId` attribute.
157
+ * - Outputs world-space position (`zWorldPos`) and UVs (`zVertexUV`)
158
+ * for use in the fragment shader.
159
+ *
160
+ * @param scope - The current programmable builder function scope.
161
+ */ vertexShader(scope) {
162
+ super.vertexShader(scope);
163
+ const pb = scope.$builder;
164
+ scope.$inputs.vertexId = pb.float().attrib('position');
165
+ if (this.drawContext.materialFlags & MaterialVaryingFlags.INSTANCING) {
166
+ scope.$l.uvinfo = this.getInstancedUniform(scope, SpriteMaterial.UVINFO);
167
+ scope.$l.anchorRotation = this.getInstancedUniform(scope, SpriteMaterial.ANCHOR_ROTATION);
168
+ } else {
169
+ scope.uvinfo = pb.vec4().uniform(2);
170
+ scope.anchorRotation = pb.vec4().uniform(2);
171
+ }
172
+ this.internalSetupUniforms(scope);
173
+ scope.$l.worldPos = ShaderHelper.getWorldMatrix(scope)[3].xyz;
174
+ scope.$l.width = pb.sqrt(pb.dot(ShaderHelper.getWorldMatrix(scope)[0].xyz, ShaderHelper.getWorldMatrix(scope)[0].xyz));
175
+ scope.$l.height = pb.sqrt(pb.dot(ShaderHelper.getWorldMatrix(scope)[1].xyz, ShaderHelper.getWorldMatrix(scope)[1].xyz));
176
+ const viewMatrix = ShaderHelper.getViewMatrix(scope);
177
+ scope.$l.forward = pb.vec3(viewMatrix[0].z, viewMatrix[1].z, viewMatrix[2].z);
178
+ scope.$l.axis = scope.$choice(pb.lessThan(pb.abs(scope.forward.y), 0.999), pb.vec3(0, 1, 0), pb.vec3(1, 0, 0));
179
+ scope.$l.right = pb.normalize(pb.cross(scope.axis, scope.forward));
180
+ scope.$l.up = pb.normalize(pb.cross(scope.forward, scope.right));
181
+ scope.$l.rotateAngle = scope.anchorRotation.z;
182
+ scope.$l.c = pb.cos(scope.rotateAngle);
183
+ scope.$l.s = pb.sin(scope.rotateAngle);
184
+ scope.$l.rightRot = pb.add(pb.mul(scope.up, scope.s), pb.mul(scope.right, scope.c));
185
+ scope.$l.upRot = pb.sub(pb.mul(scope.up, scope.c), pb.mul(scope.right, scope.s));
186
+ scope.$l.v = pb.vec2();
187
+ scope.$l.uv = pb.vec2();
188
+ scope.$l.anchor = scope.anchorRotation.xy;
189
+ scope.$if(pb.equal(scope.$inputs.vertexId, 0), function() {
190
+ scope.v = pb.neg(scope.anchor);
191
+ scope.uv = pb.vec2(scope.uvinfo.x, pb.sub(1, scope.uvinfo.y));
192
+ }).$elseif(pb.equal(scope.$inputs.vertexId, 1), function() {
193
+ scope.v = pb.sub(pb.vec2(1, 0), scope.anchor);
194
+ scope.uv = pb.vec2(scope.uvinfo.z, pb.sub(1, scope.uvinfo.y));
195
+ }).$elseif(pb.equal(scope.$inputs.vertexId, 2), function() {
196
+ scope.v = pb.sub(pb.vec2(0, 1), scope.anchor);
197
+ scope.uv = pb.vec2(scope.uvinfo.x, pb.sub(1, scope.uvinfo.w));
198
+ }).$else(function() {
199
+ scope.v = pb.sub(pb.vec2(1), scope.anchor);
200
+ scope.uv = pb.vec2(scope.uvinfo.z, pb.sub(1, scope.uvinfo.w));
201
+ });
202
+ scope.v = pb.mul(scope.v, pb.vec2(scope.width, scope.height));
203
+ scope.$outputs.zWorldPos = pb.add(scope.worldPos, pb.mul(scope.rightRot, scope.v.x), pb.mul(scope.upRot, scope.v.y));
204
+ scope.$outputs.zVertexUV = scope.uv;
205
+ ShaderHelper.setClipSpacePosition(scope, pb.mul(ShaderHelper.getViewProjectionMatrix(scope), pb.vec4(scope.$outputs.zWorldPos, 1)));
206
+ }
207
+ /**
208
+ * Builds the fragment shader for this material.
209
+ *
210
+ * @remarks
211
+ * This method:
212
+ * - Calls the base implementation.
213
+ * - Invokes {@link SpriteMaterial.internalSetupUniforms} for
214
+ * fragment-stage specific uniform declarations.
215
+ * - Computes fragment color by calling {@link SpriteMaterial.calcFragmentColor}
216
+ * if fragment color is needed.
217
+ * - Outputs the final fragment color via {@link MeshMaterial.outputFragmentColor}.
218
+ *
219
+ * @param scope - The current programmable builder function scope.
220
+ */ fragmentShader(scope) {
221
+ super.fragmentShader(scope);
222
+ this.internalSetupUniforms(scope);
223
+ if (this.needFragmentColor()) {
224
+ scope.$l.color = this.calcFragmentColor(scope);
225
+ this.outputFragmentColor(scope, scope.$inputs.zWorldPos, scope.color);
226
+ } else {
227
+ this.outputFragmentColor(scope, scope.$inputs.zWorldPos, null);
228
+ }
229
+ }
230
+ /**
231
+ * Applies runtime uniform values to the given bind group before drawing.
232
+ *
233
+ * @remarks
234
+ * This binds:
235
+ * - UV information (`uvinfo`)
236
+ * - Anchor (`anchor`)
237
+ *
238
+ * for non-instanced rendering. For instanced rendering, these values
239
+ * are expected to be provided as per-instance uniforms instead.
240
+ *
241
+ * It also calls {@link SpriteMaterial.internalApplyUniforms} to allow
242
+ * derived classes to bind additional resources (e.g. textures).
243
+ *
244
+ * @param bindGroup - The bind group to which uniforms and resources are bound.
245
+ * @param ctx - The current draw context providing rendering state.
246
+ * @param pass - Index of the active render pass.
247
+ */ applyUniformValues(bindGroup, ctx, pass) {
248
+ super.applyUniformValues(bindGroup, ctx, pass);
249
+ if (!(ctx.materialFlags & MaterialVaryingFlags.INSTANCING)) {
250
+ bindGroup.setValue('uvinfo', this._uvinfo);
251
+ bindGroup.setValue('anchorRotation', this._anchorRotation);
252
+ }
253
+ this.internalApplyUniforms(bindGroup, ctx, pass);
254
+ }
255
+ /**
256
+ * Hook for derived classes to declare additional uniforms.
257
+ *
258
+ * @remarks
259
+ * This is invoked in both the vertex and fragment shader construction
260
+ * phases, allowing subclasses to register extra uniforms or resources
261
+ * needed by their custom shading logic.
262
+ *
263
+ * The base implementation does nothing.
264
+ *
265
+ * @param _scope - The current shader function scope.
266
+ */ internalSetupUniforms(_scope) {}
267
+ /**
268
+ * Hook for derived classes to bind additional uniform values or resources.
269
+ *
270
+ * @remarks
271
+ * This is called from {@link SpriteMaterial.applyUniformValues} and is
272
+ * intended for subclasses to bind their own textures, samplers, or
273
+ * other GPU resources.
274
+ *
275
+ * The base implementation does nothing.
276
+ *
277
+ * @param _bindGroup - The bind group used for binding uniforms and resources.
278
+ * @param _ctx - The current draw context.
279
+ * @param _pass - Index of the active render pass.
280
+ */ internalApplyUniforms(_bindGroup, _ctx, _pass) {}
281
+ /**
282
+ * Computes the fragment color expression for this material.
283
+ *
284
+ * @remarks
285
+ * The default implementation simply outputs the interpolated UV
286
+ * coordinates as color \([u, v, 0, 1]\), which is mainly useful
287
+ * for debugging.
288
+ *
289
+ * Derived classes are expected to override this method to implement
290
+ * actual shading, such as sampling a texture.
291
+ *
292
+ * @param scope - The current shader function scope.
293
+ * @returns A shader expression representing the fragment color.
294
+
295
+ */ calcFragmentColor(scope) {
296
+ return scope.$builder.vec4(scope.$inputs.zVertexUV, 0, 1);
297
+ }
298
+ }
299
+
300
+ export { SpriteMaterial };
301
+ //# sourceMappingURL=sprite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sprite.js","sources":["../../src/material/sprite.ts"],"sourcesContent":["import { MeshMaterial } from './meshmaterial';\r\nimport type { BindGroup, PBFunctionScope, PBInsideFunctionScope } from '@zephyr3d/device';\r\nimport { ShaderHelper } from './shader/helper';\r\nimport { MaterialVaryingFlags } from '../values';\r\nimport type { Clonable, Immutable, Vector2 } from '@zephyr3d/base';\r\nimport { Vector4 } from '@zephyr3d/base';\r\nimport type { DrawContext } from '../render';\r\n\r\n/**\r\n * Sprite material base class.\r\n *\r\n * @remarks\r\n * This material renders a camera-facing quad (billboard) in 3D space,\r\n * using UV information and an anchor point to control how the sprite\r\n * is positioned and textured.\r\n *\r\n * Derived classes can override {@link internalSetupUniforms},\r\n * {@link internalApplyUniforms} and\r\n * {@link calcFragmentColor} to provide custom\r\n * uniforms and shading logic (e.g. sampling a texture).\r\n *\r\n * @public\r\n */\r\nexport class SpriteMaterial extends MeshMaterial implements Clonable<SpriteMaterial> {\r\n static UVINFO = this.defineInstanceUniform('uvinfo', 'vec4');\r\n static ANCHOR_ROTATION = this.defineInstanceUniform('anchorRotation', 'vec4');\r\n private _uvinfo: Vector4;\r\n private _anchorRotation: Vector4;\r\n /**\r\n * Creates a new {@link SpriteMaterial} instance.\r\n *\r\n * @remarks\r\n * - Default UV rectangle is the full texture [0, 0, 1, 1].\r\n * - Default anchor is the center [0.5, 0.5].\r\n * - Face culling is disabled (`cullMode = 'none'`) so the sprite\r\n * is visible from both sides.\r\n */\r\n constructor() {\r\n super();\r\n this._uvinfo = new Vector4(0, 0, 1, 1);\r\n this._anchorRotation = new Vector4(0.5, 0.5, 0, 0);\r\n this.cullMode = 'none';\r\n }\r\n /**\r\n * Gets the UV rectangle of the sprite in the texture.\r\n *\r\n * @returns A Vector4 storing \\([u0, v0, u1, v1]\\).\r\n */\r\n get uvinfo(): Immutable<Vector4> {\r\n return this._uvinfo;\r\n }\r\n set uvinfo(value: Immutable<Vector4>) {\r\n if (!value.equalsTo(this.uvinfo)) {\r\n this._uvinfo.set(value);\r\n this.uniformChanged();\r\n }\r\n }\r\n /**\r\n * Convenience method to set the UV rectangle via individual components.\r\n *\r\n * @param uvx0 - Left (U) coordinate.\r\n * @param uvy0 - Bottom (V) coordinate.\r\n * @param uvx1 - Right (U) coordinate.\r\n * @param uvy1 - Top (V) coordinate.\r\n */\r\n setUVInfo(uvx0: number, uvy0: number, uvx1: number, uvy1: number) {\r\n this.uvinfo = new Vector4(uvx0, uvy0, uvx1, uvy1);\r\n }\r\n /**\r\n * Gets the sprite anchor-rotation.\r\n *\r\n * @returns The current anchor-rotation.\r\n */\r\n get anchorRotation(): Immutable<Vector4> {\r\n return this._anchorRotation;\r\n }\r\n set anchorRotation(value: Immutable<Vector4>) {\r\n if (!value.equalsTo(this._anchorRotation)) {\r\n this._anchorRotation.set(value);\r\n this.uniformChanged();\r\n }\r\n }\r\n /**\r\n * Gets the sprite anchor point in normalized quad space.\r\n *\r\n * @returns The current anchor as a Vector2.\r\n */\r\n get anchor(): Immutable<Vector2> {\r\n return this._anchorRotation.xy();\r\n }\r\n set anchor(value: Immutable<Vector2>) {\r\n if (value.x !== this._anchorRotation.x || value.y !== this._anchorRotation.y) {\r\n this.anchorRotation = new Vector4(value.x, value.y, this._anchorRotation.z, this._anchorRotation.w);\r\n }\r\n }\r\n /**\r\n * Gets the sprite rotation around the Z axis.\r\n *\r\n * @returns The sprite rotation.\r\n */\r\n get rotation() {\r\n return this._anchorRotation.z;\r\n }\r\n set rotation(value) {\r\n if (value !== this._anchorRotation.z) {\r\n this.anchorRotation = new Vector4(\r\n this._anchorRotation.x,\r\n this._anchorRotation.y,\r\n value,\r\n this._anchorRotation.w\r\n );\r\n }\r\n }\r\n /**\r\n * Gets the X component of the sprite anchor.\r\n */\r\n get anchorX() {\r\n return this._anchorRotation.x;\r\n }\r\n set anchorX(value) {\r\n if (this._anchorRotation.x !== value) {\r\n this.anchorRotation = new Vector4(\r\n value,\r\n this._anchorRotation.y,\r\n this._anchorRotation.z,\r\n this._anchorRotation.w\r\n );\r\n }\r\n }\r\n /**\r\n * Gets the Y component of the sprite anchor.\r\n */\r\n get anchorY() {\r\n return this._anchorRotation.y;\r\n }\r\n set anchorY(value) {\r\n if (this._anchorRotation.y !== value) {\r\n this.anchorRotation = new Vector4(\r\n this._anchorRotation.x,\r\n value,\r\n this._anchorRotation.z,\r\n this._anchorRotation.w\r\n );\r\n }\r\n }\r\n /**\r\n * Convenience method to set both anchor components at once.\r\n *\r\n * @param anchorX - X coordinate of the anchor.\r\n * @param anchorY - Y coordinate of the anchor.\r\n */\r\n setAnchor(anchorX: number, anchorY: number) {\r\n if (this._anchorRotation.x !== anchorX || this._anchorRotation.y !== anchorY) {\r\n this.anchorRotation = new Vector4(anchorX, anchorY, this._anchorRotation.z, this._anchorRotation.w);\r\n }\r\n }\r\n /**\r\n * Creates a deep copy of this material.\r\n *\r\n * @returns A new {@link SpriteMaterial} instance with the same properties.\r\n */\r\n clone() {\r\n const other = new SpriteMaterial();\r\n other.copyFrom(this);\r\n return other;\r\n }\r\n /**\r\n * Copies all relevant state from another {@link SpriteMaterial}.\r\n *\r\n * @param other - The source material to copy from.\r\n */\r\n copyFrom(other: this) {\r\n super.copyFrom(other);\r\n this.uvinfo = other.uvinfo;\r\n this.anchorRotation = other.anchorRotation;\r\n }\r\n /**\r\n * Builds the vertex shader for this material.\r\n *\r\n * @remarks\r\n * This method:\r\n * - Calls the base implementation.\r\n * - Computes per-vertex positions for a camera-facing quad (billboard)\r\n * based on the sprite's world transform, size, and anchor.\r\n * - Selects the correct UV coordinates for each quad corner using\r\n * the `vertexId` attribute.\r\n * - Outputs world-space position (`zWorldPos`) and UVs (`zVertexUV`)\r\n * for use in the fragment shader.\r\n *\r\n * @param scope - The current programmable builder function scope.\r\n */\r\n vertexShader(scope: PBFunctionScope) {\r\n super.vertexShader(scope);\r\n const pb = scope.$builder;\r\n scope.$inputs.vertexId = pb.float().attrib('position');\r\n if (this.drawContext.materialFlags & MaterialVaryingFlags.INSTANCING) {\r\n scope.$l.uvinfo = this.getInstancedUniform(scope, SpriteMaterial.UVINFO);\r\n scope.$l.anchorRotation = this.getInstancedUniform(scope, SpriteMaterial.ANCHOR_ROTATION);\r\n } else {\r\n scope.uvinfo = pb.vec4().uniform(2);\r\n scope.anchorRotation = pb.vec4().uniform(2);\r\n }\r\n this.internalSetupUniforms(scope);\r\n scope.$l.worldPos = ShaderHelper.getWorldMatrix(scope)[3].xyz;\r\n scope.$l.width = pb.sqrt(\r\n pb.dot(ShaderHelper.getWorldMatrix(scope)[0].xyz, ShaderHelper.getWorldMatrix(scope)[0].xyz)\r\n );\r\n scope.$l.height = pb.sqrt(\r\n pb.dot(ShaderHelper.getWorldMatrix(scope)[1].xyz, ShaderHelper.getWorldMatrix(scope)[1].xyz)\r\n );\r\n const viewMatrix = ShaderHelper.getViewMatrix(scope);\r\n scope.$l.forward = pb.vec3(viewMatrix[0].z, viewMatrix[1].z, viewMatrix[2].z);\r\n scope.$l.axis = scope.$choice(\r\n pb.lessThan(pb.abs(scope.forward.y), 0.999),\r\n pb.vec3(0, 1, 0),\r\n pb.vec3(1, 0, 0)\r\n );\r\n scope.$l.right = pb.normalize(pb.cross(scope.axis, scope.forward));\r\n scope.$l.up = pb.normalize(pb.cross(scope.forward, scope.right));\r\n scope.$l.rotateAngle = scope.anchorRotation.z;\r\n scope.$l.c = pb.cos(scope.rotateAngle);\r\n scope.$l.s = pb.sin(scope.rotateAngle);\r\n scope.$l.rightRot = pb.add(pb.mul(scope.up, scope.s), pb.mul(scope.right, scope.c));\r\n scope.$l.upRot = pb.sub(pb.mul(scope.up, scope.c), pb.mul(scope.right, scope.s));\r\n scope.$l.v = pb.vec2();\r\n scope.$l.uv = pb.vec2();\r\n scope.$l.anchor = scope.anchorRotation.xy;\r\n scope\r\n .$if(pb.equal(scope.$inputs.vertexId, 0), function () {\r\n scope.v = pb.neg(scope.anchor);\r\n scope.uv = pb.vec2(scope.uvinfo.x, pb.sub(1, scope.uvinfo.y));\r\n })\r\n .$elseif(pb.equal(scope.$inputs.vertexId, 1), function () {\r\n scope.v = pb.sub(pb.vec2(1, 0), scope.anchor);\r\n scope.uv = pb.vec2(scope.uvinfo.z, pb.sub(1, scope.uvinfo.y));\r\n })\r\n .$elseif(pb.equal(scope.$inputs.vertexId, 2), function () {\r\n scope.v = pb.sub(pb.vec2(0, 1), scope.anchor);\r\n scope.uv = pb.vec2(scope.uvinfo.x, pb.sub(1, scope.uvinfo.w));\r\n })\r\n .$else(function () {\r\n scope.v = pb.sub(pb.vec2(1), scope.anchor);\r\n scope.uv = pb.vec2(scope.uvinfo.z, pb.sub(1, scope.uvinfo.w));\r\n });\r\n scope.v = pb.mul(scope.v, pb.vec2(scope.width, scope.height));\r\n scope.$outputs.zWorldPos = pb.add(\r\n scope.worldPos,\r\n pb.mul(scope.rightRot, scope.v.x),\r\n pb.mul(scope.upRot, scope.v.y)\r\n );\r\n scope.$outputs.zVertexUV = scope.uv;\r\n ShaderHelper.setClipSpacePosition(\r\n scope,\r\n pb.mul(ShaderHelper.getViewProjectionMatrix(scope), pb.vec4(scope.$outputs.zWorldPos, 1))\r\n );\r\n }\r\n /**\r\n * Builds the fragment shader for this material.\r\n *\r\n * @remarks\r\n * This method:\r\n * - Calls the base implementation.\r\n * - Invokes {@link SpriteMaterial.internalSetupUniforms} for\r\n * fragment-stage specific uniform declarations.\r\n * - Computes fragment color by calling {@link SpriteMaterial.calcFragmentColor}\r\n * if fragment color is needed.\r\n * - Outputs the final fragment color via {@link MeshMaterial.outputFragmentColor}.\r\n *\r\n * @param scope - The current programmable builder function scope.\r\n */\r\n fragmentShader(scope: PBFunctionScope) {\r\n super.fragmentShader(scope);\r\n this.internalSetupUniforms(scope);\r\n if (this.needFragmentColor()) {\r\n scope.$l.color = this.calcFragmentColor(scope);\r\n this.outputFragmentColor(scope, scope.$inputs.zWorldPos, scope.color);\r\n } else {\r\n this.outputFragmentColor(scope, scope.$inputs.zWorldPos, null);\r\n }\r\n }\r\n /**\r\n * Applies runtime uniform values to the given bind group before drawing.\r\n *\r\n * @remarks\r\n * This binds:\r\n * - UV information (`uvinfo`)\r\n * - Anchor (`anchor`)\r\n *\r\n * for non-instanced rendering. For instanced rendering, these values\r\n * are expected to be provided as per-instance uniforms instead.\r\n *\r\n * It also calls {@link SpriteMaterial.internalApplyUniforms} to allow\r\n * derived classes to bind additional resources (e.g. textures).\r\n *\r\n * @param bindGroup - The bind group to which uniforms and resources are bound.\r\n * @param ctx - The current draw context providing rendering state.\r\n * @param pass - Index of the active render pass.\r\n */\r\n applyUniformValues(bindGroup: BindGroup, ctx: DrawContext, pass: number) {\r\n super.applyUniformValues(bindGroup, ctx, pass);\r\n if (!(ctx.materialFlags & MaterialVaryingFlags.INSTANCING)) {\r\n bindGroup.setValue('uvinfo', this._uvinfo);\r\n bindGroup.setValue('anchorRotation', this._anchorRotation);\r\n }\r\n this.internalApplyUniforms(bindGroup, ctx, pass);\r\n }\r\n /**\r\n * Hook for derived classes to declare additional uniforms.\r\n *\r\n * @remarks\r\n * This is invoked in both the vertex and fragment shader construction\r\n * phases, allowing subclasses to register extra uniforms or resources\r\n * needed by their custom shading logic.\r\n *\r\n * The base implementation does nothing.\r\n *\r\n * @param _scope - The current shader function scope.\r\n */\r\n protected internalSetupUniforms(_scope: PBInsideFunctionScope) {}\r\n /**\r\n * Hook for derived classes to bind additional uniform values or resources.\r\n *\r\n * @remarks\r\n * This is called from {@link SpriteMaterial.applyUniformValues} and is\r\n * intended for subclasses to bind their own textures, samplers, or\r\n * other GPU resources.\r\n *\r\n * The base implementation does nothing.\r\n *\r\n * @param _bindGroup - The bind group used for binding uniforms and resources.\r\n * @param _ctx - The current draw context.\r\n * @param _pass - Index of the active render pass.\r\n */\r\n protected internalApplyUniforms(_bindGroup: BindGroup, _ctx: DrawContext, _pass: number) {}\r\n /**\r\n * Computes the fragment color expression for this material.\r\n *\r\n * @remarks\r\n * The default implementation simply outputs the interpolated UV\r\n * coordinates as color \\([u, v, 0, 1]\\), which is mainly useful\r\n * for debugging.\r\n *\r\n * Derived classes are expected to override this method to implement\r\n * actual shading, such as sampling a texture.\r\n *\r\n * @param scope - The current shader function scope.\r\n * @returns A shader expression representing the fragment color.\r\n\r\n */\r\n protected calcFragmentColor(scope: PBInsideFunctionScope) {\r\n return scope.$builder.vec4(scope.$inputs.zVertexUV, 0, 1);\r\n }\r\n}\r\n"],"names":["SpriteMaterial","MeshMaterial","UVINFO","defineInstanceUniform","ANCHOR_ROTATION","_uvinfo","_anchorRotation","Vector4","cullMode","uvinfo","value","equalsTo","set","uniformChanged","setUVInfo","uvx0","uvy0","uvx1","uvy1","anchorRotation","anchor","xy","x","y","z","w","rotation","anchorX","anchorY","setAnchor","clone","other","copyFrom","vertexShader","scope","pb","$builder","$inputs","vertexId","float","attrib","drawContext","materialFlags","MaterialVaryingFlags","INSTANCING","$l","getInstancedUniform","vec4","uniform","internalSetupUniforms","worldPos","ShaderHelper","getWorldMatrix","xyz","width","sqrt","dot","height","viewMatrix","getViewMatrix","forward","vec3","axis","$choice","lessThan","abs","right","normalize","cross","up","rotateAngle","c","cos","s","sin","rightRot","add","mul","upRot","sub","v","vec2","uv","$if","equal","neg","$elseif","$else","$outputs","zWorldPos","zVertexUV","setClipSpacePosition","getViewProjectionMatrix","fragmentShader","needFragmentColor","color","calcFragmentColor","outputFragmentColor","applyUniformValues","bindGroup","ctx","pass","setValue","internalApplyUniforms","_scope","_bindGroup","_ctx","_pass"],"mappings":"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"}
@@ -0,0 +1,301 @@
1
+ import { MeshMaterial } from './meshmaterial.js';
2
+ import { ShaderHelper } from './shader/helper.js';
3
+ import { MaterialVaryingFlags } from '../values.js';
4
+ import { Vector4 } from '@zephyr3d/base';
5
+
6
+ /**
7
+ * Sprite3D material base class.
8
+ *
9
+ * @remarks
10
+ * This material renders a camera-facing quad (billboard) in 3D space,
11
+ * using UV information and an anchor point to control how the sprite
12
+ * is positioned and textured.
13
+ *
14
+ * Derived classes can override {@link internalSetupUniforms},
15
+ * {@link internalApplyUniforms} and
16
+ * {@link calcFragmentColor} to provide custom
17
+ * uniforms and shading logic (e.g. sampling a texture).
18
+ *
19
+ * @public
20
+ */ class Sprite3DMaterial extends MeshMaterial {
21
+ static UVINFO = this.defineInstanceUniform('uvinfo', 'vec4');
22
+ static ANCHOR_ROTATION = this.defineInstanceUniform('anchorRotation', 'vec4');
23
+ _uvinfo;
24
+ _anchorRotation;
25
+ /**
26
+ * Creates a new {@link Sprite3DMaterial} instance.
27
+ *
28
+ * @remarks
29
+ * - Default UV rectangle is the full texture [0, 0, 1, 1].
30
+ * - Default anchor is the center [0.5, 0.5].
31
+ * - Face culling is disabled (`cullMode = 'none'`) so the sprite
32
+ * is visible from both sides.
33
+ */ constructor(){
34
+ super();
35
+ this._uvinfo = new Vector4(0, 0, 1, 1);
36
+ this._anchorRotation = new Vector4(0.5, 0.5, 0, 0);
37
+ this.cullMode = 'none';
38
+ }
39
+ /**
40
+ * Gets the UV rectangle of the sprite in the texture.
41
+ *
42
+ * @returns A Vector4 storing \([u0, v0, u1, v1]\).
43
+ */ get uvinfo() {
44
+ return this._uvinfo;
45
+ }
46
+ set uvinfo(value) {
47
+ if (!value.equalsTo(this.uvinfo)) {
48
+ this._uvinfo.set(value);
49
+ this.uniformChanged();
50
+ }
51
+ }
52
+ /**
53
+ * Convenience method to set the UV rectangle via individual components.
54
+ *
55
+ * @param uvx0 - Left (U) coordinate.
56
+ * @param uvy0 - Bottom (V) coordinate.
57
+ * @param uvx1 - Right (U) coordinate.
58
+ * @param uvy1 - Top (V) coordinate.
59
+ */ setUVInfo(uvx0, uvy0, uvx1, uvy1) {
60
+ this.uvinfo = new Vector4(uvx0, uvy0, uvx1, uvy1);
61
+ }
62
+ /**
63
+ * Gets the sprite anchor-rotation.
64
+ *
65
+ * @returns The current anchor-rotation.
66
+ */ get anchorRotation() {
67
+ return this._anchorRotation;
68
+ }
69
+ set anchorRotation(value) {
70
+ if (!value.equalsTo(this._anchorRotation)) {
71
+ this._anchorRotation.set(value);
72
+ this.uniformChanged();
73
+ }
74
+ }
75
+ /**
76
+ * Gets the sprite anchor point in normalized quad space.
77
+ *
78
+ * @returns The current anchor as a Vector2.
79
+ */ get anchor() {
80
+ return this._anchorRotation.xy();
81
+ }
82
+ set anchor(value) {
83
+ if (value.x !== this._anchorRotation.x || value.y !== this._anchorRotation.y) {
84
+ this.anchorRotation = new Vector4(value.x, value.y, this._anchorRotation.z, this._anchorRotation.w);
85
+ }
86
+ }
87
+ /**
88
+ * Gets the sprite rotation around the Z axis.
89
+ *
90
+ * @returns The sprite rotation.
91
+ */ get rotation() {
92
+ return this._anchorRotation.z;
93
+ }
94
+ set rotation(value) {
95
+ if (value !== this._anchorRotation.z) {
96
+ this.anchorRotation = new Vector4(this._anchorRotation.x, this._anchorRotation.y, value, this._anchorRotation.w);
97
+ }
98
+ }
99
+ /**
100
+ * Gets the X component of the sprite anchor.
101
+ */ get anchorX() {
102
+ return this._anchorRotation.x;
103
+ }
104
+ set anchorX(value) {
105
+ if (this._anchorRotation.x !== value) {
106
+ this.anchorRotation = new Vector4(value, this._anchorRotation.y, this._anchorRotation.z, this._anchorRotation.w);
107
+ }
108
+ }
109
+ /**
110
+ * Gets the Y component of the sprite anchor.
111
+ */ get anchorY() {
112
+ return this._anchorRotation.y;
113
+ }
114
+ set anchorY(value) {
115
+ if (this._anchorRotation.y !== value) {
116
+ this.anchorRotation = new Vector4(this._anchorRotation.x, value, this._anchorRotation.z, this._anchorRotation.w);
117
+ }
118
+ }
119
+ /**
120
+ * Convenience method to set both anchor components at once.
121
+ *
122
+ * @param anchorX - X coordinate of the anchor.
123
+ * @param anchorY - Y coordinate of the anchor.
124
+ */ setAnchor(anchorX, anchorY) {
125
+ if (this._anchorRotation.x !== anchorX || this._anchorRotation.y !== anchorY) {
126
+ this.anchorRotation = new Vector4(anchorX, anchorY, this._anchorRotation.z, this._anchorRotation.w);
127
+ }
128
+ }
129
+ /**
130
+ * Creates a deep copy of this material.
131
+ *
132
+ * @returns A new {@link Sprite3DMaterial} instance with the same properties.
133
+ */ clone() {
134
+ const other = new Sprite3DMaterial();
135
+ other.copyFrom(this);
136
+ return other;
137
+ }
138
+ /**
139
+ * Copies all relevant state from another {@link Sprite3DMaterial}.
140
+ *
141
+ * @param other - The source material to copy from.
142
+ */ copyFrom(other) {
143
+ super.copyFrom(other);
144
+ this.uvinfo = other.uvinfo;
145
+ this.anchorRotation = other.anchorRotation;
146
+ }
147
+ /**
148
+ * Builds the vertex shader for this material.
149
+ *
150
+ * @remarks
151
+ * This method:
152
+ * - Calls the base implementation.
153
+ * - Computes per-vertex positions for a camera-facing quad (billboard)
154
+ * based on the sprite's world transform, size, and anchor.
155
+ * - Selects the correct UV coordinates for each quad corner using
156
+ * the `vertexId` attribute.
157
+ * - Outputs world-space position (`zWorldPos`) and UVs (`zVertexUV`)
158
+ * for use in the fragment shader.
159
+ *
160
+ * @param scope - The current programmable builder function scope.
161
+ */ vertexShader(scope) {
162
+ super.vertexShader(scope);
163
+ const pb = scope.$builder;
164
+ scope.$inputs.vertexId = pb.float().attrib('position');
165
+ if (this.drawContext.materialFlags & MaterialVaryingFlags.INSTANCING) {
166
+ scope.$l.uvinfo = this.getInstancedUniform(scope, Sprite3DMaterial.UVINFO);
167
+ scope.$l.anchorRotation = this.getInstancedUniform(scope, Sprite3DMaterial.ANCHOR_ROTATION);
168
+ } else {
169
+ scope.uvinfo = pb.vec4().uniform(2);
170
+ scope.anchorRotation = pb.vec4().uniform(2);
171
+ }
172
+ this.internalSetupUniforms(scope);
173
+ scope.$l.worldPos = ShaderHelper.getWorldMatrix(scope)[3].xyz;
174
+ scope.$l.width = pb.sqrt(pb.dot(ShaderHelper.getWorldMatrix(scope)[0].xyz, ShaderHelper.getWorldMatrix(scope)[0].xyz));
175
+ scope.$l.height = pb.sqrt(pb.dot(ShaderHelper.getWorldMatrix(scope)[1].xyz, ShaderHelper.getWorldMatrix(scope)[1].xyz));
176
+ const viewMatrix = ShaderHelper.getViewMatrix(scope);
177
+ scope.$l.forward = pb.vec3(viewMatrix[0].z, viewMatrix[1].z, viewMatrix[2].z);
178
+ scope.$l.axis = scope.$choice(pb.lessThan(pb.abs(scope.forward.y), 0.999), pb.vec3(0, 1, 0), pb.vec3(1, 0, 0));
179
+ scope.$l.right = pb.normalize(pb.cross(scope.axis, scope.forward));
180
+ scope.$l.up = pb.normalize(pb.cross(scope.forward, scope.right));
181
+ scope.$l.rotateAngle = scope.anchorRotation.z;
182
+ scope.$l.c = pb.cos(scope.rotateAngle);
183
+ scope.$l.s = pb.sin(scope.rotateAngle);
184
+ scope.$l.rightRot = pb.add(pb.mul(scope.up, scope.s), pb.mul(scope.right, scope.c));
185
+ scope.$l.upRot = pb.sub(pb.mul(scope.up, scope.c), pb.mul(scope.right, scope.s));
186
+ scope.$l.v = pb.vec2();
187
+ scope.$l.uv = pb.vec2();
188
+ scope.$l.anchor = scope.anchorRotation.xy;
189
+ scope.$if(pb.equal(scope.$inputs.vertexId, 0), function() {
190
+ scope.v = pb.neg(scope.anchor);
191
+ scope.uv = pb.vec2(scope.uvinfo.x, pb.sub(1, scope.uvinfo.y));
192
+ }).$elseif(pb.equal(scope.$inputs.vertexId, 1), function() {
193
+ scope.v = pb.sub(pb.vec2(1, 0), scope.anchor);
194
+ scope.uv = pb.vec2(scope.uvinfo.z, pb.sub(1, scope.uvinfo.y));
195
+ }).$elseif(pb.equal(scope.$inputs.vertexId, 2), function() {
196
+ scope.v = pb.sub(pb.vec2(0, 1), scope.anchor);
197
+ scope.uv = pb.vec2(scope.uvinfo.x, pb.sub(1, scope.uvinfo.w));
198
+ }).$else(function() {
199
+ scope.v = pb.sub(pb.vec2(1), scope.anchor);
200
+ scope.uv = pb.vec2(scope.uvinfo.z, pb.sub(1, scope.uvinfo.w));
201
+ });
202
+ scope.v = pb.mul(scope.v, pb.vec2(scope.width, scope.height));
203
+ scope.$outputs.zWorldPos = pb.add(scope.worldPos, pb.mul(scope.rightRot, scope.v.x), pb.mul(scope.upRot, scope.v.y));
204
+ scope.$outputs.zVertexUV = scope.uv;
205
+ ShaderHelper.setClipSpacePosition(scope, pb.mul(ShaderHelper.getViewProjectionMatrix(scope), pb.vec4(scope.$outputs.zWorldPos, 1)));
206
+ }
207
+ /**
208
+ * Builds the fragment shader for this material.
209
+ *
210
+ * @remarks
211
+ * This method:
212
+ * - Calls the base implementation.
213
+ * - Invokes {@link Sprite3DMaterial.internalSetupUniforms} for
214
+ * fragment-stage specific uniform declarations.
215
+ * - Computes fragment color by calling {@link Sprite3DMaterial.calcFragmentColor}
216
+ * if fragment color is needed.
217
+ * - Outputs the final fragment color via {@link MeshMaterial.outputFragmentColor}.
218
+ *
219
+ * @param scope - The current programmable builder function scope.
220
+ */ fragmentShader(scope) {
221
+ super.fragmentShader(scope);
222
+ this.internalSetupUniforms(scope);
223
+ if (this.needFragmentColor()) {
224
+ scope.$l.color = this.calcFragmentColor(scope);
225
+ this.outputFragmentColor(scope, scope.$inputs.zWorldPos, scope.color);
226
+ } else {
227
+ this.outputFragmentColor(scope, scope.$inputs.zWorldPos, null);
228
+ }
229
+ }
230
+ /**
231
+ * Applies runtime uniform values to the given bind group before drawing.
232
+ *
233
+ * @remarks
234
+ * This binds:
235
+ * - UV information (`uvinfo`)
236
+ * - Anchor (`anchor`)
237
+ *
238
+ * for non-instanced rendering. For instanced rendering, these values
239
+ * are expected to be provided as per-instance uniforms instead.
240
+ *
241
+ * It also calls {@link Sprite3DMaterial.internalApplyUniforms} to allow
242
+ * derived classes to bind additional resources (e.g. textures).
243
+ *
244
+ * @param bindGroup - The bind group to which uniforms and resources are bound.
245
+ * @param ctx - The current draw context providing rendering state.
246
+ * @param pass - Index of the active render pass.
247
+ */ applyUniformValues(bindGroup, ctx, pass) {
248
+ super.applyUniformValues(bindGroup, ctx, pass);
249
+ if (!(ctx.materialFlags & MaterialVaryingFlags.INSTANCING)) {
250
+ bindGroup.setValue('uvinfo', this._uvinfo);
251
+ bindGroup.setValue('anchorRotation', this._anchorRotation);
252
+ }
253
+ this.internalApplyUniforms(bindGroup, ctx, pass);
254
+ }
255
+ /**
256
+ * Hook for derived classes to declare additional uniforms.
257
+ *
258
+ * @remarks
259
+ * This is invoked in both the vertex and fragment shader construction
260
+ * phases, allowing subclasses to register extra uniforms or resources
261
+ * needed by their custom shading logic.
262
+ *
263
+ * The base implementation does nothing.
264
+ *
265
+ * @param _scope - The current shader function scope.
266
+ */ internalSetupUniforms(_scope) {}
267
+ /**
268
+ * Hook for derived classes to bind additional uniform values or resources.
269
+ *
270
+ * @remarks
271
+ * This is called from {@link Sprite3DMaterial.applyUniformValues} and is
272
+ * intended for subclasses to bind their own textures, samplers, or
273
+ * other GPU resources.
274
+ *
275
+ * The base implementation does nothing.
276
+ *
277
+ * @param _bindGroup - The bind group used for binding uniforms and resources.
278
+ * @param _ctx - The current draw context.
279
+ * @param _pass - Index of the active render pass.
280
+ */ internalApplyUniforms(_bindGroup, _ctx, _pass) {}
281
+ /**
282
+ * Computes the fragment color expression for this material.
283
+ *
284
+ * @remarks
285
+ * The default implementation simply outputs the interpolated UV
286
+ * coordinates as color \([u, v, 0, 1]\), which is mainly useful
287
+ * for debugging.
288
+ *
289
+ * Derived classes are expected to override this method to implement
290
+ * actual shading, such as sampling a texture.
291
+ *
292
+ * @param scope - The current shader function scope.
293
+ * @returns A shader expression representing the fragment color.
294
+
295
+ */ calcFragmentColor(scope) {
296
+ return scope.$builder.vec4(scope.$inputs.zVertexUV, 0, 1);
297
+ }
298
+ }
299
+
300
+ export { Sprite3DMaterial };
301
+ //# sourceMappingURL=sprite3d.js.map