@babylonjs/lite 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +51 -0
  3. package/THIRD_PARTY_NOTICES.txt +318 -0
  4. package/{_mat4-storage-f64-CjDoht2w.js → _mat4-storage-f64-WeexU-hd.js} +2 -2
  5. package/{_mat4-storage-f64-CjDoht2w.js.map → _mat4-storage-f64-WeexU-hd.js.map} +1 -1
  6. package/{alpha-test-fragment-B7DjSnF7.js → alpha-test-fragment-x2mnjLgC.js} +2 -2
  7. package/{alpha-test-fragment-B7DjSnF7.js.map → alpha-test-fragment-x2mnjLgC.js.map} +1 -1
  8. package/{background-dds-skybox-BEX309u3.js → background-dds-skybox-BpcDr-9c.js} +3 -3
  9. package/{background-dds-skybox-BEX309u3.js.map → background-dds-skybox-BpcDr-9c.js.map} +1 -1
  10. package/{background-ground-BU0HOcM4.js → background-ground-Bm6gjWqx.js} +2 -2
  11. package/{background-ground-BU0HOcM4.js.map → background-ground-Bm6gjWqx.js.map} +1 -1
  12. package/{background-hdr-skybox--RRRic_K.js → background-hdr-skybox-CSFo8RX6.js} +3 -3
  13. package/{background-hdr-skybox--RRRic_K.js.map → background-hdr-skybox-CSFo8RX6.js.map} +1 -1
  14. package/{background-solid-skybox-BrH2fXSu.js → background-solid-skybox-DOOBeDIz.js} +2 -2
  15. package/{background-solid-skybox-BrH2fXSu.js.map → background-solid-skybox-DOOBeDIz.js.map} +1 -1
  16. package/{billboard-renderable-BHWryAeC.js → billboard-renderable-IJfCpeDS.js} +2 -2
  17. package/{billboard-renderable-BHWryAeC.js.map → billboard-renderable-IJfCpeDS.js.map} +1 -1
  18. package/{clamp-block-DqbwnQGW.js → clamp-block-BD_t8I89.js} +2 -2
  19. package/{clamp-block-DqbwnQGW.js.map → clamp-block-BD_t8I89.js.map} +1 -1
  20. package/{clearcoat-fragment-D6FSCie1.js → clearcoat-fragment-Dj7vGX2u.js} +2 -2
  21. package/{clearcoat-fragment-D6FSCie1.js.map → clearcoat-fragment-Dj7vGX2u.js.map} +1 -1
  22. package/{create-skeleton-D_uplboC.js → create-skeleton-s0hjrC3A.js} +2 -2
  23. package/{create-skeleton-D_uplboC.js.map → create-skeleton-s0hjrC3A.js.map} +1 -1
  24. package/{cubemap-skybox-material-DQcMMdf-.js → cubemap-skybox-material-8lzbgi7K.js} +2 -2
  25. package/{cubemap-skybox-material-DQcMMdf-.js.map → cubemap-skybox-material-8lzbgi7K.js.map} +1 -1
  26. package/{curve-block-21rT0JjG.js → curve-block-Ditr4R7V.js} +2 -2
  27. package/{curve-block-21rT0JjG.js.map → curve-block-Ditr4R7V.js.map} +1 -1
  28. package/{emissive-fragment-C5FtBs3y.js → emissive-fragment-BOAezkfk.js} +2 -2
  29. package/{emissive-fragment-C5FtBs3y.js.map → emissive-fragment-BOAezkfk.js.map} +1 -1
  30. package/{esm-shadow-view-c5YV4Eg9.js → esm-shadow-view-DRpyRAfa.js} +2 -2
  31. package/{esm-shadow-view-c5YV4Eg9.js.map → esm-shadow-view-DRpyRAfa.js.map} +1 -1
  32. package/{esm-shadow-view-Gtd1LWRP.js → esm-shadow-view-DmIORQGZ.js} +2 -2
  33. package/{esm-shadow-view-Gtd1LWRP.js.map → esm-shadow-view-DmIORQGZ.js.map} +1 -1
  34. package/{esm-shadow-view-Cl3rPGof.js → esm-shadow-view-JCPaOOi7.js} +2 -2
  35. package/{esm-shadow-view-Cl3rPGof.js.map → esm-shadow-view-JCPaOOi7.js.map} +1 -1
  36. package/{gaussian-splatting-pipeline-sh-7J31V23x.js → gaussian-splatting-pipeline-sh-B30Mu56i.js} +2 -2
  37. package/{gaussian-splatting-pipeline-sh-7J31V23x.js.map → gaussian-splatting-pipeline-sh-B30Mu56i.js.map} +1 -1
  38. package/{geometry-texture-output-dXk4E9uu.js → geometry-texture-output-DURiaJ_n.js} +2 -2
  39. package/{geometry-texture-output-dXk4E9uu.js.map → geometry-texture-output-DURiaJ_n.js.map} +1 -1
  40. package/{geometry-view-BsFJpBJa.js → geometry-view-DRrscyWU.js} +4 -4
  41. package/{geometry-view-BsFJpBJa.js.map → geometry-view-DRrscyWU.js.map} +1 -1
  42. package/{gltf-animation-K_zZxj_d.js → gltf-animation-BjnXkop6.js} +2 -2
  43. package/{gltf-animation-K_zZxj_d.js.map → gltf-animation-BjnXkop6.js.map} +1 -1
  44. package/{gltf-ext-basisu-CDbPclzZ.js → gltf-ext-basisu-DtzVV1Xx.js} +2 -202
  45. package/gltf-ext-basisu-DtzVV1Xx.js.map +1 -0
  46. package/{gltf-ext-node-visibility-DXCJEYr6.js → gltf-ext-node-visibility-BhX0DmiP.js} +2 -2
  47. package/{gltf-ext-node-visibility-DXCJEYr6.js.map → gltf-ext-node-visibility-BhX0DmiP.js.map} +1 -1
  48. package/{gltf-ext-quantization-CvHI_0Vg.js → gltf-ext-quantization-DaymajCR.js} +2 -2
  49. package/{gltf-ext-quantization-CvHI_0Vg.js.map → gltf-ext-quantization-DaymajCR.js.map} +1 -1
  50. package/{gltf-ext-uv-transform-DgYazJBs.js → gltf-ext-uv-transform-DFmNJ8kA.js} +2 -2
  51. package/{gltf-ext-uv-transform-DgYazJBs.js.map → gltf-ext-uv-transform-DFmNJ8kA.js.map} +1 -1
  52. package/{gltf-feature-animation-pointer-D1RJRFBw.js → gltf-feature-animation-pointer-C40tqOhL.js} +3 -3
  53. package/{gltf-feature-animation-pointer-D1RJRFBw.js.map → gltf-feature-animation-pointer-C40tqOhL.js.map} +1 -1
  54. package/{gltf-feature-animations-Cmc1uoIu.js → gltf-feature-animations-v0S_yb4T.js} +2 -2
  55. package/{gltf-feature-animations-Cmc1uoIu.js.map → gltf-feature-animations-v0S_yb4T.js.map} +1 -1
  56. package/{gltf-feature-draco-CKKzT5E3.js → gltf-feature-draco-CljWrsna.js} +2 -2
  57. package/{gltf-feature-draco-CKKzT5E3.js.map → gltf-feature-draco-CljWrsna.js.map} +1 -1
  58. package/{gltf-feature-gpu-instancing-n87SO6Vh.js → gltf-feature-gpu-instancing-BoeSm6Tn.js} +2 -2
  59. package/{gltf-feature-gpu-instancing-n87SO6Vh.js.map → gltf-feature-gpu-instancing-BoeSm6Tn.js.map} +1 -1
  60. package/{gltf-feature-lights-punctual-Ckm3ciL8.js → gltf-feature-lights-punctual-BCTwgyi_.js} +5 -5
  61. package/{gltf-feature-lights-punctual-Ckm3ciL8.js.map → gltf-feature-lights-punctual-BCTwgyi_.js.map} +1 -1
  62. package/{gltf-feature-meshopt-DLC4SF1E.js → gltf-feature-meshopt-DItMkOMt.js} +2 -2
  63. package/{gltf-feature-meshopt-DLC4SF1E.js.map → gltf-feature-meshopt-DItMkOMt.js.map} +1 -1
  64. package/{gltf-feature-morph-Cjtu7hYa.js → gltf-feature-morph-Cv0mEYIq.js} +3 -3
  65. package/{gltf-feature-morph-Cjtu7hYa.js.map → gltf-feature-morph-Cv0mEYIq.js.map} +1 -1
  66. package/{gltf-feature-registry-C63Hjp9w.js → gltf-feature-registry-wNbt6UC-.js} +15 -15
  67. package/{gltf-feature-registry-C63Hjp9w.js.map → gltf-feature-registry-wNbt6UC-.js.map} +1 -1
  68. package/{gltf-feature-skeleton-DKbOGidp.js → gltf-feature-skeleton-Deh2UBAn.js} +3 -3
  69. package/{gltf-feature-skeleton-DKbOGidp.js.map → gltf-feature-skeleton-Deh2UBAn.js.map} +1 -1
  70. package/{gltf-feature-variants-Cmzu0O0e.js → gltf-feature-variants-DGSdFNJq.js} +2 -2
  71. package/{gltf-feature-variants-Cmzu0O0e.js.map → gltf-feature-variants-DGSdFNJq.js.map} +1 -1
  72. package/{gltf-glb-parser-Cj5MHS-v.js → gltf-glb-parser-DSQWsT4r.js} +2 -2
  73. package/{gltf-glb-parser-Cj5MHS-v.js.map → gltf-glb-parser-DSQWsT4r.js.map} +1 -1
  74. package/{gltf-interleave-gHf9_t0i.js → gltf-interleave-OBqmlu-h.js} +11 -5
  75. package/gltf-interleave-OBqmlu-h.js.map +1 -0
  76. package/{gltf-normals-b2h74380.js → gltf-normals-D_P0KA4b.js} +10 -2
  77. package/gltf-normals-D_P0KA4b.js.map +1 -0
  78. package/{gltf-pbr-builder-ext-edNcjwPf.js → gltf-pbr-builder-ext-3imk8Tev.js} +2 -2
  79. package/{gltf-pbr-builder-ext-edNcjwPf.js.map → gltf-pbr-builder-ext-3imk8Tev.js.map} +1 -1
  80. package/{gltf-variants-CPxNdtP4.js → gltf-variants-Dyr54wwg.js} +4 -4
  81. package/{gltf-variants-CPxNdtP4.js.map → gltf-variants-Dyr54wwg.js.map} +1 -1
  82. package/gpu-task-timer-DVBNZfq5.js +236 -0
  83. package/gpu-task-timer-DVBNZfq5.js.map +1 -0
  84. package/gpu-timer-CUpqT_hK.js +55 -0
  85. package/gpu-timer-CUpqT_hK.js.map +1 -0
  86. package/{gs-picking-pipeline-DYaW_Lg3.js → gs-picking-pipeline-CERN-Trj.js} +2 -2
  87. package/{gs-picking-pipeline-DYaW_Lg3.js.map → gs-picking-pipeline-CERN-Trj.js.map} +1 -1
  88. package/{havok-floating-origin-Dr-18Nds.js → havok-floating-origin-VVdJRUYc.js} +2 -2
  89. package/{havok-floating-origin-Dr-18Nds.js.map → havok-floating-origin-VVdJRUYc.js.map} +1 -1
  90. package/{index-CYZDclhF.js → index-7Bk-uLSM.js} +2 -2
  91. package/{index-CYZDclhF.js.map → index-7Bk-uLSM.js.map} +1 -1
  92. package/{index-CLElg2Bo.js → index-BgY3QEzL.js} +4774 -1276
  93. package/index-BgY3QEzL.js.map +1 -0
  94. package/{index-SMJ67XwT.js → index-Dr5LK2tg.js} +2 -2
  95. package/{index-SMJ67XwT.js.map → index-Dr5LK2tg.js.map} +1 -1
  96. package/index.d.ts +1047 -13
  97. package/index.js +508 -444
  98. package/{input-block-DqEedWF2.js → input-block-DjdlndCL.js} +2 -2
  99. package/{input-block-DqEedWF2.js.map → input-block-DjdlndCL.js.map} +1 -1
  100. package/{iridescence-fragment-BHU59-gQ.js → iridescence-fragment-kfsCs8lN.js} +2 -2
  101. package/{iridescence-fragment-BHU59-gQ.js.map → iridescence-fragment-kfsCs8lN.js.map} +1 -1
  102. package/{light-block-Bv37V8vl.js → light-block-qjCrz3de.js} +2 -2
  103. package/{light-block-Bv37V8vl.js.map → light-block-qjCrz3de.js.map} +1 -1
  104. package/{loop-block-qTg8vb99.js → loop-block-C8vkQ2bz.js} +2 -2
  105. package/{loop-block-qTg8vb99.js.map → loop-block-C8vkQ2bz.js.map} +1 -1
  106. package/{manifold-AS8POaOr.js → manifold-DeXMNgxT.js} +3 -3
  107. package/{manifold-AS8POaOr.js.map → manifold-DeXMNgxT.js.map} +1 -1
  108. package/{morph-fragment-BRCUr2wQ.js → morph-fragment-NpZYyIIU.js} +2 -2
  109. package/{morph-fragment-BRCUr2wQ.js.map → morph-fragment-NpZYyIIU.js.map} +1 -1
  110. package/{multilight-wgsl-DMeppAdZ.js → multilight-wgsl-I5SncF0q.js} +2 -2
  111. package/{multilight-wgsl-DMeppAdZ.js.map → multilight-wgsl-I5SncF0q.js.map} +1 -1
  112. package/{node-env-Bc559GmY.js → node-env-D7Aee08u.js} +2 -2
  113. package/{node-env-Bc559GmY.js.map → node-env-D7Aee08u.js.map} +1 -1
  114. package/{node-geometry-view-COmWsRXK.js → node-geometry-view-DfKXWNfV.js} +3 -3
  115. package/{node-geometry-view-COmWsRXK.js.map → node-geometry-view-DfKXWNfV.js.map} +1 -1
  116. package/{node-registry-extra-compat-dWrv7gpS.js → node-registry-extra-compat-CDLeBR1P.js} +2 -2
  117. package/{node-registry-extra-compat-dWrv7gpS.js.map → node-registry-extra-compat-CDLeBR1P.js.map} +1 -1
  118. package/{node-registry-extra-math-Bn854sX9.js → node-registry-extra-math-BA8_l4lB.js} +2 -2
  119. package/{node-registry-extra-math-Bn854sX9.js.map → node-registry-extra-math-BA8_l4lB.js.map} +1 -1
  120. package/{node-renderable-B5G8WcdH.js → node-renderable-EwLLnaL1.js} +2 -2
  121. package/{node-renderable-B5G8WcdH.js.map → node-renderable-EwLLnaL1.js.map} +1 -1
  122. package/{node-shadow-CVIUlNf0.js → node-shadow-CeTmT6g4.js} +2 -2
  123. package/{node-shadow-CVIUlNf0.js.map → node-shadow-CeTmT6g4.js.map} +1 -1
  124. package/{normal-map-fragment-CQSxhjCy.js → normal-map-fragment-BHImLyM-.js} +2 -2
  125. package/{normal-map-fragment-CQSxhjCy.js.map → normal-map-fragment-BHImLyM-.js.map} +1 -1
  126. package/package.json +10 -3
  127. package/{parse-camera-pBRT_6i5.js → parse-camera-5IGdctAS.js} +2 -2
  128. package/{parse-camera-pBRT_6i5.js.map → parse-camera-5IGdctAS.js.map} +1 -1
  129. package/{pbr-geometry-view-NiZY_juX.js → pbr-geometry-view-Dthf9Aut.js} +3 -3
  130. package/{pbr-geometry-view-NiZY_juX.js.map → pbr-geometry-view-Dthf9Aut.js.map} +1 -1
  131. package/{pbr-metallic-roughness-block-full-Ta9lR2cz.js → pbr-metallic-roughness-block-full-DD6zI_Lx.js} +2 -2
  132. package/{pbr-metallic-roughness-block-full-Ta9lR2cz.js.map → pbr-metallic-roughness-block-full-DD6zI_Lx.js.map} +1 -1
  133. package/{pbr-metallic-roughness-block-JBSi-tQN.js → pbr-metallic-roughness-block-g7wjzwN_.js} +2 -2
  134. package/{pbr-metallic-roughness-block-JBSi-tQN.js.map → pbr-metallic-roughness-block-g7wjzwN_.js.map} +1 -1
  135. package/{pbr-mr-helper-core-BVWNR08D.js → pbr-mr-helper-core-CWROQ7OA.js} +2 -2
  136. package/{pbr-mr-helper-core-BVWNR08D.js.map → pbr-mr-helper-core-CWROQ7OA.js.map} +1 -1
  137. package/{pbr-refraction-C9FvFmAp.js → pbr-refraction-Dxsm_gii.js} +2 -2
  138. package/{pbr-refraction-C9FvFmAp.js.map → pbr-refraction-Dxsm_gii.js.map} +1 -1
  139. package/{pbr-renderable-DzUF2QIk.js → pbr-renderable-CuKWalEM.js} +22 -22
  140. package/{pbr-renderable-DzUF2QIk.js.map → pbr-renderable-CuKWalEM.js.map} +1 -1
  141. package/{pbr-shadow-fragment-CnqnbGYS.js → pbr-shadow-fragment-waeIBQUq.js} +2 -2
  142. package/{pbr-shadow-fragment-CnqnbGYS.js.map → pbr-shadow-fragment-waeIBQUq.js.map} +1 -1
  143. package/{pbr-tracking-3tU1kqea.js → pbr-tracking-CdeqbBrh.js} +2 -2
  144. package/{pbr-tracking-3tU1kqea.js.map → pbr-tracking-CdeqbBrh.js.map} +1 -1
  145. package/{pbr-transmission-ext-BcLjRxfB.js → pbr-transmission-ext-BNiXngZc.js} +2 -2
  146. package/{pbr-transmission-ext-BcLjRxfB.js.map → pbr-transmission-ext-BNiXngZc.js.map} +1 -1
  147. package/{recast-navigation.wasm-DG_0AFuk.js → recast-navigation.wasm-VC4lGlEe.js} +3 -3
  148. package/{recast-navigation.wasm-DG_0AFuk.js.map → recast-navigation.wasm-VC4lGlEe.js.map} +1 -1
  149. package/{recast-navigation.wasm-compat-C-Bf2ylB.js → recast-navigation.wasm-compat-CTwYOzRz.js} +3 -3
  150. package/{recast-navigation.wasm-compat-C-Bf2ylB.js.map → recast-navigation.wasm-compat-CTwYOzRz.js.map} +1 -1
  151. package/{reflectance-fragment-Dbpgw3Jt.js → reflectance-fragment-BQFZ_pgy.js} +2 -2
  152. package/{reflectance-fragment-Dbpgw3Jt.js.map → reflectance-fragment-BQFZ_pgy.js.map} +1 -1
  153. package/{rgbd-decode-DoyUquy3.js → rgbd-decode-duTlXMWd.js} +2 -2
  154. package/{rgbd-decode-DoyUquy3.js.map → rgbd-decode-duTlXMWd.js.map} +1 -1
  155. package/{scene-material-swap-nNUH4nGn.js → scene-material-swap-4qM0tpBK.js} +1 -2
  156. package/scene-material-swap-4qM0tpBK.js.map +1 -0
  157. package/{screenshot-readback-D0Sj9qq3.js → screenshot-readback-DnxR4rhp.js} +2 -2
  158. package/{screenshot-readback-D0Sj9qq3.js.map → screenshot-readback-DnxR4rhp.js.map} +1 -1
  159. package/{shader-composer-BUD_pSX4.js → shader-composer-CBy2i8nU.js} +2 -2
  160. package/{shader-composer-BUD_pSX4.js.map → shader-composer-CBy2i8nU.js.map} +1 -1
  161. package/{shader-renderable-D7-RyVxa.js → shader-renderable-DVMVD6zP.js} +41 -9
  162. package/shader-renderable-DVMVD6zP.js.map +1 -0
  163. package/{shader-thin-instance-DuBotxDO.js → shader-thin-instance-CsDo3ULk.js} +2 -2
  164. package/{shader-thin-instance-DuBotxDO.js.map → shader-thin-instance-CsDo3ULk.js.map} +1 -1
  165. package/{sheen-fragment-1MkEMcbc.js → sheen-fragment-B_Jd7wrr.js} +2 -2
  166. package/{sheen-fragment-1MkEMcbc.js.map → sheen-fragment-B_Jd7wrr.js.map} +1 -1
  167. package/{singlelight-directional-wgsl-BsV8G456.js → singlelight-directional-wgsl-Bw84txva.js} +2 -2
  168. package/{singlelight-directional-wgsl-BsV8G456.js.map → singlelight-directional-wgsl-Bw84txva.js.map} +1 -1
  169. package/{singlelight-hemispheric-wgsl-Bo0jKlW5.js → singlelight-hemispheric-wgsl-DjxhgI8r.js} +2 -2
  170. package/{singlelight-hemispheric-wgsl-Bo0jKlW5.js.map → singlelight-hemispheric-wgsl-DjxhgI8r.js.map} +1 -1
  171. package/{singlelight-point-wgsl-DV39UP5Y.js → singlelight-point-wgsl-iA1aRkXA.js} +2 -2
  172. package/{singlelight-point-wgsl-DV39UP5Y.js.map → singlelight-point-wgsl-iA1aRkXA.js.map} +1 -1
  173. package/{singlelight-spot-wgsl-yg3od6vL.js → singlelight-spot-wgsl-MDdTdstF.js} +2 -2
  174. package/{singlelight-spot-wgsl-yg3od6vL.js.map → singlelight-spot-wgsl-MDdTdstF.js.map} +1 -1
  175. package/{skeleton-fragment-DdxYG6kv.js → skeleton-fragment-COdHWFcK.js} +2 -2
  176. package/{skeleton-fragment-DdxYG6kv.js.map → skeleton-fragment-COdHWFcK.js.map} +1 -1
  177. package/{skybox-renderable-CJD4XmX5.js → skybox-renderable-DJYkfw32.js} +2 -2
  178. package/{skybox-renderable-CJD4XmX5.js.map → skybox-renderable-DJYkfw32.js.map} +1 -1
  179. package/{splat-ply-compressed-DHjyiVmI.js → splat-ply-compressed-SxMlsKNK.js} +2 -2
  180. package/{splat-ply-compressed-DHjyiVmI.js.map → splat-ply-compressed-SxMlsKNK.js.map} +1 -1
  181. package/{standard-pipeline-XTbHL7MY.js → standard-pipeline-DXFOUqU_.js} +3 -3
  182. package/{standard-pipeline-XTbHL7MY.js.map → standard-pipeline-DXFOUqU_.js.map} +1 -1
  183. package/{standard-renderable-CREWLNHI.js → standard-renderable-BAc-i-ig.js} +3 -3
  184. package/{standard-renderable-CREWLNHI.js.map → standard-renderable-BAc-i-ig.js.map} +1 -1
  185. package/{std-ambient-fragment-Bjx3VFrr.js → std-ambient-fragment-P8dHZ4An.js} +2 -2
  186. package/{std-ambient-fragment-Bjx3VFrr.js.map → std-ambient-fragment-P8dHZ4An.js.map} +1 -1
  187. package/{std-cube-reflection-fragment-y9WWdXUt.js → std-cube-reflection-fragment-CF03MuQt.js} +2 -2
  188. package/{std-cube-reflection-fragment-y9WWdXUt.js.map → std-cube-reflection-fragment-CF03MuQt.js.map} +1 -1
  189. package/{std-emissive-fragment-C8Lnmojh.js → std-emissive-fragment-P8yJGclx.js} +2 -2
  190. package/{std-emissive-fragment-C8Lnmojh.js.map → std-emissive-fragment-P8yJGclx.js.map} +1 -1
  191. package/{std-lightmap-fragment-DFxGcoA5.js → std-lightmap-fragment-CymEG79z.js} +9 -6
  192. package/std-lightmap-fragment-CymEG79z.js.map +1 -0
  193. package/{std-opacity-fragment-EXzFWiSp.js → std-opacity-fragment-DLa1zV06.js} +2 -2
  194. package/{std-opacity-fragment-EXzFWiSp.js.map → std-opacity-fragment-DLa1zV06.js.map} +1 -1
  195. package/{std-reflection-fragment-BoJORqpG.js → std-reflection-fragment-BLySsYos.js} +2 -2
  196. package/{std-reflection-fragment-BoJORqpG.js.map → std-reflection-fragment-BLySsYos.js.map} +1 -1
  197. package/{std-shadow-fragment-Bq-Wc8UJ.js → std-shadow-fragment-C_q27Mdi.js} +2 -2
  198. package/{std-shadow-fragment-Bq-Wc8UJ.js.map → std-shadow-fragment-C_q27Mdi.js.map} +1 -1
  199. package/{std-specular-fragment-CM5R5j2g.js → std-specular-fragment-CaBXyAWY.js} +2 -2
  200. package/{std-specular-fragment-CM5R5j2g.js.map → std-specular-fragment-CaBXyAWY.js.map} +1 -1
  201. package/{std-tracking-Cif_wXeT.js → std-tracking-Bw61Dv98.js} +2 -2
  202. package/{std-tracking-Cif_wXeT.js.map → std-tracking-Bw61Dv98.js.map} +1 -1
  203. package/{subsurface-fragment-BEaAXYXz.js → subsurface-fragment-BNQoG9gr.js} +2 -2
  204. package/{subsurface-fragment-BEaAXYXz.js.map → subsurface-fragment-BNQoG9gr.js.map} +1 -1
  205. package/{thin-instance-cull-binding-DWKUt5ZN.js → thin-instance-cull-binding-BNC5JiGw.js} +3 -3
  206. package/{thin-instance-cull-binding-DWKUt5ZN.js.map → thin-instance-cull-binding-BNC5JiGw.js.map} +1 -1
  207. package/{thin-instance-gpu-BDdRcNAh.js → thin-instance-gpu-C1DGstap.js} +2 -2
  208. package/{thin-instance-gpu-BDdRcNAh.js.map → thin-instance-gpu-C1DGstap.js.map} +1 -1
  209. package/{tracking-primitives-CglRNTlX.js → tracking-primitives-CMBWLxGr.js} +2 -2
  210. package/{tracking-primitives-CglRNTlX.js.map → tracking-primitives-CMBWLxGr.js.map} +1 -1
  211. package/{unlit-fragment-kxfZWlnp.js → unlit-fragment-BsHrS9XX.js} +2 -2
  212. package/{unlit-fragment-kxfZWlnp.js.map → unlit-fragment-BsHrS9XX.js.map} +1 -1
  213. package/gltf-ext-basisu-CDbPclzZ.js.map +0 -1
  214. package/gltf-interleave-gHf9_t0i.js.map +0 -1
  215. package/gltf-normals-b2h74380.js.map +0 -1
  216. package/index-CLElg2Bo.js.map +0 -1
  217. package/scene-material-swap-nNUH4nGn.js.map +0 -1
  218. package/shader-renderable-D7-RyVxa.js.map +0 -1
  219. package/std-lightmap-fragment-DFxGcoA5.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"geometry-view-BsFJpBJa.js","sources":["../src/material/standard/standard-geometry-output-shader.ts","../src/material/standard/standard-geometry-renderable.ts","../src/material/standard/geometry-view.ts"],"sourcesContent":["/** Standard geometry-output shader composer.\n *\n * Builds the WGSL for a {@link createStandardGeometryMaterialView}-wrapped\n * Standard material that targets the geometry-renderer MRT pass.\n *\n * Design — *zero bundle impact* on scenes that never load the\n * geometry-renderer task:\n *\n * 1. Reuse `composeStandardShader` verbatim. The standard composer already\n * emits the bump perturbation (`normalW = perturbNormal(...)` via the AC\n * slot), opacity-texture alpha modulation, alpha-cutout discard,\n * instancing, thin-instance colour, etc. None of that needs to be\n * re-implemented.\n * 2. Post-process the resulting fragment WGSL: change the entry signature\n * to return a `FragmentOutput` MRT struct, prepend the struct\n * declaration, and replace `return color;` with code that writes each\n * requested geometry attachment from the already-in-scope intermediate\n * variables (`normalW`, `baseColor`, `specularColor`, `alpha`,\n * `input.vp`, …).\n * 3. Add a small `geometryParams` ShaderFragment that contributes a `gp`\n * UBO binding (camera near/far + previous viewProjection) only when the\n * requested attachment list needs it (NORMALIZED_VIEW_DEPTH /\n * LINEAR_VELOCITY).\n *\n * The lighting / fog block still runs and produces a dead `color` value\n * the WGSL compiler folds away. Acceptable cost for the architectural\n * reuse — matches the user's directive: \"inject some shader code at the\n * end of the fragment to output the data for the geometry textures\".\n */\n\nimport { GeometryTextureType } from \"../../frame-graph/geometry-types.js\";\nimport type { ComposedShader, ShaderFragment, Varying } from \"../../shader/fragment-types.js\";\nimport { composeStandardShader } from \"./standard-pipeline.js\";\nimport { HAS_SPECULAR_TEXTURE, MATERIAL_ALPHA_BLEND, SPECULAR_USES_UV2 } from \"./standard-flags.js\";\n\nconst STAGE_FRAGMENT = 0x2;\nconst STAGE_VERTEX = 0x1;\n\n/** Tags whether the geometry pass needs the per-task `gp` UBO. */\nfunction needsGpUbo(attachments: readonly GeometryTextureType[]): boolean {\n for (const t of attachments) {\n if (t === GeometryTextureType.NORMALIZED_VIEW_DEPTH || t === GeometryTextureType.LINEAR_VELOCITY) {\n return true;\n }\n }\n return false;\n}\n\n/** Tags whether the geometry pass needs the previous-clip varying (velocity). */\nfunction needsVelocity(attachments: readonly GeometryTextureType[]): boolean {\n return attachments.includes(GeometryTextureType.LINEAR_VELOCITY);\n}\n\n/** Tags whether the geometry pass needs the local-position varying. */\nfunction needsLocalPos(attachments: readonly GeometryTextureType[]): boolean {\n return attachments.includes(GeometryTextureType.LOCAL_POSITION);\n}\n\n/** Per-attachment WGSL output expression. `alpha` is the in-scope standard\n * fragment alpha (mat.dc.a × opacityTex × …). `wg` is `writeGeomInfo` — a\n * binary 0/1 gate matching BJS `default.fragment.fx` PREPASS\n * (`color.a > 0.4 ? 1.0 : 0.0`). Combined with the per-attachment\n * ALPHA_COMBINE blend state, low-opacity samples preserve the destination\n * (background) while high-opacity samples overwrite it.\n *\n * All variable references resolve to symbols already declared by\n * `standard-template.ts` / the standard fragment registry:\n * - `normalW` — normalized world normal (post-bump if HAS_BUMP_TEXTURE).\n * - `input.vp` — world position.\n * - `baseColor`/`mat.tl` — diffuse texture sample (rgb) × diffuseLevel.\n * - `specularColor`/`mat.sc` — specular colour, replaced by the std-specular\n * fragment's `textureSample(sT, sS, uv).rgb` when HAS_SPECULAR_TEXTURE.\n * - `scene.view` — view matrix from the canonical SceneUniforms.\n * - `gp.cameraNearFar` / `gp.previousViewProjection` — from the geometry\n * params UBO (added only when `needsGpUbo`).\n * - `input.vCurrentClip` / `input.vPreviousClip` — added by the velocity\n * fragment when LINEAR_VELOCITY is requested. */\nfunction attachmentExpr(type: GeometryTextureType, wg: string, hasSpecular: boolean, specularUv: string): string {\n switch (type) {\n case GeometryTextureType.IRRADIANCE:\n // BJS Standard material can't split irradiance — outputs (0, 0, 0).\n return `vec4<f32>(0.0, 0.0, 0.0, ${wg})`;\n case GeometryTextureType.WORLD_POSITION:\n return `vec4<f32>(input.vp, ${wg})`;\n case GeometryTextureType.LOCAL_POSITION:\n // `vLocalPos` is contributed by the geometry-params fragment (added\n // only when LOCAL_POSITION is requested).\n return `vec4<f32>(input.vLocalPos, ${wg})`;\n case GeometryTextureType.REFLECTIVITY:\n // BJS: vec4(toLinearSpace(specularMapColor)) * writeGeometryInfo\n // (.a is glossiness when a specular texture is present). The std\n // pipeline drops the texture .a inside `specularColor`, so the\n // geometry path re-samples the specular texture here to recover it.\n return hasSpecular\n ? `(vec4<f32>(pow(textureSample(sT, sS, ${specularUv}).rgb, vec3<f32>(2.2)), textureSample(sT, sS, ${specularUv}).a) * ${wg})`\n : `vec4<f32>(pow(mat.sc.rgb, vec3<f32>(2.2)), 1.0) * ${wg}`;\n case GeometryTextureType.VIEW_DEPTH:\n return `vec4<f32>((scene.view * vec4<f32>(input.vp, 1.0)).z, 0.0, 0.0, ${wg})`;\n case GeometryTextureType.NORMALIZED_VIEW_DEPTH:\n return `vec4<f32>(((scene.view * vec4<f32>(input.vp, 1.0)).z - gp.cameraNearFar.x) / (gp.cameraNearFar.y - gp.cameraNearFar.x), 0.0, 0.0, ${wg})`;\n case GeometryTextureType.SCREENSPACE_DEPTH:\n // `clipPos` is the @builtin(position) fragment input declared by\n // shader-composer (fragment input struct).\n return `vec4<f32>(input.clipPos.z, 0.0, 0.0, ${wg})`;\n case GeometryTextureType.VIEW_NORMAL:\n return `vec4<f32>(normalize((scene.view * vec4<f32>(normalW, 0.0)).xyz), ${wg})`;\n case GeometryTextureType.WORLD_NORMAL:\n return `vec4<f32>(normalW * 0.5 + vec3<f32>(0.5), ${wg})`;\n case GeometryTextureType.ALBEDO:\n // BJS: vec4(baseColor.rgb, writeGeometryInfo). The standard\n // fragment already multiplied the diffuse sample by `mat.tl`\n // (texture level) when building `baseColor`.\n return `vec4<f32>(baseColor, ${wg})`;\n case GeometryTextureType.LINEAR_VELOCITY: {\n const cur = `(input.vCurrentClip.xy / input.vCurrentClip.w)`;\n const prev = `(input.vPreviousClip.xy / input.vPreviousClip.w)`;\n return `vec4<f32>(0.5 * (${prev} - ${cur}), 0.0, ${wg})`;\n }\n }\n}\n\n/** ShaderFragment contributing the `gp` UBO + (optionally) velocity / local-position varyings.\n *\n * Only included in the fragment list when an attachment actually needs it,\n * so opaque-only / WORLD_POSITION-only configs add zero bytes vs the bare\n * standard shader. */\nfunction createGeometryParamsFragment(needsParamsUbo: boolean, needsVelocityVaryings: boolean, needsLocalPosVarying: boolean): ShaderFragment {\n const bindings = needsParamsUbo ? [{ _name: \"gp\", _type: { _kind: \"uniform-buffer\" as const }, _visibility: STAGE_FRAGMENT | STAGE_VERTEX }] : [];\n const helpers = needsParamsUbo ? `struct gpUniforms { previousViewProjection: mat4x4<f32>, cameraNearFar: vec4<f32>, };` : \"\";\n const varyings: Varying[] = [];\n if (needsVelocityVaryings) {\n varyings.push({ _name: \"vCurrentClip\", _type: \"vec4<f32>\" }, { _name: \"vPreviousClip\", _type: \"vec4<f32>\" });\n }\n if (needsLocalPosVarying) {\n varyings.push({ _name: \"vLocalPos\", _type: \"vec3<f32>\" });\n }\n // Velocity needs the previous-world matrix on the mesh UBO too — but that\n // is out of scope of this fragment (the standard mesh UBO does not have\n // it). LINEAR_VELOCITY is therefore deferred behind a TODO; HillValley /\n // scene 145 does not request it.\n const vbParts: string[] = [];\n if (needsVelocityVaryings) {\n vbParts.push(`out.vCurrentClip = scene.viewProjection * vec4<f32>(out.vp, 1.0);`);\n vbParts.push(`out.vPreviousClip = gp.previousViewProjection * vec4<f32>(out.vp, 1.0);`);\n }\n if (needsLocalPosVarying) {\n vbParts.push(`out.vLocalPos = position;`);\n }\n const slots: ShaderFragment[\"_vertexSlots\"] = vbParts.length > 0 ? { VB: vbParts.join(\"\\n\") } : {};\n return {\n _id: \"~geometry-params\",\n _bindings: bindings,\n _helperFunctions: helpers,\n // gp UBO is also visible to the vertex stage when present, so the\n // struct declaration must be available there too.\n _vertexHelperFunctions: helpers,\n _varyings: varyings,\n _vertexSlots: slots,\n };\n}\n\n/** Compose a Standard geometry-output shader.\n *\n * Reuses {@link composeStandardShader} verbatim — every standard-material\n * feature (bump perturbation, alpha discard, instancing, …) flows through\n * the same code path. The fragment WGSL is then string-patched to switch\n * the entry-point return type to a multi-attachment `FragmentOutput`.\n *\n * @param emitColor - When true, an extra `@location(N) color: vec4<f32>`\n * attachment is appended to `FragmentOutput` (N = `attachments.length`)\n * and populated with the standard lit `color` value. Used when the\n * task's `targetTexture` is set — that target receives the real (lit)\n * material color alongside the geometry-data attachments. */\nexport function composeStandardGeometryShader(\n features: number,\n meshFeatures: number,\n extFragments: ShaderFragment[],\n attachments: readonly GeometryTextureType[],\n esmShadowDepthCode = \"\",\n emitColor = false\n): ComposedShader {\n const wantsGp = needsGpUbo(attachments);\n const wantsVelocity = needsVelocity(attachments);\n const wantsLocalPos = needsLocalPos(attachments);\n const fragments = wantsGp || wantsVelocity || wantsLocalPos ? [...extFragments, createGeometryParamsFragment(wantsGp, wantsVelocity, wantsLocalPos)] : extFragments;\n\n // Strip MATERIAL_ALPHA_BLEND so the standard fragment does NOT emit\n // ALPHA_COMBINE blend in its color output — we drive blending per\n // attachment in the geometry pipeline state instead.\n const stdFeatures = features & ~MATERIAL_ALPHA_BLEND;\n const base = composeStandardShader(stdFeatures, meshFeatures, fragments, esmShadowDepthCode);\n\n const hasSpecular = (features & HAS_SPECULAR_TEXTURE) !== 0;\n const specularUv = (features & SPECULAR_USES_UV2) !== 0 ? \"input.vv\" : \"input.vu\";\n\n // ── Post-process the fragment WGSL ────────────────────────────────────\n\n // 1) Replace the return type. `composeStandardShader` always emits\n // `-> @location(0) vec4<f32>` for the color path (no _noColorOutput\n // in our flow).\n const fragmentSignatureFrom = \"-> @location(0) vec4<f32>\";\n const fragmentSignatureTo = \"-> FragmentOutput\";\n if (!base._fragmentWGSL.includes(fragmentSignatureFrom)) {\n throw new Error(\"composeStandardGeometryShader: standard fragment signature mismatch — bypass active?\");\n }\n let frag = base._fragmentWGSL.replace(fragmentSignatureFrom, fragmentSignatureTo);\n\n // 2) Inject FragmentOutput struct right before `@fragment fn main`. When\n // `emitColor` is set, append an extra slot at @location(N) for the\n // standard `color` output (the \"real\" lit material color), with\n // N = attachments.length.\n const colorSlot = attachments.length;\n const extraColorLine = emitColor ? `\\n@location(${colorSlot}) color: vec4<f32>,` : \"\";\n const outputStruct = `struct FragmentOutput {\n${attachments.map((_, i) => `@location(${i}) f${i}: vec4<f32>,`).join(\"\\n\")}${extraColorLine}\n};\n`;\n frag = frag.replace(\"@fragment fn main\", `${outputStruct}@fragment fn main`);\n\n // 3) Replace `return color;` with MRT writes + `return out;`. We use\n // `alpha` (the standard fragment's running alpha) for the\n // writeGeometryInfo gate so opacity-texture and material-alpha\n // materials get a correct binary mask under the per-attachment\n // ALPHA_COMBINE blend pipeline state.\n const wg = `select(0.0, 1.0, alpha > 0.4)`;\n const writes = attachments.map((type, i) => `out.f${i} = ${attachmentExpr(type, wg, hasSpecular, specularUv)};`).join(\"\\n\");\n const extraColorWrite = emitColor ? `\\nout.color = color;` : \"\";\n const replacement = `var out: FragmentOutput;\n${writes}${extraColorWrite}\nreturn out;`;\n if (!frag.includes(\"return color;\")) {\n throw new Error(\"composeStandardGeometryShader: 'return color;' not found in composed fragment — template changed?\");\n }\n frag = frag.replace(\"return color;\", replacement);\n\n return { ...base, _fragmentWGSL: frag };\n}\n","/** Standard geometry-MRT renderable factory.\n *\n * Builds a {@link Renderable} that draws a single mesh through a\n * {@link createStandardGeometryMaterialView} into the geometry renderer\n * task's multi-attachment render target. Mirrors the regular\n * {@link buildStandardMeshRenderables} structure (rebuildSingle closure\n * → Renderable.bind() → DrawBinding.update/draw) so that per-mesh\n * bind groups, mesh UBO refreshes (including writeMeshLightSelection),\n * and material UBO version tracking flow through the exact same\n * contract scenes already use for ordinary Standard renderables.\n *\n * Feature parity with {@link buildStandardMeshRenderables}: thin\n * instances (matrix + optional per-instance colour), bound-texture\n * acquire/release lifecycle, sort-centre tracking for transparency\n * ordering. Shadows are intentionally excluded — the geometry pass\n * writes raw G-buffer attachments, not shaded colour.\n *\n * Per-(view, mesh-feature-variant) shared state — composed shader,\n * mesh BGL, pipeline cache — is cached on `view._geometry` keyed by\n * the mesh-feature bits that affect shader composition (thin-instance\n * matrix / colour). Per-mesh state (UBOs, bind group, sort centre)\n * lives in the closure returned by {@link buildStandardGeometryRenderable}.\n *\n * This module is imported only by {@link createStandardGeometryMaterialView}\n * — scenes that do not use the geometry renderer task pay zero bytes for it.\n */\n\nimport { F32 } from \"../../engine/typed-arrays.js\";\nimport type { EngineContext } from \"../../engine/engine.js\";\nimport type { RenderTargetSignature } from \"../../engine/render-target.js\";\nimport type { Mesh } from \"../../mesh/mesh.js\";\nimport type { MeshGroupBuilder, Renderable } from \"../../render/renderable.js\";\nimport { writeMeshLightSelection } from \"../../render/lights-ubo.js\";\nimport type { SceneContext } from \"../../scene/scene-core.js\";\nimport { createUniformBuffer } from \"../../resource/gpu-buffers.js\";\nimport { acquireTexture, releaseTexture } from \"../../resource/gpu-pool.js\";\nimport type { ComposedShader, ShaderFragment } from \"../../shader/fragment-types.js\";\nimport { targetSignatureKey } from \"../../engine/render-target.js\";\nimport { createThinInstanceFragment } from \"../../shader/fragments/thin-instance-fragment.js\";\nimport { syncThinInstanceBuffers } from \"../../mesh/thin-instance-gpu.js\";\n\nimport type { Material } from \"../material.js\";\nimport type { StandardMaterialProps } from \"./standard-material.js\";\nimport { _getStdExtsSorted, DOUBLE_SIDED, HAS_DIFFUSE_TEXTURE, HAS_OPACITY_TEXTURE, NEEDS_UV, NEEDS_UV2 } from \"./standard-flags.js\";\nimport { writeStdMaterialData } from \"./standard-pipeline.js\";\nimport { composeStandardGeometryShader } from \"./standard-geometry-output-shader.js\";\nimport { getSceneBindGroupLayout } from \"../../render/scene-helpers.js\";\nimport { collectStdBoundTextures } from \"./collect-std-bound-textures.js\";\nimport { _computeMeshFeatures, MSH_HAS_INSTANCE_COLOR, MSH_HAS_THIN_INSTANCES } from \"../mesh-features.js\";\nimport type { StandardGeometryMaterialView } from \"./geometry-view.js\";\n\n/** Singleton {@link MeshGroupBuilder} that geometry views point at via their\n * overridden `_buildGroup`. The async builder body is unreachable — geometry\n * views are dispatched per-mesh via {@link RenderTask.addMesh} which calls\n * `_rebuildSingle` directly. Centralizing the per-mesh factory here means\n * `resolvePendingMeshes` doesn't need any view-aware branching. */\nexport const standardGeometryGroupBuilder: MeshGroupBuilder = (async () => {\n throw new Error(\"standard-geometry view does not support scene group building\");\n}) as MeshGroupBuilder;\nstandardGeometryGroupBuilder._rebuildSingle = (scene: SceneContext, mesh: Mesh, materialOverride?: Material): Renderable => {\n const view = (materialOverride ?? mesh.material) as StandardGeometryMaterialView;\n return buildStandardGeometryRenderable(scene, mesh, view);\n};\nstandardGeometryGroupBuilder._materialFamily = \"standard\";\n\n/** Per-(task, source-material, mesh-variant) shared resources lazily attached\n * to the view. Cached on `view._geometry` (Map keyed by mesh-variant bits) to\n * keep the same WGSL + BGL + pipeline objects across all meshes that share\n * the view and the same shader-relevant mesh features. */\ninterface StandardGeometryViewResources {\n _composed: ComposedShader;\n _features: number;\n _meshBGL: GPUBindGroupLayout;\n _pipelineLayout: GPUPipelineLayout;\n _vertModule: GPUShaderModule;\n _fragModule: GPUShaderModule;\n _pipelines: Map<string, GPURenderPipeline>;\n /** Ext fragments that contributed bindings — used by per-mesh bind groups. */\n _extFragments: readonly { _ext: ReturnType<typeof _getStdExtsSorted>[number] }[];\n _alphaBlend: boolean;\n /** Shared material UBO and dirty-version state (one per source material in this view). */\n _matUBO: GPUBuffer;\n _matData: Float32Array;\n _lastUboVersion: number;\n /** Optional UV-transform UBO. Allocated when the view's features include NEEDS_UV. */\n _upUBO: GPUBuffer | null;\n}\n\n/** Pack the mesh-feature bits that change shader composition / pipeline\n * into a 2-bit variant key. At most 4 variants per view in the worst case. */\nfunction _variantKey(meshFeatures: number): number {\n let k = 0;\n if (meshFeatures & MSH_HAS_THIN_INSTANCES) {\n k |= 1;\n }\n if (meshFeatures & MSH_HAS_INSTANCE_COLOR) {\n k |= 2;\n }\n return k;\n}\n\n/** Build a {@link Renderable} for one mesh drawn through a Standard geometry view.\n * Reuses or creates per-(view, mesh-variant) shared resources on `view._geometry`. */\nexport function buildStandardGeometryRenderable(scene: SceneContext, mesh: Mesh, view: StandardGeometryMaterialView): Renderable {\n const engine = scene.surface.engine;\n const device = engine._device;\n const source = view.source as StandardMaterialProps;\n // Geometry pass has no receiver path — pass receiveShadows=false.\n const meshFeatures = _computeMeshFeatures(mesh, false);\n const variantKey = _variantKey(meshFeatures);\n const res = _ensureViewResources(view, engine, meshFeatures, variantKey);\n const features = res._features;\n\n // Per-mesh UBOs + bind group.\n const meshUboData = new F32(res._composed._meshUboSpec._totalBytes / 4);\n meshUboData.set(mesh.worldMatrix, 0);\n writeMeshLightSelection(mesh, scene.lights, meshUboData);\n const meshUBO = createUniformBuffer(engine, meshUboData);\n\n const bg = _createGeometryMeshBindGroup(engine, view, res, mesh, meshUBO);\n\n // Acquire all textures the standard shader references so the GPU-pool\n // doesn't release them while the geometry pass holds bind groups on\n // them. Mirrors standard-renderable's lifecycle exactly.\n const boundTextures = collectStdBoundTextures(source);\n for (const t of boundTextures) {\n acquireTexture(t);\n }\n const prevDisposables = (scene as SceneContext)._meshDisposables.get(mesh) ?? [];\n (scene as SceneContext)._meshDisposables.set(mesh, [\n ...prevDisposables,\n () => {\n for (const t of boundTextures) {\n releaseTexture(t);\n }\n },\n ]);\n\n let _lastWorldVersion = mesh.worldMatrixVersion;\n let _lastLightsCount = scene.lights.length;\n\n const needsUV = (features & NEEDS_UV) !== 0;\n const needsUV2 = (features & NEEDS_UV2) !== 0;\n const isAlphaBlend = res._alphaBlend;\n const hasThinInstances = (meshFeatures & MSH_HAS_THIN_INSTANCES) !== 0;\n const hasInstanceColor = (meshFeatures & MSH_HAS_INSTANCE_COLOR) !== 0;\n const sortCenter = [mesh.worldMatrix[12]!, mesh.worldMatrix[13]!, mesh.worldMatrix[14]!] as [number, number, number];\n\n const update = (): void => {\n if (mesh.worldMatrixVersion !== _lastWorldVersion || scene.lights.length !== _lastLightsCount) {\n sortCenter[0] = mesh.worldMatrix[12]!;\n sortCenter[1] = mesh.worldMatrix[13]!;\n sortCenter[2] = mesh.worldMatrix[14]!;\n meshUboData.set(mesh.worldMatrix, 0);\n writeMeshLightSelection(mesh, scene.lights, meshUboData);\n device.queue.writeBuffer(meshUBO, 0, meshUboData as Float32Array<ArrayBuffer>);\n _lastWorldVersion = mesh.worldMatrixVersion;\n _lastLightsCount = scene.lights.length;\n }\n if (source._uboVersion !== res._lastUboVersion) {\n res._lastUboVersion = source._uboVersion;\n const textureLevel = (features & HAS_DIFFUSE_TEXTURE) !== 0 ? 1.0 : 0.0;\n res._matData.fill(0);\n writeStdMaterialData(res._matData, source, textureLevel);\n device.queue.writeBuffer(res._matUBO, 0, res._matData.buffer, 0, 96);\n }\n };\n\n const draw = (pass: GPURenderPassEncoder | GPURenderBundleEncoder): number => {\n if (mesh.visible === false) {\n return 0;\n }\n pass.setBindGroup(1, bg);\n const g = (mesh as Mesh)._gpu;\n let slot = 0;\n pass.setVertexBuffer(slot++, g.positionBuffer);\n pass.setVertexBuffer(slot++, g.normalBuffer);\n if (needsUV && g.uvBuffer) {\n pass.setVertexBuffer(slot++, g.uvBuffer);\n }\n if (needsUV2 && g.uv2Buffer) {\n pass.setVertexBuffer(slot++, g.uv2Buffer);\n }\n const ti = hasThinInstances ? mesh.thinInstances : null;\n if (ti) {\n slot = syncThinInstanceBuffers(engine, ti, pass, slot, hasInstanceColor);\n }\n pass.setIndexBuffer(g.indexBuffer, g.indexFormat);\n if (ti && ti.count > 0) {\n pass.drawIndexed(g.indexCount, ti.count);\n } else {\n pass.drawIndexed(g.indexCount);\n }\n return 1;\n };\n\n const r: Renderable = {\n order: mesh.renderOrder ?? (isAlphaBlend ? 200 : 100),\n isTransparent: isAlphaBlend,\n mesh,\n bind(eng: EngineContext, sig: RenderTargetSignature) {\n return {\n renderable: r,\n pipeline: _getOrCreateGeometryPipeline(eng as EngineContext, sig, view, res),\n update,\n draw,\n };\n },\n };\n r._worldCenter = sortCenter;\n return r;\n}\n\n// ─── Shared per-view resources ─────────────────────────────────────────────\n\nfunction _ensureViewResources(view: StandardGeometryMaterialView, engine: EngineContext, meshFeatures: number, variantKey: number): StandardGeometryViewResources {\n let cache = view._geometry as Map<number, StandardGeometryViewResources> | undefined;\n if (!cache) {\n cache = new Map();\n Object.defineProperty(view, \"_geometry\", { value: cache, enumerable: false, configurable: true });\n }\n const cached = cache.get(variantKey);\n if (cached) {\n return cached;\n }\n const source = view.source as StandardMaterialProps;\n const features = view._renderFeatures.features;\n\n // Collect the same ext fragments the regular Standard renderable would —\n // bump, opacity, specular, … — so the shared shader code is identical.\n const sortedExts = _getStdExtsSorted();\n const frags: ShaderFragment[] = [];\n const usedExts: { _ext: (typeof sortedExts)[number] }[] = [];\n for (const ext of sortedExts) {\n if (features & ext._feature) {\n const f = ext._frag(features);\n if (f) {\n frags.push(f);\n usedExts.push({ _ext: ext });\n }\n }\n }\n\n // Thin instances. Mirror standard-renderable: when per-instance colour is\n // present we override the fragment's AT slot with a BC slot that\n // multiplies the final lit `color` (only consumed when `emitColor` is on\n // — otherwise WGSL folds the dead code).\n if (meshFeatures & MSH_HAS_THIN_INSTANCES) {\n const hasColor = (meshFeatures & MSH_HAS_INSTANCE_COLOR) !== 0;\n const tiFrag = createThinInstanceFragment(hasColor);\n if (hasColor) {\n const { _fragmentSlots: _drop, ...rest } = tiFrag;\n frags.push({\n ...rest,\n _fragmentSlots: {\n BC: `color = vec4<f32>(color.rgb * input.vInstanceColor.rgb, color.a * input.vInstanceColor.a);`,\n },\n });\n } else {\n frags.push(tiFrag);\n }\n }\n\n const composed = composeStandardGeometryShader(features, meshFeatures, frags, view._geometryAttachments, \"\", view._emitColor);\n const device = engine._device;\n const meshBGL = device.createBindGroupLayout(composed._meshBGLDescriptor);\n // Pipeline layout: scene BG (group 0) + mesh BG (group 1). Geometry pass\n // has no shadow receiver group.\n const sceneBGL = getSceneBindGroupLayout(engine);\n const pipelineLayout = device.createPipelineLayout({\n bindGroupLayouts: [sceneBGL, meshBGL],\n });\n const vertModule = device.createShaderModule({ code: composed._vertexWGSL });\n const fragModule = device.createShaderModule({ code: composed._fragmentWGSL });\n\n // Re-detect alpha-blend from the *source* material — the view masked it\n // out so the composer doesn't emit standard's source-over color blend.\n const alphaBlend = source.alpha < 1 || (features & HAS_OPACITY_TEXTURE) !== 0;\n\n // Shared material UBO (one per source material per view). All meshes of\n // this material reuse the same UBO; updates are version-guarded.\n const matData = new F32(24);\n const textureLevel = (features & HAS_DIFFUSE_TEXTURE) !== 0 ? 1.0 : 0.0;\n writeStdMaterialData(matData, source, textureLevel);\n const matUBO = createUniformBuffer(engine, matData);\n\n // UV transform UBO when the vertex stage emits UV math.\n let upUBO: GPUBuffer | null = null;\n if ((features & NEEDS_UV) !== 0) {\n const uvData = new F32(4);\n let scaleX = 1;\n let scaleY = 1;\n let offsetY = 0;\n if ((features & HAS_DIFFUSE_TEXTURE) !== 0 && source.diffuseTexture) {\n scaleX = source.uvScale[0];\n scaleY = source.uvScale[1];\n if (source.diffuseTexture.invertY) {\n offsetY = scaleY;\n scaleY = -scaleY;\n }\n } else if ((features & HAS_OPACITY_TEXTURE) !== 0 && source.opacityTexture?.invertY) {\n offsetY = 1;\n scaleY = -1;\n } else if (source.bumpTexture?.invertY) {\n offsetY = 1;\n scaleY = -1;\n }\n uvData[0] = scaleX;\n uvData[1] = scaleY;\n uvData[2] = 0;\n uvData[3] = offsetY;\n upUBO = createUniformBuffer(engine, uvData);\n }\n\n const res: StandardGeometryViewResources = {\n _composed: composed,\n _features: features,\n _meshBGL: meshBGL,\n _pipelineLayout: pipelineLayout,\n _vertModule: vertModule,\n _fragModule: fragModule,\n _pipelines: new Map(),\n _extFragments: usedExts,\n _alphaBlend: alphaBlend,\n _matUBO: matUBO,\n _matData: matData,\n _lastUboVersion: source._uboVersion,\n _upUBO: upUBO,\n };\n cache.set(variantKey, res);\n return res;\n}\n\nfunction _createGeometryMeshBindGroup(\n engine: EngineContext,\n view: StandardGeometryMaterialView,\n res: StandardGeometryViewResources,\n _mesh: Mesh,\n meshUBO: GPUBuffer\n): GPUBindGroup {\n const source = view.source as StandardMaterialProps;\n const features = res._features;\n let nextBinding = 0;\n const entries: GPUBindGroupEntry[] = [\n { binding: nextBinding++, resource: { buffer: meshUBO } },\n { binding: nextBinding++, resource: { buffer: res._matUBO } },\n ];\n if ((features & HAS_DIFFUSE_TEXTURE) !== 0 && source.diffuseTexture) {\n const tex = source.diffuseTexture;\n entries.push({ binding: nextBinding++, resource: tex.texture.createView() }, { binding: nextBinding++, resource: tex.sampler });\n }\n if ((features & NEEDS_UV) !== 0 && res._upUBO) {\n entries.push({ binding: nextBinding++, resource: { buffer: res._upUBO } });\n }\n for (const used of res._extFragments) {\n if (used._ext._bind) {\n nextBinding = used._ext._bind(source, entries, nextBinding);\n }\n }\n // Geometry-params `gp` UBO is contributed by the geometry composer as the\n // last fragment, so its binding is appended last. Present iff the\n // requested attachments need it (LINEAR_VELOCITY or NORMALIZED_VIEW_DEPTH).\n if (view._gpUBO) {\n entries.push({ binding: nextBinding++, resource: { buffer: view._gpUBO } });\n }\n return engine._device.createBindGroup({ layout: res._meshBGL, entries });\n}\n\nfunction _getOrCreateGeometryPipeline(\n engine: EngineContext,\n sig: RenderTargetSignature,\n view: StandardGeometryMaterialView,\n res: StandardGeometryViewResources\n): GPURenderPipeline {\n const key = targetSignatureKey(sig);\n const cached = res._pipelines.get(key);\n if (cached) {\n return cached;\n }\n const device = engine._device;\n const formats = (sig as RenderTargetSignature & { _colorFormats?: readonly GPUTextureFormat[] })._colorFormats ?? (sig._colorFormat ? [sig._colorFormat] : []);\n if (formats.length === 0) {\n throw new Error(\"standard-geometry: render target has no color attachments\");\n }\n const alphaBlend = res._alphaBlend;\n const blendState: GPUBlendState | undefined = alphaBlend\n ? {\n color: { srcFactor: \"src-alpha\", dstFactor: \"one-minus-src-alpha\", operation: \"add\" },\n alpha: { srcFactor: \"src-alpha\", dstFactor: \"one-minus-src-alpha\", operation: \"add\" },\n }\n : undefined;\n const colorTargets: GPUColorTargetState[] = formats.map((fmt) => (blendState ? { format: fmt, blend: blendState } : { format: fmt }));\n const cullMode = (res._features & DOUBLE_SIDED) !== 0 ? \"none\" : view._reverseCulling ? \"front\" : \"back\";\n const pipeline = device.createRenderPipeline({\n layout: res._pipelineLayout,\n vertex: { module: res._vertModule, entryPoint: \"main\", buffers: res._composed._vertexBufferLayouts },\n fragment: { module: res._fragModule, entryPoint: \"main\", targets: colorTargets },\n depthStencil: sig._depthStencilFormat\n ? {\n format: sig._depthStencilFormat,\n depthCompare: sig._depthCompare ?? \"greater-equal\",\n // BJS disables depth-write for transparent/opacity meshes in the\n // geometry pass so background depth survives partially-transparent pixels.\n depthWriteEnabled: !alphaBlend,\n }\n : undefined,\n multisample: { count: sig._sampleCount },\n // Geometry MRT renders to offscreen targets, so it needs the same\n // Render upright — front face is always \"ccw\".\n primitive: { topology: \"triangle-list\", cullMode, frontFace: \"ccw\" },\n });\n res._pipelines.set(key, pipeline);\n return pipeline;\n}\n","/** Standard material view helper that targets geometry-rendering MRT output.\n *\n * The geometry renderer task wraps each Standard caster material in a\n * `StandardGeometryMaterialView`. The view carries the per-task attachment\n * list, target-texture intent, optional `gp` UBO (shared across the task's\n * materials), and reverse-culling flag. The view also shadows\n * {@link Material._buildGroup} with {@link standardGeometryGroupBuilder} so\n * that `RenderTask.addMesh` (and the geometry renderer task) materialize a\n * {@link Renderable} through the shared standard geometry renderable\n * infrastructure — no view-aware branching required in core render-task.\n *\n * The geometry-output WGSL itself is produced by post-processing the regular\n * composed standard shader in `./standard-geometry-output-shader.ts`. */\n\nimport { createMaterialView } from \"../material-view.js\";\nimport type { MaterialView } from \"../material.js\";\nimport type { GeometryTextureType } from \"../../frame-graph/geometry-types.js\";\nimport { GEOMETRY_OUTPUT, MATERIAL_ALPHA_BLEND } from \"./standard-flags.js\";\nimport type { StandardMaterialProps } from \"./standard-material.js\";\nimport { standardGeometryGroupBuilder } from \"./standard-geometry-renderable.js\";\n\n/** Per-task ordered attachment list driving the geometry template. The array\n * index is the MRT color-attachment slot used in `@location(i)`. */\nexport type StandardGeometryAttachments = readonly GeometryTextureType[];\n\n/** Per-(task, material) geometry view configuration. All fields are owned by\n * the geometry renderer task; the view captures them so per-mesh renderables\n * pick up the same pipeline state and bindings. */\nexport interface StandardGeometryViewConfig {\n /** Ordered MRT attachment list — index = `@location(i)`. */\n readonly attachments: StandardGeometryAttachments;\n /** When true, the composed fragment emits the real (lit) material color\n * at `@location(N)` (N = attachments.length). The target texture is\n * added to the pipeline color-target list at the same slot. */\n readonly emitColor: boolean;\n /** Per-task previous-VP + camera-near-far UBO. Required when\n * {@link attachments} contains `NORMALIZED_VIEW_DEPTH` or\n * `LINEAR_VELOCITY`; ignored otherwise. */\n readonly gpUBO?: GPUBuffer | null;\n /** Flip culling direction. */\n readonly reverseCulling?: boolean;\n}\n\n/** Standard material view that emits geometry textures instead of shaded colour. */\nexport interface StandardGeometryMaterialView extends MaterialView {\n /** @internal Ordered MRT attachment list — index = `@location(i)`. */\n readonly _geometryAttachments: StandardGeometryAttachments;\n /** @internal Geometry pipeline carries an extra `@location(N)` color attachment. */\n readonly _emitColor: boolean;\n /** @internal Optional per-task geometry-params UBO shared with the composer's\n * `geometryParams` fragment. */\n readonly _gpUBO: GPUBuffer | null;\n /** @internal */\n readonly _reverseCulling: boolean;\n /** @internal Shared per-view resources cache populated lazily by the renderable\n * factory. Opaque to callers. */\n _geometry?: unknown;\n}\n\n/** Wrap a Standard material as a geometry-output view.\n * - Sets the `GEOMETRY_OUTPUT` feature bit.\n * - Clears `MATERIAL_ALPHA_BLEND`: the geometry pipeline drives blending per\n * attachment via the pipeline color-target state, not via the standard\n * fragment's source-over color output.\n * - Shadows `_buildGroup` with {@link standardGeometryGroupBuilder} so the\n * natural `material._buildGroup._rebuildSingle` dispatch in\n * `resolvePendingMeshes` builds a geometry-MRT renderable for this view. */\nexport function createStandardGeometryMaterialView(source: StandardMaterialProps, config: StandardGeometryViewConfig): StandardGeometryMaterialView {\n const baseFeatures = source._renderFeatures?.features ?? 0;\n const view = createMaterialView(source, { features: (baseFeatures & ~MATERIAL_ALPHA_BLEND) | GEOMETRY_OUTPUT }) as StandardGeometryMaterialView;\n Object.defineProperty(view, \"_geometryAttachments\", { value: config.attachments, enumerable: false });\n Object.defineProperty(view, \"_emitColor\", { value: config.emitColor, enumerable: false });\n Object.defineProperty(view, \"_gpUBO\", { value: config.gpUBO ?? null, enumerable: false });\n Object.defineProperty(view, \"_reverseCulling\", { value: config.reverseCulling ?? false, enumerable: false });\n Object.defineProperty(view, \"_buildGroup\", { value: standardGeometryGroupBuilder, enumerable: false });\n return view;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"geometry-view-DRrscyWU.js","sources":["../src/material/standard/standard-geometry-output-shader.ts","../src/material/standard/standard-geometry-renderable.ts","../src/material/standard/geometry-view.ts"],"sourcesContent":["/** Standard geometry-output shader composer.\n *\n * Builds the WGSL for a {@link createStandardGeometryMaterialView}-wrapped\n * Standard material that targets the geometry-renderer MRT pass.\n *\n * Design — *zero bundle impact* on scenes that never load the\n * geometry-renderer task:\n *\n * 1. Reuse `composeStandardShader` verbatim. The standard composer already\n * emits the bump perturbation (`normalW = perturbNormal(...)` via the AC\n * slot), opacity-texture alpha modulation, alpha-cutout discard,\n * instancing, thin-instance colour, etc. None of that needs to be\n * re-implemented.\n * 2. Post-process the resulting fragment WGSL: change the entry signature\n * to return a `FragmentOutput` MRT struct, prepend the struct\n * declaration, and replace `return color;` with code that writes each\n * requested geometry attachment from the already-in-scope intermediate\n * variables (`normalW`, `baseColor`, `specularColor`, `alpha`,\n * `input.vp`, …).\n * 3. Add a small `geometryParams` ShaderFragment that contributes a `gp`\n * UBO binding (camera near/far + previous viewProjection) only when the\n * requested attachment list needs it (NORMALIZED_VIEW_DEPTH /\n * LINEAR_VELOCITY).\n *\n * The lighting / fog block still runs and produces a dead `color` value\n * the WGSL compiler folds away. Acceptable cost for the architectural\n * reuse — matches the user's directive: \"inject some shader code at the\n * end of the fragment to output the data for the geometry textures\".\n */\n\nimport { GeometryTextureType } from \"../../frame-graph/geometry-types.js\";\nimport type { ComposedShader, ShaderFragment, Varying } from \"../../shader/fragment-types.js\";\nimport { composeStandardShader } from \"./standard-pipeline.js\";\nimport { HAS_SPECULAR_TEXTURE, MATERIAL_ALPHA_BLEND, SPECULAR_USES_UV2 } from \"./standard-flags.js\";\n\nconst STAGE_FRAGMENT = 0x2;\nconst STAGE_VERTEX = 0x1;\n\n/** Tags whether the geometry pass needs the per-task `gp` UBO. */\nfunction needsGpUbo(attachments: readonly GeometryTextureType[]): boolean {\n for (const t of attachments) {\n if (t === GeometryTextureType.NORMALIZED_VIEW_DEPTH || t === GeometryTextureType.LINEAR_VELOCITY) {\n return true;\n }\n }\n return false;\n}\n\n/** Tags whether the geometry pass needs the previous-clip varying (velocity). */\nfunction needsVelocity(attachments: readonly GeometryTextureType[]): boolean {\n return attachments.includes(GeometryTextureType.LINEAR_VELOCITY);\n}\n\n/** Tags whether the geometry pass needs the local-position varying. */\nfunction needsLocalPos(attachments: readonly GeometryTextureType[]): boolean {\n return attachments.includes(GeometryTextureType.LOCAL_POSITION);\n}\n\n/** Per-attachment WGSL output expression. `alpha` is the in-scope standard\n * fragment alpha (mat.dc.a × opacityTex × …). `wg` is `writeGeomInfo` — a\n * binary 0/1 gate matching BJS `default.fragment.fx` PREPASS\n * (`color.a > 0.4 ? 1.0 : 0.0`). Combined with the per-attachment\n * ALPHA_COMBINE blend state, low-opacity samples preserve the destination\n * (background) while high-opacity samples overwrite it.\n *\n * All variable references resolve to symbols already declared by\n * `standard-template.ts` / the standard fragment registry:\n * - `normalW` — normalized world normal (post-bump if HAS_BUMP_TEXTURE).\n * - `input.vp` — world position.\n * - `baseColor`/`mat.tl` — diffuse texture sample (rgb) × diffuseLevel.\n * - `specularColor`/`mat.sc` — specular colour, replaced by the std-specular\n * fragment's `textureSample(sT, sS, uv).rgb` when HAS_SPECULAR_TEXTURE.\n * - `scene.view` — view matrix from the canonical SceneUniforms.\n * - `gp.cameraNearFar` / `gp.previousViewProjection` — from the geometry\n * params UBO (added only when `needsGpUbo`).\n * - `input.vCurrentClip` / `input.vPreviousClip` — added by the velocity\n * fragment when LINEAR_VELOCITY is requested. */\nfunction attachmentExpr(type: GeometryTextureType, wg: string, hasSpecular: boolean, specularUv: string): string {\n switch (type) {\n case GeometryTextureType.IRRADIANCE:\n // BJS Standard material can't split irradiance — outputs (0, 0, 0).\n return `vec4<f32>(0.0, 0.0, 0.0, ${wg})`;\n case GeometryTextureType.WORLD_POSITION:\n return `vec4<f32>(input.vp, ${wg})`;\n case GeometryTextureType.LOCAL_POSITION:\n // `vLocalPos` is contributed by the geometry-params fragment (added\n // only when LOCAL_POSITION is requested).\n return `vec4<f32>(input.vLocalPos, ${wg})`;\n case GeometryTextureType.REFLECTIVITY:\n // BJS: vec4(toLinearSpace(specularMapColor)) * writeGeometryInfo\n // (.a is glossiness when a specular texture is present). The std\n // pipeline drops the texture .a inside `specularColor`, so the\n // geometry path re-samples the specular texture here to recover it.\n return hasSpecular\n ? `(vec4<f32>(pow(textureSample(sT, sS, ${specularUv}).rgb, vec3<f32>(2.2)), textureSample(sT, sS, ${specularUv}).a) * ${wg})`\n : `vec4<f32>(pow(mat.sc.rgb, vec3<f32>(2.2)), 1.0) * ${wg}`;\n case GeometryTextureType.VIEW_DEPTH:\n return `vec4<f32>((scene.view * vec4<f32>(input.vp, 1.0)).z, 0.0, 0.0, ${wg})`;\n case GeometryTextureType.NORMALIZED_VIEW_DEPTH:\n return `vec4<f32>(((scene.view * vec4<f32>(input.vp, 1.0)).z - gp.cameraNearFar.x) / (gp.cameraNearFar.y - gp.cameraNearFar.x), 0.0, 0.0, ${wg})`;\n case GeometryTextureType.SCREENSPACE_DEPTH:\n // `clipPos` is the @builtin(position) fragment input declared by\n // shader-composer (fragment input struct).\n return `vec4<f32>(input.clipPos.z, 0.0, 0.0, ${wg})`;\n case GeometryTextureType.VIEW_NORMAL:\n return `vec4<f32>(normalize((scene.view * vec4<f32>(normalW, 0.0)).xyz), ${wg})`;\n case GeometryTextureType.WORLD_NORMAL:\n return `vec4<f32>(normalW * 0.5 + vec3<f32>(0.5), ${wg})`;\n case GeometryTextureType.ALBEDO:\n // BJS: vec4(baseColor.rgb, writeGeometryInfo). The standard\n // fragment already multiplied the diffuse sample by `mat.tl`\n // (texture level) when building `baseColor`.\n return `vec4<f32>(baseColor, ${wg})`;\n case GeometryTextureType.LINEAR_VELOCITY: {\n const cur = `(input.vCurrentClip.xy / input.vCurrentClip.w)`;\n const prev = `(input.vPreviousClip.xy / input.vPreviousClip.w)`;\n return `vec4<f32>(0.5 * (${prev} - ${cur}), 0.0, ${wg})`;\n }\n }\n}\n\n/** ShaderFragment contributing the `gp` UBO + (optionally) velocity / local-position varyings.\n *\n * Only included in the fragment list when an attachment actually needs it,\n * so opaque-only / WORLD_POSITION-only configs add zero bytes vs the bare\n * standard shader. */\nfunction createGeometryParamsFragment(needsParamsUbo: boolean, needsVelocityVaryings: boolean, needsLocalPosVarying: boolean): ShaderFragment {\n const bindings = needsParamsUbo ? [{ _name: \"gp\", _type: { _kind: \"uniform-buffer\" as const }, _visibility: STAGE_FRAGMENT | STAGE_VERTEX }] : [];\n const helpers = needsParamsUbo ? `struct gpUniforms { previousViewProjection: mat4x4<f32>, cameraNearFar: vec4<f32>, };` : \"\";\n const varyings: Varying[] = [];\n if (needsVelocityVaryings) {\n varyings.push({ _name: \"vCurrentClip\", _type: \"vec4<f32>\" }, { _name: \"vPreviousClip\", _type: \"vec4<f32>\" });\n }\n if (needsLocalPosVarying) {\n varyings.push({ _name: \"vLocalPos\", _type: \"vec3<f32>\" });\n }\n // Velocity needs the previous-world matrix on the mesh UBO too — but that\n // is out of scope of this fragment (the standard mesh UBO does not have\n // it). LINEAR_VELOCITY is therefore deferred behind a TODO; HillValley /\n // scene 145 does not request it.\n const vbParts: string[] = [];\n if (needsVelocityVaryings) {\n vbParts.push(`out.vCurrentClip = scene.viewProjection * vec4<f32>(out.vp, 1.0);`);\n vbParts.push(`out.vPreviousClip = gp.previousViewProjection * vec4<f32>(out.vp, 1.0);`);\n }\n if (needsLocalPosVarying) {\n vbParts.push(`out.vLocalPos = position;`);\n }\n const slots: ShaderFragment[\"_vertexSlots\"] = vbParts.length > 0 ? { VB: vbParts.join(\"\\n\") } : {};\n return {\n _id: \"~geometry-params\",\n _bindings: bindings,\n _helperFunctions: helpers,\n // gp UBO is also visible to the vertex stage when present, so the\n // struct declaration must be available there too.\n _vertexHelperFunctions: helpers,\n _varyings: varyings,\n _vertexSlots: slots,\n };\n}\n\n/** Compose a Standard geometry-output shader.\n *\n * Reuses {@link composeStandardShader} verbatim — every standard-material\n * feature (bump perturbation, alpha discard, instancing, …) flows through\n * the same code path. The fragment WGSL is then string-patched to switch\n * the entry-point return type to a multi-attachment `FragmentOutput`.\n *\n * @param emitColor - When true, an extra `@location(N) color: vec4<f32>`\n * attachment is appended to `FragmentOutput` (N = `attachments.length`)\n * and populated with the standard lit `color` value. Used when the\n * task's `targetTexture` is set — that target receives the real (lit)\n * material color alongside the geometry-data attachments. */\nexport function composeStandardGeometryShader(\n features: number,\n meshFeatures: number,\n extFragments: ShaderFragment[],\n attachments: readonly GeometryTextureType[],\n esmShadowDepthCode = \"\",\n emitColor = false\n): ComposedShader {\n const wantsGp = needsGpUbo(attachments);\n const wantsVelocity = needsVelocity(attachments);\n const wantsLocalPos = needsLocalPos(attachments);\n const fragments = wantsGp || wantsVelocity || wantsLocalPos ? [...extFragments, createGeometryParamsFragment(wantsGp, wantsVelocity, wantsLocalPos)] : extFragments;\n\n // Strip MATERIAL_ALPHA_BLEND so the standard fragment does NOT emit\n // ALPHA_COMBINE blend in its color output — we drive blending per\n // attachment in the geometry pipeline state instead.\n const stdFeatures = features & ~MATERIAL_ALPHA_BLEND;\n const base = composeStandardShader(stdFeatures, meshFeatures, fragments, esmShadowDepthCode);\n\n const hasSpecular = (features & HAS_SPECULAR_TEXTURE) !== 0;\n const specularUv = (features & SPECULAR_USES_UV2) !== 0 ? \"input.vv\" : \"input.vu\";\n\n // ── Post-process the fragment WGSL ────────────────────────────────────\n\n // 1) Replace the return type. `composeStandardShader` always emits\n // `-> @location(0) vec4<f32>` for the color path (no _noColorOutput\n // in our flow).\n const fragmentSignatureFrom = \"-> @location(0) vec4<f32>\";\n const fragmentSignatureTo = \"-> FragmentOutput\";\n if (!base._fragmentWGSL.includes(fragmentSignatureFrom)) {\n throw new Error(\"composeStandardGeometryShader: standard fragment signature mismatch — bypass active?\");\n }\n let frag = base._fragmentWGSL.replace(fragmentSignatureFrom, fragmentSignatureTo);\n\n // 2) Inject FragmentOutput struct right before `@fragment fn main`. When\n // `emitColor` is set, append an extra slot at @location(N) for the\n // standard `color` output (the \"real\" lit material color), with\n // N = attachments.length.\n const colorSlot = attachments.length;\n const extraColorLine = emitColor ? `\\n@location(${colorSlot}) color: vec4<f32>,` : \"\";\n const outputStruct = `struct FragmentOutput {\n${attachments.map((_, i) => `@location(${i}) f${i}: vec4<f32>,`).join(\"\\n\")}${extraColorLine}\n};\n`;\n frag = frag.replace(\"@fragment fn main\", `${outputStruct}@fragment fn main`);\n\n // 3) Replace `return color;` with MRT writes + `return out;`. We use\n // `alpha` (the standard fragment's running alpha) for the\n // writeGeometryInfo gate so opacity-texture and material-alpha\n // materials get a correct binary mask under the per-attachment\n // ALPHA_COMBINE blend pipeline state.\n const wg = `select(0.0, 1.0, alpha > 0.4)`;\n const writes = attachments.map((type, i) => `out.f${i} = ${attachmentExpr(type, wg, hasSpecular, specularUv)};`).join(\"\\n\");\n const extraColorWrite = emitColor ? `\\nout.color = color;` : \"\";\n const replacement = `var out: FragmentOutput;\n${writes}${extraColorWrite}\nreturn out;`;\n if (!frag.includes(\"return color;\")) {\n throw new Error(\"composeStandardGeometryShader: 'return color;' not found in composed fragment — template changed?\");\n }\n frag = frag.replace(\"return color;\", replacement);\n\n return { ...base, _fragmentWGSL: frag };\n}\n","/** Standard geometry-MRT renderable factory.\n *\n * Builds a {@link Renderable} that draws a single mesh through a\n * {@link createStandardGeometryMaterialView} into the geometry renderer\n * task's multi-attachment render target. Mirrors the regular\n * {@link buildStandardMeshRenderables} structure (rebuildSingle closure\n * → Renderable.bind() → DrawBinding.update/draw) so that per-mesh\n * bind groups, mesh UBO refreshes (including writeMeshLightSelection),\n * and material UBO version tracking flow through the exact same\n * contract scenes already use for ordinary Standard renderables.\n *\n * Feature parity with {@link buildStandardMeshRenderables}: thin\n * instances (matrix + optional per-instance colour), bound-texture\n * acquire/release lifecycle, sort-centre tracking for transparency\n * ordering. Shadows are intentionally excluded — the geometry pass\n * writes raw G-buffer attachments, not shaded colour.\n *\n * Per-(view, mesh-feature-variant) shared state — composed shader,\n * mesh BGL, pipeline cache — is cached on `view._geometry` keyed by\n * the mesh-feature bits that affect shader composition (thin-instance\n * matrix / colour). Per-mesh state (UBOs, bind group, sort centre)\n * lives in the closure returned by {@link buildStandardGeometryRenderable}.\n *\n * This module is imported only by {@link createStandardGeometryMaterialView}\n * — scenes that do not use the geometry renderer task pay zero bytes for it.\n */\n\nimport { F32 } from \"../../engine/typed-arrays.js\";\nimport type { EngineContext } from \"../../engine/engine.js\";\nimport type { RenderTargetSignature } from \"../../engine/render-target.js\";\nimport type { Mesh } from \"../../mesh/mesh.js\";\nimport type { MeshGroupBuilder, Renderable } from \"../../render/renderable.js\";\nimport { writeMeshLightSelection } from \"../../render/lights-ubo.js\";\nimport type { SceneContext } from \"../../scene/scene-core.js\";\nimport { createUniformBuffer } from \"../../resource/gpu-buffers.js\";\nimport { acquireTexture, releaseTexture } from \"../../resource/gpu-pool.js\";\nimport type { ComposedShader, ShaderFragment } from \"../../shader/fragment-types.js\";\nimport { targetSignatureKey } from \"../../engine/render-target.js\";\nimport { createThinInstanceFragment } from \"../../shader/fragments/thin-instance-fragment.js\";\nimport { syncThinInstanceBuffers } from \"../../mesh/thin-instance-gpu.js\";\n\nimport type { Material } from \"../material.js\";\nimport type { StandardMaterialProps } from \"./standard-material.js\";\nimport { _getStdExtsSorted, DOUBLE_SIDED, HAS_DIFFUSE_TEXTURE, HAS_OPACITY_TEXTURE, NEEDS_UV, NEEDS_UV2 } from \"./standard-flags.js\";\nimport { writeStdMaterialData } from \"./standard-pipeline.js\";\nimport { composeStandardGeometryShader } from \"./standard-geometry-output-shader.js\";\nimport { getSceneBindGroupLayout } from \"../../render/scene-helpers.js\";\nimport { collectStdBoundTextures } from \"./collect-std-bound-textures.js\";\nimport { _computeMeshFeatures, MSH_HAS_INSTANCE_COLOR, MSH_HAS_THIN_INSTANCES } from \"../mesh-features.js\";\nimport type { StandardGeometryMaterialView } from \"./geometry-view.js\";\n\n/** Singleton {@link MeshGroupBuilder} that geometry views point at via their\n * overridden `_buildGroup`. The async builder body is unreachable — geometry\n * views are dispatched per-mesh via {@link RenderTask.addMesh} which calls\n * `_rebuildSingle` directly. Centralizing the per-mesh factory here means\n * `resolvePendingMeshes` doesn't need any view-aware branching. */\nexport const standardGeometryGroupBuilder: MeshGroupBuilder = (async () => {\n throw new Error(\"standard-geometry view does not support scene group building\");\n}) as MeshGroupBuilder;\nstandardGeometryGroupBuilder._rebuildSingle = (scene: SceneContext, mesh: Mesh, materialOverride?: Material): Renderable => {\n const view = (materialOverride ?? mesh.material) as StandardGeometryMaterialView;\n return buildStandardGeometryRenderable(scene, mesh, view);\n};\nstandardGeometryGroupBuilder._materialFamily = \"standard\";\n\n/** Per-(task, source-material, mesh-variant) shared resources lazily attached\n * to the view. Cached on `view._geometry` (Map keyed by mesh-variant bits) to\n * keep the same WGSL + BGL + pipeline objects across all meshes that share\n * the view and the same shader-relevant mesh features. */\ninterface StandardGeometryViewResources {\n _composed: ComposedShader;\n _features: number;\n _meshBGL: GPUBindGroupLayout;\n _pipelineLayout: GPUPipelineLayout;\n _vertModule: GPUShaderModule;\n _fragModule: GPUShaderModule;\n _pipelines: Map<string, GPURenderPipeline>;\n /** Ext fragments that contributed bindings — used by per-mesh bind groups. */\n _extFragments: readonly { _ext: ReturnType<typeof _getStdExtsSorted>[number] }[];\n _alphaBlend: boolean;\n /** Shared material UBO and dirty-version state (one per source material in this view). */\n _matUBO: GPUBuffer;\n _matData: Float32Array;\n _lastUboVersion: number;\n /** Optional UV-transform UBO. Allocated when the view's features include NEEDS_UV. */\n _upUBO: GPUBuffer | null;\n}\n\n/** Pack the mesh-feature bits that change shader composition / pipeline\n * into a 2-bit variant key. At most 4 variants per view in the worst case. */\nfunction _variantKey(meshFeatures: number): number {\n let k = 0;\n if (meshFeatures & MSH_HAS_THIN_INSTANCES) {\n k |= 1;\n }\n if (meshFeatures & MSH_HAS_INSTANCE_COLOR) {\n k |= 2;\n }\n return k;\n}\n\n/** Build a {@link Renderable} for one mesh drawn through a Standard geometry view.\n * Reuses or creates per-(view, mesh-variant) shared resources on `view._geometry`. */\nexport function buildStandardGeometryRenderable(scene: SceneContext, mesh: Mesh, view: StandardGeometryMaterialView): Renderable {\n const engine = scene.surface.engine;\n const device = engine._device;\n const source = view.source as StandardMaterialProps;\n // Geometry pass has no receiver path — pass receiveShadows=false.\n const meshFeatures = _computeMeshFeatures(mesh, false);\n const variantKey = _variantKey(meshFeatures);\n const res = _ensureViewResources(view, engine, meshFeatures, variantKey);\n const features = res._features;\n\n // Per-mesh UBOs + bind group.\n const meshUboData = new F32(res._composed._meshUboSpec._totalBytes / 4);\n meshUboData.set(mesh.worldMatrix, 0);\n writeMeshLightSelection(mesh, scene.lights, meshUboData);\n const meshUBO = createUniformBuffer(engine, meshUboData);\n\n const bg = _createGeometryMeshBindGroup(engine, view, res, mesh, meshUBO);\n\n // Acquire all textures the standard shader references so the GPU-pool\n // doesn't release them while the geometry pass holds bind groups on\n // them. Mirrors standard-renderable's lifecycle exactly.\n const boundTextures = collectStdBoundTextures(source);\n for (const t of boundTextures) {\n acquireTexture(t);\n }\n const prevDisposables = (scene as SceneContext)._meshDisposables.get(mesh) ?? [];\n (scene as SceneContext)._meshDisposables.set(mesh, [\n ...prevDisposables,\n () => {\n for (const t of boundTextures) {\n releaseTexture(t);\n }\n },\n ]);\n\n let _lastWorldVersion = mesh.worldMatrixVersion;\n let _lastLightsCount = scene.lights.length;\n\n const needsUV = (features & NEEDS_UV) !== 0;\n const needsUV2 = (features & NEEDS_UV2) !== 0;\n const isAlphaBlend = res._alphaBlend;\n const hasThinInstances = (meshFeatures & MSH_HAS_THIN_INSTANCES) !== 0;\n const hasInstanceColor = (meshFeatures & MSH_HAS_INSTANCE_COLOR) !== 0;\n const sortCenter = [mesh.worldMatrix[12]!, mesh.worldMatrix[13]!, mesh.worldMatrix[14]!] as [number, number, number];\n\n const update = (): void => {\n if (mesh.worldMatrixVersion !== _lastWorldVersion || scene.lights.length !== _lastLightsCount) {\n sortCenter[0] = mesh.worldMatrix[12]!;\n sortCenter[1] = mesh.worldMatrix[13]!;\n sortCenter[2] = mesh.worldMatrix[14]!;\n meshUboData.set(mesh.worldMatrix, 0);\n writeMeshLightSelection(mesh, scene.lights, meshUboData);\n device.queue.writeBuffer(meshUBO, 0, meshUboData as Float32Array<ArrayBuffer>);\n _lastWorldVersion = mesh.worldMatrixVersion;\n _lastLightsCount = scene.lights.length;\n }\n if (source._uboVersion !== res._lastUboVersion) {\n res._lastUboVersion = source._uboVersion;\n const textureLevel = (features & HAS_DIFFUSE_TEXTURE) !== 0 ? 1.0 : 0.0;\n res._matData.fill(0);\n writeStdMaterialData(res._matData, source, textureLevel);\n device.queue.writeBuffer(res._matUBO, 0, res._matData.buffer, 0, 96);\n }\n };\n\n const draw = (pass: GPURenderPassEncoder | GPURenderBundleEncoder): number => {\n if (mesh.visible === false) {\n return 0;\n }\n pass.setBindGroup(1, bg);\n const g = (mesh as Mesh)._gpu;\n let slot = 0;\n pass.setVertexBuffer(slot++, g.positionBuffer);\n pass.setVertexBuffer(slot++, g.normalBuffer);\n if (needsUV && g.uvBuffer) {\n pass.setVertexBuffer(slot++, g.uvBuffer);\n }\n if (needsUV2 && g.uv2Buffer) {\n pass.setVertexBuffer(slot++, g.uv2Buffer);\n }\n const ti = hasThinInstances ? mesh.thinInstances : null;\n if (ti) {\n slot = syncThinInstanceBuffers(engine, ti, pass, slot, hasInstanceColor);\n }\n pass.setIndexBuffer(g.indexBuffer, g.indexFormat);\n if (ti && ti.count > 0) {\n pass.drawIndexed(g.indexCount, ti.count);\n } else {\n pass.drawIndexed(g.indexCount);\n }\n return 1;\n };\n\n const r: Renderable = {\n order: mesh.renderOrder ?? (isAlphaBlend ? 200 : 100),\n isTransparent: isAlphaBlend,\n mesh,\n bind(eng: EngineContext, sig: RenderTargetSignature) {\n return {\n renderable: r,\n pipeline: _getOrCreateGeometryPipeline(eng as EngineContext, sig, view, res),\n update,\n draw,\n };\n },\n };\n r._worldCenter = sortCenter;\n return r;\n}\n\n// ─── Shared per-view resources ─────────────────────────────────────────────\n\nfunction _ensureViewResources(view: StandardGeometryMaterialView, engine: EngineContext, meshFeatures: number, variantKey: number): StandardGeometryViewResources {\n let cache = view._geometry as Map<number, StandardGeometryViewResources> | undefined;\n if (!cache) {\n cache = new Map();\n Object.defineProperty(view, \"_geometry\", { value: cache, enumerable: false, configurable: true });\n }\n const cached = cache.get(variantKey);\n if (cached) {\n return cached;\n }\n const source = view.source as StandardMaterialProps;\n const features = view._renderFeatures.features;\n\n // Collect the same ext fragments the regular Standard renderable would —\n // bump, opacity, specular, … — so the shared shader code is identical.\n const sortedExts = _getStdExtsSorted();\n const frags: ShaderFragment[] = [];\n const usedExts: { _ext: (typeof sortedExts)[number] }[] = [];\n for (const ext of sortedExts) {\n if (features & ext._feature) {\n const f = ext._frag(features);\n if (f) {\n frags.push(f);\n usedExts.push({ _ext: ext });\n }\n }\n }\n\n // Thin instances. Mirror standard-renderable: when per-instance colour is\n // present we override the fragment's AT slot with a BC slot that\n // multiplies the final lit `color` (only consumed when `emitColor` is on\n // — otherwise WGSL folds the dead code).\n if (meshFeatures & MSH_HAS_THIN_INSTANCES) {\n const hasColor = (meshFeatures & MSH_HAS_INSTANCE_COLOR) !== 0;\n const tiFrag = createThinInstanceFragment(hasColor);\n if (hasColor) {\n const { _fragmentSlots: _drop, ...rest } = tiFrag;\n frags.push({\n ...rest,\n _fragmentSlots: {\n BC: `color = vec4<f32>(color.rgb * input.vInstanceColor.rgb, color.a * input.vInstanceColor.a);`,\n },\n });\n } else {\n frags.push(tiFrag);\n }\n }\n\n const composed = composeStandardGeometryShader(features, meshFeatures, frags, view._geometryAttachments, \"\", view._emitColor);\n const device = engine._device;\n const meshBGL = device.createBindGroupLayout(composed._meshBGLDescriptor);\n // Pipeline layout: scene BG (group 0) + mesh BG (group 1). Geometry pass\n // has no shadow receiver group.\n const sceneBGL = getSceneBindGroupLayout(engine);\n const pipelineLayout = device.createPipelineLayout({\n bindGroupLayouts: [sceneBGL, meshBGL],\n });\n const vertModule = device.createShaderModule({ code: composed._vertexWGSL });\n const fragModule = device.createShaderModule({ code: composed._fragmentWGSL });\n\n // Re-detect alpha-blend from the *source* material — the view masked it\n // out so the composer doesn't emit standard's source-over color blend.\n const alphaBlend = source.alpha < 1 || (features & HAS_OPACITY_TEXTURE) !== 0;\n\n // Shared material UBO (one per source material per view). All meshes of\n // this material reuse the same UBO; updates are version-guarded.\n const matData = new F32(24);\n const textureLevel = (features & HAS_DIFFUSE_TEXTURE) !== 0 ? 1.0 : 0.0;\n writeStdMaterialData(matData, source, textureLevel);\n const matUBO = createUniformBuffer(engine, matData);\n\n // UV transform UBO when the vertex stage emits UV math.\n let upUBO: GPUBuffer | null = null;\n if ((features & NEEDS_UV) !== 0) {\n const uvData = new F32(4);\n let scaleX = 1;\n let scaleY = 1;\n let offsetY = 0;\n if ((features & HAS_DIFFUSE_TEXTURE) !== 0 && source.diffuseTexture) {\n scaleX = source.uvScale[0];\n scaleY = source.uvScale[1];\n if (source.diffuseTexture.invertY) {\n offsetY = scaleY;\n scaleY = -scaleY;\n }\n } else if ((features & HAS_OPACITY_TEXTURE) !== 0 && source.opacityTexture?.invertY) {\n offsetY = 1;\n scaleY = -1;\n } else if (source.bumpTexture?.invertY) {\n offsetY = 1;\n scaleY = -1;\n }\n uvData[0] = scaleX;\n uvData[1] = scaleY;\n uvData[2] = 0;\n uvData[3] = offsetY;\n upUBO = createUniformBuffer(engine, uvData);\n }\n\n const res: StandardGeometryViewResources = {\n _composed: composed,\n _features: features,\n _meshBGL: meshBGL,\n _pipelineLayout: pipelineLayout,\n _vertModule: vertModule,\n _fragModule: fragModule,\n _pipelines: new Map(),\n _extFragments: usedExts,\n _alphaBlend: alphaBlend,\n _matUBO: matUBO,\n _matData: matData,\n _lastUboVersion: source._uboVersion,\n _upUBO: upUBO,\n };\n cache.set(variantKey, res);\n return res;\n}\n\nfunction _createGeometryMeshBindGroup(\n engine: EngineContext,\n view: StandardGeometryMaterialView,\n res: StandardGeometryViewResources,\n _mesh: Mesh,\n meshUBO: GPUBuffer\n): GPUBindGroup {\n const source = view.source as StandardMaterialProps;\n const features = res._features;\n let nextBinding = 0;\n const entries: GPUBindGroupEntry[] = [\n { binding: nextBinding++, resource: { buffer: meshUBO } },\n { binding: nextBinding++, resource: { buffer: res._matUBO } },\n ];\n if ((features & HAS_DIFFUSE_TEXTURE) !== 0 && source.diffuseTexture) {\n const tex = source.diffuseTexture;\n entries.push({ binding: nextBinding++, resource: tex.texture.createView() }, { binding: nextBinding++, resource: tex.sampler });\n }\n if ((features & NEEDS_UV) !== 0 && res._upUBO) {\n entries.push({ binding: nextBinding++, resource: { buffer: res._upUBO } });\n }\n for (const used of res._extFragments) {\n if (used._ext._bind) {\n nextBinding = used._ext._bind(source, entries, nextBinding);\n }\n }\n // Geometry-params `gp` UBO is contributed by the geometry composer as the\n // last fragment, so its binding is appended last. Present iff the\n // requested attachments need it (LINEAR_VELOCITY or NORMALIZED_VIEW_DEPTH).\n if (view._gpUBO) {\n entries.push({ binding: nextBinding++, resource: { buffer: view._gpUBO } });\n }\n return engine._device.createBindGroup({ layout: res._meshBGL, entries });\n}\n\nfunction _getOrCreateGeometryPipeline(\n engine: EngineContext,\n sig: RenderTargetSignature,\n view: StandardGeometryMaterialView,\n res: StandardGeometryViewResources\n): GPURenderPipeline {\n const key = targetSignatureKey(sig);\n const cached = res._pipelines.get(key);\n if (cached) {\n return cached;\n }\n const device = engine._device;\n const formats = (sig as RenderTargetSignature & { _colorFormats?: readonly GPUTextureFormat[] })._colorFormats ?? (sig._colorFormat ? [sig._colorFormat] : []);\n if (formats.length === 0) {\n throw new Error(\"standard-geometry: render target has no color attachments\");\n }\n const alphaBlend = res._alphaBlend;\n const blendState: GPUBlendState | undefined = alphaBlend\n ? {\n color: { srcFactor: \"src-alpha\", dstFactor: \"one-minus-src-alpha\", operation: \"add\" },\n alpha: { srcFactor: \"src-alpha\", dstFactor: \"one-minus-src-alpha\", operation: \"add\" },\n }\n : undefined;\n const colorTargets: GPUColorTargetState[] = formats.map((fmt) => (blendState ? { format: fmt, blend: blendState } : { format: fmt }));\n const cullMode = (res._features & DOUBLE_SIDED) !== 0 ? \"none\" : view._reverseCulling ? \"front\" : \"back\";\n const pipeline = device.createRenderPipeline({\n layout: res._pipelineLayout,\n vertex: { module: res._vertModule, entryPoint: \"main\", buffers: res._composed._vertexBufferLayouts },\n fragment: { module: res._fragModule, entryPoint: \"main\", targets: colorTargets },\n depthStencil: sig._depthStencilFormat\n ? {\n format: sig._depthStencilFormat,\n depthCompare: sig._depthCompare ?? \"greater-equal\",\n // BJS disables depth-write for transparent/opacity meshes in the\n // geometry pass so background depth survives partially-transparent pixels.\n depthWriteEnabled: !alphaBlend,\n }\n : undefined,\n multisample: { count: sig._sampleCount },\n // Geometry MRT renders to offscreen targets, so it needs the same\n // Render upright — front face is always \"ccw\".\n primitive: { topology: \"triangle-list\", cullMode, frontFace: \"ccw\" },\n });\n res._pipelines.set(key, pipeline);\n return pipeline;\n}\n","/** Standard material view helper that targets geometry-rendering MRT output.\n *\n * The geometry renderer task wraps each Standard caster material in a\n * `StandardGeometryMaterialView`. The view carries the per-task attachment\n * list, target-texture intent, optional `gp` UBO (shared across the task's\n * materials), and reverse-culling flag. The view also shadows\n * {@link Material._buildGroup} with {@link standardGeometryGroupBuilder} so\n * that `RenderTask.addMesh` (and the geometry renderer task) materialize a\n * {@link Renderable} through the shared standard geometry renderable\n * infrastructure — no view-aware branching required in core render-task.\n *\n * The geometry-output WGSL itself is produced by post-processing the regular\n * composed standard shader in `./standard-geometry-output-shader.ts`. */\n\nimport { createMaterialView } from \"../material-view.js\";\nimport type { MaterialView } from \"../material.js\";\nimport type { GeometryTextureType } from \"../../frame-graph/geometry-types.js\";\nimport { GEOMETRY_OUTPUT, MATERIAL_ALPHA_BLEND } from \"./standard-flags.js\";\nimport type { StandardMaterialProps } from \"./standard-material.js\";\nimport { standardGeometryGroupBuilder } from \"./standard-geometry-renderable.js\";\n\n/** Per-task ordered attachment list driving the geometry template. The array\n * index is the MRT color-attachment slot used in `@location(i)`. */\nexport type StandardGeometryAttachments = readonly GeometryTextureType[];\n\n/** Per-(task, material) geometry view configuration. All fields are owned by\n * the geometry renderer task; the view captures them so per-mesh renderables\n * pick up the same pipeline state and bindings. */\nexport interface StandardGeometryViewConfig {\n /** Ordered MRT attachment list — index = `@location(i)`. */\n readonly attachments: StandardGeometryAttachments;\n /** When true, the composed fragment emits the real (lit) material color\n * at `@location(N)` (N = attachments.length). The target texture is\n * added to the pipeline color-target list at the same slot. */\n readonly emitColor: boolean;\n /** Per-task previous-VP + camera-near-far UBO. Required when\n * {@link attachments} contains `NORMALIZED_VIEW_DEPTH` or\n * `LINEAR_VELOCITY`; ignored otherwise. */\n readonly gpUBO?: GPUBuffer | null;\n /** Flip culling direction. */\n readonly reverseCulling?: boolean;\n}\n\n/** Standard material view that emits geometry textures instead of shaded colour. */\nexport interface StandardGeometryMaterialView extends MaterialView {\n /** @internal Ordered MRT attachment list — index = `@location(i)`. */\n readonly _geometryAttachments: StandardGeometryAttachments;\n /** @internal Geometry pipeline carries an extra `@location(N)` color attachment. */\n readonly _emitColor: boolean;\n /** @internal Optional per-task geometry-params UBO shared with the composer's\n * `geometryParams` fragment. */\n readonly _gpUBO: GPUBuffer | null;\n /** @internal */\n readonly _reverseCulling: boolean;\n /** @internal Shared per-view resources cache populated lazily by the renderable\n * factory. Opaque to callers. */\n _geometry?: unknown;\n}\n\n/** Wrap a Standard material as a geometry-output view.\n * - Sets the `GEOMETRY_OUTPUT` feature bit.\n * - Clears `MATERIAL_ALPHA_BLEND`: the geometry pipeline drives blending per\n * attachment via the pipeline color-target state, not via the standard\n * fragment's source-over color output.\n * - Shadows `_buildGroup` with {@link standardGeometryGroupBuilder} so the\n * natural `material._buildGroup._rebuildSingle` dispatch in\n * `resolvePendingMeshes` builds a geometry-MRT renderable for this view. */\nexport function createStandardGeometryMaterialView(source: StandardMaterialProps, config: StandardGeometryViewConfig): StandardGeometryMaterialView {\n const baseFeatures = source._renderFeatures?.features ?? 0;\n const view = createMaterialView(source, { features: (baseFeatures & ~MATERIAL_ALPHA_BLEND) | GEOMETRY_OUTPUT }) as StandardGeometryMaterialView;\n Object.defineProperty(view, \"_geometryAttachments\", { value: config.attachments, enumerable: false });\n Object.defineProperty(view, \"_emitColor\", { value: config.emitColor, enumerable: false });\n Object.defineProperty(view, \"_gpUBO\", { value: config.gpUBO ?? null, enumerable: false });\n Object.defineProperty(view, \"_reverseCulling\", { value: config.reverseCulling ?? false, enumerable: false });\n Object.defineProperty(view, \"_buildGroup\", { value: standardGeometryGroupBuilder, enumerable: false });\n return view;\n}\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { ba as mat4Invert, bb as mat4Identity, bc as getLoaderTmpAnim, bd as mat4MultiplyInto, a as F32, b8 as computeNodeWorldMatrix, r as resolveAccessor, be as INTERP_CUBICSPLINE, bf as INTERP_STEP, bg as INTERP_LINEAR, bh as PATH_WEIGHTS, bi as PATH_SCALE, bj as PATH_ROTATION, bk as PATH_TRANSLATION, bl as findParent } from "./index-CLElg2Bo.js";
1
+ import { bf as mat4Invert, bg as mat4Identity, bh as getLoaderTmpAnim, bi as mat4MultiplyInto, a as F32, bd as computeNodeWorldMatrix, r as resolveAccessor, bj as INTERP_CUBICSPLINE, bk as INTERP_STEP, bl as INTERP_LINEAR, bm as PATH_WEIGHTS, bn as PATH_SCALE, bo as PATH_ROTATION, bp as PATH_TRANSLATION, bq as findParent } from "./index-BgY3QEzL.js";
2
2
  let _parsePointerChannel = null;
3
3
  let _convertSampler = null;
4
4
  function _installPointerHandlers(parser, converter) {
@@ -242,4 +242,4 @@ export {
242
242
  extractSkin,
243
243
  parseAnimationData
244
244
  };
245
- //# sourceMappingURL=gltf-animation-K_zZxj_d.js.map
245
+ //# sourceMappingURL=gltf-animation-BjnXkop6.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"gltf-animation-K_zZxj_d.js","sources":["../src/loader-gltf/gltf-animation.ts"],"sourcesContent":["/**\n * Lazy-loaded animation/skin parsing for glTF.\n * Dynamically imported by load-gltf.ts only when a glTF contains animations or skins.\n *\n * This module is pointer-feature agnostic: KHR_animation_pointer (and the\n * non-Float32 sampler conversion that CubeVisibility-style assets need) are\n * installed via the registration seam below, so scenes that don't declare\n * the extension pay zero bytes for it.\n */\nimport { F32 } from \"../engine/typed-arrays.js\";\nimport type { Mat4 } from \"../math/types.js\";\nimport type { Mesh } from \"../mesh/mesh.js\";\nimport type { GltfAnimationData, AnimationClip, AnimationSampler, AnimationChannel, NodeRest, SkeletonBinding, MorphBinding, AnimatedNodeTarget } from \"../animation/types.js\";\nimport { INTERP_LINEAR, INTERP_STEP, INTERP_CUBICSPLINE, PATH_TRANSLATION, PATH_ROTATION, PATH_SCALE, PATH_WEIGHTS } from \"../animation/types.js\";\nimport { mat4Identity } from \"../math/mat4-identity.js\";\nimport { mat4Invert } from \"../math/mat4-invert.js\";\nimport { mat4MultiplyInto } from \"../math/mat4-multiply-into.js\";\nimport type { Mat4Storage } from \"../math/types.js\";\nimport { resolveAccessor, computeNodeWorldMatrix, findParent } from \"./gltf-parser.js\";\nimport { getLoaderTmpAnim } from \"./_loader-scratch.js\";\nimport type { SceneNode } from \"../scene/scene-node.js\";\n\n/** Registration seam for KHR_animation_pointer. The pointer feature module\n * calls `_installPointerHandlers` on side-effect import; if never called,\n * pointer channels are skipped and non-Float32 samplers fall back to the\n * aliasing fast path (which throws on misaligned/short accessors). */\nexport type PointerChannelParser = (ptr: string, channel: any, nodeMap: readonly (SceneNode | undefined)[] | undefined) => AnimationChannel | null;\nexport type SamplerConverter = (src: ArrayBufferView, length: number, normalized: boolean) => Float32Array;\nlet _parsePointerChannel: PointerChannelParser | null = null;\nlet _convertSampler: SamplerConverter | null = null;\nexport function _installPointerHandlers(parser: PointerChannelParser, converter: SamplerConverter): void {\n _parsePointerChannel = parser;\n _convertSampler = converter;\n}\n\n/** Convert sampler input/output to Float32Array. Default: reinterpret existing\n * Float32 accessor as Float32Array (legacy behaviour; fast but requires\n * aligned Float32 data). KHR_animation_pointer installs a converter that\n * additionally handles non-Float32 / normalized accessors. */\nfunction toSamplerFloat32(src: ArrayBufferView, length: number, normalized: boolean): Float32Array {\n if (_convertSampler) {\n return _convertSampler(src, length, normalized);\n }\n return new F32(src.buffer, src.byteOffset, length);\n}\n\n/** Parsed skin/skeleton data. */\nexport interface GltfSkinData {\n /** Node indices of joints in this skin. */\n jointNodes: number[];\n /** Inverse bind matrices — one 4×4 per joint (column-major Float32Array). */\n inverseBindMatrices: Float32Array;\n /** World matrices of each joint at rest pose. */\n jointWorldMatrices: Mat4[];\n /** World matrix of the mesh node that owns this skin. */\n meshWorldMatrix: Mat4;\n}\n\n// ─── Skin / Skeleton Extraction ─────────────────────────────────────\n\n/** Resolve a skin's inverse-bind matrices, filling with identities when absent. */\nfunction resolveIBMs(json: any, binChunk: DataView, skin: any): Float32Array {\n const jointCount = skin.joints.length;\n if (skin.inverseBindMatrices !== undefined) {\n const ibmData = resolveAccessor(json, binChunk, skin.inverseBindMatrices);\n return new F32(ibmData._data.buffer, ibmData._data.byteOffset, jointCount * 16);\n }\n const out = new F32(jointCount * 16);\n for (let i = 0; i < jointCount; i++) {\n const o = i * 16;\n out[o] = out[o + 5] = out[o + 10] = out[o + 15] = 1;\n }\n return out;\n}\n\nexport function extractSkin(\n json: any,\n binChunk: DataView,\n skinIdx: number,\n meshWorldMatrix: Mat4,\n parentMap: Map<number, number>,\n worldMatrixCache: Map<number, Mat4>\n): GltfSkinData {\n const skin = json.skins[skinIdx];\n const jointNodes: number[] = skin.joints;\n const inverseBindMatrices = resolveIBMs(json, binChunk, skin);\n const jointWorldMatrices: Mat4[] = jointNodes.map((nodeIdx) => computeNodeWorldMatrix(json, nodeIdx, parentMap, worldMatrixCache));\n return { jointNodes, inverseBindMatrices, jointWorldMatrices, meshWorldMatrix };\n}\n\n/** Compute rest-pose bone texture data. Each bone gets 4 vec4 (one 4×4 matrix).\n * Formula: boneMatrix[i] = inverse(meshWorld) * jointWorld[i] * IBM[i]\n * At rest pose this simplifies to identity for each bone. */\nexport function computeBoneTextureData(skin: GltfSkinData): Float32Array {\n const numBones = skin.jointNodes.length;\n const data = new F32(numBones * 16);\n const invMeshWorld = mat4Invert(skin.meshWorldMatrix) ?? mat4Identity();\n const tmp = getLoaderTmpAnim() as unknown as Mat4Storage;\n for (let i = 0; i < numBones; i++) {\n mat4MultiplyInto(tmp, 0, invMeshWorld as unknown as Mat4Storage, 0, skin.jointWorldMatrices[i]! as unknown as Mat4Storage, 0);\n mat4MultiplyInto(data, i * 16, tmp, 0, skin.inverseBindMatrices, i * 16);\n }\n return data;\n}\n\n// ─── Animation Parsing ──────────────────────────────────────────────\n\nconst INTERP_MAP: Record<string, 0 | 1 | 2> = {\n LINEAR: INTERP_LINEAR,\n STEP: INTERP_STEP,\n CUBICSPLINE: INTERP_CUBICSPLINE,\n};\n\nconst PATH_MAP: Record<string, 0 | 1 | 2 | 3> = {\n translation: PATH_TRANSLATION,\n rotation: PATH_ROTATION,\n scale: PATH_SCALE,\n weights: PATH_WEIGHTS,\n};\n\n/**\n * Parse glTF animation data: clips, node hierarchy, and skeleton bindings.\n * Returns null if no animations, or no drivable state at all (no skeletons,\n * no morphs, no pointer channels).\n *\n * `nodeMap` (optional) maps glTF node index → SceneNode. It's required to\n * resolve KHR_animation_pointer targets that write to node properties.\n */\nexport function parseAnimationData(\n json: any,\n binChunk: DataView,\n meshes: Mesh[],\n parentMap: Map<number, number>,\n worldMatrixCache: Map<number, Mat4>,\n nodeMap?: readonly (SceneNode | undefined)[]\n): GltfAnimationData | null {\n if (!json.animations || json.animations.length === 0) {\n return null;\n }\n\n let pointerChannelCount = 0;\n\n // Parse animation clips\n const clips: AnimationClip[] = [];\n for (const anim of json.animations) {\n const samplers: AnimationSampler[] = [];\n for (const s of anim.samplers) {\n const inputAcc = resolveAccessor(json, binChunk, s.input);\n const outputAcc = resolveAccessor(json, binChunk, s.output);\n const inNorm = json.accessors[s.input]?.normalized === true;\n const outNorm = json.accessors[s.output]?.normalized === true;\n samplers.push({\n input: toSamplerFloat32(inputAcc._data, inputAcc._count, inNorm),\n output: toSamplerFloat32(outputAcc._data, outputAcc._count * outputAcc._componentCount, outNorm),\n interpolation: INTERP_MAP[s.interpolation ?? \"LINEAR\"] ?? INTERP_LINEAR,\n });\n }\n\n const channels: AnimationChannel[] = [];\n for (const c of anim.channels) {\n // KHR_animation_pointer: delegated to the registered pointer parser\n // (installed by gltf-feature-animation-pointer on side-effect import).\n const ptr = c.target?.extensions?.KHR_animation_pointer?.pointer;\n if (ptr) {\n if (!_parsePointerChannel) {\n continue;\n }\n const ch = _parsePointerChannel(ptr, c, nodeMap);\n if (ch) {\n channels.push(ch);\n pointerChannelCount++;\n }\n continue;\n }\n if (c.target.node === undefined) {\n continue;\n }\n const path = PATH_MAP[c.target.path];\n if (path === undefined) {\n continue;\n }\n channels.push({ samplerIdx: c.sampler, nodeIdx: c.target.node, path });\n }\n\n let duration = 0;\n for (const s of samplers) {\n if (s.input.length > 0) {\n const last = s.input[s.input.length - 1]!;\n if (last > duration) {\n duration = last;\n }\n }\n }\n\n clips.push({ name: anim.name ?? \"\", channels, samplers, duration });\n }\n\n // Build node hierarchy (rest-pose TRS + parent indices)\n const nodeCount = json.nodes?.length ?? 0;\n const nodes: NodeRest[] = [];\n for (let i = 0; i < nodeCount; i++) {\n const n = json.nodes[i];\n const t = n.translation ?? [0, 0, 0];\n const r = n.rotation ?? [0, 0, 0, 1];\n const s = n.scale ?? [1, 1, 1];\n nodes.push({\n parentIdx: findParent(parentMap, i),\n _matrix: n.matrix as Mat4 | undefined,\n tx: t[0],\n ty: t[1],\n tz: t[2],\n rx: r[0],\n ry: r[1],\n rz: r[2],\n rw: r[3],\n sx: s[0],\n sy: s[1],\n sz: s[2],\n });\n }\n\n // Build skeleton bindings (connect skin data to GPU bone textures)\n // First, build node→gpuMesh mapping by replaying extraction order\n const nodeToMeshIndices = new Map<number, number[]>();\n let gpuIdx = 0;\n for (let ni = 0; ni < nodeCount; ni++) {\n const node = json.nodes[ni];\n if (node.mesh === undefined) {\n continue;\n }\n const mesh = json.meshes[node.mesh];\n const indices: number[] = [];\n for (let p = 0; p < mesh.primitives.length; p++) {\n indices.push(gpuIdx++);\n }\n nodeToMeshIndices.set(ni, indices);\n }\n\n const skeletons: SkeletonBinding[] = [];\n for (let nodeIdx = 0; nodeIdx < nodeCount; nodeIdx++) {\n const node = json.nodes[nodeIdx];\n if (node.skin === undefined || !json.skins) {\n continue;\n }\n\n const meshIndices = nodeToMeshIndices.get(nodeIdx);\n if (!meshIndices) {\n continue;\n }\n\n const skin = json.skins[node.skin];\n const jointNodes: number[] = skin.joints;\n const inverseBindMatrices = resolveIBMs(json, binChunk, skin);\n\n const meshWorldMatrix = computeNodeWorldMatrix(json, nodeIdx, parentMap, worldMatrixCache);\n const invMeshWorld = mat4Invert(meshWorldMatrix) ?? mat4Identity();\n\n // Create a binding for EACH mesh primitive of this skinned node\n for (const mi of meshIndices) {\n const mesh = meshes[mi];\n const skeleton = mesh?.skeleton;\n if (!skeleton) {\n continue;\n }\n skeletons.push({\n jointNodes,\n inverseBindMatrices,\n invMeshWorld,\n boneTexture: skeleton.boneTexture,\n boneCount: jointNodes.length,\n boneMatrices: skeleton.boneMatrices,\n runtimeSkeleton: skeleton,\n });\n }\n }\n\n // Build morph bindings (connect morph-target meshes to GPU weight buffers)\n const morphBindings: MorphBinding[] = [];\n for (let nodeIdx = 0; nodeIdx < nodeCount; nodeIdx++) {\n const node = json.nodes[nodeIdx];\n if (node.mesh === undefined) {\n continue;\n }\n const gltfMesh = json.meshes[node.mesh];\n if (!gltfMesh.primitives?.[0]?.targets?.length) {\n continue;\n }\n\n const meshIndices = nodeToMeshIndices.get(nodeIdx);\n if (!meshIndices) {\n continue;\n }\n\n for (const mi of meshIndices) {\n const mesh = meshes[mi];\n const morphTargets = mesh?.morphTargets;\n if (!morphTargets) {\n continue;\n }\n morphBindings.push({\n nodeIdx,\n weightsBuffer: morphTargets.weightsBuffer,\n weights: morphTargets.weights,\n targetCount: morphTargets.count,\n runtimeMorphTargets: morphTargets,\n });\n }\n }\n\n // Build the node-TRS writeback inputs. `nodeTargets` exposes each glTF node's\n // live scene node (via the structural AnimatedNodeTarget view) so the controller\n // can push evaluated local TRS back onto the scene graph, moving non-skinned\n // node-animated meshes and their descendants. `excludedNodeIndices` lists nodes\n // that MUST NOT be written: skin joints (driven by the skeleton path) plus\n // skinned-mesh nodes and all their ancestors — their bone matrices bake an\n // `invMeshWorld` captured at load, so moving them at runtime would\n // double-transform the skinned vertices.\n const nodeTargets: readonly (AnimatedNodeTarget | undefined)[] = (nodeMap as readonly (AnimatedNodeTarget | undefined)[] | undefined) ?? [];\n const excludedNodeIndices = new Set<number>();\n for (const skin of json.skins ?? []) {\n for (const ji of skin.joints ?? []) {\n excludedNodeIndices.add(ji);\n }\n }\n for (let ni = 0; ni < nodeCount; ni++) {\n if (json.nodes[ni]?.skin === undefined) {\n continue;\n }\n let p = ni;\n while (p >= 0 && !excludedNodeIndices.has(p)) {\n excludedNodeIndices.add(p);\n p = findParent(parentMap, p);\n }\n }\n\n if (\n clips.length === 0 ||\n (skeletons.length === 0 && morphBindings.length === 0 && pointerChannelCount === 0 && !hasWritableNodeChannel(clips, nodeTargets, excludedNodeIndices))\n ) {\n return null;\n }\n return { clips, nodes, skeletons, morphBindings, nodeTargets, excludedNodeIndices };\n}\n\n/** True if any clip animates a non-excluded node that has a live scene target —\n * i.e. there is at least one plain node-TRS channel the controller can write\n * back. Lets purely-skinned/morph/pointer assets short-circuit unchanged. */\nfunction hasWritableNodeChannel(clips: readonly AnimationClip[], nodeTargets: readonly (AnimatedNodeTarget | undefined)[], excludedNodeIndices: ReadonlySet<number>): boolean {\n for (const clip of clips) {\n for (const ch of clip.channels) {\n if (\n (ch.path === PATH_TRANSLATION || ch.path === PATH_ROTATION || ch.path === PATH_SCALE) &&\n ch.nodeIdx >= 0 &&\n !excludedNodeIndices.has(ch.nodeIdx) &&\n nodeTargets[ch.nodeIdx]\n ) {\n return true;\n }\n }\n }\n return false;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gltf-animation-BjnXkop6.js","sources":["../src/loader-gltf/gltf-animation.ts"],"sourcesContent":["/**\n * Lazy-loaded animation/skin parsing for glTF.\n * Dynamically imported by load-gltf.ts only when a glTF contains animations or skins.\n *\n * This module is pointer-feature agnostic: KHR_animation_pointer (and the\n * non-Float32 sampler conversion that CubeVisibility-style assets need) are\n * installed via the registration seam below, so scenes that don't declare\n * the extension pay zero bytes for it.\n */\nimport { F32 } from \"../engine/typed-arrays.js\";\nimport type { Mat4 } from \"../math/types.js\";\nimport type { Mesh } from \"../mesh/mesh.js\";\nimport type { GltfAnimationData, AnimationClip, AnimationSampler, AnimationChannel, NodeRest, SkeletonBinding, MorphBinding, AnimatedNodeTarget } from \"../animation/types.js\";\nimport { INTERP_LINEAR, INTERP_STEP, INTERP_CUBICSPLINE, PATH_TRANSLATION, PATH_ROTATION, PATH_SCALE, PATH_WEIGHTS } from \"../animation/types.js\";\nimport { mat4Identity } from \"../math/mat4-identity.js\";\nimport { mat4Invert } from \"../math/mat4-invert.js\";\nimport { mat4MultiplyInto } from \"../math/mat4-multiply-into.js\";\nimport type { Mat4Storage } from \"../math/types.js\";\nimport { resolveAccessor, computeNodeWorldMatrix, findParent } from \"./gltf-parser.js\";\nimport { getLoaderTmpAnim } from \"./_loader-scratch.js\";\nimport type { SceneNode } from \"../scene/scene-node.js\";\n\n/** Registration seam for KHR_animation_pointer. The pointer feature module\n * calls `_installPointerHandlers` on side-effect import; if never called,\n * pointer channels are skipped and non-Float32 samplers fall back to the\n * aliasing fast path (which throws on misaligned/short accessors). */\nexport type PointerChannelParser = (ptr: string, channel: any, nodeMap: readonly (SceneNode | undefined)[] | undefined) => AnimationChannel | null;\nexport type SamplerConverter = (src: ArrayBufferView, length: number, normalized: boolean) => Float32Array;\nlet _parsePointerChannel: PointerChannelParser | null = null;\nlet _convertSampler: SamplerConverter | null = null;\nexport function _installPointerHandlers(parser: PointerChannelParser, converter: SamplerConverter): void {\n _parsePointerChannel = parser;\n _convertSampler = converter;\n}\n\n/** Convert sampler input/output to Float32Array. Default: reinterpret existing\n * Float32 accessor as Float32Array (legacy behaviour; fast but requires\n * aligned Float32 data). KHR_animation_pointer installs a converter that\n * additionally handles non-Float32 / normalized accessors. */\nfunction toSamplerFloat32(src: ArrayBufferView, length: number, normalized: boolean): Float32Array {\n if (_convertSampler) {\n return _convertSampler(src, length, normalized);\n }\n return new F32(src.buffer, src.byteOffset, length);\n}\n\n/** Parsed skin/skeleton data. */\nexport interface GltfSkinData {\n /** Node indices of joints in this skin. */\n jointNodes: number[];\n /** Inverse bind matrices — one 4×4 per joint (column-major Float32Array). */\n inverseBindMatrices: Float32Array;\n /** World matrices of each joint at rest pose. */\n jointWorldMatrices: Mat4[];\n /** World matrix of the mesh node that owns this skin. */\n meshWorldMatrix: Mat4;\n}\n\n// ─── Skin / Skeleton Extraction ─────────────────────────────────────\n\n/** Resolve a skin's inverse-bind matrices, filling with identities when absent. */\nfunction resolveIBMs(json: any, binChunk: DataView, skin: any): Float32Array {\n const jointCount = skin.joints.length;\n if (skin.inverseBindMatrices !== undefined) {\n const ibmData = resolveAccessor(json, binChunk, skin.inverseBindMatrices);\n return new F32(ibmData._data.buffer, ibmData._data.byteOffset, jointCount * 16);\n }\n const out = new F32(jointCount * 16);\n for (let i = 0; i < jointCount; i++) {\n const o = i * 16;\n out[o] = out[o + 5] = out[o + 10] = out[o + 15] = 1;\n }\n return out;\n}\n\nexport function extractSkin(\n json: any,\n binChunk: DataView,\n skinIdx: number,\n meshWorldMatrix: Mat4,\n parentMap: Map<number, number>,\n worldMatrixCache: Map<number, Mat4>\n): GltfSkinData {\n const skin = json.skins[skinIdx];\n const jointNodes: number[] = skin.joints;\n const inverseBindMatrices = resolveIBMs(json, binChunk, skin);\n const jointWorldMatrices: Mat4[] = jointNodes.map((nodeIdx) => computeNodeWorldMatrix(json, nodeIdx, parentMap, worldMatrixCache));\n return { jointNodes, inverseBindMatrices, jointWorldMatrices, meshWorldMatrix };\n}\n\n/** Compute rest-pose bone texture data. Each bone gets 4 vec4 (one 4×4 matrix).\n * Formula: boneMatrix[i] = inverse(meshWorld) * jointWorld[i] * IBM[i]\n * At rest pose this simplifies to identity for each bone. */\nexport function computeBoneTextureData(skin: GltfSkinData): Float32Array {\n const numBones = skin.jointNodes.length;\n const data = new F32(numBones * 16);\n const invMeshWorld = mat4Invert(skin.meshWorldMatrix) ?? mat4Identity();\n const tmp = getLoaderTmpAnim() as unknown as Mat4Storage;\n for (let i = 0; i < numBones; i++) {\n mat4MultiplyInto(tmp, 0, invMeshWorld as unknown as Mat4Storage, 0, skin.jointWorldMatrices[i]! as unknown as Mat4Storage, 0);\n mat4MultiplyInto(data, i * 16, tmp, 0, skin.inverseBindMatrices, i * 16);\n }\n return data;\n}\n\n// ─── Animation Parsing ──────────────────────────────────────────────\n\nconst INTERP_MAP: Record<string, 0 | 1 | 2> = {\n LINEAR: INTERP_LINEAR,\n STEP: INTERP_STEP,\n CUBICSPLINE: INTERP_CUBICSPLINE,\n};\n\nconst PATH_MAP: Record<string, 0 | 1 | 2 | 3> = {\n translation: PATH_TRANSLATION,\n rotation: PATH_ROTATION,\n scale: PATH_SCALE,\n weights: PATH_WEIGHTS,\n};\n\n/**\n * Parse glTF animation data: clips, node hierarchy, and skeleton bindings.\n * Returns null if no animations, or no drivable state at all (no skeletons,\n * no morphs, no pointer channels).\n *\n * `nodeMap` (optional) maps glTF node index → SceneNode. It's required to\n * resolve KHR_animation_pointer targets that write to node properties.\n */\nexport function parseAnimationData(\n json: any,\n binChunk: DataView,\n meshes: Mesh[],\n parentMap: Map<number, number>,\n worldMatrixCache: Map<number, Mat4>,\n nodeMap?: readonly (SceneNode | undefined)[]\n): GltfAnimationData | null {\n if (!json.animations || json.animations.length === 0) {\n return null;\n }\n\n let pointerChannelCount = 0;\n\n // Parse animation clips\n const clips: AnimationClip[] = [];\n for (const anim of json.animations) {\n const samplers: AnimationSampler[] = [];\n for (const s of anim.samplers) {\n const inputAcc = resolveAccessor(json, binChunk, s.input);\n const outputAcc = resolveAccessor(json, binChunk, s.output);\n const inNorm = json.accessors[s.input]?.normalized === true;\n const outNorm = json.accessors[s.output]?.normalized === true;\n samplers.push({\n input: toSamplerFloat32(inputAcc._data, inputAcc._count, inNorm),\n output: toSamplerFloat32(outputAcc._data, outputAcc._count * outputAcc._componentCount, outNorm),\n interpolation: INTERP_MAP[s.interpolation ?? \"LINEAR\"] ?? INTERP_LINEAR,\n });\n }\n\n const channels: AnimationChannel[] = [];\n for (const c of anim.channels) {\n // KHR_animation_pointer: delegated to the registered pointer parser\n // (installed by gltf-feature-animation-pointer on side-effect import).\n const ptr = c.target?.extensions?.KHR_animation_pointer?.pointer;\n if (ptr) {\n if (!_parsePointerChannel) {\n continue;\n }\n const ch = _parsePointerChannel(ptr, c, nodeMap);\n if (ch) {\n channels.push(ch);\n pointerChannelCount++;\n }\n continue;\n }\n if (c.target.node === undefined) {\n continue;\n }\n const path = PATH_MAP[c.target.path];\n if (path === undefined) {\n continue;\n }\n channels.push({ samplerIdx: c.sampler, nodeIdx: c.target.node, path });\n }\n\n let duration = 0;\n for (const s of samplers) {\n if (s.input.length > 0) {\n const last = s.input[s.input.length - 1]!;\n if (last > duration) {\n duration = last;\n }\n }\n }\n\n clips.push({ name: anim.name ?? \"\", channels, samplers, duration });\n }\n\n // Build node hierarchy (rest-pose TRS + parent indices)\n const nodeCount = json.nodes?.length ?? 0;\n const nodes: NodeRest[] = [];\n for (let i = 0; i < nodeCount; i++) {\n const n = json.nodes[i];\n const t = n.translation ?? [0, 0, 0];\n const r = n.rotation ?? [0, 0, 0, 1];\n const s = n.scale ?? [1, 1, 1];\n nodes.push({\n parentIdx: findParent(parentMap, i),\n _matrix: n.matrix as Mat4 | undefined,\n tx: t[0],\n ty: t[1],\n tz: t[2],\n rx: r[0],\n ry: r[1],\n rz: r[2],\n rw: r[3],\n sx: s[0],\n sy: s[1],\n sz: s[2],\n });\n }\n\n // Build skeleton bindings (connect skin data to GPU bone textures)\n // First, build node→gpuMesh mapping by replaying extraction order\n const nodeToMeshIndices = new Map<number, number[]>();\n let gpuIdx = 0;\n for (let ni = 0; ni < nodeCount; ni++) {\n const node = json.nodes[ni];\n if (node.mesh === undefined) {\n continue;\n }\n const mesh = json.meshes[node.mesh];\n const indices: number[] = [];\n for (let p = 0; p < mesh.primitives.length; p++) {\n indices.push(gpuIdx++);\n }\n nodeToMeshIndices.set(ni, indices);\n }\n\n const skeletons: SkeletonBinding[] = [];\n for (let nodeIdx = 0; nodeIdx < nodeCount; nodeIdx++) {\n const node = json.nodes[nodeIdx];\n if (node.skin === undefined || !json.skins) {\n continue;\n }\n\n const meshIndices = nodeToMeshIndices.get(nodeIdx);\n if (!meshIndices) {\n continue;\n }\n\n const skin = json.skins[node.skin];\n const jointNodes: number[] = skin.joints;\n const inverseBindMatrices = resolveIBMs(json, binChunk, skin);\n\n const meshWorldMatrix = computeNodeWorldMatrix(json, nodeIdx, parentMap, worldMatrixCache);\n const invMeshWorld = mat4Invert(meshWorldMatrix) ?? mat4Identity();\n\n // Create a binding for EACH mesh primitive of this skinned node\n for (const mi of meshIndices) {\n const mesh = meshes[mi];\n const skeleton = mesh?.skeleton;\n if (!skeleton) {\n continue;\n }\n skeletons.push({\n jointNodes,\n inverseBindMatrices,\n invMeshWorld,\n boneTexture: skeleton.boneTexture,\n boneCount: jointNodes.length,\n boneMatrices: skeleton.boneMatrices,\n runtimeSkeleton: skeleton,\n });\n }\n }\n\n // Build morph bindings (connect morph-target meshes to GPU weight buffers)\n const morphBindings: MorphBinding[] = [];\n for (let nodeIdx = 0; nodeIdx < nodeCount; nodeIdx++) {\n const node = json.nodes[nodeIdx];\n if (node.mesh === undefined) {\n continue;\n }\n const gltfMesh = json.meshes[node.mesh];\n if (!gltfMesh.primitives?.[0]?.targets?.length) {\n continue;\n }\n\n const meshIndices = nodeToMeshIndices.get(nodeIdx);\n if (!meshIndices) {\n continue;\n }\n\n for (const mi of meshIndices) {\n const mesh = meshes[mi];\n const morphTargets = mesh?.morphTargets;\n if (!morphTargets) {\n continue;\n }\n morphBindings.push({\n nodeIdx,\n weightsBuffer: morphTargets.weightsBuffer,\n weights: morphTargets.weights,\n targetCount: morphTargets.count,\n runtimeMorphTargets: morphTargets,\n });\n }\n }\n\n // Build the node-TRS writeback inputs. `nodeTargets` exposes each glTF node's\n // live scene node (via the structural AnimatedNodeTarget view) so the controller\n // can push evaluated local TRS back onto the scene graph, moving non-skinned\n // node-animated meshes and their descendants. `excludedNodeIndices` lists nodes\n // that MUST NOT be written: skin joints (driven by the skeleton path) plus\n // skinned-mesh nodes and all their ancestors — their bone matrices bake an\n // `invMeshWorld` captured at load, so moving them at runtime would\n // double-transform the skinned vertices.\n const nodeTargets: readonly (AnimatedNodeTarget | undefined)[] = (nodeMap as readonly (AnimatedNodeTarget | undefined)[] | undefined) ?? [];\n const excludedNodeIndices = new Set<number>();\n for (const skin of json.skins ?? []) {\n for (const ji of skin.joints ?? []) {\n excludedNodeIndices.add(ji);\n }\n }\n for (let ni = 0; ni < nodeCount; ni++) {\n if (json.nodes[ni]?.skin === undefined) {\n continue;\n }\n let p = ni;\n while (p >= 0 && !excludedNodeIndices.has(p)) {\n excludedNodeIndices.add(p);\n p = findParent(parentMap, p);\n }\n }\n\n if (\n clips.length === 0 ||\n (skeletons.length === 0 && morphBindings.length === 0 && pointerChannelCount === 0 && !hasWritableNodeChannel(clips, nodeTargets, excludedNodeIndices))\n ) {\n return null;\n }\n return { clips, nodes, skeletons, morphBindings, nodeTargets, excludedNodeIndices };\n}\n\n/** True if any clip animates a non-excluded node that has a live scene target —\n * i.e. there is at least one plain node-TRS channel the controller can write\n * back. Lets purely-skinned/morph/pointer assets short-circuit unchanged. */\nfunction hasWritableNodeChannel(clips: readonly AnimationClip[], nodeTargets: readonly (AnimatedNodeTarget | undefined)[], excludedNodeIndices: ReadonlySet<number>): boolean {\n for (const clip of clips) {\n for (const ch of clip.channels) {\n if (\n (ch.path === PATH_TRANSLATION || ch.path === PATH_ROTATION || ch.path === PATH_SCALE) &&\n ch.nodeIdx >= 0 &&\n !excludedNodeIndices.has(ch.nodeIdx) &&\n nodeTargets[ch.nodeIdx]\n ) {\n return true;\n }\n }\n }\n return false;\n}\n"],"names":[],"mappings":"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"}
@@ -1,204 +1,4 @@
1
- import { e as U8, bR as getCompressedFormat, T as TU, ax as acquireTexture, L as U8C, br as getOrCreateSampler, U as U32, r as resolveAccessor, D as DV, a as F32 } from "./index-CLElg2Bo.js";
2
- const KTX2_DECODER_URL = "https://cdn.babylonjs.com/babylon.ktx2Decoder.js";
3
- let _ktx2DecoderPromise = null;
4
- const GL_RGBA8 = 32856;
5
- const GL_R8 = 33321;
6
- const GL_RG8 = 33323;
7
- const RGBA_CAPS = { astc: false, bptc: false, s3tc: false, pvrtc: false, etc2: false, etc1: false };
8
- function loadKtx2Decoder() {
9
- if (_ktx2DecoderPromise) {
10
- return _ktx2DecoderPromise;
11
- }
12
- _ktx2DecoderPromise = new Promise((resolve, reject) => {
13
- const w = globalThis;
14
- const init = () => {
15
- const mod = w.KTX2DECODER;
16
- if (!mod) {
17
- reject(new Error("KTX2: decoder global KTX2DECODER not found after script load"));
18
- return;
19
- }
20
- mod.MSCTranscoder.UseFromWorkerThread = false;
21
- mod.WASMMemoryManager.LoadBinariesFromCurrentThread = true;
22
- resolve(new mod.KTX2Decoder());
23
- };
24
- if (w.KTX2DECODER) {
25
- init();
26
- return;
27
- }
28
- const script = document.createElement("script");
29
- script.src = KTX2_DECODER_URL;
30
- script.async = true;
31
- script.onload = init;
32
- script.onerror = () => reject(new Error(`KTX2: failed to load ${script.src}`));
33
- document.head.appendChild(script);
34
- });
35
- _ktx2DecoderPromise.catch(() => {
36
- _ktx2DecoderPromise = null;
37
- });
38
- return _ktx2DecoderPromise;
39
- }
40
- function srgbFormat(format) {
41
- switch (format) {
42
- case "rgba8unorm":
43
- return "rgba8unorm-srgb";
44
- case "bc1-rgba-unorm":
45
- return "bc1-rgba-unorm-srgb";
46
- case "bc2-rgba-unorm":
47
- return "bc2-rgba-unorm-srgb";
48
- case "bc3-rgba-unorm":
49
- return "bc3-rgba-unorm-srgb";
50
- case "bc7-rgba-unorm":
51
- return "bc7-rgba-unorm-srgb";
52
- case "etc2-rgb8unorm":
53
- return "etc2-rgb8unorm-srgb";
54
- case "etc2-rgb8a1unorm":
55
- return "etc2-rgb8a1unorm-srgb";
56
- case "etc2-rgba8unorm":
57
- return "etc2-rgba8unorm-srgb";
58
- case "astc-4x4-unorm":
59
- return "astc-4x4-unorm-srgb";
60
- case "astc-5x4-unorm":
61
- return "astc-5x4-unorm-srgb";
62
- case "astc-5x5-unorm":
63
- return "astc-5x5-unorm-srgb";
64
- case "astc-6x5-unorm":
65
- return "astc-6x5-unorm-srgb";
66
- case "astc-6x6-unorm":
67
- return "astc-6x6-unorm-srgb";
68
- case "astc-8x5-unorm":
69
- return "astc-8x5-unorm-srgb";
70
- case "astc-8x6-unorm":
71
- return "astc-8x6-unorm-srgb";
72
- case "astc-8x8-unorm":
73
- return "astc-8x8-unorm-srgb";
74
- case "astc-10x5-unorm":
75
- return "astc-10x5-unorm-srgb";
76
- case "astc-10x6-unorm":
77
- return "astc-10x6-unorm-srgb";
78
- case "astc-10x8-unorm":
79
- return "astc-10x8-unorm-srgb";
80
- case "astc-10x10-unorm":
81
- return "astc-10x10-unorm-srgb";
82
- case "astc-12x10-unorm":
83
- return "astc-12x10-unorm-srgb";
84
- case "astc-12x12-unorm":
85
- return "astc-12x12-unorm-srgb";
86
- default:
87
- return format;
88
- }
89
- }
90
- function uncompressedInfo(glFormat) {
91
- switch (glFormat) {
92
- case GL_RGBA8:
93
- return { format: "rgba8unorm", bytesPerPixel: 4 };
94
- case GL_R8:
95
- return { format: "r8unorm", bytesPerPixel: 1 };
96
- case GL_RG8:
97
- return { format: "rg8unorm", bytesPerPixel: 2 };
98
- default:
99
- return null;
100
- }
101
- }
102
- function validateDecoded(decoded) {
103
- var _a;
104
- if (decoded.errors) {
105
- throw new Error(`KTX2: ${decoded.errors}`);
106
- }
107
- if (!decoded.mipmaps.length) {
108
- throw new Error("KTX2: decoder produced no mipmaps");
109
- }
110
- for (let i = 0; i < decoded.mipmaps.length; i++) {
111
- if (!((_a = decoded.mipmaps[i]) == null ? void 0 : _a.data)) {
112
- throw new Error(`KTX2: decoder produced an empty mip ${i}`);
113
- }
114
- }
115
- return decoded.mipmaps;
116
- }
117
- function makeSampler(engine, mipCount) {
118
- return getOrCreateSampler(engine, {
119
- addressModeU: "repeat",
120
- addressModeV: "repeat",
121
- minFilter: "linear",
122
- magFilter: "linear",
123
- mipmapFilter: mipCount > 1 ? "linear" : "nearest",
124
- maxAnisotropy: mipCount > 1 ? 4 : 1
125
- });
126
- }
127
- function uploadCompressed(engine, mips, format, sRGB) {
128
- if (!engine._device.features.has(format.feature)) {
129
- throw new Error(`KTX2: device does not support ${format.feature}`);
130
- }
131
- const width = mips[0].width;
132
- const height = mips[0].height;
133
- const texture = engine._device.createTexture({
134
- size: { width, height },
135
- format: sRGB ? srgbFormat(format.gpuFormat) : format.gpuFormat,
136
- mipLevelCount: mips.length,
137
- usage: TU.TEXTURE_BINDING | TU.COPY_DST
138
- });
139
- for (let level = 0; level < mips.length; level++) {
140
- const mip = mips[level];
141
- const blocksPerRow = Math.ceil(mip.width / format.blockW);
142
- const rowBytes = blocksPerRow * format.blockBytes;
143
- const copyW = blocksPerRow * format.blockW;
144
- const copyH = Math.ceil(mip.height / format.blockH) * format.blockH;
145
- engine._device.queue.writeTexture({ texture, mipLevel: level }, mip.data, { bytesPerRow: rowBytes }, { width: copyW, height: copyH });
146
- }
147
- const tex2d = { texture, view: texture.createView(), sampler: makeSampler(engine, mips.length), width, height, invertY: true };
148
- acquireTexture(tex2d);
149
- return tex2d;
150
- }
151
- function uploadUncompressed(engine, mips, info, sRGB) {
152
- const width = mips[0].width;
153
- const height = mips[0].height;
154
- const texture = engine._device.createTexture({
155
- size: { width, height },
156
- format: sRGB ? srgbFormat(info.format) : info.format,
157
- mipLevelCount: mips.length,
158
- usage: TU.TEXTURE_BINDING | TU.COPY_DST
159
- });
160
- for (let level = 0; level < mips.length; level++) {
161
- const mip = mips[level];
162
- const expected = mip.width * mip.height * info.bytesPerPixel;
163
- if (mip.data.length !== expected) {
164
- throw new Error(`KTX2: uncompressed mip ${level} has ${mip.data.length} bytes, expected ${expected}`);
165
- }
166
- engine._device.queue.writeTexture(
167
- { texture, mipLevel: level },
168
- mip.data,
169
- { bytesPerRow: mip.width * info.bytesPerPixel },
170
- { width: mip.width, height: mip.height }
171
- );
172
- }
173
- const tex2d = { texture, view: texture.createView(), sampler: makeSampler(engine, mips.length), width, height, invertY: true };
174
- acquireTexture(tex2d);
175
- return tex2d;
176
- }
177
- async function uploadKtx2Texture2D(engine, buffer, sRGB) {
178
- const decoder = await loadKtx2Decoder();
179
- const decoded = await decoder.decode(new U8(buffer), RGBA_CAPS, { forceRGBA: true });
180
- const mips = validateDecoded(decoded);
181
- const compressed = getCompressedFormat(decoded.transcodedFormat);
182
- if (compressed) {
183
- return uploadCompressed(engine, mips, compressed, sRGB);
184
- }
185
- const uncompressed = uncompressedInfo(decoded.transcodedFormat);
186
- if (uncompressed) {
187
- return uploadUncompressed(engine, mips, uncompressed, sRGB);
188
- }
189
- throw new Error(`KTX2: unsupported transcoded format 0x${decoded.transcodedFormat.toString(16)}`);
190
- }
191
- async function decodeKtx2ImageBitmapFromBuffer(buffer) {
192
- const decoder = await loadKtx2Decoder();
193
- const decoded = await decoder.decode(new U8(buffer), RGBA_CAPS, { forceRGBA: true });
194
- const mip0 = validateDecoded(decoded)[0];
195
- if (mip0.data.length !== mip0.width * mip0.height * 4) {
196
- throw new Error("KTX2: RGBA decode size does not match image dimensions");
197
- }
198
- const pixels = new U8C(mip0.data.length);
199
- pixels.set(mip0.data);
200
- return createImageBitmap(new ImageData(pixels, mip0.width, mip0.height));
201
- }
1
+ import { U as U32, r as resolveAccessor, ba as uploadKtx2Texture2D, D as DV, a as F32, e as U8, bb as decodeKtx2ImageBitmapFromBuffer } from "./index-BgY3QEzL.js";
202
2
  const NAME = "KHR_texture_basisu";
203
3
  const FLOAT = 5126;
204
4
  const COMPONENT_BYTES = { 5120: 1, 5121: 1, 5122: 2, 5123: 2, 5125: 4, 5126: 4 };
@@ -484,4 +284,4 @@ const ext = {
484
284
  export {
485
285
  ext as default
486
286
  };
487
- //# sourceMappingURL=gltf-ext-basisu-CDbPclzZ.js.map
287
+ //# sourceMappingURL=gltf-ext-basisu-DtzVV1Xx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gltf-ext-basisu-DtzVV1Xx.js","sources":["../src/loader-gltf/gltf-ext-basisu.ts"],"sourcesContent":["/** KHR_texture_basisu glTF texture-source extension.\n *\n * The extension redirects textureInfos whose glTF texture declares\n * `extensions.KHR_texture_basisu.source` to the referenced KTX2 image and\n * uploads it through the lazily fetched KTX2 decoder. Core glTF\n * material parsing remains extension-agnostic: this module only loads when the\n * asset lists KHR_texture_basisu in `extensionsUsed`.\n */\n\nimport { F32, U32, U8, DV } from \"../engine/typed-arrays.js\";\nimport type { GltfMatExtCtx } from \"./gltf-material.js\";\nimport type { GltfFeature } from \"./gltf-feature.js\";\nimport type { DecodedPrimitive } from \"./gltf-feature.js\";\nimport type { PbrMaterialProps } from \"../material/pbr/pbr-material.js\";\nimport type { Texture2D } from \"../texture/texture-2d.js\";\nimport { resolveAccessor } from \"./gltf-parser.js\";\nimport { decodeKtx2ImageBitmapFromBuffer, uploadKtx2Texture2D } from \"../texture/ktx2-loader.js\";\n\nconst NAME = \"KHR_texture_basisu\";\nconst FLOAT = 5126;\n// glTF accessor component types → byte size. Interleaved (strided) vertex attributes can be any of these,\n// not just FLOAT (e.g. a normalized `COLOR_0: UNSIGNED_BYTE`), so the strided reader must handle them all.\nconst COMPONENT_BYTES: Record<number, number> = { 5120: 1, 5121: 1, 5122: 2, 5123: 2, 5125: 4, 5126: 4 };\nconst TYPE_SIZES: Record<string, number> = {\n SCALAR: 1,\n VEC2: 2,\n VEC3: 3,\n VEC4: 4,\n MAT2: 4,\n MAT3: 9,\n MAT4: 16,\n};\nconst BASISU_MATERIAL_DATA = \"__basisuMaterialData\";\n\ninterface BasisuMaterialData {\n json: any;\n binChunk: DataView;\n baseUrl: string;\n baseColorTexture?: any;\n metallicRoughnessTexture?: any;\n normalTexture?: any;\n occlusionTexture?: any;\n emissiveTexture?: any;\n specularTexture?: any;\n specularColorTexture?: any;\n bitmaps?: Map<number, Promise<ImageBitmap>>;\n textures?: Map<string, Texture2D>;\n}\n\nfunction basisSourceIndex(tex: unknown): number | null {\n const source = (tex as { extensions?: { KHR_texture_basisu?: { source?: unknown } } } | undefined)?.extensions?.KHR_texture_basisu?.source;\n return typeof source === \"number\" ? source : null;\n}\n\nfunction textureIndex(texInfo: unknown): number | null {\n const index = (texInfo as { index?: unknown } | undefined)?.index;\n return typeof index === \"number\" ? index : null;\n}\n\nfunction textureUsesBasisu(json: any, texInfo: unknown): boolean {\n const index = textureIndex(texInfo);\n return index !== null && basisSourceIndex(json.textures?.[index]) !== null;\n}\n\nfunction stripBasisuTexture(json: any, owner: any, slot: keyof BasisuMaterialData, data: BasisuMaterialData): boolean {\n if (!textureUsesBasisu(json, owner?.[slot])) {\n return false;\n }\n data[slot] = owner[slot];\n delete owner[slot];\n return true;\n}\n\nfunction prepareBasisuMaterials(json: any, binChunk: DataView, baseUrl: string): void {\n for (const mat of json.materials ?? []) {\n const data: BasisuMaterialData = { json, binChunk, baseUrl };\n const pbr = mat.pbrMetallicRoughness ?? {};\n let hasBasisu = stripBasisuTexture(json, pbr, \"baseColorTexture\", data);\n hasBasisu = stripBasisuTexture(json, pbr, \"metallicRoughnessTexture\", data) || hasBasisu;\n hasBasisu = stripBasisuTexture(json, mat, \"normalTexture\", data) || hasBasisu;\n hasBasisu = stripBasisuTexture(json, mat, \"occlusionTexture\", data) || hasBasisu;\n hasBasisu = stripBasisuTexture(json, mat, \"emissiveTexture\", data) || hasBasisu;\n const spec = mat.extensions?.KHR_materials_specular;\n if (spec) {\n hasBasisu = stripBasisuTexture(json, spec, \"specularTexture\", data) || hasBasisu;\n hasBasisu = stripBasisuTexture(json, spec, \"specularColorTexture\", data) || hasBasisu;\n }\n if (hasBasisu) {\n Object.defineProperty(mat, BASISU_MATERIAL_DATA, { value: data });\n }\n }\n}\n\nasync function resolveImageBuffer(ctx: BasisuMaterialData, imageIdx: number): Promise<ArrayBuffer> {\n const image = ctx.json.images?.[imageIdx];\n if (!image) {\n throw new Error(`${NAME}: image ${imageIdx} not found`);\n }\n if (image.bufferView !== undefined) {\n const bv = ctx.json.bufferViews?.[image.bufferView];\n if (!bv) {\n throw new Error(`${NAME}: bufferView ${image.bufferView} not found`);\n }\n const offset = ctx.binChunk.byteOffset + (bv.byteOffset ?? 0);\n const copy = new U8(bv.byteLength);\n copy.set(new U8(ctx.binChunk.buffer, offset, bv.byteLength));\n return copy.buffer;\n }\n if (image.uri) {\n const url = new URL(image.uri, ctx.baseUrl + \"x\").href;\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`${NAME}: failed to load image ${response.status} ${response.statusText}`);\n }\n return response.arrayBuffer();\n }\n throw new Error(`${NAME}: image has neither bufferView nor uri`);\n}\n\nasync function loadBasisuBitmap(data: BasisuMaterialData, texInfo: unknown): Promise<ImageBitmap | null> {\n const index = textureIndex(texInfo);\n if (index === null) {\n return null;\n }\n const source = basisSourceIndex(data.json.textures?.[index]);\n if (source === null) {\n return null;\n }\n data.bitmaps ??= new Map();\n let bitmap = data.bitmaps.get(index);\n if (!bitmap) {\n bitmap = resolveImageBuffer(data, source).then(decodeKtx2ImageBitmapFromBuffer);\n data.bitmaps.set(index, bitmap);\n }\n return bitmap;\n}\n\nasync function uploadBasisuTexture(data: BasisuMaterialData, ctx: GltfMatExtCtx, texInfo: unknown, sRGB: boolean): Promise<Texture2D | undefined> {\n const index = textureIndex(texInfo);\n if (index === null) {\n return undefined;\n }\n data.textures ??= new Map();\n const key = `${index}:${sRGB ? 1 : 0}`;\n let tex = data.textures.get(key);\n if (!tex) {\n const source = basisSourceIndex(data.json.textures?.[index]);\n if (source === null) {\n return undefined;\n }\n tex = await uploadKtx2Texture2D(ctx._engine, await resolveImageBuffer(data, source), sRGB);\n data.textures.set(key, tex);\n }\n return tex;\n}\n\nasync function compositeOrm(mr: ImageBitmap, occ: ImageBitmap): Promise<ImageBitmap> {\n const w = mr.width;\n const h = mr.height;\n const c1 = new OffscreenCanvas(w, h);\n const x1 = c1.getContext(\"2d\")!;\n x1.drawImage(mr, 0, 0, w, h);\n const d1 = x1.getImageData(0, 0, w, h);\n const c2 = new OffscreenCanvas(w, h);\n const x2 = c2.getContext(\"2d\")!;\n x2.drawImage(occ, 0, 0, w, h);\n const d2 = x2.getImageData(0, 0, w, h);\n for (let j = 0; j < d1.data.length; j += 4) {\n d1.data[j] = d2.data[j]!;\n }\n x1.putImageData(d1, 0, 0);\n return createImageBitmap(c1);\n}\n\nasync function uploadOrmTexture(data: BasisuMaterialData, ctx: GltfMatExtCtx): Promise<Texture2D | undefined> {\n const mrInfo = data.metallicRoughnessTexture;\n const occInfo = data.occlusionTexture;\n const mrIndex = textureIndex(mrInfo);\n const occIndex = textureIndex(occInfo);\n if (mrIndex === null && occIndex === null) {\n return undefined;\n }\n if (mrIndex === null || occIndex === null || mrIndex === occIndex) {\n return uploadBasisuTexture(data, ctx, mrInfo ?? occInfo, false);\n }\n data.textures ??= new Map();\n const key = `orm:${mrIndex}:${occIndex}`;\n let tex = data.textures.get(key);\n if (!tex) {\n const [mr, occ] = await Promise.all([loadBasisuBitmap(data, mrInfo), loadBasisuBitmap(data, occInfo)]);\n if (!mr || !occ) {\n return undefined;\n }\n tex = ctx._uploadImage(await compositeOrm(mr, occ), false);\n data.textures.set(key, tex);\n }\n return tex;\n}\n\n// Read one interleaved attribute component, decoding its glTF component type to a float. NORMALIZED integer\n// attributes (the `normalized` accessor flag) map to [0,1] (unsigned) or [-1,1] (signed); non-normalized ones\n// pass through as their integer value. DataView handles unaligned little-endian reads, so any stride is fine.\nfunction readComponent(view: DataView, offset: number, componentType: number, normalized: boolean): number {\n switch (componentType) {\n case FLOAT:\n return view.getFloat32(offset, true);\n case 5125: {\n const v = view.getUint32(offset, true);\n return normalized ? v / 4294967295 : v;\n }\n case 5123: {\n const v = view.getUint16(offset, true);\n return normalized ? v / 65535 : v;\n }\n case 5122: {\n const v = view.getInt16(offset, true);\n return normalized ? Math.max(v / 32767, -1) : v;\n }\n case 5121: {\n const v = view.getUint8(offset);\n return normalized ? v / 255 : v;\n }\n case 5120: {\n const v = view.getInt8(offset);\n return normalized ? Math.max(v / 127, -1) : v;\n }\n default:\n throw new Error(`${NAME}: strided accessor uses unsupported component type: ${componentType}`);\n }\n}\n\nfunction readStridedFloat(json: any, binChunk: DataView, accessorIdx: number): Float32Array {\n const accessor = json.accessors[accessorIdx];\n const bufferView = json.bufferViews[accessor.bufferView];\n const componentType = accessor.componentType;\n const compBytes = COMPONENT_BYTES[componentType];\n if (!compBytes) {\n throw new Error(`${NAME}: strided accessor ${accessorIdx} uses unsupported component type: ${componentType}`);\n }\n const componentCount = TYPE_SIZES[accessor.type] ?? 1;\n const elementBytes = componentCount * compBytes;\n const byteStride = bufferView.byteStride ?? elementBytes;\n if (byteStride < elementBytes) {\n throw new Error(`${NAME}: invalid accessor stride ${byteStride} for accessor ${accessorIdx}`);\n }\n const normalized = accessor.normalized === true;\n const baseOffset = binChunk.byteOffset + (bufferView.byteOffset ?? 0) + (accessor.byteOffset ?? 0);\n const view = new DV(binChunk.buffer);\n const out = new F32(accessor.count * componentCount);\n for (let i = 0, o = 0; i < accessor.count; i++) {\n const src = baseOffset + i * byteStride;\n for (let c = 0; c < componentCount; c++, o++) {\n out[o] = readComponent(view, src + c * compBytes, componentType, normalized);\n }\n }\n return out;\n}\n\nconst ext: GltfFeature = {\n id: NAME,\n async preMesh(json, binChunk, baseUrl) {\n const gltf = json as any;\n prepareBasisuMaterials(gltf, binChunk, baseUrl);\n const decoded = new Map<unknown, DecodedPrimitive>();\n for (const mesh of gltf.meshes ?? []) {\n for (const primitive of mesh.primitives ?? []) {\n const attrs = primitive.attributes ?? {};\n const strided = Object.keys(attrs).some((name) => gltf.bufferViews?.[gltf.accessors?.[attrs[name]]?.bufferView]?.byteStride !== undefined);\n if (!strided) {\n continue;\n }\n const attributes = new Map<string, Float32Array>();\n for (const name of Object.keys(attrs)) {\n const accessorIdx = attrs[name];\n const accessor = gltf.accessors[accessorIdx];\n if (gltf.bufferViews?.[accessor.bufferView]?.byteStride !== undefined) {\n attributes.set(name, readStridedFloat(gltf, binChunk, accessorIdx));\n }\n }\n const posAcc = gltf.accessors[attrs.POSITION];\n const idx =\n primitive.indices === undefined ? new U32(0) : new U32(resolveAccessor(gltf, binChunk, primitive.indices)._data as Uint16Array | Uint32Array | Uint8Array);\n decoded.set(primitive, {\n _attributes: attributes,\n _indices: idx,\n _vertexCount: posAcc.count,\n _indexCount: idx.length,\n });\n }\n }\n return decoded;\n },\n async applyMaterial(mat, ctx) {\n const data = mat._rawMatDef?.[BASISU_MATERIAL_DATA] as BasisuMaterialData | undefined;\n if (!data) {\n return null;\n }\n const [baseColorTexture, ormTexture, normalTexture, emissiveTexture, specularTexture, specularColorTexture] = await Promise.all([\n uploadBasisuTexture(data, ctx, data.baseColorTexture, true),\n uploadOrmTexture(data, ctx),\n uploadBasisuTexture(data, ctx, data.normalTexture, false),\n uploadBasisuTexture(data, ctx, data.emissiveTexture, true),\n uploadBasisuTexture(data, ctx, data.specularTexture, false),\n uploadBasisuTexture(data, ctx, data.specularColorTexture, true),\n ]);\n const out: Partial<PbrMaterialProps> = {\n ...(baseColorTexture ? { baseColorTexture } : undefined),\n ...(ormTexture\n ? {\n ormTexture,\n ...(data.metallicRoughnessTexture ? { metallicFactor: mat._metallicFactor, roughnessFactor: mat._roughnessFactor } : undefined),\n ...(data.occlusionTexture ? { occlusionStrength: 1.0, occlusionTexCoord: data.occlusionTexture.texCoord ?? 0 } : undefined),\n }\n : undefined),\n ...(normalTexture ? { normalTexture, normalTextureScale: data.normalTexture?.scale ?? 1 } : undefined),\n ...(emissiveTexture ? { emissiveTexture } : undefined),\n ...(specularTexture ? { metallicReflectanceTexture: specularTexture, useOnlyMetallicFromMetallicReflectanceTexture: true } : undefined),\n ...(specularColorTexture ? { reflectanceTexture: specularColorTexture } : undefined),\n };\n if (!out.baseColorTexture && !out.ormTexture && !out.normalTexture && !out.emissiveTexture && !out.metallicReflectanceTexture && !out.reflectanceTexture) {\n return null;\n }\n return out;\n },\n};\n\nexport default ext;\n"],"names":["_b","_a"],"mappings":"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"}