@npm9912/v-map 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (438) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +185 -0
  3. package/dist/cjs/_commonjsHelpers-B83fTs8d.js +36 -0
  4. package/dist/cjs/app-globals-V2Kpy_OQ.js +5 -0
  5. package/dist/cjs/cesium-provider-BiFFyAl9.js +2598 -0
  6. package/dist/cjs/deck-provider-Ctq3Q8a1.js +47824 -0
  7. package/dist/cjs/geotiff-CEwvF9cG.js +47 -0
  8. package/dist/cjs/geotiff-source-RaNzzWkC.js +1522 -0
  9. package/dist/cjs/index-B1oGO1g-.js +10658 -0
  10. package/dist/cjs/index-B8LHqjyg.js +1765 -0
  11. package/dist/cjs/index-BIL4VsgP.js +310 -0
  12. package/dist/cjs/index-Blku2QY8.js +167 -0
  13. package/dist/cjs/index-CJvvX4yx.js +21 -0
  14. package/dist/cjs/index-CbVT-Con.js +699 -0
  15. package/dist/cjs/index-ISOEpMC3.js +20478 -0
  16. package/dist/cjs/index-JSwBbvGA.js +1621 -0
  17. package/dist/cjs/index.browser-DQhD8Jwl.js +6873 -0
  18. package/dist/cjs/index.cjs.js +2 -0
  19. package/dist/cjs/layer-extension-B_olS0rc.js +65 -0
  20. package/dist/cjs/leaflet-provider-DOqfs7g5.js +1815 -0
  21. package/dist/cjs/loader.cjs.js +13 -0
  22. package/dist/cjs/main-dist-7TykwFci.js +2655 -0
  23. package/dist/cjs/messages-D7h4m8Tx.js +186 -0
  24. package/dist/cjs/openlayers-provider-Dfeg6L4n.js +1604 -0
  25. package/dist/cjs/polygon-layer-B9PrN7vr.js +1300 -0
  26. package/dist/cjs/scenegraph-layer-DwNoxQdi.js +2530 -0
  27. package/dist/cjs/styleconfig-CVRqArk-.js +23 -0
  28. package/dist/cjs/v-map-builder.cjs.entry.js +3786 -0
  29. package/dist/cjs/v-map-layer-geojson_12.cjs.entry.js +40894 -0
  30. package/dist/cjs/v-map-layer-helper-iAzxAg9I.js +285 -0
  31. package/dist/cjs/v-map-layer-terrain-geotiff.cjs.entry.js +258 -0
  32. package/dist/cjs/v-map-layercontrol.cjs.entry.js +247 -0
  33. package/dist/cjs/v-map.cjs.js +25 -0
  34. package/dist/cjs/v-map.v-map-layer-osm.v-map-layergroup-BsXp3BoL.js +582 -0
  35. package/dist/cjs/v-map_3.cjs.entry.js +12 -0
  36. package/dist/collection/collection-manifest.json +30 -0
  37. package/dist/collection/components/v-map/v-map.css +3 -0
  38. package/dist/collection/components/v-map/v-map.js +467 -0
  39. package/dist/collection/components/v-map/v-map.test.js +33 -0
  40. package/dist/collection/components/v-map-builder/v-map-builder.css +1 -0
  41. package/dist/collection/components/v-map-builder/v-map-builder.js +913 -0
  42. package/dist/collection/components/v-map-builder/v-map-builder.test.js +56 -0
  43. package/dist/collection/components/v-map-layer-geojson/v-map-layer-geojson.js +862 -0
  44. package/dist/collection/components/v-map-layer-geojson/v-map-layer-geojson.test.js +42 -0
  45. package/dist/collection/components/v-map-layer-geotiff/v-map-layer-geotiff.css +4 -0
  46. package/dist/collection/components/v-map-layer-geotiff/v-map-layer-geotiff.js +500 -0
  47. package/dist/collection/components/v-map-layer-geotiff/v-map-layer-geotiff.test.js +38 -0
  48. package/dist/collection/components/v-map-layer-google/v-map-layer-google.css +1 -0
  49. package/dist/collection/components/v-map-layer-google/v-map-layer-google.js +442 -0
  50. package/dist/collection/components/v-map-layer-osm/error-api.test.js +108 -0
  51. package/dist/collection/components/v-map-layer-osm/v-map-layer-osm.css +4 -0
  52. package/dist/collection/components/v-map-layer-osm/v-map-layer-osm.js +311 -0
  53. package/dist/collection/components/v-map-layer-osm/v-map-layer-osm.test.js +36 -0
  54. package/dist/collection/components/v-map-layer-scatterplot/v-map-layer-scatterplot.css +1 -0
  55. package/dist/collection/components/v-map-layer-scatterplot/v-map-layer-scatterplot.js +305 -0
  56. package/dist/collection/components/v-map-layer-terrain/v-map-layer-terrain.css +3 -0
  57. package/dist/collection/components/v-map-layer-terrain/v-map-layer-terrain.js +548 -0
  58. package/dist/collection/components/v-map-layer-terrain/v-map-layer-terrain.test.js +36 -0
  59. package/dist/collection/components/v-map-layer-terrain-geotiff/v-map-layer-terrain-geotiff.css +3 -0
  60. package/dist/collection/components/v-map-layer-terrain-geotiff/v-map-layer-terrain-geotiff.js +735 -0
  61. package/dist/collection/components/v-map-layer-terrain-geotiff/v-map-layer-terrain-geotiff.test.js +42 -0
  62. package/dist/collection/components/v-map-layer-tile3d/v-map-layer-tile3d.css +3 -0
  63. package/dist/collection/components/v-map-layer-tile3d/v-map-layer-tile3d.js +449 -0
  64. package/dist/collection/components/v-map-layer-tile3d/v-map-layer-tile3d.test.js +50 -0
  65. package/dist/collection/components/v-map-layer-wcs/v-map-layer-wcs.css +1 -0
  66. package/dist/collection/components/v-map-layer-wcs/v-map-layer-wcs.js +448 -0
  67. package/dist/collection/components/v-map-layer-wcs/v-map-layer-wcs.test.js +39 -0
  68. package/dist/collection/components/v-map-layer-wfs/v-map-layer-wfs.css +1 -0
  69. package/dist/collection/components/v-map-layer-wfs/v-map-layer-wfs.js +489 -0
  70. package/dist/collection/components/v-map-layer-wfs/v-map-layer-wfs.test.js +43 -0
  71. package/dist/collection/components/v-map-layer-wkt/v-map-layer-wkt.css +1 -0
  72. package/dist/collection/components/v-map-layer-wkt/v-map-layer-wkt.js +811 -0
  73. package/dist/collection/components/v-map-layer-wkt/v-map-layer-wkt.test.js +34 -0
  74. package/dist/collection/components/v-map-layer-wms/v-map-layer-wms.css +1 -0
  75. package/dist/collection/components/v-map-layer-wms/v-map-layer-wms.js +453 -0
  76. package/dist/collection/components/v-map-layer-wms/v-map-layer-wms.test.js +36 -0
  77. package/dist/collection/components/v-map-layer-xyz/v-map-layer-xyz.css +1 -0
  78. package/dist/collection/components/v-map-layer-xyz/v-map-layer-xyz.js +331 -0
  79. package/dist/collection/components/v-map-layer-xyz/v-map-layer-xyz.test.js +28 -0
  80. package/dist/collection/components/v-map-layercontrol/v-map-layercontrol.css +74 -0
  81. package/dist/collection/components/v-map-layercontrol/v-map-layercontrol.js +277 -0
  82. package/dist/collection/components/v-map-layercontrol/v-map-layercontrol.test.js +134 -0
  83. package/dist/collection/components/v-map-layergroup/v-map-layergroup.css +4 -0
  84. package/dist/collection/components/v-map-layergroup/v-map-layergroup.js +212 -0
  85. package/dist/collection/components/v-map-layergroup/v-map-layergroup.test.js +39 -0
  86. package/dist/collection/components/v-map-style/v-map-style.css +38 -0
  87. package/dist/collection/components/v-map-style/v-map-style.js +492 -0
  88. package/dist/collection/components/v-map-style/v-map-style.unit.js +62 -0
  89. package/dist/collection/index.js +1 -0
  90. package/dist/collection/layer/v-map-layer-helper.js +281 -0
  91. package/dist/collection/layer/v-map-layer-helper.unit.js +234 -0
  92. package/dist/collection/lib/cesium-loader.js +58 -0
  93. package/dist/collection/lib/ensure-importmap.js +12 -0
  94. package/dist/collection/lib/ensure-importmap.unit.js +57 -0
  95. package/dist/collection/lib/versions.gen.js +6 -0
  96. package/dist/collection/lib/vstyle.js +8 -0
  97. package/dist/collection/map-provider/cesium/CesiumGeoTIFFTerrainProvider.js +285 -0
  98. package/dist/collection/map-provider/cesium/CesiumLayerGroups.js +159 -0
  99. package/dist/collection/map-provider/cesium/GeoTIFFImageryProvider.js +192 -0
  100. package/dist/collection/map-provider/cesium/GeoTIFFImageryProvider.test.js +57 -0
  101. package/dist/collection/map-provider/cesium/cesium-provider.js +1408 -0
  102. package/dist/collection/map-provider/cesium/i-layer.js +1 -0
  103. package/dist/collection/map-provider/cesium/layer-manager.js +467 -0
  104. package/dist/collection/map-provider/deck/DeckGLGeoTIFFLayer.js +483 -0
  105. package/dist/collection/map-provider/deck/DeckGLGeoTIFFTerrainLayer.js +410 -0
  106. package/dist/collection/map-provider/deck/LayerGroupWithModel.js +169 -0
  107. package/dist/collection/map-provider/deck/LayerGroups.js +192 -0
  108. package/dist/collection/map-provider/deck/LayerModel.js +1 -0
  109. package/dist/collection/map-provider/deck/RenderableGroup.js +1 -0
  110. package/dist/collection/map-provider/deck/deck-provider.js +1563 -0
  111. package/dist/collection/map-provider/geotiff/geotiff-source.js +172 -0
  112. package/dist/collection/map-provider/geotiff/utils/AABB2D.js +24 -0
  113. package/dist/collection/map-provider/geotiff/utils/BVHNode2D.js +166 -0
  114. package/dist/collection/map-provider/geotiff/utils/GeoTIFFTileProcessor.js +484 -0
  115. package/dist/collection/map-provider/geotiff/utils/Triangle.js +1 -0
  116. package/dist/collection/map-provider/geotiff/utils/Triangulation.js +321 -0
  117. package/dist/collection/map-provider/geotiff/utils/colormap-utils.js +190 -0
  118. package/dist/collection/map-provider/geotiff/utils/normalization-utils.js +122 -0
  119. package/dist/collection/map-provider/geotiff/utils/sampling-utils.js +108 -0
  120. package/dist/collection/map-provider/leaflet/GeoTIFFGridLayer.js +147 -0
  121. package/dist/collection/map-provider/leaflet/WCSGridLayer.js +124 -0
  122. package/dist/collection/map-provider/leaflet/google-map-tiles-layer.js +352 -0
  123. package/dist/collection/map-provider/leaflet/leaflet-helpers.js +94 -0
  124. package/dist/collection/map-provider/leaflet/leaflet-provider.js +1095 -0
  125. package/dist/collection/map-provider/ol/CustomGeoTiff.js +145 -0
  126. package/dist/collection/map-provider/ol/openlayers-helper.js +26 -0
  127. package/dist/collection/map-provider/ol/openlayers-provider.js +1427 -0
  128. package/dist/collection/map-provider/provider-factory.js +44 -0
  129. package/dist/collection/map-provider/provider-factory.unit.js +66 -0
  130. package/dist/collection/testing/browser-test-utils.js +49 -0
  131. package/dist/collection/testing/e2e-testing.js +122 -0
  132. package/dist/collection/testing/e2e-utils.js +70 -0
  133. package/dist/collection/testing/geotiff-test-server.js +100 -0
  134. package/dist/collection/testing/mocks/geostyler-lyrx-parser.js +12 -0
  135. package/dist/collection/testing/mocks/geostyler-mapbox-parser.js +12 -0
  136. package/dist/collection/testing/mocks/geostyler-qgis-parser.js +12 -0
  137. package/dist/collection/testing/mocks/geostyler-sld-parser.js +13 -0
  138. package/dist/collection/testing/mocks/geostyler-style.js +5 -0
  139. package/dist/collection/testing/setupTests.browser.js +1 -0
  140. package/dist/collection/testing/setupTests.stencil.js +20 -0
  141. package/dist/collection/testing/setupTests.vitest.js +59 -0
  142. package/dist/collection/testing/stencil-testing-wrapper.js +43 -0
  143. package/dist/collection/testing/styleMock.js +1 -0
  144. package/dist/collection/types/color.js +1 -0
  145. package/dist/collection/types/cssmode.js +1 -0
  146. package/dist/collection/types/flavour.js +1 -0
  147. package/dist/collection/types/layerconfig.js +1 -0
  148. package/dist/collection/types/lonlat.js +1 -0
  149. package/dist/collection/types/mapinitoptions.js +1 -0
  150. package/dist/collection/types/mapprovider.js +1 -0
  151. package/dist/collection/types/provideroptions.js +1 -0
  152. package/dist/collection/types/styleconfig.js +19 -0
  153. package/dist/collection/types/styling.js +13 -0
  154. package/dist/collection/types/styling.unit.js +37 -0
  155. package/dist/collection/types/vmaplayer.js +1 -0
  156. package/dist/collection/utils/async-mutex.js +28 -0
  157. package/dist/collection/utils/diff.js +142 -0
  158. package/dist/collection/utils/diff.unit.js +59 -0
  159. package/dist/collection/utils/dom-env.js +43 -0
  160. package/dist/collection/utils/dom-env.unit.js +92 -0
  161. package/dist/collection/utils/events.js +8 -0
  162. package/dist/collection/utils/logger.js +183 -0
  163. package/dist/collection/utils/logger.unit.js +98 -0
  164. package/dist/collection/utils/messages.js +12 -0
  165. package/dist/collection/utils/spatial-utils.js +27 -0
  166. package/dist/collection/utils/spatial-utils.unit.js +24 -0
  167. package/dist/components/_commonjsHelpers.js +1 -0
  168. package/dist/components/cesium-provider.js +1 -0
  169. package/dist/components/deck-provider.js +1 -0
  170. package/dist/components/events.js +1 -0
  171. package/dist/components/geotiff-source.js +1 -0
  172. package/dist/components/geotiff.js +4 -0
  173. package/dist/components/index.browser.js +15 -0
  174. package/dist/components/index.d.ts +35 -0
  175. package/dist/components/index.js +1 -0
  176. package/dist/components/index2.js +1 -0
  177. package/dist/components/index3.js +1 -0
  178. package/dist/components/index4.js +1 -0
  179. package/dist/components/index5.js +1 -0
  180. package/dist/components/index6.js +1 -0
  181. package/dist/components/index7.js +1 -0
  182. package/dist/components/index8.js +7 -0
  183. package/dist/components/layer-extension.js +1 -0
  184. package/dist/components/leaflet-provider.js +1 -0
  185. package/dist/components/main-dist.js +1 -0
  186. package/dist/components/messages.js +1 -0
  187. package/dist/components/openlayers-provider.js +1 -0
  188. package/dist/components/polygon-layer.js +1 -0
  189. package/dist/components/scenegraph-layer.js +1 -0
  190. package/dist/components/styleconfig.js +1 -0
  191. package/dist/components/styling.js +1 -0
  192. package/dist/components/v-map-builder.d.ts +11 -0
  193. package/dist/components/v-map-builder.js +2 -0
  194. package/dist/components/v-map-layer-geojson.d.ts +11 -0
  195. package/dist/components/v-map-layer-geojson.js +1 -0
  196. package/dist/components/v-map-layer-geojson2.js +1 -0
  197. package/dist/components/v-map-layer-geotiff.d.ts +11 -0
  198. package/dist/components/v-map-layer-geotiff.js +1 -0
  199. package/dist/components/v-map-layer-geotiff2.js +1 -0
  200. package/dist/components/v-map-layer-google.d.ts +11 -0
  201. package/dist/components/v-map-layer-google.js +1 -0
  202. package/dist/components/v-map-layer-google2.js +1 -0
  203. package/dist/components/v-map-layer-helper.js +1 -0
  204. package/dist/components/v-map-layer-osm.d.ts +11 -0
  205. package/dist/components/v-map-layer-osm.js +1 -0
  206. package/dist/components/v-map-layer-osm2.js +1 -0
  207. package/dist/components/v-map-layer-scatterplot.d.ts +11 -0
  208. package/dist/components/v-map-layer-scatterplot.js +1 -0
  209. package/dist/components/v-map-layer-scatterplot2.js +1 -0
  210. package/dist/components/v-map-layer-terrain-geotiff.d.ts +11 -0
  211. package/dist/components/v-map-layer-terrain-geotiff.js +1 -0
  212. package/dist/components/v-map-layer-terrain.d.ts +11 -0
  213. package/dist/components/v-map-layer-terrain.js +1 -0
  214. package/dist/components/v-map-layer-terrain2.js +1 -0
  215. package/dist/components/v-map-layer-tile3d.d.ts +11 -0
  216. package/dist/components/v-map-layer-tile3d.js +1 -0
  217. package/dist/components/v-map-layer-tile3d2.js +1 -0
  218. package/dist/components/v-map-layer-wcs.d.ts +11 -0
  219. package/dist/components/v-map-layer-wcs.js +1 -0
  220. package/dist/components/v-map-layer-wcs2.js +1 -0
  221. package/dist/components/v-map-layer-wfs.d.ts +11 -0
  222. package/dist/components/v-map-layer-wfs.js +1 -0
  223. package/dist/components/v-map-layer-wfs2.js +1 -0
  224. package/dist/components/v-map-layer-wkt.d.ts +11 -0
  225. package/dist/components/v-map-layer-wkt.js +1 -0
  226. package/dist/components/v-map-layer-wkt2.js +1 -0
  227. package/dist/components/v-map-layer-wms.d.ts +11 -0
  228. package/dist/components/v-map-layer-wms.js +1 -0
  229. package/dist/components/v-map-layer-wms2.js +1 -0
  230. package/dist/components/v-map-layer-xyz.d.ts +11 -0
  231. package/dist/components/v-map-layer-xyz.js +1 -0
  232. package/dist/components/v-map-layer-xyz2.js +1 -0
  233. package/dist/components/v-map-layercontrol.d.ts +11 -0
  234. package/dist/components/v-map-layercontrol.js +1 -0
  235. package/dist/components/v-map-layergroup.d.ts +11 -0
  236. package/dist/components/v-map-layergroup.js +1 -0
  237. package/dist/components/v-map-layergroup2.js +1 -0
  238. package/dist/components/v-map-style.d.ts +11 -0
  239. package/dist/components/v-map-style.js +1 -0
  240. package/dist/components/v-map-style2.js +10 -0
  241. package/dist/components/v-map.d.ts +11 -0
  242. package/dist/components/v-map.js +1 -0
  243. package/dist/components/v-map2.js +1 -0
  244. package/dist/esm/_commonjsHelpers-E-ZsRS8r.js +32 -0
  245. package/dist/esm/app-globals-DQuL1Twl.js +3 -0
  246. package/dist/esm/cesium-provider-BJfAup3w.js +2596 -0
  247. package/dist/esm/deck-provider-C7U9VDEq.js +47709 -0
  248. package/dist/esm/geotiff-BEWxTIfH.js +45 -0
  249. package/dist/esm/geotiff-source-esnDnC-u.js +1516 -0
  250. package/dist/esm/index-B1zwA4IC.js +685 -0
  251. package/dist/esm/index-BBpiaTpT.js +165 -0
  252. package/dist/esm/index-BIEmlzCf.js +1697 -0
  253. package/dist/esm/index-BUHa4Jj0.js +307 -0
  254. package/dist/esm/index-DbSdn93t.js +20461 -0
  255. package/dist/esm/index-RpJarvr_.js +10656 -0
  256. package/dist/esm/index-jN06TXUp.js +14 -0
  257. package/dist/esm/index-jzneDarq.js +1613 -0
  258. package/dist/esm/index.browser-DhQAXuA7.js +6860 -0
  259. package/dist/esm/index.js +1 -0
  260. package/dist/esm/layer-extension-CZXK5goK.js +63 -0
  261. package/dist/esm/leaflet-provider-Q41TB6ku.js +1794 -0
  262. package/dist/esm/loader.js +11 -0
  263. package/dist/esm/main-dist-CwnA7_Xn.js +2652 -0
  264. package/dist/esm/messages-CMKJzsgL.js +180 -0
  265. package/dist/esm/openlayers-provider-CMsDsQTQ.js +1602 -0
  266. package/dist/esm/polygon-layer-ByhxGhWC.js +1295 -0
  267. package/dist/esm/scenegraph-layer-09K_B6DT.js +2526 -0
  268. package/dist/esm/styleconfig-B-bAcABs.js +21 -0
  269. package/dist/esm/v-map-builder.entry.js +3784 -0
  270. package/dist/esm/v-map-layer-geojson_12.entry.js +40881 -0
  271. package/dist/esm/v-map-layer-helper-Dys44Cgo.js +283 -0
  272. package/dist/esm/v-map-layer-terrain-geotiff.entry.js +256 -0
  273. package/dist/esm/v-map-layercontrol.entry.js +245 -0
  274. package/dist/esm/v-map.js +21 -0
  275. package/dist/esm/v-map.v-map-layer-osm.v-map-layergroup-B4pFHuSf.js +572 -0
  276. package/dist/esm/v-map_3.entry.js +4 -0
  277. package/dist/index.cjs.js +1 -0
  278. package/dist/index.js +1 -0
  279. package/dist/types/cesium-augment.d.ts +5 -0
  280. package/dist/types/components/v-map/v-map.d.ts +70 -0
  281. package/dist/types/components/v-map/v-map.test.d.ts +1 -0
  282. package/dist/types/components/v-map-builder/v-map-builder.d.ts +48 -0
  283. package/dist/types/components/v-map-builder/v-map-builder.test.d.ts +1 -0
  284. package/dist/types/components/v-map-layer-geojson/v-map-layer-geojson.d.ts +129 -0
  285. package/dist/types/components/v-map-layer-geojson/v-map-layer-geojson.test.d.ts +1 -0
  286. package/dist/types/components/v-map-layer-geotiff/v-map-layer-geotiff.d.ts +74 -0
  287. package/dist/types/components/v-map-layer-geotiff/v-map-layer-geotiff.test.d.ts +1 -0
  288. package/dist/types/components/v-map-layer-google/v-map-layer-google.d.ts +78 -0
  289. package/dist/types/components/v-map-layer-osm/error-api.test.d.ts +1 -0
  290. package/dist/types/components/v-map-layer-osm/v-map-layer-osm.d.ts +50 -0
  291. package/dist/types/components/v-map-layer-osm/v-map-layer-osm.test.d.ts +1 -0
  292. package/dist/types/components/v-map-layer-scatterplot/v-map-layer-scatterplot.d.ts +54 -0
  293. package/dist/types/components/v-map-layer-terrain/v-map-layer-terrain.d.ts +74 -0
  294. package/dist/types/components/v-map-layer-terrain/v-map-layer-terrain.test.d.ts +1 -0
  295. package/dist/types/components/v-map-layer-terrain-geotiff/v-map-layer-terrain-geotiff.d.ts +117 -0
  296. package/dist/types/components/v-map-layer-terrain-geotiff/v-map-layer-terrain-geotiff.test.d.ts +1 -0
  297. package/dist/types/components/v-map-layer-tile3d/v-map-layer-tile3d.d.ts +69 -0
  298. package/dist/types/components/v-map-layer-tile3d/v-map-layer-tile3d.test.d.ts +1 -0
  299. package/dist/types/components/v-map-layer-wcs/v-map-layer-wcs.d.ts +47 -0
  300. package/dist/types/components/v-map-layer-wcs/v-map-layer-wcs.test.d.ts +1 -0
  301. package/dist/types/components/v-map-layer-wfs/v-map-layer-wfs.d.ts +59 -0
  302. package/dist/types/components/v-map-layer-wfs/v-map-layer-wfs.test.d.ts +1 -0
  303. package/dist/types/components/v-map-layer-wkt/v-map-layer-wkt.d.ts +132 -0
  304. package/dist/types/components/v-map-layer-wkt/v-map-layer-wkt.test.d.ts +1 -0
  305. package/dist/types/components/v-map-layer-wms/v-map-layer-wms.d.ts +76 -0
  306. package/dist/types/components/v-map-layer-wms/v-map-layer-wms.test.d.ts +1 -0
  307. package/dist/types/components/v-map-layer-xyz/v-map-layer-xyz.d.ts +59 -0
  308. package/dist/types/components/v-map-layer-xyz/v-map-layer-xyz.test.d.ts +1 -0
  309. package/dist/types/components/v-map-layercontrol/v-map-layercontrol.d.ts +44 -0
  310. package/dist/types/components/v-map-layercontrol/v-map-layercontrol.test.d.ts +1 -0
  311. package/dist/types/components/v-map-layergroup/v-map-layergroup.d.ts +31 -0
  312. package/dist/types/components/v-map-layergroup/v-map-layergroup.test.d.ts +1 -0
  313. package/dist/types/components/v-map-style/v-map-style.d.ts +75 -0
  314. package/dist/types/components/v-map-style/v-map-style.unit.d.ts +1 -0
  315. package/dist/types/components.d.ts +2391 -0
  316. package/dist/types/globals.d.ts +16 -0
  317. package/dist/types/index.d.ts +10 -0
  318. package/dist/types/layer/v-map-layer-helper.d.ts +45 -0
  319. package/dist/types/layer/v-map-layer-helper.unit.d.ts +1 -0
  320. package/dist/types/leaflet-augment.d.ts +15 -0
  321. package/dist/types/lib/cesium-loader.d.ts +3 -0
  322. package/dist/types/lib/ensure-importmap.d.ts +3 -0
  323. package/dist/types/lib/ensure-importmap.unit.d.ts +1 -0
  324. package/dist/types/lib/versions.gen.d.ts +5 -0
  325. package/dist/types/lib/vstyle.d.ts +44 -0
  326. package/dist/types/map-provider/cesium/CesiumGeoTIFFTerrainProvider.d.ts +92 -0
  327. package/dist/types/map-provider/cesium/CesiumLayerGroups.d.ts +64 -0
  328. package/dist/types/map-provider/cesium/GeoTIFFImageryProvider.d.ts +75 -0
  329. package/dist/types/map-provider/cesium/GeoTIFFImageryProvider.test.d.ts +1 -0
  330. package/dist/types/map-provider/cesium/cesium-provider.d.ts +87 -0
  331. package/dist/types/map-provider/cesium/i-layer.d.ts +11 -0
  332. package/dist/types/map-provider/cesium/layer-manager.d.ts +31 -0
  333. package/dist/types/map-provider/deck/DeckGLGeoTIFFLayer.d.ts +91 -0
  334. package/dist/types/map-provider/deck/DeckGLGeoTIFFTerrainLayer.d.ts +82 -0
  335. package/dist/types/map-provider/deck/LayerGroupWithModel.d.ts +55 -0
  336. package/dist/types/map-provider/deck/LayerGroups.d.ts +63 -0
  337. package/dist/types/map-provider/deck/LayerModel.d.ts +8 -0
  338. package/dist/types/map-provider/deck/RenderableGroup.d.ts +20 -0
  339. package/dist/types/map-provider/deck/deck-provider.d.ts +92 -0
  340. package/dist/types/map-provider/geotiff/geotiff-source.d.ts +30 -0
  341. package/dist/types/map-provider/geotiff/utils/AABB2D.d.ts +28 -0
  342. package/dist/types/map-provider/geotiff/utils/BVHNode2D.d.ts +36 -0
  343. package/dist/types/map-provider/geotiff/utils/GeoTIFFTileProcessor.d.ts +116 -0
  344. package/dist/types/map-provider/geotiff/utils/Triangle.d.ts +5 -0
  345. package/dist/types/map-provider/geotiff/utils/Triangulation.d.ts +94 -0
  346. package/dist/types/map-provider/geotiff/utils/colormap-utils.d.ts +47 -0
  347. package/dist/types/map-provider/geotiff/utils/normalization-utils.d.ts +39 -0
  348. package/dist/types/map-provider/geotiff/utils/sampling-utils.d.ts +13 -0
  349. package/dist/types/map-provider/leaflet/GeoTIFFGridLayer.d.ts +34 -0
  350. package/dist/types/map-provider/leaflet/WCSGridLayer.d.ts +38 -0
  351. package/dist/types/map-provider/leaflet/google-map-tiles-layer.d.ts +73 -0
  352. package/dist/types/map-provider/leaflet/leaflet-helpers.d.ts +6 -0
  353. package/dist/types/map-provider/leaflet/leaflet-provider.d.ts +73 -0
  354. package/dist/types/map-provider/ol/CustomGeoTiff.d.ts +14 -0
  355. package/dist/types/map-provider/ol/openlayers-helper.d.ts +2 -0
  356. package/dist/types/map-provider/ol/openlayers-provider.d.ts +80 -0
  357. package/dist/types/map-provider/provider-factory.d.ts +12 -0
  358. package/dist/types/map-provider/provider-factory.unit.d.ts +1 -0
  359. package/dist/types/namespaces.d.ts +3 -0
  360. package/dist/types/ol-augment.d.ts +3 -0
  361. package/dist/types/ol-override.d.ts +7 -0
  362. package/dist/types/ol.d.ts +10 -0
  363. package/dist/types/stencil-public-runtime.d.ts +1860 -0
  364. package/dist/types/testing/browser-test-utils.d.ts +6 -0
  365. package/dist/types/testing/e2e-testing.d.ts +5 -0
  366. package/dist/types/testing/e2e-utils.d.ts +4 -0
  367. package/dist/types/testing/geotiff-test-server.d.ts +5 -0
  368. package/dist/types/testing/mocks/geostyler-lyrx-parser.d.ts +11 -0
  369. package/dist/types/testing/mocks/geostyler-mapbox-parser.d.ts +11 -0
  370. package/dist/types/testing/mocks/geostyler-qgis-parser.d.ts +11 -0
  371. package/dist/types/testing/mocks/geostyler-sld-parser.d.ts +11 -0
  372. package/dist/types/testing/mocks/geostyler-style.d.ts +5 -0
  373. package/dist/types/testing/setupTests.browser.d.ts +1 -0
  374. package/dist/types/testing/setupTests.stencil.d.ts +1 -0
  375. package/dist/types/testing/setupTests.vitest.d.ts +1 -0
  376. package/dist/types/testing/stencil-testing-wrapper.d.ts +3 -0
  377. package/dist/types/types/color.d.ts +1 -0
  378. package/dist/types/types/cssmode.d.ts +1 -0
  379. package/dist/types/types/flavour.d.ts +1 -0
  380. package/dist/types/types/layerconfig.d.ts +207 -0
  381. package/dist/types/types/lonlat.d.ts +1 -0
  382. package/dist/types/types/mapinitoptions.d.ts +4 -0
  383. package/dist/types/types/mapprovider.d.ts +46 -0
  384. package/dist/types/types/provideroptions.d.ts +8 -0
  385. package/dist/types/types/styleconfig.d.ts +27 -0
  386. package/dist/types/types/styling.d.ts +24 -0
  387. package/dist/types/types/styling.unit.d.ts +1 -0
  388. package/dist/types/types/vmaplayer.d.ts +10 -0
  389. package/dist/types/utils/async-mutex.d.ts +7 -0
  390. package/dist/types/utils/diff.d.ts +64 -0
  391. package/dist/types/utils/diff.unit.d.ts +1 -0
  392. package/dist/types/utils/dom-env.d.ts +5 -0
  393. package/dist/types/utils/dom-env.unit.d.ts +1 -0
  394. package/dist/types/utils/events.d.ts +29 -0
  395. package/dist/types/utils/logger.d.ts +47 -0
  396. package/dist/types/utils/logger.unit.d.ts +1 -0
  397. package/dist/types/utils/messages.d.ts +12 -0
  398. package/dist/types/utils/spatial-utils.d.ts +6 -0
  399. package/dist/types/utils/spatial-utils.unit.d.ts +1 -0
  400. package/dist/types/versions.d.ts +7 -0
  401. package/dist/v-map/index.esm.js +0 -0
  402. package/dist/v-map/p--vVleK-M.js +1 -0
  403. package/dist/v-map/p-09d10db0.entry.js +1 -0
  404. package/dist/v-map/p-5eba6058.entry.js +10 -0
  405. package/dist/v-map/p-6b102336.entry.js +1 -0
  406. package/dist/v-map/p-B-bAcABs.js +1 -0
  407. package/dist/v-map/p-BBpiaTpT.js +1 -0
  408. package/dist/v-map/p-BdijL4Av.js +1 -0
  409. package/dist/v-map/p-Be3r33VF.js +4 -0
  410. package/dist/v-map/p-BeFu0ap4.js +1 -0
  411. package/dist/v-map/p-BxFJezdK.js +1 -0
  412. package/dist/v-map/p-CMKJzsgL.js +1 -0
  413. package/dist/v-map/p-CXfA_q8m.js +1 -0
  414. package/dist/v-map/p-CZqY0yW4.js +1 -0
  415. package/dist/v-map/p-CafTHT9i.js +1 -0
  416. package/dist/v-map/p-DCTHyf58.js +1 -0
  417. package/dist/v-map/p-DQuL1Twl.js +1 -0
  418. package/dist/v-map/p-DR9McdNX.js +1 -0
  419. package/dist/v-map/p-Dckgonw8.js +1 -0
  420. package/dist/v-map/p-DhQAXuA7.js +15 -0
  421. package/dist/v-map/p-DmICdG34.js +7 -0
  422. package/dist/v-map/p-DrOQ9V4h.js +1 -0
  423. package/dist/v-map/p-DvHXtWUg.js +1 -0
  424. package/dist/v-map/p-E-ZsRS8r.js +1 -0
  425. package/dist/v-map/p-MyTSFnEk.js +1 -0
  426. package/dist/v-map/p-RpJarvr_.js +1 -0
  427. package/dist/v-map/p-WaMDUuAz.js +1 -0
  428. package/dist/v-map/p-aa410e64.entry.js +2 -0
  429. package/dist/v-map/p-c21c93fe.entry.js +1 -0
  430. package/dist/v-map/p-jzneDarq.js +2 -0
  431. package/dist/v-map/p-uiIP-taz.js +1 -0
  432. package/dist/v-map/v-map.esm.js +1 -0
  433. package/loader/cdn.js +1 -0
  434. package/loader/index.cjs.js +1 -0
  435. package/loader/index.d.ts +24 -0
  436. package/loader/index.es2017.js +1 -0
  437. package/loader/index.js +2 -0
  438. package/package.json +193 -0
@@ -0,0 +1,2526 @@
1
+ import { postProcessGLTF, GLTFLoader } from '@loaders.gl/gltf';
2
+ import { aK as lighting, a0 as Matrix4, V as Vector3, u as uid, aL as log, M as Model, G as Geometry, aM as Quaternion, L as Layer, p as project32, a as picking, aN as MATRIX_ATTRIBUTES, j as defaultLogger, aO as shouldComposeModelMatrix } from './deck-provider-C7U9VDEq.js';
3
+
4
+ // luma.gl
5
+ // SPDX-License-Identifier: MIT
6
+ // Copyright (c) vis.gl contributors
7
+ // Attribution:
8
+ // MIT license, Copyright (c) 2016-2017 Mohamad Moneimne and Contributors
9
+ // This fragment shader defines a reference implementation for Physically Based Shading of
10
+ // a microfacet surface material defined by a glTF model.
11
+ // TODO - better do the checks outside of shader
12
+ const vs$2 = /* glsl */ `\
13
+ out vec3 pbr_vPosition;
14
+ out vec2 pbr_vUV;
15
+
16
+ #ifdef HAS_NORMALS
17
+ # ifdef HAS_TANGENTS
18
+ out mat3 pbr_vTBN;
19
+ # else
20
+ out vec3 pbr_vNormal;
21
+ # endif
22
+ #endif
23
+
24
+ void pbr_setPositionNormalTangentUV(vec4 position, vec4 normal, vec4 tangent, vec2 uv)
25
+ {
26
+ vec4 pos = pbrProjection.modelMatrix * position;
27
+ pbr_vPosition = vec3(pos.xyz) / pos.w;
28
+
29
+ #ifdef HAS_NORMALS
30
+ #ifdef HAS_TANGENTS
31
+ vec3 normalW = normalize(vec3(pbrProjection.normalMatrix * vec4(normal.xyz, 0.0)));
32
+ vec3 tangentW = normalize(vec3(pbrProjection.modelMatrix * vec4(tangent.xyz, 0.0)));
33
+ vec3 bitangentW = cross(normalW, tangentW) * tangent.w;
34
+ pbr_vTBN = mat3(tangentW, bitangentW, normalW);
35
+ #else // HAS_TANGENTS != 1
36
+ pbr_vNormal = normalize(vec3(pbrProjection.modelMatrix * vec4(normal.xyz, 0.0)));
37
+ #endif
38
+ #endif
39
+
40
+ #ifdef HAS_UV
41
+ pbr_vUV = uv;
42
+ #else
43
+ pbr_vUV = vec2(0.,0.);
44
+ #endif
45
+ }
46
+ `;
47
+ const fs$2 = /* glsl */ `\
48
+ precision highp float;
49
+
50
+ uniform pbrMaterialUniforms {
51
+ // Material is unlit
52
+ bool unlit;
53
+
54
+ // Base color map
55
+ bool baseColorMapEnabled;
56
+ vec4 baseColorFactor;
57
+
58
+ bool normalMapEnabled;
59
+ float normalScale; // #ifdef HAS_NORMALMAP
60
+
61
+ bool emissiveMapEnabled;
62
+ vec3 emissiveFactor; // #ifdef HAS_EMISSIVEMAP
63
+
64
+ vec2 metallicRoughnessValues;
65
+ bool metallicRoughnessMapEnabled;
66
+
67
+ bool occlusionMapEnabled;
68
+ float occlusionStrength; // #ifdef HAS_OCCLUSIONMAP
69
+
70
+ bool alphaCutoffEnabled;
71
+ float alphaCutoff; // #ifdef ALPHA_CUTOFF
72
+
73
+ // IBL
74
+ bool IBLenabled;
75
+ vec2 scaleIBLAmbient; // #ifdef USE_IBL
76
+
77
+ // debugging flags used for shader output of intermediate PBR variables
78
+ // #ifdef PBR_DEBUG
79
+ vec4 scaleDiffBaseMR;
80
+ vec4 scaleFGDSpec;
81
+ // #endif
82
+ } pbrMaterial;
83
+
84
+ // Samplers
85
+ #ifdef HAS_BASECOLORMAP
86
+ uniform sampler2D pbr_baseColorSampler;
87
+ #endif
88
+ #ifdef HAS_NORMALMAP
89
+ uniform sampler2D pbr_normalSampler;
90
+ #endif
91
+ #ifdef HAS_EMISSIVEMAP
92
+ uniform sampler2D pbr_emissiveSampler;
93
+ #endif
94
+ #ifdef HAS_METALROUGHNESSMAP
95
+ uniform sampler2D pbr_metallicRoughnessSampler;
96
+ #endif
97
+ #ifdef HAS_OCCLUSIONMAP
98
+ uniform sampler2D pbr_occlusionSampler;
99
+ #endif
100
+ #ifdef USE_IBL
101
+ uniform samplerCube pbr_diffuseEnvSampler;
102
+ uniform samplerCube pbr_specularEnvSampler;
103
+ uniform sampler2D pbr_brdfLUT;
104
+ #endif
105
+
106
+ // Inputs from vertex shader
107
+
108
+ in vec3 pbr_vPosition;
109
+ in vec2 pbr_vUV;
110
+
111
+ #ifdef HAS_NORMALS
112
+ #ifdef HAS_TANGENTS
113
+ in mat3 pbr_vTBN;
114
+ #else
115
+ in vec3 pbr_vNormal;
116
+ #endif
117
+ #endif
118
+
119
+ // Encapsulate the various inputs used by the various functions in the shading equation
120
+ // We store values in this struct to simplify the integration of alternative implementations
121
+ // of the shading terms, outlined in the Readme.MD Appendix.
122
+ struct PBRInfo {
123
+ float NdotL; // cos angle between normal and light direction
124
+ float NdotV; // cos angle between normal and view direction
125
+ float NdotH; // cos angle between normal and half vector
126
+ float LdotH; // cos angle between light direction and half vector
127
+ float VdotH; // cos angle between view direction and half vector
128
+ float perceptualRoughness; // roughness value, as authored by the model creator (input to shader)
129
+ float metalness; // metallic value at the surface
130
+ vec3 reflectance0; // full reflectance color (normal incidence angle)
131
+ vec3 reflectance90; // reflectance color at grazing angle
132
+ float alphaRoughness; // roughness mapped to a more linear change in the roughness (proposed by [2])
133
+ vec3 diffuseColor; // color contribution from diffuse lighting
134
+ vec3 specularColor; // color contribution from specular lighting
135
+ vec3 n; // normal at surface point
136
+ vec3 v; // vector from surface point to camera
137
+ };
138
+
139
+ const float M_PI = 3.141592653589793;
140
+ const float c_MinRoughness = 0.04;
141
+
142
+ vec4 SRGBtoLINEAR(vec4 srgbIn)
143
+ {
144
+ #ifdef MANUAL_SRGB
145
+ #ifdef SRGB_FAST_APPROXIMATION
146
+ vec3 linOut = pow(srgbIn.xyz,vec3(2.2));
147
+ #else // SRGB_FAST_APPROXIMATION
148
+ vec3 bLess = step(vec3(0.04045),srgbIn.xyz);
149
+ vec3 linOut = mix( srgbIn.xyz/vec3(12.92), pow((srgbIn.xyz+vec3(0.055))/vec3(1.055),vec3(2.4)), bLess );
150
+ #endif //SRGB_FAST_APPROXIMATION
151
+ return vec4(linOut,srgbIn.w);;
152
+ #else //MANUAL_SRGB
153
+ return srgbIn;
154
+ #endif //MANUAL_SRGB
155
+ }
156
+
157
+ // Find the normal for this fragment, pulling either from a predefined normal map
158
+ // or from the interpolated mesh normal and tangent attributes.
159
+ vec3 getNormal()
160
+ {
161
+ // Retrieve the tangent space matrix
162
+ #ifndef HAS_TANGENTS
163
+ vec3 pos_dx = dFdx(pbr_vPosition);
164
+ vec3 pos_dy = dFdy(pbr_vPosition);
165
+ vec3 tex_dx = dFdx(vec3(pbr_vUV, 0.0));
166
+ vec3 tex_dy = dFdy(vec3(pbr_vUV, 0.0));
167
+ vec3 t = (tex_dy.t * pos_dx - tex_dx.t * pos_dy) / (tex_dx.s * tex_dy.t - tex_dy.s * tex_dx.t);
168
+
169
+ #ifdef HAS_NORMALS
170
+ vec3 ng = normalize(pbr_vNormal);
171
+ #else
172
+ vec3 ng = cross(pos_dx, pos_dy);
173
+ #endif
174
+
175
+ t = normalize(t - ng * dot(ng, t));
176
+ vec3 b = normalize(cross(ng, t));
177
+ mat3 tbn = mat3(t, b, ng);
178
+ #else // HAS_TANGENTS
179
+ mat3 tbn = pbr_vTBN;
180
+ #endif
181
+
182
+ #ifdef HAS_NORMALMAP
183
+ vec3 n = texture(pbr_normalSampler, pbr_vUV).rgb;
184
+ n = normalize(tbn * ((2.0 * n - 1.0) * vec3(pbrMaterial.normalScale, pbrMaterial.normalScale, 1.0)));
185
+ #else
186
+ // The tbn matrix is linearly interpolated, so we need to re-normalize
187
+ vec3 n = normalize(tbn[2].xyz);
188
+ #endif
189
+
190
+ return n;
191
+ }
192
+
193
+ // Calculation of the lighting contribution from an optional Image Based Light source.
194
+ // Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1].
195
+ // See our README.md on Environment Maps [3] for additional discussion.
196
+ #ifdef USE_IBL
197
+ vec3 getIBLContribution(PBRInfo pbrInfo, vec3 n, vec3 reflection)
198
+ {
199
+ float mipCount = 9.0; // resolution of 512x512
200
+ float lod = (pbrInfo.perceptualRoughness * mipCount);
201
+ // retrieve a scale and bias to F0. See [1], Figure 3
202
+ vec3 brdf = SRGBtoLINEAR(texture(pbr_brdfLUT,
203
+ vec2(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness))).rgb;
204
+ vec3 diffuseLight = SRGBtoLINEAR(texture(pbr_diffuseEnvSampler, n)).rgb;
205
+
206
+ #ifdef USE_TEX_LOD
207
+ vec3 specularLight = SRGBtoLINEAR(texture(pbr_specularEnvSampler, reflection, lod)).rgb;
208
+ #else
209
+ vec3 specularLight = SRGBtoLINEAR(texture(pbr_specularEnvSampler, reflection)).rgb;
210
+ #endif
211
+
212
+ vec3 diffuse = diffuseLight * pbrInfo.diffuseColor;
213
+ vec3 specular = specularLight * (pbrInfo.specularColor * brdf.x + brdf.y);
214
+
215
+ // For presentation, this allows us to disable IBL terms
216
+ diffuse *= pbrMaterial.scaleIBLAmbient.x;
217
+ specular *= pbrMaterial.scaleIBLAmbient.y;
218
+
219
+ return diffuse + specular;
220
+ }
221
+ #endif
222
+
223
+ // Basic Lambertian diffuse
224
+ // Implementation from Lambert's Photometria https://archive.org/details/lambertsphotome00lambgoog
225
+ // See also [1], Equation 1
226
+ vec3 diffuse(PBRInfo pbrInfo)
227
+ {
228
+ return pbrInfo.diffuseColor / M_PI;
229
+ }
230
+
231
+ // The following equation models the Fresnel reflectance term of the spec equation (aka F())
232
+ // Implementation of fresnel from [4], Equation 15
233
+ vec3 specularReflection(PBRInfo pbrInfo)
234
+ {
235
+ return pbrInfo.reflectance0 +
236
+ (pbrInfo.reflectance90 - pbrInfo.reflectance0) *
237
+ pow(clamp(1.0 - pbrInfo.VdotH, 0.0, 1.0), 5.0);
238
+ }
239
+
240
+ // This calculates the specular geometric attenuation (aka G()),
241
+ // where rougher material will reflect less light back to the viewer.
242
+ // This implementation is based on [1] Equation 4, and we adopt their modifications to
243
+ // alphaRoughness as input as originally proposed in [2].
244
+ float geometricOcclusion(PBRInfo pbrInfo)
245
+ {
246
+ float NdotL = pbrInfo.NdotL;
247
+ float NdotV = pbrInfo.NdotV;
248
+ float r = pbrInfo.alphaRoughness;
249
+
250
+ float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL)));
251
+ float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV)));
252
+ return attenuationL * attenuationV;
253
+ }
254
+
255
+ // The following equation(s) model the distribution of microfacet normals across
256
+ // the area being drawn (aka D())
257
+ // Implementation from "Average Irregularity Representation of a Roughened Surface
258
+ // for Ray Reflection" by T. S. Trowbridge, and K. P. Reitz
259
+ // Follows the distribution function recommended in the SIGGRAPH 2013 course notes
260
+ // from EPIC Games [1], Equation 3.
261
+ float microfacetDistribution(PBRInfo pbrInfo)
262
+ {
263
+ float roughnessSq = pbrInfo.alphaRoughness * pbrInfo.alphaRoughness;
264
+ float f = (pbrInfo.NdotH * roughnessSq - pbrInfo.NdotH) * pbrInfo.NdotH + 1.0;
265
+ return roughnessSq / (M_PI * f * f);
266
+ }
267
+
268
+ void PBRInfo_setAmbientLight(inout PBRInfo pbrInfo) {
269
+ pbrInfo.NdotL = 1.0;
270
+ pbrInfo.NdotH = 0.0;
271
+ pbrInfo.LdotH = 0.0;
272
+ pbrInfo.VdotH = 1.0;
273
+ }
274
+
275
+ void PBRInfo_setDirectionalLight(inout PBRInfo pbrInfo, vec3 lightDirection) {
276
+ vec3 n = pbrInfo.n;
277
+ vec3 v = pbrInfo.v;
278
+ vec3 l = normalize(lightDirection); // Vector from surface point to light
279
+ vec3 h = normalize(l+v); // Half vector between both l and v
280
+
281
+ pbrInfo.NdotL = clamp(dot(n, l), 0.001, 1.0);
282
+ pbrInfo.NdotH = clamp(dot(n, h), 0.0, 1.0);
283
+ pbrInfo.LdotH = clamp(dot(l, h), 0.0, 1.0);
284
+ pbrInfo.VdotH = clamp(dot(v, h), 0.0, 1.0);
285
+ }
286
+
287
+ void PBRInfo_setPointLight(inout PBRInfo pbrInfo, PointLight pointLight) {
288
+ vec3 light_direction = normalize(pointLight.position - pbr_vPosition);
289
+ PBRInfo_setDirectionalLight(pbrInfo, light_direction);
290
+ }
291
+
292
+ vec3 calculateFinalColor(PBRInfo pbrInfo, vec3 lightColor) {
293
+ // Calculate the shading terms for the microfacet specular shading model
294
+ vec3 F = specularReflection(pbrInfo);
295
+ float G = geometricOcclusion(pbrInfo);
296
+ float D = microfacetDistribution(pbrInfo);
297
+
298
+ // Calculation of analytical lighting contribution
299
+ vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInfo);
300
+ vec3 specContrib = F * G * D / (4.0 * pbrInfo.NdotL * pbrInfo.NdotV);
301
+ // Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law)
302
+ return pbrInfo.NdotL * lightColor * (diffuseContrib + specContrib);
303
+ }
304
+
305
+ vec4 pbr_filterColor(vec4 colorUnused)
306
+ {
307
+ // The albedo may be defined from a base texture or a flat color
308
+ #ifdef HAS_BASECOLORMAP
309
+ vec4 baseColor = SRGBtoLINEAR(texture(pbr_baseColorSampler, pbr_vUV)) * pbrMaterial.baseColorFactor;
310
+ #else
311
+ vec4 baseColor = pbrMaterial.baseColorFactor;
312
+ #endif
313
+
314
+ #ifdef ALPHA_CUTOFF
315
+ if (baseColor.a < pbrMaterial.alphaCutoff) {
316
+ discard;
317
+ }
318
+ #endif
319
+
320
+ vec3 color = vec3(0, 0, 0);
321
+
322
+ if(pbrMaterial.unlit){
323
+ color.rgb = baseColor.rgb;
324
+ }
325
+ else{
326
+ // Metallic and Roughness material properties are packed together
327
+ // In glTF, these factors can be specified by fixed scalar values
328
+ // or from a metallic-roughness map
329
+ float perceptualRoughness = pbrMaterial.metallicRoughnessValues.y;
330
+ float metallic = pbrMaterial.metallicRoughnessValues.x;
331
+ #ifdef HAS_METALROUGHNESSMAP
332
+ // Roughness is stored in the 'g' channel, metallic is stored in the 'b' channel.
333
+ // This layout intentionally reserves the 'r' channel for (optional) occlusion map data
334
+ vec4 mrSample = texture(pbr_metallicRoughnessSampler, pbr_vUV);
335
+ perceptualRoughness = mrSample.g * perceptualRoughness;
336
+ metallic = mrSample.b * metallic;
337
+ #endif
338
+ perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);
339
+ metallic = clamp(metallic, 0.0, 1.0);
340
+ // Roughness is authored as perceptual roughness; as is convention,
341
+ // convert to material roughness by squaring the perceptual roughness [2].
342
+ float alphaRoughness = perceptualRoughness * perceptualRoughness;
343
+
344
+ vec3 f0 = vec3(0.04);
345
+ vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - f0);
346
+ diffuseColor *= 1.0 - metallic;
347
+ vec3 specularColor = mix(f0, baseColor.rgb, metallic);
348
+
349
+ // Compute reflectance.
350
+ float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
351
+
352
+ // For typical incident reflectance range (between 4% to 100%) set the grazing
353
+ // reflectance to 100% for typical fresnel effect.
354
+ // For very low reflectance range on highly diffuse objects (below 4%),
355
+ // incrementally reduce grazing reflecance to 0%.
356
+ float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
357
+ vec3 specularEnvironmentR0 = specularColor.rgb;
358
+ vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
359
+
360
+ vec3 n = getNormal(); // normal at surface point
361
+ vec3 v = normalize(pbrProjection.camera - pbr_vPosition); // Vector from surface point to camera
362
+
363
+ float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
364
+ vec3 reflection = -normalize(reflect(v, n));
365
+
366
+ PBRInfo pbrInfo = PBRInfo(
367
+ 0.0, // NdotL
368
+ NdotV,
369
+ 0.0, // NdotH
370
+ 0.0, // LdotH
371
+ 0.0, // VdotH
372
+ perceptualRoughness,
373
+ metallic,
374
+ specularEnvironmentR0,
375
+ specularEnvironmentR90,
376
+ alphaRoughness,
377
+ diffuseColor,
378
+ specularColor,
379
+ n,
380
+ v
381
+ );
382
+
383
+
384
+ #ifdef USE_LIGHTS
385
+ // Apply ambient light
386
+ PBRInfo_setAmbientLight(pbrInfo);
387
+ color += calculateFinalColor(pbrInfo, lighting.ambientColor);
388
+
389
+ // Apply directional light
390
+ for(int i = 0; i < lighting.directionalLightCount; i++) {
391
+ if (i < lighting.directionalLightCount) {
392
+ PBRInfo_setDirectionalLight(pbrInfo, lighting_getDirectionalLight(i).direction);
393
+ color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);
394
+ }
395
+ }
396
+
397
+ // Apply point light
398
+ for(int i = 0; i < lighting.pointLightCount; i++) {
399
+ if (i < lighting.pointLightCount) {
400
+ PBRInfo_setPointLight(pbrInfo, lighting_getPointLight(i));
401
+ float attenuation = getPointLightAttenuation(lighting_getPointLight(i), distance(lighting_getPointLight(i).position, pbr_vPosition));
402
+ color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);
403
+ }
404
+ }
405
+ #endif
406
+
407
+ // Calculate lighting contribution from image based lighting source (IBL)
408
+ #ifdef USE_IBL
409
+ if (pbrMaterial.IBLenabled) {
410
+ color += getIBLContribution(pbrInfo, n, reflection);
411
+ }
412
+ #endif
413
+
414
+ // Apply optional PBR terms for additional (optional) shading
415
+ #ifdef HAS_OCCLUSIONMAP
416
+ if (pbrMaterial.occlusionMapEnabled) {
417
+ float ao = texture(pbr_occlusionSampler, pbr_vUV).r;
418
+ color = mix(color, color * ao, pbrMaterial.occlusionStrength);
419
+ }
420
+ #endif
421
+
422
+ #ifdef HAS_EMISSIVEMAP
423
+ if (pbrMaterial.emissiveMapEnabled) {
424
+ vec3 emissive = SRGBtoLINEAR(texture(pbr_emissiveSampler, pbr_vUV)).rgb * pbrMaterial.emissiveFactor;
425
+ color += emissive;
426
+ }
427
+ #endif
428
+
429
+ // This section uses mix to override final color for reference app visualization
430
+ // of various parameters in the lighting equation.
431
+ #ifdef PBR_DEBUG
432
+ // TODO: Figure out how to debug multiple lights
433
+
434
+ // color = mix(color, F, pbr_scaleFGDSpec.x);
435
+ // color = mix(color, vec3(G), pbr_scaleFGDSpec.y);
436
+ // color = mix(color, vec3(D), pbr_scaleFGDSpec.z);
437
+ // color = mix(color, specContrib, pbr_scaleFGDSpec.w);
438
+
439
+ // color = mix(color, diffuseContrib, pbr_scaleDiffBaseMR.x);
440
+ color = mix(color, baseColor.rgb, pbrMaterial.scaleDiffBaseMR.y);
441
+ color = mix(color, vec3(metallic), pbrMaterial.scaleDiffBaseMR.z);
442
+ color = mix(color, vec3(perceptualRoughness), pbrMaterial.scaleDiffBaseMR.w);
443
+ #endif
444
+
445
+ }
446
+
447
+ return vec4(pow(color,vec3(1.0/2.2)), baseColor.a);
448
+ }
449
+ `;
450
+
451
+ // luma.gl
452
+ // SPDX-License-Identifier: MIT
453
+ // Copyright (c) vis.gl contributors
454
+ // Attribution:
455
+ // MIT license, Copyright (c) 2016-2017 Mohamad Moneimne and Contributors
456
+ // This fragment shader defines a reference implementation for Physically Based Shading of
457
+ // a microfacet surface material defined by a glTF model.
458
+ // TODO - better do the checks outside of shader
459
+ const source = /* wgsl */ `\
460
+ struct PBRFragmentInputs {
461
+ pbr_vPosition: vec3f,
462
+ pbr_vUV: vec2f,
463
+ pbr_vTBN: mat3f,
464
+ pbr_vNormal: vec3f
465
+ };
466
+
467
+ var fragmentInputs: PBRFragmentInputs;
468
+
469
+ fn pbr_setPositionNormalTangentUV(position: vec4f, normal: vec4f, tangent: vec4f, uv: vec2f)
470
+ {
471
+ var pos: vec4f = pbrProjection.modelMatrix * position;
472
+ pbr_vPosition = vec3(pos.xyz) / pos.w;
473
+
474
+ #ifdef HAS_NORMALS
475
+ #ifdef HAS_TANGENTS
476
+ let normalW: vec3f = normalize(vec3(pbrProjection.normalMatrix * vec4(normal.xyz, 0.0)));
477
+ let tangentW: vec3f = normalize(vec3(pbrProjection.modelMatrix * vec4(tangent.xyz, 0.0)));
478
+ let bitangentW: vec3f = cross(normalW, tangentW) * tangent.w;
479
+ fragmentInputs,pbr_vTBN = mat3(tangentW, bitangentW, normalW);
480
+ #else // HAS_TANGENTS != 1
481
+ fragmentInputs.pbr_vNormal = normalize(vec3(pbrProjection.modelMatrix * vec4(normal.xyz, 0.0)));
482
+ #endif
483
+ #endif
484
+
485
+ #ifdef HAS_UV
486
+ pbr_vUV = uv;
487
+ #else
488
+ pbr_vUV = vec2(0.,0.);
489
+ #endif
490
+ }
491
+
492
+ struct pbrMaterialUniforms {
493
+ // Material is unlit
494
+ unlit: uint32,
495
+
496
+ // Base color map
497
+ baseColorMapEnabled: uint32,
498
+ baseColorFactor: vec4f,
499
+
500
+ normalMapEnabled : uint32,
501
+ normalScale: f32, // #ifdef HAS_NORMALMAP
502
+
503
+ emissiveMapEnabled: uint32,
504
+ emissiveFactor: vec3f, // #ifdef HAS_EMISSIVEMAP
505
+
506
+ metallicRoughnessValues: vec2f,
507
+ metallicRoughnessMapEnabled: uint32,
508
+
509
+ occlusionMapEnabled: i32,
510
+ occlusionStrength: f32, // #ifdef HAS_OCCLUSIONMAP
511
+
512
+ alphaCutoffEnabled: i32,
513
+ alphaCutoff: f32, // #ifdef ALPHA_CUTOFF
514
+
515
+ // IBL
516
+ IBLenabled: i32,
517
+ scaleIBLAmbient: vec2f, // #ifdef USE_IBL
518
+
519
+ // debugging flags used for shader output of intermediate PBR variables
520
+ // #ifdef PBR_DEBUG
521
+ scaleDiffBaseMR: vec4f,
522
+ scaleFGDSpec: vec4f
523
+ // #endif
524
+ }
525
+
526
+ @binding(2) @group(0) var<uniform> material : pbrMaterialUniforms;
527
+
528
+ // Samplers
529
+ #ifdef HAS_BASECOLORMAP
530
+ uniform sampler2D pbr_baseColorSampler;
531
+ #endif
532
+ #ifdef HAS_NORMALMAP
533
+ uniform sampler2D pbr_normalSampler;
534
+ #endif
535
+ #ifdef HAS_EMISSIVEMAP
536
+ uniform sampler2D pbr_emissiveSampler;
537
+ #endif
538
+ #ifdef HAS_METALROUGHNESSMAP
539
+ uniform sampler2D pbr_metallicRoughnessSampler;
540
+ #endif
541
+ #ifdef HAS_OCCLUSIONMAP
542
+ uniform sampler2D pbr_occlusionSampler;
543
+ #endif
544
+ #ifdef USE_IBL
545
+ uniform samplerCube pbr_diffuseEnvSampler;
546
+ uniform samplerCube pbr_specularEnvSampler;
547
+ uniform sampler2D pbr_brdfLUT;
548
+ #endif
549
+
550
+ // Encapsulate the various inputs used by the various functions in the shading equation
551
+ // We store values in this struct to simplify the integration of alternative implementations
552
+ // of the shading terms, outlined in the Readme.MD Appendix.
553
+ struct PBRInfo {
554
+ NdotL: f32, // cos angle between normal and light direction
555
+ NdotV: f32, // cos angle between normal and view direction
556
+ NdotH: f32, // cos angle between normal and half vector
557
+ LdotH: f32, // cos angle between light direction and half vector
558
+ VdotH: f32, // cos angle between view direction and half vector
559
+ perceptualRoughness: f32, // roughness value, as authored by the model creator (input to shader)
560
+ metalness: f32, // metallic value at the surface
561
+ reflectance0: vec3f, // full reflectance color (normal incidence angle)
562
+ reflectance90: vec3f, // reflectance color at grazing angle
563
+ alphaRoughness: f32, // roughness mapped to a more linear change in the roughness (proposed by [2])
564
+ diffuseColor: vec3f, // color contribution from diffuse lighting
565
+ specularColor: vec3f, // color contribution from specular lighting
566
+ n: vec3f, // normal at surface point
567
+ v: vec3f, // vector from surface point to camera
568
+ };
569
+
570
+ const M_PI = 3.141592653589793;
571
+ const c_MinRoughness = 0.04;
572
+
573
+ fn SRGBtoLINEAR(srgbIn: vec4f ) -> vec4f
574
+ {
575
+ #ifdef MANUAL_SRGB
576
+ #ifdef SRGB_FAST_APPROXIMATION
577
+ var linOut: vec3f = pow(srgbIn.xyz,vec3(2.2));
578
+ #else // SRGB_FAST_APPROXIMATION
579
+ var bLess: vec3f = step(vec3(0.04045),srgbIn.xyz);
580
+ var linOut: vec3f = mix( srgbIn.xyz/vec3(12.92), pow((srgbIn.xyz+vec3(0.055))/vec3(1.055),vec3(2.4)), bLess );
581
+ #endif //SRGB_FAST_APPROXIMATION
582
+ return vec4f(linOut,srgbIn.w);;
583
+ #else //MANUAL_SRGB
584
+ return srgbIn;
585
+ #endif //MANUAL_SRGB
586
+ }
587
+
588
+ // Find the normal for this fragment, pulling either from a predefined normal map
589
+ // or from the interpolated mesh normal and tangent attributes.
590
+ fn getNormal() -> vec3f
591
+ {
592
+ // Retrieve the tangent space matrix
593
+ #ifndef HAS_TANGENTS
594
+ var pos_dx: vec3f = dFdx(pbr_vPosition);
595
+ var pos_dy: vec3f = dFdy(pbr_vPosition);
596
+ var tex_dx: vec3f = dFdx(vec3(pbr_vUV, 0.0));
597
+ var tex_dy: vec3f = dFdy(vec3(pbr_vUV, 0.0));
598
+ var t: vec3f = (tex_dy.t * pos_dx - tex_dx.t * pos_dy) / (tex_dx.s * tex_dy.t - tex_dy.s * tex_dx.t);
599
+
600
+ #ifdef HAS_NORMALS
601
+ var ng: vec3f = normalize(pbr_vNormal);
602
+ #else
603
+ var ng: vec3f = cross(pos_dx, pos_dy);
604
+ #endif
605
+
606
+ t = normalize(t - ng * dot(ng, t));
607
+ var b: vec3f = normalize(cross(ng, t));
608
+ var tbn: mat3f = mat3f(t, b, ng);
609
+ #else // HAS_TANGENTS
610
+ var tbn: mat3f = pbr_vTBN;
611
+ #endif
612
+
613
+ #ifdef HAS_NORMALMAP
614
+ vec3 n = texture(pbr_normalSampler, pbr_vUV).rgb;
615
+ n = normalize(tbn * ((2.0 * n - 1.0) * vec3(pbrMaterial.normalScale, pbrMaterial.normalScale, 1.0)));
616
+ #else
617
+ // The tbn matrix is linearly interpolated, so we need to re-normalize
618
+ vec3 n = normalize(tbn[2].xyz);
619
+ #endif
620
+
621
+ return n;
622
+ }
623
+
624
+ // Calculation of the lighting contribution from an optional Image Based Light source.
625
+ // Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1].
626
+ // See our README.md on Environment Maps [3] for additional discussion.
627
+ #ifdef USE_IBL
628
+ fn getIBLContribution(PBRInfo pbrInfo, vec3 n, vec3 reflection) -> vec3f
629
+ {
630
+ float mipCount = 9.0; // resolution of 512x512
631
+ float lod = (pbrInfo.perceptualRoughness * mipCount);
632
+ // retrieve a scale and bias to F0. See [1], Figure 3
633
+ vec3 brdf = SRGBtoLINEAR(texture(pbr_brdfLUT,
634
+ vec2(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness))).rgb;
635
+ vec3 diffuseLight = SRGBtoLINEAR(texture(pbr_diffuseEnvSampler, n)).rgb;
636
+
637
+ #ifdef USE_TEX_LOD
638
+ vec3 specularLight = SRGBtoLINEAR(texture(pbr_specularEnvSampler, reflection, lod)).rgb;
639
+ #else
640
+ vec3 specularLight = SRGBtoLINEAR(texture(pbr_specularEnvSampler, reflection)).rgb;
641
+ #endif
642
+
643
+ vec3 diffuse = diffuseLight * pbrInfo.diffuseColor;
644
+ vec3 specular = specularLight * (pbrInfo.specularColor * brdf.x + brdf.y);
645
+
646
+ // For presentation, this allows us to disable IBL terms
647
+ diffuse *= pbrMaterial.scaleIBLAmbient.x;
648
+ specular *= pbrMaterial.scaleIBLAmbient.y;
649
+
650
+ return diffuse + specular;
651
+ }
652
+ #endif
653
+
654
+ // Basic Lambertian diffuse
655
+ // Implementation from Lambert's Photometria https://archive.org/details/lambertsphotome00lambgoog
656
+ // See also [1], Equation 1
657
+ fn diffuse(pbrInfo: PBRInfo) -> vec3<f32> {
658
+ return pbrInfo.diffuseColor / PI;
659
+ }
660
+
661
+ // The following equation models the Fresnel reflectance term of the spec equation (aka F())
662
+ // Implementation of fresnel from [4], Equation 15
663
+ fn specularReflection(pbrInfo: PBRInfo) -> vec3<f32> {
664
+ return pbrInfo.reflectance0 +
665
+ (pbrInfo.reflectance90 - pbrInfo.reflectance0) *
666
+ pow(clamp(1.0 - pbrInfo.VdotH, 0.0, 1.0), 5.0);
667
+ }
668
+
669
+ // This calculates the specular geometric attenuation (aka G()),
670
+ // where rougher material will reflect less light back to the viewer.
671
+ // This implementation is based on [1] Equation 4, and we adopt their modifications to
672
+ // alphaRoughness as input as originally proposed in [2].
673
+ fn geometricOcclusion(pbrInfo: PBRInfo) -> f32 {
674
+ let NdotL: f32 = pbrInfo.NdotL;
675
+ let NdotV: f32 = pbrInfo.NdotV;
676
+ let r: f32 = pbrInfo.alphaRoughness;
677
+
678
+ let attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL)));
679
+ let attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV)));
680
+ return attenuationL * attenuationV;
681
+ }
682
+
683
+ // The following equation(s) model the distribution of microfacet normals across
684
+ // the area being drawn (aka D())
685
+ // Implementation from "Average Irregularity Representation of a Roughened Surface
686
+ // for Ray Reflection" by T. S. Trowbridge, and K. P. Reitz
687
+ // Follows the distribution function recommended in the SIGGRAPH 2013 course notes
688
+ // from EPIC Games [1], Equation 3.
689
+ fn microfacetDistribution(pbrInfo: PBRInfo) -> f32 {
690
+ let roughnessSq = pbrInfo.alphaRoughness * pbrInfo.alphaRoughness;
691
+ let f = (pbrInfo.NdotH * roughnessSq - pbrInfo.NdotH) * pbrInfo.NdotH + 1.0;
692
+ return roughnessSq / (PI * f * f);
693
+ }
694
+
695
+ fn PBRInfo_setAmbientLight(pbrInfo: ptr<function, PBRInfo>) {
696
+ (*pbrInfo).NdotL = 1.0;
697
+ (*pbrInfo).NdotH = 0.0;
698
+ (*pbrInfo).LdotH = 0.0;
699
+ (*pbrInfo).VdotH = 1.0;
700
+ }
701
+
702
+ fn PBRInfo_setDirectionalLight(pbrInfo: ptr<function, PBRInfo>, lightDirection: vec3<f32>) {
703
+ let n = (*pbrInfo).n;
704
+ let v = (*pbrInfo).v;
705
+ let l = normalize(lightDirection); // Vector from surface point to light
706
+ let h = normalize(l + v); // Half vector between both l and v
707
+
708
+ (*pbrInfo).NdotL = clamp(dot(n, l), 0.001, 1.0);
709
+ (*pbrInfo).NdotH = clamp(dot(n, h), 0.0, 1.0);
710
+ (*pbrInfo).LdotH = clamp(dot(l, h), 0.0, 1.0);
711
+ (*pbrInfo).VdotH = clamp(dot(v, h), 0.0, 1.0);
712
+ }
713
+
714
+ fn PBRInfo_setPointLight(pbrInfo: ptr<function, PBRInfo>, pointLight: PointLight) {
715
+ let light_direction = normalize(pointLight.position - pbr_vPosition);
716
+ PBRInfo_setDirectionalLight(pbrInfo, light_direction);
717
+ }
718
+
719
+ fn calculateFinalColor(pbrInfo: PBRInfo, lightColor: vec3<f32>) -> vec3<f32> {
720
+ // Calculate the shading terms for the microfacet specular shading model
721
+ let F = specularReflection(pbrInfo);
722
+ let G = geometricOcclusion(pbrInfo);
723
+ let D = microfacetDistribution(pbrInfo);
724
+
725
+ // Calculation of analytical lighting contribution
726
+ let diffuseContrib = (1.0 - F) * diffuse(pbrInfo);
727
+ let specContrib = F * G * D / (4.0 * pbrInfo.NdotL * pbrInfo.NdotV);
728
+ // Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law)
729
+ return pbrInfo.NdotL * lightColor * (diffuseContrib + specContrib);
730
+ }
731
+
732
+ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
733
+ // The albedo may be defined from a base texture or a flat color
734
+ var baseColor: vec4<f32>;
735
+ #ifdef HAS_BASECOLORMAP
736
+ baseColor = SRGBtoLINEAR(textureSample(pbr_baseColorSampler, pbr_baseColorSampler, pbr_vUV)) * pbrMaterial.baseColorFactor;
737
+ #else
738
+ baseColor = pbrMaterial.baseColorFactor;
739
+ #endif
740
+
741
+ #ifdef ALPHA_CUTOFF
742
+ if (baseColor.a < pbrMaterial.alphaCutoff) {
743
+ discard;
744
+ }
745
+ #endif
746
+
747
+ var color = vec3<f32>(0.0, 0.0, 0.0);
748
+
749
+ if (pbrMaterial.unlit) {
750
+ color = baseColor.rgb;
751
+ } else {
752
+ // Metallic and Roughness material properties are packed together
753
+ // In glTF, these factors can be specified by fixed scalar values
754
+ // or from a metallic-roughness map
755
+ var perceptualRoughness = pbrMaterial.metallicRoughnessValues.y;
756
+ var metallic = pbrMaterial.metallicRoughnessValues.x;
757
+ #ifdef HAS_METALROUGHNESSMAP
758
+ // Roughness is stored in the 'g' channel, metallic is stored in the 'b' channel.
759
+ // This layout intentionally reserves the 'r' channel for (optional) occlusion map data
760
+ let mrSample = textureSample(pbr_metallicRoughnessSampler, pbr_metallicRoughnessSampler, pbr_vUV);
761
+ perceptualRoughness = mrSample.g * perceptualRoughness;
762
+ metallic = mrSample.b * metallic;
763
+ #endif
764
+ perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);
765
+ metallic = clamp(metallic, 0.0, 1.0);
766
+ // Roughness is authored as perceptual roughness; as is convention,
767
+ // convert to material roughness by squaring the perceptual roughness [2].
768
+ let alphaRoughness = perceptualRoughness * perceptualRoughness;
769
+
770
+ let f0 = vec3<f32>(0.04);
771
+ var diffuseColor = baseColor.rgb * (vec3<f32>(1.0) - f0);
772
+ diffuseColor *= 1.0 - metallic;
773
+ let specularColor = mix(f0, baseColor.rgb, metallic);
774
+
775
+ // Compute reflectance.
776
+ let reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
777
+
778
+ // For typical incident reflectance range (between 4% to 100%) set the grazing
779
+ // reflectance to 100% for typical fresnel effect.
780
+ // For very low reflectance range on highly diffuse objects (below 4%),
781
+ // incrementally reduce grazing reflectance to 0%.
782
+ let reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
783
+ let specularEnvironmentR0 = specularColor;
784
+ let specularEnvironmentR90 = vec3<f32>(1.0, 1.0, 1.0) * reflectance90;
785
+
786
+ let n = getNormal(); // normal at surface point
787
+ let v = normalize(pbrProjection.camera - pbr_vPosition); // Vector from surface point to camera
788
+
789
+ let NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
790
+ let reflection = -normalize(reflect(v, n));
791
+
792
+ var pbrInfo = PBRInfo(
793
+ 0.0, // NdotL
794
+ NdotV,
795
+ 0.0, // NdotH
796
+ 0.0, // LdotH
797
+ 0.0, // VdotH
798
+ perceptualRoughness,
799
+ metallic,
800
+ specularEnvironmentR0,
801
+ specularEnvironmentR90,
802
+ alphaRoughness,
803
+ diffuseColor,
804
+ specularColor,
805
+ n,
806
+ v
807
+ );
808
+
809
+ #ifdef USE_LIGHTS
810
+ // Apply ambient light
811
+ PBRInfo_setAmbientLight(&pbrInfo);
812
+ color += calculateFinalColor(pbrInfo, lighting.ambientColor);
813
+
814
+ // Apply directional light
815
+ for (var i = 0; i < lighting.directionalLightCount; i++) {
816
+ if (i < lighting.directionalLightCount) {
817
+ PBRInfo_setDirectionalLight(&pbrInfo, lighting_getDirectionalLight(i).direction);
818
+ color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);
819
+ }
820
+ }
821
+
822
+ // Apply point light
823
+ for (var i = 0; i < lighting.pointLightCount; i++) {
824
+ if (i < lighting.pointLightCount) {
825
+ PBRInfo_setPointLight(&pbrInfo, lighting_getPointLight(i));
826
+ let attenuation = getPointLightAttenuation(lighting_getPointLight(i), distance(lighting_getPointLight(i).position, pbr_vPosition));
827
+ color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);
828
+ }
829
+ }
830
+ #endif
831
+
832
+ // Calculate lighting contribution from image based lighting source (IBL)
833
+ #ifdef USE_IBL
834
+ if (pbrMaterial.IBLenabled) {
835
+ color += getIBLContribution(pbrInfo, n, reflection);
836
+ }
837
+ #endif
838
+
839
+ // Apply optional PBR terms for additional (optional) shading
840
+ #ifdef HAS_OCCLUSIONMAP
841
+ if (pbrMaterial.occlusionMapEnabled) {
842
+ let ao = textureSample(pbr_occlusionSampler, pbr_occlusionSampler, pbr_vUV).r;
843
+ color = mix(color, color * ao, pbrMaterial.occlusionStrength);
844
+ }
845
+ #endif
846
+
847
+ #ifdef HAS_EMISSIVEMAP
848
+ if (pbrMaterial.emissiveMapEnabled) {
849
+ let emissive = SRGBtoLINEAR(textureSample(pbr_emissiveSampler, pbr_emissiveSampler, pbr_vUV)).rgb * pbrMaterial.emissiveFactor;
850
+ color += emissive;
851
+ }
852
+ #endif
853
+
854
+ // This section uses mix to override final color for reference app visualization
855
+ // of various parameters in the lighting equation.
856
+ #ifdef PBR_DEBUG
857
+ // TODO: Figure out how to debug multiple lights
858
+
859
+ // color = mix(color, F, pbr_scaleFGDSpec.x);
860
+ // color = mix(color, vec3(G), pbr_scaleFGDSpec.y);
861
+ // color = mix(color, vec3(D), pbr_scaleFGDSpec.z);
862
+ // color = mix(color, specContrib, pbr_scaleFGDSpec.w);
863
+
864
+ // color = mix(color, diffuseContrib, pbr_scaleDiffBaseMR.x);
865
+ color = mix(color, baseColor.rgb, pbrMaterial.scaleDiffBaseMR.y);
866
+ color = mix(color, vec3<f32>(metallic), pbrMaterial.scaleDiffBaseMR.z);
867
+ color = mix(color, vec3<f32>(perceptualRoughness), pbrMaterial.scaleDiffBaseMR.w);
868
+ #endif
869
+ }
870
+
871
+ return vec4<f32>(pow(color, vec3<f32>(1.0 / 2.2)), baseColor.a);
872
+ }
873
+ `;
874
+
875
+ // luma.gl
876
+ // SPDX-License-Identifier: MIT
877
+ // Copyright (c) vis.gl contributors
878
+ const uniformBlock$1 = /* glsl */ `\
879
+ uniform pbrProjectionUniforms {
880
+ mat4 modelViewProjectionMatrix;
881
+ mat4 modelMatrix;
882
+ mat4 normalMatrix;
883
+ vec3 camera;
884
+ } pbrProjection;
885
+ `;
886
+ const pbrProjection = {
887
+ name: 'pbrProjection',
888
+ vs: uniformBlock$1,
889
+ fs: uniformBlock$1,
890
+ // TODO why is this needed?
891
+ getUniforms: props => props,
892
+ uniformTypes: {
893
+ modelViewProjectionMatrix: 'mat4x4<f32>',
894
+ modelMatrix: 'mat4x4<f32>',
895
+ normalMatrix: 'mat4x4<f32>',
896
+ camera: 'vec3<i32>'
897
+ }
898
+ };
899
+
900
+ // luma.gl
901
+ // SPDX-License-Identifier: MIT
902
+ // Copyright (c) vis.gl contributors
903
+ /**
904
+ * An implementation of PBR (Physically-Based Rendering).
905
+ * Physically Based Shading of a microfacet surface defined by a glTF material.
906
+ */
907
+ const pbrMaterial = {
908
+ props: {},
909
+ uniforms: {},
910
+ name: 'pbrMaterial',
911
+ dependencies: [lighting, pbrProjection],
912
+ source,
913
+ vs: vs$2,
914
+ fs: fs$2,
915
+ defines: {
916
+ LIGHTING_FRAGMENT: true,
917
+ HAS_NORMALMAP: false,
918
+ HAS_EMISSIVEMAP: false,
919
+ HAS_OCCLUSIONMAP: false,
920
+ HAS_BASECOLORMAP: false,
921
+ HAS_METALROUGHNESSMAP: false,
922
+ ALPHA_CUTOFF: false,
923
+ USE_IBL: false,
924
+ PBR_DEBUG: false
925
+ },
926
+ getUniforms: props => props,
927
+ uniformTypes: {
928
+ // Material is unlit
929
+ unlit: 'i32',
930
+ // Base color map
931
+ baseColorMapEnabled: 'i32',
932
+ baseColorFactor: 'vec4<f32>',
933
+ normalMapEnabled: 'i32',
934
+ normalScale: 'f32', // #ifdef HAS_NORMALMAP
935
+ emissiveMapEnabled: 'i32',
936
+ emissiveFactor: 'vec3<f32>', // #ifdef HAS_EMISSIVEMAP
937
+ metallicRoughnessValues: 'vec2<f32>',
938
+ metallicRoughnessMapEnabled: 'i32',
939
+ occlusionMapEnabled: 'i32',
940
+ occlusionStrength: 'f32', // #ifdef HAS_OCCLUSIONMAP
941
+ alphaCutoffEnabled: 'i32',
942
+ alphaCutoff: 'f32', // #ifdef ALPHA_CUTOFF
943
+ // IBL
944
+ IBLenabled: 'i32',
945
+ scaleIBLAmbient: 'vec2<f32>', // #ifdef USE_IBL
946
+ // debugging flags used for shader output of intermediate PBR variables
947
+ // #ifdef PBR_DEBUG
948
+ scaleDiffBaseMR: 'vec4<f32>',
949
+ scaleFGDSpec: 'vec4<f32>'
950
+ }
951
+ };
952
+
953
+ // luma.gl
954
+ // SPDX-License-Identifier: MIT
955
+ // Copyright (c) vis.gl contributors
956
+ class ScenegraphNode {
957
+ id;
958
+ matrix = new Matrix4();
959
+ display = true;
960
+ position = new Vector3();
961
+ rotation = new Vector3();
962
+ scale = new Vector3(1, 1, 1);
963
+ userData = {};
964
+ props = {};
965
+ constructor(props = {}) {
966
+ const { id } = props;
967
+ this.id = id || uid(this.constructor.name);
968
+ this._setScenegraphNodeProps(props);
969
+ }
970
+ getBounds() {
971
+ return null;
972
+ }
973
+ destroy() { }
974
+ /** @deprecated use .destroy() */
975
+ delete() {
976
+ this.destroy();
977
+ }
978
+ setProps(props) {
979
+ this._setScenegraphNodeProps(props);
980
+ return this;
981
+ }
982
+ toString() {
983
+ return `{type: ScenegraphNode, id: ${this.id})}`;
984
+ }
985
+ setPosition(position) {
986
+ // assert(position.length === 3, 'setPosition requires vector argument');
987
+ this.position = position;
988
+ return this;
989
+ }
990
+ setRotation(rotation) {
991
+ // assert(rotation.length === 3, 'setRotation requires vector argument');
992
+ this.rotation = rotation;
993
+ return this;
994
+ }
995
+ setScale(scale) {
996
+ // assert(scale.length === 3, 'setScale requires vector argument');
997
+ this.scale = scale;
998
+ return this;
999
+ }
1000
+ setMatrix(matrix, copyMatrix = true) {
1001
+ if (copyMatrix) {
1002
+ this.matrix.copy(matrix);
1003
+ }
1004
+ else {
1005
+ this.matrix = matrix;
1006
+ }
1007
+ }
1008
+ setMatrixComponents(components) {
1009
+ const { position, rotation, scale, update = true } = components;
1010
+ if (position) {
1011
+ this.setPosition(position);
1012
+ }
1013
+ if (rotation) {
1014
+ this.setRotation(rotation);
1015
+ }
1016
+ if (scale) {
1017
+ this.setScale(scale);
1018
+ }
1019
+ if (update) {
1020
+ this.updateMatrix();
1021
+ }
1022
+ return this;
1023
+ }
1024
+ updateMatrix() {
1025
+ const pos = this.position;
1026
+ const rot = this.rotation;
1027
+ const scale = this.scale;
1028
+ this.matrix.identity();
1029
+ this.matrix.translate(pos);
1030
+ this.matrix.rotateXYZ(rot);
1031
+ this.matrix.scale(scale);
1032
+ return this;
1033
+ }
1034
+ update(options = {}) {
1035
+ const { position, rotation, scale } = options;
1036
+ if (position) {
1037
+ this.setPosition(position);
1038
+ }
1039
+ if (rotation) {
1040
+ this.setRotation(rotation);
1041
+ }
1042
+ if (scale) {
1043
+ this.setScale(scale);
1044
+ }
1045
+ this.updateMatrix();
1046
+ return this;
1047
+ }
1048
+ getCoordinateUniforms(viewMatrix, modelMatrix) {
1049
+ // TODO - solve multiple class problem
1050
+ // assert(viewMatrix instanceof Matrix4);
1051
+ // assert(viewMatrix);
1052
+ modelMatrix = modelMatrix || this.matrix;
1053
+ const worldMatrix = new Matrix4(viewMatrix).multiplyRight(modelMatrix);
1054
+ const worldInverse = worldMatrix.invert();
1055
+ const worldInverseTranspose = worldInverse.transpose();
1056
+ return {
1057
+ viewMatrix,
1058
+ modelMatrix,
1059
+ objectMatrix: modelMatrix,
1060
+ worldMatrix,
1061
+ worldInverseMatrix: worldInverse,
1062
+ worldInverseTransposeMatrix: worldInverseTranspose
1063
+ };
1064
+ }
1065
+ // TODO - copied code, not yet vetted
1066
+ /*
1067
+ transform() {
1068
+ if (!this.parent) {
1069
+ this.endPosition.set(this.position);
1070
+ this.endRotation.set(this.rotation);
1071
+ this.endScale.set(this.scale);
1072
+ } else {
1073
+ const parent = this.parent;
1074
+ this.endPosition.set(this.position.add(parent.endPosition));
1075
+ this.endRotation.set(this.rotation.add(parent.endRotation));
1076
+ this.endScale.set(this.scale.add(parent.endScale));
1077
+ }
1078
+
1079
+ const ch = this.children;
1080
+ for (let i = 0; i < ch.length; ++i) {
1081
+ ch[i].transform();
1082
+ }
1083
+
1084
+ return this;
1085
+ }
1086
+ */
1087
+ _setScenegraphNodeProps(props) {
1088
+ // if ('display' in props) {
1089
+ // this.display = props.display;
1090
+ // }
1091
+ if ('position' in props) {
1092
+ this.setPosition(props.position);
1093
+ }
1094
+ if ('rotation' in props) {
1095
+ this.setRotation(props.rotation);
1096
+ }
1097
+ if ('scale' in props) {
1098
+ this.setScale(props.scale);
1099
+ }
1100
+ // Matrix overwrites other props
1101
+ if ('matrix' in props) {
1102
+ this.setMatrix(props.matrix);
1103
+ }
1104
+ Object.assign(this.props, props);
1105
+ }
1106
+ }
1107
+
1108
+ // luma.gl
1109
+ // SPDX-License-Identifier: MIT
1110
+ // Copyright (c) vis.gl contributors
1111
+ class GroupNode extends ScenegraphNode {
1112
+ children;
1113
+ constructor(props = {}) {
1114
+ props = Array.isArray(props) ? { children: props } : props;
1115
+ const { children = [] } = props;
1116
+ log.assert(children.every(child => child instanceof ScenegraphNode), 'every child must an instance of ScenegraphNode');
1117
+ super(props);
1118
+ this.children = children;
1119
+ }
1120
+ getBounds() {
1121
+ const result = [
1122
+ [Infinity, Infinity, Infinity],
1123
+ [-Infinity, -Infinity, -Infinity]
1124
+ ];
1125
+ this.traverse((node, { worldMatrix }) => {
1126
+ const bounds = node.getBounds();
1127
+ if (!bounds) {
1128
+ return;
1129
+ }
1130
+ const [min, max] = bounds;
1131
+ const center = new Vector3(min).add(max).divide([2, 2, 2]);
1132
+ worldMatrix.transformAsPoint(center, center);
1133
+ const halfSize = new Vector3(max).subtract(min).divide([2, 2, 2]);
1134
+ worldMatrix.transformAsVector(halfSize, halfSize);
1135
+ for (let v = 0; v < 8; v++) {
1136
+ // Test all 8 corners of the box
1137
+ const position = new Vector3(v & 0b001 ? -1 : 1, v & 0b010 ? -1 : 1, v & 0b100 ? -1 : 1)
1138
+ .multiply(halfSize)
1139
+ .add(center);
1140
+ for (let i = 0; i < 3; i++) {
1141
+ result[0][i] = Math.min(result[0][i], position[i]);
1142
+ result[1][i] = Math.max(result[1][i], position[i]);
1143
+ }
1144
+ }
1145
+ });
1146
+ if (!Number.isFinite(result[0][0])) {
1147
+ return null;
1148
+ }
1149
+ return result;
1150
+ }
1151
+ destroy() {
1152
+ this.children.forEach(child => child.destroy());
1153
+ this.removeAll();
1154
+ super.destroy();
1155
+ }
1156
+ // Unpacks arrays and nested arrays of children
1157
+ add(...children) {
1158
+ for (const child of children) {
1159
+ if (Array.isArray(child)) {
1160
+ this.add(...child);
1161
+ }
1162
+ else {
1163
+ this.children.push(child);
1164
+ }
1165
+ }
1166
+ return this;
1167
+ }
1168
+ remove(child) {
1169
+ const children = this.children;
1170
+ const indexOf = children.indexOf(child);
1171
+ if (indexOf > -1) {
1172
+ children.splice(indexOf, 1);
1173
+ }
1174
+ return this;
1175
+ }
1176
+ removeAll() {
1177
+ this.children = [];
1178
+ return this;
1179
+ }
1180
+ traverse(visitor, { worldMatrix = new Matrix4() } = {}) {
1181
+ const modelMatrix = new Matrix4(worldMatrix).multiplyRight(this.matrix);
1182
+ for (const child of this.children) {
1183
+ if (child instanceof GroupNode) {
1184
+ child.traverse(visitor, { worldMatrix: modelMatrix });
1185
+ }
1186
+ else {
1187
+ visitor(child, { worldMatrix: modelMatrix });
1188
+ }
1189
+ }
1190
+ }
1191
+ }
1192
+
1193
+ // luma.gl
1194
+ // SPDX-License-Identifier: MIT
1195
+ // Copyright (c) vis.gl contributors
1196
+ class ModelNode extends ScenegraphNode {
1197
+ model;
1198
+ bounds = null;
1199
+ managedResources;
1200
+ // TODO - is this used? override callbacks to make sure we call them with this
1201
+ // onBeforeRender = null;
1202
+ // onAfterRender = null;
1203
+ // AfterRender = null;
1204
+ constructor(props) {
1205
+ super(props);
1206
+ // Create new Model or used supplied Model
1207
+ this.model = props.model;
1208
+ this.managedResources = props.managedResources || [];
1209
+ this.bounds = props.bounds || null;
1210
+ this.setProps(props);
1211
+ }
1212
+ destroy() {
1213
+ if (this.model) {
1214
+ this.model.destroy();
1215
+ // @ts-expect-error
1216
+ this.model = null;
1217
+ }
1218
+ this.managedResources.forEach(resource => resource.destroy());
1219
+ this.managedResources = [];
1220
+ }
1221
+ getBounds() {
1222
+ return this.bounds;
1223
+ }
1224
+ // Expose model methods
1225
+ draw(renderPass) {
1226
+ // Return value indicates if something was actually drawn
1227
+ return this.model.draw(renderPass);
1228
+ }
1229
+ }
1230
+
1231
+ // luma.gl
1232
+ // SPDX-License-Identifier: MIT
1233
+ // Copyright (c) vis.gl contributors
1234
+ function convertSampler(gltfSampler) {
1235
+ return {
1236
+ addressModeU: convertSamplerWrapMode(gltfSampler.wrapS),
1237
+ addressModeV: convertSamplerWrapMode(gltfSampler.wrapT),
1238
+ magFilter: convertSamplerMagFilter(gltfSampler.magFilter),
1239
+ ...convertSamplerMinFilter(gltfSampler.minFilter)
1240
+ };
1241
+ }
1242
+ function convertSamplerWrapMode(mode) {
1243
+ switch (mode) {
1244
+ case 33071:
1245
+ return 'clamp-to-edge';
1246
+ case 10497:
1247
+ return 'repeat';
1248
+ case 33648:
1249
+ return 'mirror-repeat';
1250
+ default:
1251
+ return undefined;
1252
+ }
1253
+ }
1254
+ function convertSamplerMagFilter(mode) {
1255
+ switch (mode) {
1256
+ case 9728:
1257
+ return 'nearest';
1258
+ case 9729:
1259
+ return 'linear';
1260
+ default:
1261
+ return undefined;
1262
+ }
1263
+ }
1264
+ function convertSamplerMinFilter(mode) {
1265
+ switch (mode) {
1266
+ case 9728:
1267
+ return { minFilter: 'nearest' };
1268
+ case 9729:
1269
+ return { minFilter: 'linear' };
1270
+ case 9984:
1271
+ return { minFilter: 'nearest', mipmapFilter: 'nearest' };
1272
+ case 9985:
1273
+ return { minFilter: 'linear', mipmapFilter: 'nearest' };
1274
+ case 9986:
1275
+ return { minFilter: 'nearest', mipmapFilter: 'linear' };
1276
+ case 9987:
1277
+ return { minFilter: 'linear', mipmapFilter: 'linear' };
1278
+ default:
1279
+ return {};
1280
+ }
1281
+ }
1282
+
1283
+ // luma.gl
1284
+ // SPDX-License-Identifier: MIT
1285
+ // Copyright (c) vis.gl contributors
1286
+ /**
1287
+ * Parses a GLTF material definition into uniforms and parameters for the PBR shader module
1288
+ */
1289
+ function parsePBRMaterial(device, material, attributes, options) {
1290
+ const parsedMaterial = {
1291
+ defines: {
1292
+ // TODO: Use EXT_sRGB if available (Standard in WebGL 2.0)
1293
+ MANUAL_SRGB: true,
1294
+ SRGB_FAST_APPROXIMATION: true
1295
+ },
1296
+ bindings: {},
1297
+ uniforms: {
1298
+ // TODO: find better values?
1299
+ camera: [0, 0, 0], // Model should override
1300
+ metallicRoughnessValues: [1, 1] // Default is 1 and 1
1301
+ },
1302
+ parameters: {},
1303
+ glParameters: {},
1304
+ generatedTextures: []
1305
+ };
1306
+ // TODO - always available
1307
+ parsedMaterial.defines['USE_TEX_LOD'] = true;
1308
+ const { imageBasedLightingEnvironment } = options;
1309
+ if (imageBasedLightingEnvironment) {
1310
+ parsedMaterial.bindings.pbr_diffuseEnvSampler =
1311
+ imageBasedLightingEnvironment.diffuseEnvSampler.texture;
1312
+ parsedMaterial.bindings.pbr_specularEnvSampler =
1313
+ imageBasedLightingEnvironment.specularEnvSampler.texture;
1314
+ parsedMaterial.bindings.pbr_BrdfLUT = imageBasedLightingEnvironment.brdfLutTexture.texture;
1315
+ parsedMaterial.uniforms.scaleIBLAmbient = [1, 1];
1316
+ }
1317
+ if (options?.pbrDebug) {
1318
+ parsedMaterial.defines['PBR_DEBUG'] = true;
1319
+ // Override final color for reference app visualization of various parameters in the lighting equation.
1320
+ parsedMaterial.uniforms.scaleDiffBaseMR = [0, 0, 0, 0];
1321
+ parsedMaterial.uniforms.scaleFGDSpec = [0, 0, 0, 0];
1322
+ }
1323
+ if (attributes['NORMAL'])
1324
+ parsedMaterial.defines['HAS_NORMALS'] = true;
1325
+ if (attributes['TANGENT'] && options?.useTangents)
1326
+ parsedMaterial.defines['HAS_TANGENTS'] = true;
1327
+ if (attributes['TEXCOORD_0'])
1328
+ parsedMaterial.defines['HAS_UV'] = true;
1329
+ if (options?.imageBasedLightingEnvironment)
1330
+ parsedMaterial.defines['USE_IBL'] = true;
1331
+ if (options?.lights)
1332
+ parsedMaterial.defines['USE_LIGHTS'] = true;
1333
+ if (material) {
1334
+ parseMaterial(device, material, parsedMaterial);
1335
+ }
1336
+ return parsedMaterial;
1337
+ }
1338
+ /** Parse GLTF material record */
1339
+ function parseMaterial(device, material, parsedMaterial) {
1340
+ parsedMaterial.uniforms.unlit = Boolean(material.unlit);
1341
+ if (material.pbrMetallicRoughness) {
1342
+ parsePbrMetallicRoughness(device, material.pbrMetallicRoughness, parsedMaterial);
1343
+ }
1344
+ if (material.normalTexture) {
1345
+ addTexture(device, material.normalTexture, 'pbr_normalSampler', 'HAS_NORMALMAP', parsedMaterial);
1346
+ const { scale = 1 } = material.normalTexture;
1347
+ parsedMaterial.uniforms.normalScale = scale;
1348
+ }
1349
+ if (material.occlusionTexture) {
1350
+ addTexture(device, material.occlusionTexture, 'pbr_occlusionSampler', 'HAS_OCCLUSIONMAP', parsedMaterial);
1351
+ const { strength = 1 } = material.occlusionTexture;
1352
+ parsedMaterial.uniforms.occlusionStrength = strength;
1353
+ }
1354
+ if (material.emissiveTexture) {
1355
+ addTexture(device, material.emissiveTexture, 'pbr_emissiveSampler', 'HAS_EMISSIVEMAP', parsedMaterial);
1356
+ parsedMaterial.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];
1357
+ }
1358
+ switch (material.alphaMode || 'MASK') {
1359
+ case 'MASK':
1360
+ const { alphaCutoff = 0.5 } = material;
1361
+ parsedMaterial.defines['ALPHA_CUTOFF'] = true;
1362
+ parsedMaterial.uniforms.alphaCutoff = alphaCutoff;
1363
+ break;
1364
+ case 'BLEND':
1365
+ log.warn('glTF BLEND alphaMode might not work well because it requires mesh sorting')();
1366
+ // WebGPU style parameters
1367
+ parsedMaterial.parameters.blend = true;
1368
+ parsedMaterial.parameters.blendColorOperation = 'add';
1369
+ parsedMaterial.parameters.blendColorSrcFactor = 'src-alpha';
1370
+ parsedMaterial.parameters.blendColorDstFactor = 'one-minus-src-alpha';
1371
+ parsedMaterial.parameters.blendAlphaOperation = 'add';
1372
+ parsedMaterial.parameters.blendAlphaSrcFactor = 'one';
1373
+ parsedMaterial.parameters.blendAlphaDstFactor = 'one-minus-src-alpha';
1374
+ // GL parameters
1375
+ // TODO - remove in favor of parameters
1376
+ parsedMaterial.glParameters['blend'] = true;
1377
+ parsedMaterial.glParameters['blendEquation'] = 32774;
1378
+ parsedMaterial.glParameters['blendFunc'] = [
1379
+ 770,
1380
+ 771,
1381
+ 1,
1382
+ 771
1383
+ ];
1384
+ break;
1385
+ }
1386
+ }
1387
+ /** Parse GLTF material sub record */
1388
+ function parsePbrMetallicRoughness(device, pbrMetallicRoughness, parsedMaterial) {
1389
+ if (pbrMetallicRoughness.baseColorTexture) {
1390
+ addTexture(device, pbrMetallicRoughness.baseColorTexture, 'pbr_baseColorSampler', 'HAS_BASECOLORMAP', parsedMaterial);
1391
+ }
1392
+ parsedMaterial.uniforms.baseColorFactor = pbrMetallicRoughness.baseColorFactor || [1, 1, 1, 1];
1393
+ if (pbrMetallicRoughness.metallicRoughnessTexture) {
1394
+ addTexture(device, pbrMetallicRoughness.metallicRoughnessTexture, 'pbr_metallicRoughnessSampler', 'HAS_METALROUGHNESSMAP', parsedMaterial);
1395
+ }
1396
+ const { metallicFactor = 1, roughnessFactor = 1 } = pbrMetallicRoughness;
1397
+ parsedMaterial.uniforms.metallicRoughnessValues = [metallicFactor, roughnessFactor];
1398
+ }
1399
+ /** Create a texture from a glTF texture/sampler/image combo and add it to bindings */
1400
+ function addTexture(device, gltfTexture, uniformName, define, parsedMaterial) {
1401
+ const image = gltfTexture.texture.source.image;
1402
+ let textureOptions;
1403
+ if (image.compressed) {
1404
+ textureOptions = image;
1405
+ }
1406
+ else {
1407
+ // Texture2D accepts a promise that returns an image as data (Async Textures)
1408
+ textureOptions = { data: image };
1409
+ }
1410
+ const gltfSampler = {
1411
+ wrapS: 10497, // default REPEAT S (U) wrapping mode.
1412
+ wrapT: 10497, // default REPEAT T (V) wrapping mode.
1413
+ ...gltfTexture?.texture?.sampler
1414
+ };
1415
+ const texture = device.createTexture({
1416
+ id: gltfTexture.uniformName || gltfTexture.id,
1417
+ sampler: convertSampler(gltfSampler),
1418
+ ...textureOptions
1419
+ });
1420
+ parsedMaterial.bindings[uniformName] = texture;
1421
+ if (define)
1422
+ parsedMaterial.defines[define] = true;
1423
+ parsedMaterial.generatedTextures.push(texture);
1424
+ }
1425
+ /*
1426
+ /**
1427
+ * Parses a GLTF material definition into uniforms and parameters for the PBR shader module
1428
+ *
1429
+ export class PBRMaterialParser {
1430
+ readonly device: Device;
1431
+
1432
+ readonly defines: Record<string, boolean>;
1433
+ readonly bindings: Record<string, Binding>;
1434
+ readonly uniforms: Record<string, any>;
1435
+ readonly parameters: Record<string, any>;
1436
+
1437
+ /** Hold on to generated textures, we destroy them in the destroy method *
1438
+ readonly generatedTextures: Texture[];
1439
+
1440
+ constructor(device: Device, props: PBRMaterialParserProps) {
1441
+ const {attributes, material, pbrDebug, imageBasedLightingEnvironment, lights, useTangents} =
1442
+ props;
1443
+ this.device = device;
1444
+
1445
+ this.defines = {
1446
+ // TODO: Use EXT_sRGB if available (Standard in WebGL 2.0)
1447
+ MANUAL_SRGB: true,
1448
+ SRGB_FAST_APPROXIMATION: true
1449
+ };
1450
+
1451
+ if (this.device.features.has('glsl-texture-lod')) {
1452
+ this.defines.USE_TEX_LOD = true;
1453
+ }
1454
+
1455
+ this.uniforms = {
1456
+ // TODO: find better values?
1457
+ camera: [0, 0, 0], // Model should override
1458
+
1459
+ metallicRoughnessValues: [1, 1] // Default is 1 and 1
1460
+ };
1461
+
1462
+ this.bindings = {};
1463
+
1464
+ this.parameters = {};
1465
+ this.generatedTextures = [];
1466
+
1467
+ if (imageBasedLightingEnvironment) {
1468
+ this.bindings.pbr_diffuseEnvSampler = imageBasedLightingEnvironment.getDiffuseEnvSampler();
1469
+ this.bindings.pbr_specularEnvSampler = imageBasedLightingEnvironment.getSpecularEnvSampler();
1470
+ this.bindings.pbr_BrdfLUT = imageBasedLightingEnvironment.getBrdfTexture();
1471
+ this.uniforms.scaleIBLAmbient = [1, 1];
1472
+ }
1473
+
1474
+ if (pbrDebug) {
1475
+ // Override final color for reference app visualization
1476
+ // of various parameters in the lighting equation.
1477
+ this.uniforms.scaleDiffBaseMR = [0, 0, 0, 0];
1478
+ this.uniforms.scaleFGDSpec = [0, 0, 0, 0];
1479
+ }
1480
+
1481
+ this.defineIfPresent(attributes.NORMAL, 'HAS_NORMALS');
1482
+ this.defineIfPresent(attributes.TANGENT && useTangents, 'HAS_TANGENTS');
1483
+ this.defineIfPresent(attributes.TEXCOORD_0, 'HAS_UV');
1484
+
1485
+ this.defineIfPresent(imageBasedLightingEnvironment, 'USE_IBL');
1486
+ this.defineIfPresent(lights, 'USE_LIGHTS');
1487
+ this.defineIfPresent(pbrDebug, 'PBR_DEBUG');
1488
+
1489
+ if (material) {
1490
+ this.parseMaterial(material);
1491
+ }
1492
+ }
1493
+
1494
+ /**
1495
+ * Destroy all generated resources to release memory.
1496
+ *
1497
+ destroy(): void {
1498
+ this.generatedTextures.forEach(texture => texture.destroy());
1499
+ }
1500
+
1501
+ /** Add a define if the the value is non-nullish *
1502
+ defineIfPresent(value: unknown, name: string): void {
1503
+ if (value) {
1504
+ this.defines[name] = 1;
1505
+ }
1506
+ }
1507
+
1508
+ /** Parse GLTF material record *
1509
+ parseMaterial(material) {
1510
+ this.uniforms.unlit = Boolean(material.unlit);
1511
+
1512
+ if (material.pbrMetallicRoughness) {
1513
+ this.parsePbrMetallicRoughness(material.pbrMetallicRoughness);
1514
+ }
1515
+ if (material.normalTexture) {
1516
+ this.addTexture(material.normalTexture, 'pbr_normalSampler', 'HAS_NORMALMAP');
1517
+
1518
+ const {scale = 1} = material.normalTexture;
1519
+ this.uniforms.normalScale = scale;
1520
+ }
1521
+ if (material.occlusionTexture) {
1522
+ this.addTexture(material.occlusionTexture, 'pbr_occlusionSampler', 'HAS_OCCLUSIONMAP');
1523
+
1524
+ const {strength = 1} = material.occlusionTexture;
1525
+ this.uniforms.occlusionStrength = strength;
1526
+ }
1527
+ if (material.emissiveTexture) {
1528
+ this.addTexture(material.emissiveTexture, 'pbr_emissiveSampler', 'HAS_EMISSIVEMAP');
1529
+ this.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];
1530
+ }
1531
+ if (material.alphaMode === 'MASK') {
1532
+ const {alphaCutoff = 0.5} = material;
1533
+ this.defines.ALPHA_CUTOFF = true;
1534
+ this.uniforms.u_AlphaCutoff = alphaCutoff;
1535
+ } else if (material.alphaMode === 'BLEND') {
1536
+ log.warn('BLEND alphaMode might not work well because it requires mesh sorting')();
1537
+ Object.assign(this.parameters, {
1538
+ blend: true,
1539
+ blendEquation: GL.FUNC_ADD,
1540
+ blendFunc: [GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA, GL.ONE, GL.ONE_MINUS_SRC_ALPHA]
1541
+ });
1542
+ }
1543
+ }
1544
+
1545
+ /** Parse GLTF material sub record *
1546
+ parsePbrMetallicRoughness(pbrMetallicRoughness) {
1547
+ if (pbrMetallicRoughness.baseColorTexture) {
1548
+ this.addTexture(
1549
+ pbrMetallicRoughness.baseColorTexture,
1550
+ 'pbr_baseColorSampler',
1551
+ 'HAS_BASECOLORMAP'
1552
+ );
1553
+ }
1554
+ this.uniforms.baseColorFactor = pbrMetallicRoughness.baseColorFactor || [1, 1, 1, 1];
1555
+
1556
+ if (pbrMetallicRoughness.metallicRoughnessTexture) {
1557
+ this.addTexture(
1558
+ pbrMetallicRoughness.metallicRoughnessTexture,
1559
+ 'pbr_metallicRoughnessSampler',
1560
+ 'HAS_METALROUGHNESSMAP'
1561
+ );
1562
+ }
1563
+ const {metallicFactor = 1, roughnessFactor = 1} = pbrMetallicRoughness;
1564
+ this.uniforms.metallicRoughnessValues = [metallicFactor, roughnessFactor];
1565
+ }
1566
+
1567
+ /** Create a texture from a glTF texture/sampler/image combo and add it to bindings *
1568
+ addTexture(gltfTexture, name, define = null) {
1569
+ const parameters = gltfTexture?.texture?.sampler?.parameters || {};
1570
+
1571
+ const image = gltfTexture.texture.source.image;
1572
+ let textureOptions;
1573
+ let specialTextureParameters = {};
1574
+ if (image.compressed) {
1575
+ textureOptions = image;
1576
+ specialTextureParameters = {
1577
+ [GL.TEXTURE_MIN_FILTER]: image.data.length > 1 ? GL.LINEAR_MIPMAP_NEAREST : GL.LINEAR
1578
+ };
1579
+ } else {
1580
+ // Texture2D accepts a promise that returns an image as data (Async Textures)
1581
+ textureOptions = {data: image};
1582
+ }
1583
+
1584
+ const texture: Texture = this.device.createTexture({
1585
+ id: gltfTexture.name || gltfTexture.id,
1586
+ parameters: {
1587
+ ...parameters,
1588
+ ...specialTextureParameters
1589
+ },
1590
+ pixelStore: {
1591
+ [GL.UNPACK_FLIP_Y_WEBGL]: false
1592
+ },
1593
+ ...textureOptions
1594
+ });
1595
+ this.bindings[name] = texture;
1596
+ this.defineIfPresent(define, define);
1597
+ this.generatedTextures.push(texture);
1598
+ }
1599
+ }
1600
+ */
1601
+
1602
+ // luma.gl
1603
+ // SPDX-License-Identifier: MIT
1604
+ // Copyright (c) vis.gl contributors
1605
+ // NOTE: Modules other than `@luma.gl/webgl` should not import `GL` from
1606
+ // `@luma.gl/constants`. Locally we use `GLEnum` instead of `GL` to avoid
1607
+ // conflicts with the `babel-plugin-inline-webgl-constants` plugin.
1608
+ // eslint-disable-next-line no-shadow
1609
+ var GLEnum;
1610
+ (function (GLEnum) {
1611
+ GLEnum[GLEnum["POINTS"] = 0] = "POINTS";
1612
+ GLEnum[GLEnum["LINES"] = 1] = "LINES";
1613
+ GLEnum[GLEnum["LINE_LOOP"] = 2] = "LINE_LOOP";
1614
+ GLEnum[GLEnum["LINE_STRIP"] = 3] = "LINE_STRIP";
1615
+ GLEnum[GLEnum["TRIANGLES"] = 4] = "TRIANGLES";
1616
+ GLEnum[GLEnum["TRIANGLE_STRIP"] = 5] = "TRIANGLE_STRIP";
1617
+ GLEnum[GLEnum["TRIANGLE_FAN"] = 6] = "TRIANGLE_FAN";
1618
+ })(GLEnum || (GLEnum = {}));
1619
+ function convertGLDrawModeToTopology(drawMode) {
1620
+ // prettier-ignore
1621
+ switch (drawMode) {
1622
+ case GLEnum.POINTS: return 'point-list';
1623
+ case GLEnum.LINES: return 'line-list';
1624
+ case GLEnum.LINE_STRIP: return 'line-strip';
1625
+ case GLEnum.TRIANGLES: return 'triangle-list';
1626
+ case GLEnum.TRIANGLE_STRIP: return 'triangle-strip';
1627
+ default: throw new Error(String(drawMode));
1628
+ }
1629
+ }
1630
+
1631
+ // luma.gl
1632
+ // SPDX-License-Identifier: MIT
1633
+ // Copyright (c) vis.gl contributors
1634
+ const SHADER = /* WGSL */ `
1635
+ layout(0) positions: vec4; // in vec4 POSITION;
1636
+
1637
+ #ifdef HAS_NORMALS
1638
+ in vec4 normals; // in vec4 NORMAL;
1639
+ #endif
1640
+
1641
+ #ifdef HAS_TANGENTS
1642
+ in vec4 TANGENT;
1643
+ #endif
1644
+
1645
+ #ifdef HAS_UV
1646
+ // in vec2 TEXCOORD_0;
1647
+ in vec2 texCoords;
1648
+ #endif
1649
+
1650
+ @vertex
1651
+ void main(void) {
1652
+ vec4 _NORMAL = vec4(0.);
1653
+ vec4 _TANGENT = vec4(0.);
1654
+ vec2 _TEXCOORD_0 = vec2(0.);
1655
+
1656
+ #ifdef HAS_NORMALS
1657
+ _NORMAL = normals;
1658
+ #endif
1659
+
1660
+ #ifdef HAS_TANGENTS
1661
+ _TANGENT = TANGENT;
1662
+ #endif
1663
+
1664
+ #ifdef HAS_UV
1665
+ _TEXCOORD_0 = texCoords;
1666
+ #endif
1667
+
1668
+ pbr_setPositionNormalTangentUV(positions, _NORMAL, _TANGENT, _TEXCOORD_0);
1669
+ gl_Position = u_MVPMatrix * positions;
1670
+ }
1671
+
1672
+ @fragment
1673
+ out vec4 fragmentColor;
1674
+
1675
+ void main(void) {
1676
+ vec3 pos = pbr_vPosition;
1677
+ fragmentColor = pbr_filterColor(vec4(1.0));
1678
+ }
1679
+ `;
1680
+ // TODO rename attributes to POSITION/NORMAL etc
1681
+ // See gpu-geometry.ts: getAttributeBuffersFromGeometry()
1682
+ const vs$1 = /* glsl */ `\
1683
+ #version 300 es
1684
+
1685
+ // in vec4 POSITION;
1686
+ in vec4 positions;
1687
+
1688
+ #ifdef HAS_NORMALS
1689
+ // in vec4 NORMAL;
1690
+ in vec4 normals;
1691
+ #endif
1692
+
1693
+ #ifdef HAS_TANGENTS
1694
+ in vec4 TANGENT;
1695
+ #endif
1696
+
1697
+ #ifdef HAS_UV
1698
+ // in vec2 TEXCOORD_0;
1699
+ in vec2 texCoords;
1700
+ #endif
1701
+
1702
+ void main(void) {
1703
+ vec4 _NORMAL = vec4(0.);
1704
+ vec4 _TANGENT = vec4(0.);
1705
+ vec2 _TEXCOORD_0 = vec2(0.);
1706
+
1707
+ #ifdef HAS_NORMALS
1708
+ _NORMAL = normals;
1709
+ #endif
1710
+
1711
+ #ifdef HAS_TANGENTS
1712
+ _TANGENT = TANGENT;
1713
+ #endif
1714
+
1715
+ #ifdef HAS_UV
1716
+ _TEXCOORD_0 = texCoords;
1717
+ #endif
1718
+
1719
+ pbr_setPositionNormalTangentUV(positions, _NORMAL, _TANGENT, _TEXCOORD_0);
1720
+ gl_Position = pbrProjection.modelViewProjectionMatrix * positions;
1721
+ }
1722
+ `;
1723
+ const fs$1 = /* glsl */ `\
1724
+ #version 300 es
1725
+ out vec4 fragmentColor;
1726
+
1727
+ void main(void) {
1728
+ vec3 pos = pbr_vPosition;
1729
+ fragmentColor = pbr_filterColor(vec4(1.0));
1730
+ }
1731
+ `;
1732
+ /** Creates a luma.gl Model from GLTF data*/
1733
+ function createGLTFModel(device, options) {
1734
+ const { id, geometry, parsedPPBRMaterial, vertexCount, modelOptions = {} } = options;
1735
+ log.info(4, 'createGLTFModel defines: ', parsedPPBRMaterial.defines)();
1736
+ // Calculate managedResources
1737
+ // TODO: Implement resource management logic that will
1738
+ // not deallocate resources/textures/buffers that are shared
1739
+ const managedResources = [];
1740
+ // managedResources.push(...parsedMaterial.generatedTextures);
1741
+ // managedResources.push(...Object.values(attributes).map((attribute) => attribute.buffer));
1742
+ const parameters = {
1743
+ depthWriteEnabled: true,
1744
+ depthCompare: 'less',
1745
+ depthFormat: 'depth24plus',
1746
+ cullMode: 'back'
1747
+ };
1748
+ const modelProps = {
1749
+ id,
1750
+ source: SHADER,
1751
+ vs: vs$1,
1752
+ fs: fs$1,
1753
+ geometry,
1754
+ topology: geometry.topology,
1755
+ vertexCount,
1756
+ modules: [pbrMaterial],
1757
+ ...modelOptions,
1758
+ defines: { ...parsedPPBRMaterial.defines, ...modelOptions.defines },
1759
+ parameters: { ...parameters, ...parsedPPBRMaterial.parameters, ...modelOptions.parameters }
1760
+ };
1761
+ const model = new Model(device, modelProps);
1762
+ const { camera, ...pbrMaterialProps } = {
1763
+ ...parsedPPBRMaterial.uniforms,
1764
+ ...modelOptions.uniforms,
1765
+ ...parsedPPBRMaterial.bindings,
1766
+ ...modelOptions.bindings
1767
+ };
1768
+ model.shaderInputs.setProps({ pbrMaterial: pbrMaterialProps, pbrProjection: { camera } });
1769
+ return new ModelNode({ managedResources, model });
1770
+ }
1771
+
1772
+ // luma.gl
1773
+ // SPDX-License-Identifier: MIT
1774
+ // Copyright (c) vis.gl contributors
1775
+ const defaultOptions = {
1776
+ modelOptions: {},
1777
+ pbrDebug: false,
1778
+ imageBasedLightingEnvironment: undefined,
1779
+ lights: true,
1780
+ useTangents: false
1781
+ };
1782
+ /**
1783
+ * GLTF instantiator for luma.gl
1784
+ * Walks the parsed and resolved glTF structure and builds a luma.gl scenegraph
1785
+ */
1786
+ function parseGLTF(device, gltf, options_ = {}) {
1787
+ const options = { ...defaultOptions, ...options_ };
1788
+ const sceneNodes = gltf.scenes.map(gltfScene => createScene(device, gltfScene, gltf.nodes, options));
1789
+ return sceneNodes;
1790
+ }
1791
+ function createScene(device, gltfScene, gltfNodes, options) {
1792
+ const gltfSceneNodes = gltfScene.nodes || [];
1793
+ const nodes = gltfSceneNodes.map(node => createNode(device, node, gltfNodes, options));
1794
+ const sceneNode = new GroupNode({
1795
+ id: gltfScene.name || gltfScene.id,
1796
+ children: nodes
1797
+ });
1798
+ return sceneNode;
1799
+ }
1800
+ function createNode(device, gltfNode, gltfNodes, options) {
1801
+ if (!gltfNode._node) {
1802
+ const gltfChildren = gltfNode.children || [];
1803
+ const children = gltfChildren.map(child => createNode(device, child, gltfNodes, options));
1804
+ // Node can have children nodes and meshes at the same time
1805
+ if (gltfNode.mesh) {
1806
+ children.push(createMesh(device, gltfNode.mesh, options));
1807
+ }
1808
+ const node = new GroupNode({
1809
+ id: gltfNode.name || gltfNode.id,
1810
+ children
1811
+ });
1812
+ if (gltfNode.matrix) {
1813
+ node.setMatrix(gltfNode.matrix);
1814
+ }
1815
+ else {
1816
+ node.matrix.identity();
1817
+ if (gltfNode.translation) {
1818
+ node.matrix.translate(gltfNode.translation);
1819
+ }
1820
+ if (gltfNode.rotation) {
1821
+ const rotationMatrix = new Matrix4().fromQuaternion(gltfNode.rotation);
1822
+ node.matrix.multiplyRight(rotationMatrix);
1823
+ }
1824
+ if (gltfNode.scale) {
1825
+ node.matrix.scale(gltfNode.scale);
1826
+ }
1827
+ }
1828
+ gltfNode._node = node;
1829
+ }
1830
+ // Copy _node so that gltf-animator can access
1831
+ const topLevelNode = gltfNodes.find(node => node.id === gltfNode.id);
1832
+ topLevelNode._node = gltfNode._node;
1833
+ return gltfNode._node;
1834
+ }
1835
+ function createMesh(device, gltfMesh, options) {
1836
+ // TODO: avoid changing the gltf
1837
+ if (!gltfMesh._mesh) {
1838
+ const gltfPrimitives = gltfMesh.primitives || [];
1839
+ const primitives = gltfPrimitives.map((gltfPrimitive, i) => createPrimitive(device, gltfPrimitive, i, gltfMesh, options));
1840
+ const mesh = new GroupNode({
1841
+ id: gltfMesh.name || gltfMesh.id,
1842
+ children: primitives
1843
+ });
1844
+ gltfMesh._mesh = mesh;
1845
+ }
1846
+ return gltfMesh._mesh;
1847
+ }
1848
+ function createPrimitive(device, gltfPrimitive, i, gltfMesh, options) {
1849
+ const id = gltfPrimitive.name || `${gltfMesh.name || gltfMesh.id}-primitive-${i}`;
1850
+ const topology = convertGLDrawModeToTopology(gltfPrimitive.mode || 4);
1851
+ const vertexCount = gltfPrimitive.indices
1852
+ ? gltfPrimitive.indices.count
1853
+ : getVertexCount();
1854
+ const geometry = createGeometry(id, gltfPrimitive, topology);
1855
+ const parsedPPBRMaterial = parsePBRMaterial(device, gltfPrimitive.material, geometry.attributes, options);
1856
+ const modelNode = createGLTFModel(device, {
1857
+ id,
1858
+ geometry: createGeometry(id, gltfPrimitive, topology),
1859
+ parsedPPBRMaterial,
1860
+ modelOptions: options.modelOptions,
1861
+ vertexCount
1862
+ });
1863
+ modelNode.bounds = [gltfPrimitive.attributes.POSITION.min, gltfPrimitive.attributes.POSITION.max];
1864
+ // TODO this holds on to all the CPU side texture and attribute data
1865
+ // modelNode.material = gltfPrimitive.material;
1866
+ return modelNode;
1867
+ }
1868
+ function getVertexCount(attributes) {
1869
+ throw new Error('getVertexCount not implemented');
1870
+ }
1871
+ function createGeometry(id, gltfPrimitive, topology) {
1872
+ const attributes = {};
1873
+ for (const [attributeName, attribute] of Object.entries(gltfPrimitive.attributes)) {
1874
+ const { components, size, value } = attribute;
1875
+ attributes[attributeName] = { size: size ?? components, value };
1876
+ }
1877
+ return new Geometry({
1878
+ id,
1879
+ topology,
1880
+ indices: gltfPrimitive.indices.value,
1881
+ attributes
1882
+ });
1883
+ }
1884
+
1885
+ const scratchQuaternion = new Quaternion();
1886
+ function interpolate(time, { input, interpolation, output }, target, path) {
1887
+ const maxTime = input[input.length - 1];
1888
+ const animationTime = time % maxTime;
1889
+ const nextIndex = input.findIndex(t => t >= animationTime);
1890
+ const previousIndex = Math.max(0, nextIndex - 1);
1891
+ if (!Array.isArray(target[path])) {
1892
+ switch (path) {
1893
+ case 'translation':
1894
+ target[path] = [0, 0, 0];
1895
+ break;
1896
+ case 'rotation':
1897
+ target[path] = [0, 0, 0, 1];
1898
+ break;
1899
+ case 'scale':
1900
+ target[path] = [1, 1, 1];
1901
+ break;
1902
+ default:
1903
+ log.warn(`Bad animation path ${path}`)();
1904
+ }
1905
+ }
1906
+ // assert(target[path].length === output[previousIndex].length);
1907
+ const previousTime = input[previousIndex];
1908
+ const nextTime = input[nextIndex];
1909
+ switch (interpolation) {
1910
+ case 'STEP':
1911
+ stepInterpolate(target, path, output[previousIndex]);
1912
+ break;
1913
+ case 'LINEAR':
1914
+ if (nextTime > previousTime) {
1915
+ const ratio = (animationTime - previousTime) / (nextTime - previousTime);
1916
+ linearInterpolate(target, path, output[previousIndex], output[nextIndex], ratio);
1917
+ }
1918
+ break;
1919
+ case 'CUBICSPLINE':
1920
+ if (nextTime > previousTime) {
1921
+ const ratio = (animationTime - previousTime) / (nextTime - previousTime);
1922
+ const tDiff = nextTime - previousTime;
1923
+ const p0 = output[3 * previousIndex + 1];
1924
+ const outTangent0 = output[3 * previousIndex + 2];
1925
+ const inTangent1 = output[3 * nextIndex + 0];
1926
+ const p1 = output[3 * nextIndex + 1];
1927
+ cubicsplineInterpolate(target, path, { p0, outTangent0, inTangent1, p1, tDiff, ratio });
1928
+ }
1929
+ break;
1930
+ default:
1931
+ log.warn(`Interpolation ${interpolation} not supported`)();
1932
+ break;
1933
+ }
1934
+ }
1935
+ function linearInterpolate(target, path, start, stop, ratio) {
1936
+ if (!target[path]) {
1937
+ throw new Error();
1938
+ }
1939
+ if (path === 'rotation') {
1940
+ // SLERP when path is rotation
1941
+ scratchQuaternion.slerp({ start, target: stop, ratio });
1942
+ for (let i = 0; i < scratchQuaternion.length; i++) {
1943
+ target[path][i] = scratchQuaternion[i];
1944
+ }
1945
+ }
1946
+ else {
1947
+ // regular interpolation
1948
+ for (let i = 0; i < start.length; i++) {
1949
+ target[path][i] = ratio * stop[i] + (1 - ratio) * start[i];
1950
+ }
1951
+ }
1952
+ }
1953
+ function cubicsplineInterpolate(target, path, { p0, outTangent0, inTangent1, p1, tDiff, ratio: t }) {
1954
+ if (!target[path]) {
1955
+ throw new Error();
1956
+ }
1957
+ // TODO: Quaternion might need normalization
1958
+ for (let i = 0; i < target[path].length; i++) {
1959
+ const m0 = outTangent0[i] * tDiff;
1960
+ const m1 = inTangent1[i] * tDiff;
1961
+ target[path][i] =
1962
+ (2 * Math.pow(t, 3) - 3 * Math.pow(t, 2) + 1) * p0[i] +
1963
+ (Math.pow(t, 3) - 2 * Math.pow(t, 2) + t) * m0 +
1964
+ (-2 * Math.pow(t, 3) + 3 * Math.pow(t, 2)) * p1[i] +
1965
+ (Math.pow(t, 3) - Math.pow(t, 2)) * m1;
1966
+ }
1967
+ }
1968
+ function stepInterpolate(target, path, value) {
1969
+ if (!target[path]) {
1970
+ throw new Error();
1971
+ }
1972
+ for (let i = 0; i < value.length; i++) {
1973
+ target[path][i] = value[i];
1974
+ }
1975
+ }
1976
+
1977
+ // luma.gl
1978
+ // SPDX-License-Identifier: MIT
1979
+ // Copyright (c) vis.gl contributors
1980
+ class GLTFSingleAnimator {
1981
+ animation;
1982
+ startTime = 0;
1983
+ playing = true;
1984
+ speed = 1;
1985
+ constructor(props) {
1986
+ this.animation = props.animation;
1987
+ this.animation.name ||= 'unnamed';
1988
+ Object.assign(this, props);
1989
+ }
1990
+ setTime(timeMs) {
1991
+ if (!this.playing) {
1992
+ return;
1993
+ }
1994
+ const absTime = timeMs / 1000;
1995
+ const time = (absTime - this.startTime) * this.speed;
1996
+ this.animation.channels.forEach(({ sampler, target, path }) => {
1997
+ interpolate(time, sampler, target, path);
1998
+ applyTranslationRotationScale(target, target._node);
1999
+ });
2000
+ }
2001
+ }
2002
+ class GLTFAnimator {
2003
+ animations;
2004
+ constructor(props) {
2005
+ this.animations = props.animations.map((animation, index) => {
2006
+ const name = animation.name || `Animation-${index}`;
2007
+ return new GLTFSingleAnimator({
2008
+ animation: { name, channels: animation.channels }
2009
+ });
2010
+ });
2011
+ }
2012
+ /** @deprecated Use .setTime(). Will be removed (deck.gl is using this) */
2013
+ animate(time) {
2014
+ log.warn('GLTFAnimator#animate is deprecated. Use GLTFAnimator#setTime instead')();
2015
+ this.setTime(time);
2016
+ }
2017
+ setTime(time) {
2018
+ this.animations.forEach(animation => animation.setTime(time));
2019
+ }
2020
+ getAnimations() {
2021
+ return this.animations;
2022
+ }
2023
+ }
2024
+ // TODO: share with GLTFInstantiator
2025
+ const scratchMatrix = new Matrix4();
2026
+ function applyTranslationRotationScale(gltfNode, node) {
2027
+ node.matrix.identity();
2028
+ if (gltfNode.translation) {
2029
+ node.matrix.translate(gltfNode.translation);
2030
+ }
2031
+ if (gltfNode.rotation) {
2032
+ const rotationMatrix = scratchMatrix.fromQuaternion(gltfNode.rotation);
2033
+ node.matrix.multiplyRight(rotationMatrix);
2034
+ }
2035
+ if (gltfNode.scale) {
2036
+ node.matrix.scale(gltfNode.scale);
2037
+ }
2038
+ }
2039
+
2040
+ // luma.gl
2041
+ // SPDX-License-Identifier: MIT
2042
+ // Copyright (c) vis.gl contributors
2043
+ const ATTRIBUTE_TYPE_TO_COMPONENTS = {
2044
+ SCALAR: 1,
2045
+ VEC2: 2,
2046
+ VEC3: 3,
2047
+ VEC4: 4,
2048
+ MAT2: 4,
2049
+ MAT3: 9,
2050
+ MAT4: 16
2051
+ };
2052
+ const ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY = {
2053
+ 5120: Int8Array,
2054
+ 5121: Uint8Array,
2055
+ 5122: Int16Array,
2056
+ 5123: Uint16Array,
2057
+ 5125: Uint32Array,
2058
+ 5126: Float32Array
2059
+ };
2060
+ function accessorToTypedArray(accessor) {
2061
+ const ArrayType = ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY[accessor.componentType];
2062
+ const components = ATTRIBUTE_TYPE_TO_COMPONENTS[accessor.type];
2063
+ const length = components * accessor.count;
2064
+ const { buffer, byteOffset = 0 } = accessor.bufferView?.data ?? {};
2065
+ const typedArray = new ArrayType(buffer, byteOffset + (accessor.byteOffset || 0), length);
2066
+ return { typedArray, components };
2067
+ }
2068
+
2069
+ // luma.gl
2070
+ // SPDX-License-Identifier: MIT
2071
+ // Copyright (c) vis.gl contributors
2072
+ function parseGLTFAnimations(gltf) {
2073
+ const gltfAnimations = gltf.animations || [];
2074
+ return gltfAnimations.map((animation, index) => {
2075
+ const name = animation.name || `Animation-${index}`;
2076
+ const samplers = animation.samplers.map(({ input, interpolation = 'LINEAR', output }) => ({
2077
+ input: accessorToJsArray(gltf.accessors[input]),
2078
+ interpolation,
2079
+ output: accessorToJsArray(gltf.accessors[output])
2080
+ }));
2081
+ const channels = animation.channels.map(({ sampler, target }) => ({
2082
+ sampler: samplers[sampler],
2083
+ target: gltf.nodes[target.node ?? 0],
2084
+ path: target.path
2085
+ }));
2086
+ return { name, channels };
2087
+ });
2088
+ }
2089
+ //
2090
+ function accessorToJsArray(accessor) {
2091
+ if (!accessor._animation) {
2092
+ const { typedArray: array, components } = accessorToTypedArray(accessor);
2093
+ if (components === 1) {
2094
+ accessor._animation = Array.from(array);
2095
+ }
2096
+ else {
2097
+ // Slice array
2098
+ const slicedArray = [];
2099
+ for (let i = 0; i < array.length; i += components) {
2100
+ slicedArray.push(Array.from(array.slice(i, i + components)));
2101
+ }
2102
+ accessor._animation = slicedArray;
2103
+ }
2104
+ }
2105
+ return accessor._animation;
2106
+ }
2107
+
2108
+ /** Deeply copies a JS data structure */
2109
+ function deepCopy(object) {
2110
+ // don't copy binary data
2111
+ if (ArrayBuffer.isView(object) ||
2112
+ object instanceof ArrayBuffer ||
2113
+ object instanceof ImageBitmap) {
2114
+ return object;
2115
+ }
2116
+ if (Array.isArray(object)) {
2117
+ return object.map(deepCopy);
2118
+ }
2119
+ if (object && typeof object === 'object') {
2120
+ const result = {};
2121
+ for (const key in object) {
2122
+ result[key] = deepCopy(object[key]);
2123
+ }
2124
+ return result;
2125
+ }
2126
+ return object;
2127
+ }
2128
+
2129
+ // luma.gl
2130
+ // SPDX-License-Identifier: MIT
2131
+ // Copyright (c) vis.gl contributors
2132
+ function createScenegraphsFromGLTF(device, gltf, options) {
2133
+ gltf = deepCopy(gltf);
2134
+ const scenes = parseGLTF(device, gltf, options);
2135
+ // Note: There is a nasty dependency on injected nodes in the glTF
2136
+ const animations = parseGLTFAnimations(gltf);
2137
+ const animator = new GLTFAnimator({ animations });
2138
+ return { scenes, animator };
2139
+ }
2140
+
2141
+ // deck.gl
2142
+ // SPDX-License-Identifier: MIT
2143
+ // Copyright (c) vis.gl contributors
2144
+ async function waitForGLTFAssets(gltfObjects) {
2145
+ const remaining = [];
2146
+ gltfObjects.scenes.forEach(scene => {
2147
+ scene.traverse((modelNode) => {
2148
+ // Not really clear how we can access the uniforms?
2149
+ // TODO v9 getUnforms() was removed, hack it with props.uniforms
2150
+ // Object.values((modelNode as ModelNode).model.uniforms).forEach((uniform: any) => {
2151
+ // if (uniform.loaded === false) {
2152
+ // remaining.push(uniform);
2153
+ // }
2154
+ // });
2155
+ });
2156
+ });
2157
+ return await waitWhileCondition(() => remaining.some(uniform => !uniform.loaded));
2158
+ }
2159
+ async function waitWhileCondition(condition) {
2160
+ while (condition()) {
2161
+ await new Promise(resolve => requestAnimationFrame(resolve));
2162
+ }
2163
+ }
2164
+
2165
+ // deck.gl
2166
+ // SPDX-License-Identifier: MIT
2167
+ // Copyright (c) vis.gl contributors
2168
+ const uniformBlock = `\
2169
+ uniform scenegraphUniforms {
2170
+ float sizeScale;
2171
+ float sizeMinPixels;
2172
+ float sizeMaxPixels;
2173
+ mat4 sceneModelMatrix;
2174
+ bool composeModelMatrix;
2175
+ } scenegraph;
2176
+ `;
2177
+ const scenegraphUniforms = {
2178
+ name: 'scenegraph',
2179
+ vs: uniformBlock,
2180
+ fs: uniformBlock,
2181
+ uniformTypes: {
2182
+ sizeScale: 'f32',
2183
+ sizeMinPixels: 'f32',
2184
+ sizeMaxPixels: 'f32',
2185
+ sceneModelMatrix: 'mat4x4<f32>',
2186
+ composeModelMatrix: 'f32'
2187
+ }
2188
+ };
2189
+
2190
+ // deck.gl
2191
+ // SPDX-License-Identifier: MIT
2192
+ // Copyright (c) vis.gl contributors
2193
+ var vs = `\
2194
+ #version 300 es
2195
+ #define SHADER_NAME scenegraph-layer-vertex-shader
2196
+ in vec3 instancePositions;
2197
+ in vec3 instancePositions64Low;
2198
+ in vec4 instanceColors;
2199
+ in vec3 instancePickingColors;
2200
+ in vec3 instanceModelMatrixCol0;
2201
+ in vec3 instanceModelMatrixCol1;
2202
+ in vec3 instanceModelMatrixCol2;
2203
+ in vec3 instanceTranslation;
2204
+ in vec3 positions;
2205
+ #ifdef HAS_UV
2206
+ in vec2 texCoords;
2207
+ #endif
2208
+ #ifdef LIGHTING_PBR
2209
+ #ifdef HAS_NORMALS
2210
+ in vec3 normals;
2211
+ #endif
2212
+ #endif
2213
+ out vec4 vColor;
2214
+ #ifndef LIGHTING_PBR
2215
+ #ifdef HAS_UV
2216
+ out vec2 vTEXCOORD_0;
2217
+ #endif
2218
+ #endif
2219
+ void main(void) {
2220
+ #if defined(HAS_UV) && !defined(LIGHTING_PBR)
2221
+ vTEXCOORD_0 = texCoords;
2222
+ geometry.uv = texCoords;
2223
+ #endif
2224
+ geometry.worldPosition = instancePositions;
2225
+ geometry.pickingColor = instancePickingColors;
2226
+ mat3 instanceModelMatrix = mat3(instanceModelMatrixCol0, instanceModelMatrixCol1, instanceModelMatrixCol2);
2227
+ vec3 normal = vec3(0.0, 0.0, 1.0);
2228
+ #ifdef LIGHTING_PBR
2229
+ #ifdef HAS_NORMALS
2230
+ normal = instanceModelMatrix * (scenegraph.sceneModelMatrix * vec4(normals, 0.0)).xyz;
2231
+ #endif
2232
+ #endif
2233
+ float originalSize = project_size_to_pixel(scenegraph.sizeScale);
2234
+ float clampedSize = clamp(originalSize, scenegraph.sizeMinPixels, scenegraph.sizeMaxPixels);
2235
+ vec3 pos = (instanceModelMatrix * (scenegraph.sceneModelMatrix * vec4(positions, 1.0)).xyz) * scenegraph.sizeScale * (clampedSize / originalSize) + instanceTranslation;
2236
+ if(scenegraph.composeModelMatrix) {
2237
+ DECKGL_FILTER_SIZE(pos, geometry);
2238
+ geometry.normal = project_normal(normal);
2239
+ geometry.worldPosition += pos;
2240
+ gl_Position = project_position_to_clipspace(pos + instancePositions, instancePositions64Low, vec3(0.0), geometry.position);
2241
+ }
2242
+ else {
2243
+ pos = project_size(pos);
2244
+ DECKGL_FILTER_SIZE(pos, geometry);
2245
+ gl_Position = project_position_to_clipspace(instancePositions, instancePositions64Low, pos, geometry.position);
2246
+ geometry.normal = project_normal(normal);
2247
+ }
2248
+ DECKGL_FILTER_GL_POSITION(gl_Position, geometry);
2249
+ #ifdef LIGHTING_PBR
2250
+ pbr_vPosition = geometry.position.xyz;
2251
+ #ifdef HAS_NORMALS
2252
+ pbr_vNormal = geometry.normal;
2253
+ #endif
2254
+ #ifdef HAS_UV
2255
+ pbr_vUV = texCoords;
2256
+ #else
2257
+ pbr_vUV = vec2(0., 0.);
2258
+ #endif
2259
+ geometry.uv = pbr_vUV;
2260
+ #endif
2261
+ vColor = instanceColors;
2262
+ DECKGL_FILTER_COLOR(vColor, geometry);
2263
+ }
2264
+ `;
2265
+
2266
+ // deck.gl
2267
+ // SPDX-License-Identifier: MIT
2268
+ // Copyright (c) vis.gl contributors
2269
+ var fs = `\
2270
+ #version 300 es
2271
+ #define SHADER_NAME scenegraph-layer-fragment-shader
2272
+ in vec4 vColor;
2273
+ out vec4 fragColor;
2274
+ #ifndef LIGHTING_PBR
2275
+ #if defined(HAS_UV) && defined(HAS_BASECOLORMAP)
2276
+ in vec2 vTEXCOORD_0;
2277
+ uniform sampler2D pbr_baseColorSampler;
2278
+ #endif
2279
+ #endif
2280
+ void main(void) {
2281
+ #ifdef LIGHTING_PBR
2282
+ fragColor = vColor * pbr_filterColor(vec4(0));
2283
+ geometry.uv = pbr_vUV;
2284
+ #else
2285
+ #if defined(HAS_UV) && defined(HAS_BASECOLORMAP)
2286
+ fragColor = vColor * texture(pbr_baseColorSampler, vTEXCOORD_0);
2287
+ geometry.uv = vTEXCOORD_0;
2288
+ #else
2289
+ fragColor = vColor;
2290
+ #endif
2291
+ #endif
2292
+ fragColor.a *= layer.opacity;
2293
+ DECKGL_FILTER_COLOR(fragColor, geometry);
2294
+ }
2295
+ `;
2296
+
2297
+ // deck.gl
2298
+ // SPDX-License-Identifier: MIT
2299
+ // Copyright (c) vis.gl contributors
2300
+ const DEFAULT_COLOR = [255, 255, 255, 255];
2301
+ const defaultProps = {
2302
+ scenegraph: { type: 'object', value: null, async: true },
2303
+ getScene: gltf => {
2304
+ if (gltf && gltf.scenes) {
2305
+ // gltf post processor replaces `gltf.scene` number with the scene `object`
2306
+ return typeof gltf.scene === 'object' ? gltf.scene : gltf.scenes[gltf.scene || 0];
2307
+ }
2308
+ return gltf;
2309
+ },
2310
+ getAnimator: scenegraph => scenegraph && scenegraph.animator,
2311
+ _animations: null,
2312
+ sizeScale: { type: 'number', value: 1, min: 0 },
2313
+ sizeMinPixels: { type: 'number', min: 0, value: 0 },
2314
+ sizeMaxPixels: { type: 'number', min: 0, value: Number.MAX_SAFE_INTEGER },
2315
+ getPosition: { type: 'accessor', value: (x) => x.position },
2316
+ getColor: { type: 'accessor', value: DEFAULT_COLOR },
2317
+ // flat or pbr
2318
+ _lighting: 'flat',
2319
+ // _lighting must be pbr for this to work
2320
+ _imageBasedLightingEnvironment: undefined,
2321
+ // yaw, pitch and roll are in degrees
2322
+ // https://en.wikipedia.org/wiki/Euler_angles
2323
+ // [pitch, yaw, roll]
2324
+ getOrientation: { type: 'accessor', value: [0, 0, 0] },
2325
+ getScale: { type: 'accessor', value: [1, 1, 1] },
2326
+ getTranslation: { type: 'accessor', value: [0, 0, 0] },
2327
+ // 4x4 matrix
2328
+ getTransformMatrix: { type: 'accessor', value: [] },
2329
+ loaders: [GLTFLoader]
2330
+ };
2331
+ /** Render a number of instances of a complete glTF scenegraph. */
2332
+ class ScenegraphLayer extends Layer {
2333
+ getShaders() {
2334
+ const defines = {};
2335
+ let pbr;
2336
+ if (this.props._lighting === 'pbr') {
2337
+ pbr = pbrMaterial;
2338
+ defines.LIGHTING_PBR = 1;
2339
+ }
2340
+ else {
2341
+ // Dummy shader module needed to handle
2342
+ // pbrMaterial.pbr_baseColorSampler binding
2343
+ pbr = { name: 'pbrMaterial' };
2344
+ }
2345
+ const modules = [project32, picking, scenegraphUniforms, pbr];
2346
+ return super.getShaders({ defines, vs, fs, modules });
2347
+ }
2348
+ initializeState() {
2349
+ const attributeManager = this.getAttributeManager();
2350
+ // attributeManager is always defined for primitive layers
2351
+ attributeManager.addInstanced({
2352
+ instancePositions: {
2353
+ size: 3,
2354
+ type: 'float64',
2355
+ fp64: this.use64bitPositions(),
2356
+ accessor: 'getPosition',
2357
+ transition: true
2358
+ },
2359
+ instanceColors: {
2360
+ type: 'unorm8',
2361
+ size: this.props.colorFormat.length,
2362
+ accessor: 'getColor',
2363
+ defaultValue: DEFAULT_COLOR,
2364
+ transition: true
2365
+ },
2366
+ instanceModelMatrix: MATRIX_ATTRIBUTES
2367
+ });
2368
+ }
2369
+ updateState(params) {
2370
+ super.updateState(params);
2371
+ const { props, oldProps } = params;
2372
+ if (props.scenegraph !== oldProps.scenegraph) {
2373
+ this._updateScenegraph();
2374
+ }
2375
+ else if (props._animations !== oldProps._animations) {
2376
+ this._applyAnimationsProp(this.state.animator, props._animations);
2377
+ }
2378
+ }
2379
+ finalizeState(context) {
2380
+ super.finalizeState(context);
2381
+ this.state.scenegraph?.destroy();
2382
+ }
2383
+ get isLoaded() {
2384
+ return Boolean(this.state?.scenegraph && super.isLoaded);
2385
+ }
2386
+ _updateScenegraph() {
2387
+ const props = this.props;
2388
+ const { device } = this.context;
2389
+ let scenegraphData = null;
2390
+ if (props.scenegraph instanceof ScenegraphNode) {
2391
+ // Signature 1: props.scenegraph is a proper luma.gl Scenegraph
2392
+ scenegraphData = { scenes: [props.scenegraph] };
2393
+ }
2394
+ else if (props.scenegraph && typeof props.scenegraph === 'object') {
2395
+ // Converts loaders.gl gltf to luma.gl scenegraph using the undocumented @luma.gl/experimental function
2396
+ const gltf = props.scenegraph;
2397
+ // Tiles3DLoader already processes GLTF
2398
+ const processedGLTF = gltf.json ? postProcessGLTF(gltf) : gltf;
2399
+ const gltfObjects = createScenegraphsFromGLTF(device, processedGLTF, this._getModelOptions());
2400
+ scenegraphData = { gltf: processedGLTF, ...gltfObjects };
2401
+ waitForGLTFAssets(gltfObjects)
2402
+ .then(() => {
2403
+ this.setNeedsRedraw();
2404
+ })
2405
+ .catch(ex => {
2406
+ this.raiseError(ex, 'loading glTF');
2407
+ });
2408
+ }
2409
+ const options = { layer: this, device: this.context.device };
2410
+ const scenegraph = props.getScene(scenegraphData, options);
2411
+ const animator = props.getAnimator(scenegraphData, options);
2412
+ if (scenegraph instanceof GroupNode) {
2413
+ this.state.scenegraph?.destroy();
2414
+ this._applyAnimationsProp(animator, props._animations);
2415
+ const models = [];
2416
+ scenegraph.traverse(node => {
2417
+ if (node instanceof ModelNode) {
2418
+ models.push(node.model);
2419
+ }
2420
+ });
2421
+ this.setState({ scenegraph, animator, models });
2422
+ this.getAttributeManager().invalidateAll();
2423
+ }
2424
+ else if (scenegraph !== null) {
2425
+ defaultLogger.warn('invalid scenegraph:', scenegraph)();
2426
+ }
2427
+ }
2428
+ _applyAnimationsProp(animator, animationsProp) {
2429
+ if (!animator || !animationsProp) {
2430
+ return;
2431
+ }
2432
+ const animations = animator.getAnimations();
2433
+ // sort() to ensure '*' comes first so that other values can override
2434
+ Object.keys(animationsProp)
2435
+ .sort()
2436
+ .forEach(key => {
2437
+ // Key can be:
2438
+ // - number for index number
2439
+ // - name for animation name
2440
+ // - * to affect all animations
2441
+ const value = animationsProp[key];
2442
+ if (key === '*') {
2443
+ animations.forEach(animation => {
2444
+ Object.assign(animation, value);
2445
+ });
2446
+ }
2447
+ else if (Number.isFinite(Number(key))) {
2448
+ const number = Number(key);
2449
+ if (number >= 0 && number < animations.length) {
2450
+ Object.assign(animations[number], value);
2451
+ }
2452
+ else {
2453
+ defaultLogger.warn(`animation ${key} not found`)();
2454
+ }
2455
+ }
2456
+ else {
2457
+ const findResult = animations.find(({ animation }) => animation.name === key);
2458
+ if (findResult) {
2459
+ Object.assign(findResult, value);
2460
+ }
2461
+ else {
2462
+ defaultLogger.warn(`animation ${key} not found`)();
2463
+ }
2464
+ }
2465
+ });
2466
+ }
2467
+ _getModelOptions() {
2468
+ const { _imageBasedLightingEnvironment } = this.props;
2469
+ let env;
2470
+ if (_imageBasedLightingEnvironment) {
2471
+ if (typeof _imageBasedLightingEnvironment === 'function') {
2472
+ env = _imageBasedLightingEnvironment({ gl: this.context.gl, layer: this });
2473
+ }
2474
+ else {
2475
+ env = _imageBasedLightingEnvironment;
2476
+ }
2477
+ }
2478
+ return {
2479
+ imageBasedLightingEnvironment: env,
2480
+ modelOptions: {
2481
+ id: this.props.id,
2482
+ isInstanced: true,
2483
+ bufferLayout: this.getAttributeManager().getBufferLayouts(),
2484
+ ...this.getShaders()
2485
+ },
2486
+ // tangents are not supported
2487
+ useTangents: false
2488
+ };
2489
+ }
2490
+ draw({ context }) {
2491
+ if (!this.state.scenegraph)
2492
+ return;
2493
+ if (this.props._animations && this.state.animator) {
2494
+ this.state.animator.animate(context.timeline.getTime());
2495
+ this.setNeedsRedraw();
2496
+ }
2497
+ const { viewport, renderPass } = this.context;
2498
+ const { sizeScale, sizeMinPixels, sizeMaxPixels, coordinateSystem } = this.props;
2499
+ const pbrProjectionProps = {
2500
+ camera: viewport.cameraPosition
2501
+ };
2502
+ const numInstances = this.getNumInstances();
2503
+ this.state.scenegraph.traverse((node, { worldMatrix }) => {
2504
+ if (node instanceof ModelNode) {
2505
+ const { model } = node;
2506
+ model.setInstanceCount(numInstances);
2507
+ const scenegraphProps = {
2508
+ sizeScale,
2509
+ sizeMinPixels,
2510
+ sizeMaxPixels,
2511
+ composeModelMatrix: shouldComposeModelMatrix(viewport, coordinateSystem),
2512
+ sceneModelMatrix: worldMatrix
2513
+ };
2514
+ model.shaderInputs.setProps({
2515
+ pbrProjection: pbrProjectionProps,
2516
+ scenegraph: scenegraphProps
2517
+ });
2518
+ model.draw(renderPass);
2519
+ }
2520
+ });
2521
+ }
2522
+ }
2523
+ ScenegraphLayer.defaultProps = defaultProps;
2524
+ ScenegraphLayer.layerName = 'ScenegraphLayer';
2525
+
2526
+ export { ScenegraphLayer as S, parsePBRMaterial as a, pbrMaterial as p };