@navaramap/three 0.0.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 (350) hide show
  1. package/LICENSE +8 -0
  2. package/dist/assets/atmosphere/README.md +1 -0
  3. package/dist/assets/atmosphere/higher_order_scattering.bin +0 -0
  4. package/dist/assets/atmosphere/higher_order_scattering.exr +0 -0
  5. package/dist/assets/atmosphere/irradiance.bin +0 -0
  6. package/dist/assets/atmosphere/irradiance.exr +0 -0
  7. package/dist/assets/atmosphere/scattering.bin +0 -0
  8. package/dist/assets/atmosphere/scattering.exr +0 -0
  9. package/dist/assets/atmosphere/single_mie_scattering.bin +0 -0
  10. package/dist/assets/atmosphere/single_mie_scattering.exr +0 -0
  11. package/dist/assets/atmosphere/stars.bin +0 -0
  12. package/dist/assets/atmosphere/transmittance.bin +0 -0
  13. package/dist/assets/atmosphere/transmittance.exr +0 -0
  14. package/dist/assets/cloud/README.md +1 -0
  15. package/dist/assets/cloud/local_weather.png +0 -0
  16. package/dist/assets/cloud/shape.bin +1 -0
  17. package/dist/assets/cloud/shape_detail.bin +1 -0
  18. package/dist/assets/cloud/turbulence.png +0 -0
  19. package/dist/assets/fontWorker-CEJEfRpb.js +2 -0
  20. package/dist/assets/fontWorker-CEJEfRpb.js.map +1 -0
  21. package/dist/assets/index-BUB-ijMO.js +12 -0
  22. package/dist/assets/index-BUB-ijMO.js.map +1 -0
  23. package/dist/assets/navara_wasm_font_worker_bg-665OLxjy.wasm +0 -0
  24. package/dist/assets/navara_wasm_worker_bg-BXhKC5bE.wasm +0 -0
  25. package/dist/assets/noise/README.md +1 -0
  26. package/dist/assets/noise/stbn.bin +0 -0
  27. package/dist/assets/water/README.md +3 -0
  28. package/dist/assets/water/waternormals.jpg +0 -0
  29. package/dist/index.d.ts +10114 -0
  30. package/dist/index.js +34481 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/index.umd.cjs +6345 -0
  33. package/dist/index.umd.cjs.map +1 -0
  34. package/package.json +95 -0
  35. package/src/Color.ts +111 -0
  36. package/src/ShadowMapViewers.ts +49 -0
  37. package/src/atmosphere.test.ts +76 -0
  38. package/src/atmosphere.ts +364 -0
  39. package/src/bufferView.ts +90 -0
  40. package/src/camera.ts +182 -0
  41. package/src/concurrency.ts +15 -0
  42. package/src/constants/assets.ts +30 -0
  43. package/src/constants/decoder.ts +7 -0
  44. package/src/constants/index.ts +2 -0
  45. package/src/core/BaseDesc.ts +142 -0
  46. package/src/core/BaseHandle.ts +126 -0
  47. package/src/core/DescRegistry.ts +88 -0
  48. package/src/core/EffectDesc.ts +343 -0
  49. package/src/core/EffectDescRegistry.ts +31 -0
  50. package/src/core/InstancedMeshDesc.ts +413 -0
  51. package/src/core/LightDesc.ts +216 -0
  52. package/src/core/LightDescRegistry.ts +32 -0
  53. package/src/core/MeshDesc.ts +457 -0
  54. package/src/core/MeshDescRegistry.ts +32 -0
  55. package/src/core/MeshDescWithSelectiveEffect.ts +129 -0
  56. package/src/core/Registries.ts +59 -0
  57. package/src/core/SelectiveEffectRegistry.ts +90 -0
  58. package/src/core/ViewContext.ts +235 -0
  59. package/src/core/errors.ts +16 -0
  60. package/src/core/index.ts +50 -0
  61. package/src/device.ts +414 -0
  62. package/src/effects/CustomEffectPass.ts +28 -0
  63. package/src/effects/copy.ts +10 -0
  64. package/src/effects/effect.ts +87 -0
  65. package/src/effects/index.ts +4 -0
  66. package/src/effects/render.ts +10 -0
  67. package/src/evaluations/FeatureEvaluator.ts +529 -0
  68. package/src/evaluations/index.ts +1 -0
  69. package/src/event/HillshadeContext.test.ts +232 -0
  70. package/src/event/HillshadeContext.ts +299 -0
  71. package/src/event/context.ts +279 -0
  72. package/src/event/feature.ts +357 -0
  73. package/src/event/featureEvent.ts +81 -0
  74. package/src/event/features/billboard.ts +30 -0
  75. package/src/event/features/model.ts +192 -0
  76. package/src/event/features/modelGpuBytes.test.ts +69 -0
  77. package/src/event/features/modelGpuBytes.ts +87 -0
  78. package/src/event/features/point.ts +25 -0
  79. package/src/event/features/polygon.ts +23 -0
  80. package/src/event/features/polygonOutline.ts +19 -0
  81. package/src/event/features/polyline.ts +19 -0
  82. package/src/event/features/text.ts +71 -0
  83. package/src/event/hillshade.test.ts +842 -0
  84. package/src/event/hillshade.ts +588 -0
  85. package/src/event/index.ts +700 -0
  86. package/src/event/loaders.ts +53 -0
  87. package/src/event/tile.ts +19 -0
  88. package/src/event/worker.ts +999 -0
  89. package/src/event/workerTaskSettlement.test.ts +243 -0
  90. package/src/event/workerTaskSettlement.ts +128 -0
  91. package/src/inMemoryBufferStore.test.ts +60 -0
  92. package/src/inMemoryBufferStore.ts +67 -0
  93. package/src/index.iife.ts +11 -0
  94. package/src/index.ts +2556 -0
  95. package/src/input.ts +144 -0
  96. package/src/layer.ts +183 -0
  97. package/src/layers/effect/FinalCopyEffectDesc.ts +29 -0
  98. package/src/layers/effect/MRTPassEffectDesc.ts +105 -0
  99. package/src/layers/effect/README.md +9 -0
  100. package/src/layers/effect/SelectiveEffectDesc.ts +113 -0
  101. package/src/layers/effect/SkyEnvMapEffectDesc.ts +58 -0
  102. package/src/layers/effect/TransparentPassEffectDesc.ts +62 -0
  103. package/src/layers/effect/index.ts +5 -0
  104. package/src/layers/index.ts +1 -0
  105. package/src/layersManager.ts +63 -0
  106. package/src/light.ts +15 -0
  107. package/src/loaders/AbortableImageLoader.ts +203 -0
  108. package/src/loaders/AbortableTextureLoader.ts +74 -0
  109. package/src/loaders/index.ts +5 -0
  110. package/src/material/enhancer/DESIGN.md +300 -0
  111. package/src/material/enhancer/MaterialEnhancer.ts +112 -0
  112. package/src/material/enhancer/ShaderReplacer.test.ts +114 -0
  113. package/src/material/enhancer/ShaderReplacer.ts +97 -0
  114. package/src/material/enhancer/batchTexture.ts +8 -0
  115. package/src/material/enhancer/index.ts +46 -0
  116. package/src/material/enhancer/instancedSprite/index.ts +7 -0
  117. package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/index.test.ts +214 -0
  118. package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/index.ts +134 -0
  119. package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/markers.ts +21 -0
  120. package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/material.ts +32 -0
  121. package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/mutates.test.ts +277 -0
  122. package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/mutates.ts +151 -0
  123. package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/shader.test.ts +114 -0
  124. package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/shader.ts +49 -0
  125. package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/state.test.ts +82 -0
  126. package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/state.ts +80 -0
  127. package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/types.ts +146 -0
  128. package/src/material/enhancer/instancedSprite/instancedSpriteMaterialEnhancer.ts +105 -0
  129. package/src/material/enhancer/model/index.ts +25 -0
  130. package/src/material/enhancer/model/modelBaseEnhancer/index.test.ts +74 -0
  131. package/src/material/enhancer/model/modelBaseEnhancer/index.ts +110 -0
  132. package/src/material/enhancer/model/modelBaseEnhancer/markers.ts +27 -0
  133. package/src/material/enhancer/model/modelBaseEnhancer/material.test.ts +66 -0
  134. package/src/material/enhancer/model/modelBaseEnhancer/material.ts +44 -0
  135. package/src/material/enhancer/model/modelBaseEnhancer/mutates.test.ts +84 -0
  136. package/src/material/enhancer/model/modelBaseEnhancer/mutates.ts +47 -0
  137. package/src/material/enhancer/model/modelBaseEnhancer/shader.test.ts +24 -0
  138. package/src/material/enhancer/model/modelBaseEnhancer/shader.ts +162 -0
  139. package/src/material/enhancer/model/modelBaseEnhancer/state.test.ts +103 -0
  140. package/src/material/enhancer/model/modelBaseEnhancer/state.ts +52 -0
  141. package/src/material/enhancer/model/modelBaseEnhancer/types.ts +89 -0
  142. package/src/material/enhancer/model/modelMaterialEnhancer.ts +91 -0
  143. package/src/material/enhancer/model/modelWaterEnhancer/index.test.ts +71 -0
  144. package/src/material/enhancer/model/modelWaterEnhancer/index.ts +175 -0
  145. package/src/material/enhancer/model/modelWaterEnhancer/material.test.ts +48 -0
  146. package/src/material/enhancer/model/modelWaterEnhancer/material.ts +25 -0
  147. package/src/material/enhancer/model/modelWaterEnhancer/mutates.test.ts +89 -0
  148. package/src/material/enhancer/model/modelWaterEnhancer/mutates.ts +89 -0
  149. package/src/material/enhancer/model/modelWaterEnhancer/shader.test.ts +34 -0
  150. package/src/material/enhancer/model/modelWaterEnhancer/shader.ts +111 -0
  151. package/src/material/enhancer/model/modelWaterEnhancer/state.test.ts +105 -0
  152. package/src/material/enhancer/model/modelWaterEnhancer/state.ts +59 -0
  153. package/src/material/enhancer/model/modelWaterEnhancer/types.ts +141 -0
  154. package/src/material/enhancer/model/pntsEnhancer/index.test.ts +96 -0
  155. package/src/material/enhancer/model/pntsEnhancer/index.ts +82 -0
  156. package/src/material/enhancer/model/pntsEnhancer/markers.ts +6 -0
  157. package/src/material/enhancer/model/pntsEnhancer/material.test.ts +37 -0
  158. package/src/material/enhancer/model/pntsEnhancer/material.ts +21 -0
  159. package/src/material/enhancer/model/pntsEnhancer/mutates.test.ts +80 -0
  160. package/src/material/enhancer/model/pntsEnhancer/mutates.ts +29 -0
  161. package/src/material/enhancer/model/pntsEnhancer/shader.test.ts +32 -0
  162. package/src/material/enhancer/model/pntsEnhancer/shader.ts +56 -0
  163. package/src/material/enhancer/model/pntsEnhancer/state.test.ts +87 -0
  164. package/src/material/enhancer/model/pntsEnhancer/state.ts +29 -0
  165. package/src/material/enhancer/model/pntsEnhancer/types.ts +38 -0
  166. package/src/material/enhancer/polygon/index.ts +22 -0
  167. package/src/material/enhancer/polygon/polygonBaseEnhancer/index.test.ts +101 -0
  168. package/src/material/enhancer/polygon/polygonBaseEnhancer/index.ts +130 -0
  169. package/src/material/enhancer/polygon/polygonBaseEnhancer/markers.ts +23 -0
  170. package/src/material/enhancer/polygon/polygonBaseEnhancer/material.test.ts +19 -0
  171. package/src/material/enhancer/polygon/polygonBaseEnhancer/material.ts +38 -0
  172. package/src/material/enhancer/polygon/polygonBaseEnhancer/mutates.test.ts +75 -0
  173. package/src/material/enhancer/polygon/polygonBaseEnhancer/mutates.ts +122 -0
  174. package/src/material/enhancer/polygon/polygonBaseEnhancer/shader.test.ts +25 -0
  175. package/src/material/enhancer/polygon/polygonBaseEnhancer/shader.ts +249 -0
  176. package/src/material/enhancer/polygon/polygonBaseEnhancer/state.test.ts +102 -0
  177. package/src/material/enhancer/polygon/polygonBaseEnhancer/state.ts +92 -0
  178. package/src/material/enhancer/polygon/polygonBaseEnhancer/types.ts +150 -0
  179. package/src/material/enhancer/polygon/polygonMaterialEnhancer.ts +97 -0
  180. package/src/material/enhancer/polygon/polygonWaterEnhancer/index.test.ts +72 -0
  181. package/src/material/enhancer/polygon/polygonWaterEnhancer/index.ts +164 -0
  182. package/src/material/enhancer/polygon/polygonWaterEnhancer/material.test.ts +48 -0
  183. package/src/material/enhancer/polygon/polygonWaterEnhancer/material.ts +35 -0
  184. package/src/material/enhancer/polygon/polygonWaterEnhancer/mutates.ts +61 -0
  185. package/src/material/enhancer/polygon/polygonWaterEnhancer/shader.test.ts +34 -0
  186. package/src/material/enhancer/polygon/polygonWaterEnhancer/shader.ts +96 -0
  187. package/src/material/enhancer/polygon/polygonWaterEnhancer/state.test.ts +98 -0
  188. package/src/material/enhancer/polygon/polygonWaterEnhancer/state.ts +57 -0
  189. package/src/material/enhancer/polygon/polygonWaterEnhancer/types.ts +115 -0
  190. package/src/material/enhancer/polyline/index.ts +7 -0
  191. package/src/material/enhancer/polyline/polylineBaseEnhancer/index.test.ts +157 -0
  192. package/src/material/enhancer/polyline/polylineBaseEnhancer/index.ts +154 -0
  193. package/src/material/enhancer/polyline/polylineBaseEnhancer/markers.ts +19 -0
  194. package/src/material/enhancer/polyline/polylineBaseEnhancer/material.test.ts +42 -0
  195. package/src/material/enhancer/polyline/polylineBaseEnhancer/material.ts +38 -0
  196. package/src/material/enhancer/polyline/polylineBaseEnhancer/mutates.test.ts +120 -0
  197. package/src/material/enhancer/polyline/polylineBaseEnhancer/mutates.ts +169 -0
  198. package/src/material/enhancer/polyline/polylineBaseEnhancer/shader.test.ts +67 -0
  199. package/src/material/enhancer/polyline/polylineBaseEnhancer/shader.ts +75 -0
  200. package/src/material/enhancer/polyline/polylineBaseEnhancer/state.test.ts +55 -0
  201. package/src/material/enhancer/polyline/polylineBaseEnhancer/state.ts +91 -0
  202. package/src/material/enhancer/polyline/polylineBaseEnhancer/types.ts +170 -0
  203. package/src/material/enhancer/polyline/polylineMaterialEnhancer.ts +102 -0
  204. package/src/material/enhancer/sdfText/index.ts +7 -0
  205. package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/index.ts +125 -0
  206. package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/markers.ts +19 -0
  207. package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/material.test.ts +35 -0
  208. package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/material.ts +32 -0
  209. package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/mutates.test.ts +381 -0
  210. package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/mutates.ts +232 -0
  211. package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/shader.ts +36 -0
  212. package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/state.test.ts +118 -0
  213. package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/state.ts +107 -0
  214. package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/types.ts +184 -0
  215. package/src/material/enhancer/sdfText/sdfTextMaterialEnhancer.ts +100 -0
  216. package/src/material/enhancer/shadowMap/index.ts +7 -0
  217. package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/index.ts +97 -0
  218. package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/markers.ts +10 -0
  219. package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/material.ts +31 -0
  220. package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/mutates.ts +8 -0
  221. package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/shader.test.ts +17 -0
  222. package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/shader.ts +53 -0
  223. package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/state.ts +17 -0
  224. package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/types.ts +26 -0
  225. package/src/material/enhancer/test-utils/shaderCompatibility.ts +124 -0
  226. package/src/material/enhancer/tileComposite/compose.test.ts +95 -0
  227. package/src/material/enhancer/tileComposite/compose.ts +112 -0
  228. package/src/material/enhancer/tileComposite/index.ts +23 -0
  229. package/src/material/enhancer/tileComposite/tileCompositeBaseEnhancer/index.ts +11 -0
  230. package/src/material/enhancer/tileComposite/tileCompositeBaseEnhancer/mutates.ts +132 -0
  231. package/src/material/enhancer/tileComposite/tileCompositeBaseEnhancer/shader.ts +245 -0
  232. package/src/material/enhancer/tileComposite/tileCompositeBaseEnhancer/types.ts +43 -0
  233. package/src/material/enhancer/tileComposite/tileElevationHeatmapEnhancer/index.ts +29 -0
  234. package/src/material/enhancer/tileComposite/tileElevationHeatmapEnhancer/mutates.ts +68 -0
  235. package/src/material/enhancer/tileComposite/tileElevationHeatmapEnhancer/shader.ts +24 -0
  236. package/src/material/enhancer/tileComposite/tileHillshadeEnhancer/index.ts +29 -0
  237. package/src/material/enhancer/tileComposite/tileHillshadeEnhancer/mutates.ts +34 -0
  238. package/src/material/enhancer/tileComposite/tileHillshadeEnhancer/shader.ts +36 -0
  239. package/src/material/enhancer/tileComposite/tileWaterEnhancer/index.ts +23 -0
  240. package/src/material/enhancer/tileComposite/tileWaterEnhancer/mutates.ts +23 -0
  241. package/src/material/enhancer/tileComposite/tileWaterEnhancer/shader.ts +8 -0
  242. package/src/material/enhancer/tileComposite/tileWatermaskEnhancer/index.ts +23 -0
  243. package/src/material/enhancer/tileComposite/tileWatermaskEnhancer/mutates.ts +34 -0
  244. package/src/material/enhancer/tileComposite/tileWatermaskEnhancer/shader.ts +13 -0
  245. package/src/material/enhancer/tileComposite/types.ts +58 -0
  246. package/src/material/index.ts +3 -0
  247. package/src/material/macro/index.ts +1 -0
  248. package/src/material/macro/tileShader.test.ts +136 -0
  249. package/src/material/macro/tileShader.ts +287 -0
  250. package/src/material/overrideMaterialsForMRT.ts +439 -0
  251. package/src/material/selectiveEffectMaterialSetup.test.ts +52 -0
  252. package/src/material/selectiveEffectMaterialSetup.ts +53 -0
  253. package/src/material/types/index.ts +1 -0
  254. package/src/material/types/uniform.ts +1 -0
  255. package/src/mesh/DrapedMesh.ts +101 -0
  256. package/src/mesh/batchTexture.test.ts +646 -0
  257. package/src/mesh/batchTexture.ts +437 -0
  258. package/src/mesh/batchedFeature.ts +186 -0
  259. package/src/mesh/batchedSdfText.ts +484 -0
  260. package/src/mesh/featureMesh.ts +43 -0
  261. package/src/mesh/index.ts +16 -0
  262. package/src/mesh/instanced.ts +117 -0
  263. package/src/mesh/model.ts +483 -0
  264. package/src/mesh/pickableMesh.ts +55 -0
  265. package/src/mesh/pickableMeshWrapper.ts +529 -0
  266. package/src/mesh/polygon.ts +699 -0
  267. package/src/mesh/polygonOutline.ts +393 -0
  268. package/src/mesh/polyline.ts +523 -0
  269. package/src/mesh/releaseGeometryArrays.ts +57 -0
  270. package/src/mesh/rtcRteHelper.ts +211 -0
  271. package/src/mesh/sdfText.test.ts +200 -0
  272. package/src/mesh/sdfText.ts +1019 -0
  273. package/src/mesh/sprite/billboardAtlas.test.ts +177 -0
  274. package/src/mesh/sprite/billboardAtlas.ts +210 -0
  275. package/src/mesh/sprite/billboardAtlasImageLoader.ts +29 -0
  276. package/src/mesh/sprite/index.ts +1 -0
  277. package/src/mesh/sprite/instancedSprite.ts +694 -0
  278. package/src/mesh/tile.test.ts +393 -0
  279. package/src/mesh/tile.ts +1790 -0
  280. package/src/object3DEvent.ts +6 -0
  281. package/src/orchestrators/RenderPassOrchestrator.ts +147 -0
  282. package/src/orchestrators/index.ts +1 -0
  283. package/src/passes/AllDepthCopyPass.ts +165 -0
  284. package/src/passes/CustomRenderPass.ts +279 -0
  285. package/src/passes/NormalCopyPass.ts +125 -0
  286. package/src/passes/RenderTargetCopyPass.ts +91 -0
  287. package/src/passes/SkyEnvMapPass.ts +58 -0
  288. package/src/passes/index.ts +5 -0
  289. package/src/pick/pickHelper.ts +273 -0
  290. package/src/pick/pickTerrain.ts +254 -0
  291. package/src/plugins/AttributionPlugin/AttributionPlugin.test.ts +210 -0
  292. package/src/plugins/AttributionPlugin/attribution.test.ts +225 -0
  293. package/src/plugins/AttributionPlugin/attribution.ts +355 -0
  294. package/src/plugins/AttributionPlugin/attributionStyles.ts +163 -0
  295. package/src/plugins/AttributionPlugin/index.ts +702 -0
  296. package/src/plugins/index.ts +1 -0
  297. package/src/quality.ts +1 -0
  298. package/src/renderOrder.ts +3 -0
  299. package/src/scene.test.ts +164 -0
  300. package/src/scene.ts +127 -0
  301. package/src/shaders/index.ts +1 -0
  302. package/src/solar.test.ts +81 -0
  303. package/src/solar.ts +101 -0
  304. package/src/source.ts +80 -0
  305. package/src/stats.ts +102 -0
  306. package/src/tasks/computeVertexNormalsAsync.ts +15 -0
  307. package/src/tasks/constructPolygonBatchedFeature.ts +34 -0
  308. package/src/tasks/constructPolylineBatchedFeature.ts +27 -0
  309. package/src/tasks/constructQuantizedMeshTerrainMesh.ts +24 -0
  310. package/src/tasks/constructTerrainMesh.ts +25 -0
  311. package/src/tasks/getImageDataFromBlob.ts +13 -0
  312. package/src/tasks/getImageDataFromImageBitmap.ts +12 -0
  313. package/src/tasks/parseMvtTile.ts +22 -0
  314. package/src/tasks/queueTask.ts +19 -0
  315. package/src/tasks/toCreasedNormalsAsync.ts +18 -0
  316. package/src/tasks/upsampleQuantizedMeshTerrainMesh.ts +44 -0
  317. package/src/tasks/upsampleTerrainMesh.ts +39 -0
  318. package/src/texture.ts +19 -0
  319. package/src/textures.ts +13 -0
  320. package/src/tileTexture/CompositeShader.snapshot.test.ts +59 -0
  321. package/src/tileTexture/CompositeShader.test.ts +168 -0
  322. package/src/tileTexture/CompositeShader.ts +53 -0
  323. package/src/tileTexture/SlotPlanner.test.ts +105 -0
  324. package/src/tileTexture/SlotPlanner.ts +102 -0
  325. package/src/tileTexture/TileTextureCache.test.ts +227 -0
  326. package/src/tileTexture/TileTextureCache.ts +192 -0
  327. package/src/tileTexture/TileTextureCompositor.test.ts +260 -0
  328. package/src/tileTexture/TileTextureCompositor.ts +421 -0
  329. package/src/tileTexture/__snapshots__/CompositeShader.snapshot.test.ts.snap +2649 -0
  330. package/src/tileTexture/index.ts +8 -0
  331. package/src/tileTexture/types.ts +150 -0
  332. package/src/type/index.ts +261 -0
  333. package/src/uniforms.ts +20 -0
  334. package/src/utils/arraysEqual.ts +9 -0
  335. package/src/utils/blendModes.ts +80 -0
  336. package/src/utils/geometry.ts +53 -0
  337. package/src/utils/hillshadeNormalMapGenerator.ts +193 -0
  338. package/src/utils/index.ts +8 -0
  339. package/src/utils/object.test.ts +14 -0
  340. package/src/utils/object.ts +7 -0
  341. package/src/utils/replacer.test.ts +42 -0
  342. package/src/utils/replacer.ts +89 -0
  343. package/src/utils/screen.ts +29 -0
  344. package/src/utils/textureFragmentIndex.test.ts +224 -0
  345. package/src/utils/textureFragmentIndex.ts +97 -0
  346. package/src/utils/worker.ts +3 -0
  347. package/src/vite-env.d.ts +2 -0
  348. package/src/worker/index.ts +13 -0
  349. package/src/worker/tasks/computeVertexNormals.ts +15 -0
  350. package/src/worker/tasks/toCreasedNormals.ts +22 -0
@@ -0,0 +1,8 @@
1
+ import type { ShadowMapDepthMutates } from "./types";
2
+
3
+ export const createShadowMapDepthMutates = (): ShadowMapDepthMutates => {
4
+ return {
5
+ update: () => {},
6
+ updateUniforms: (_uniforms) => {},
7
+ };
8
+ };
@@ -0,0 +1,17 @@
1
+ import { testShaderCompatibility } from "../../test-utils/shaderCompatibility";
2
+
3
+ import { SHADOW_MAP_DEPTH_SHADER_MARKERS } from "./markers";
4
+
5
+ import { createShadowMapDepthEnhancer, type SupportedMaterial } from ".";
6
+
7
+ testShaderCompatibility(
8
+ "shadowMapDepthEnhancer",
9
+ (material) => createShadowMapDepthEnhancer(material as SupportedMaterial),
10
+ [
11
+ {
12
+ name: "Default props",
13
+ props: {},
14
+ },
15
+ ],
16
+ SHADOW_MAP_DEPTH_SHADER_MARKERS,
17
+ );
@@ -0,0 +1,53 @@
1
+ import ShadowMapDepthFragment from "@shaders/glsl/chunks/shadowmap_depth_fragment.glsl";
2
+ import ShadowMapDepthParsFragment from "@shaders/glsl/chunks/shadowmap_depth_pars_fragment.glsl";
3
+ import ShadowMapDepthParsVertex from "@shaders/glsl/chunks/shadowmap_depth_pars_vertex.glsl";
4
+ import ShadowMapDepthVertex from "@shaders/glsl/chunks/shadowmap_depth_vertex.glsl";
5
+ import type { WebGLProgramParametersWithUniforms } from "three";
6
+
7
+ import { createReplacer } from "../../../../utils";
8
+
9
+ import type { ShadowMapDepthMutates, ShadowMapDepthState } from "./types";
10
+
11
+ export const transformShader = (
12
+ shader: WebGLProgramParametersWithUniforms,
13
+ _state: ShadowMapDepthState,
14
+ mutates: ShadowMapDepthMutates,
15
+ ): void => {
16
+ mutates.updateUniforms(shader.uniforms, _state);
17
+
18
+ shader.vertexShader = createReplacer(shader.vertexShader)
19
+ .replace(
20
+ "#include <common>",
21
+ `
22
+ #include <common>
23
+ #include <packing>
24
+ ${ShadowMapDepthParsVertex}
25
+ `,
26
+ )
27
+ .replace(
28
+ "#include <clipping_planes_vertex>",
29
+ `
30
+ #include <clipping_planes_vertex>
31
+ ${ShadowMapDepthVertex}
32
+ `,
33
+ ).source;
34
+
35
+ // Transform fragment shader - add shadow map depth output
36
+ shader.fragmentShader = createReplacer(shader.fragmentShader)
37
+ .replace(
38
+ "#include <common>",
39
+ `
40
+ #include <common>
41
+ #include <packing>
42
+ `,
43
+ )
44
+ .replace(
45
+ "void main() {",
46
+ `
47
+ ${ShadowMapDepthParsFragment}
48
+
49
+ void main() {
50
+ ${ShadowMapDepthFragment}
51
+ `,
52
+ ).source;
53
+ };
@@ -0,0 +1,17 @@
1
+ import type { ShadowMapDepthProps, ShadowMapDepthState } from "./types";
2
+
3
+ export const DEFAULT_SHADOW_MAP_DEPTH_PROPS: Required<ShadowMapDepthProps> = {};
4
+
5
+ export const DEFAULT_SHADOW_MAP_DEPTH_STATE: ShadowMapDepthState = {};
6
+
7
+ /**
8
+ * Update immutable state from props.
9
+ * This enhancer has minimal state since it primarily holds external refs.
10
+ *
11
+ * @param _props - The props to apply (currently unused)
12
+ * @param currentState - The current state to use as fallback
13
+ */
14
+ export const updateState = (
15
+ _props: ShadowMapDepthProps,
16
+ _currentState: ShadowMapDepthState,
17
+ ): ShadowMapDepthState => ({});
@@ -0,0 +1,26 @@
1
+ /* eslint-disable @typescript-eslint/no-empty-object-type */
2
+ import type { Mutates } from "../../MaterialEnhancer";
3
+
4
+ export type ShadowMapDepthProps = {};
5
+
6
+ /**
7
+ * Immutable state for the shadow map depth enhancer.
8
+ * This enhancer has no internal state that changes - it just holds external refs.
9
+ */
10
+ export type ShadowMapDepthState = Readonly<{}>;
11
+
12
+ /**
13
+ * Mutable references (uniforms) for the shadow map depth enhancer.
14
+ * These are external refs passed via props.
15
+ */
16
+ export type ShadowMapDepthRefs = {};
17
+
18
+ export type ShadowMapDepthUniforms = Partial<ShadowMapDepthRefs>;
19
+
20
+ /**
21
+ * Mutation functions for the shadow map depth enhancer.
22
+ */
23
+ export type ShadowMapDepthMutates = Mutates<
24
+ ShadowMapDepthState,
25
+ ShadowMapDepthUniforms
26
+ >;
@@ -0,0 +1,124 @@
1
+ import type { Material, WebGLProgramParametersWithUniforms } from "three";
2
+ import {
3
+ MeshBasicMaterial,
4
+ MeshLambertMaterial,
5
+ MeshPhongMaterial,
6
+ MeshPhysicalMaterial,
7
+ MeshStandardMaterial,
8
+ PointsMaterial,
9
+ ShaderLib,
10
+ ShaderMaterial,
11
+ } from "three";
12
+ import { beforeAll, describe, expect, it } from "vitest";
13
+
14
+ import { overrideMaterialsForMRT } from "../../overrideMaterialsForMRT";
15
+ import type { MaterialEnhancer, ShaderName } from "../MaterialEnhancer";
16
+ import type { ShaderMarkers } from "../ShaderReplacer";
17
+
18
+ type InferProps<E> =
19
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
20
+ E extends MaterialEnhancer<any, infer P, any, any, any> ? P : never;
21
+
22
+ const SHADER_MATERIAL_MAP: Record<ShaderName, new () => Material> = {
23
+ basic: MeshBasicMaterial,
24
+ lambert: MeshLambertMaterial,
25
+ phong: MeshPhongMaterial,
26
+ standard: MeshStandardMaterial,
27
+ physical: MeshPhysicalMaterial,
28
+ points: PointsMaterial,
29
+ shader: ShaderMaterial, // Custom ShaderMaterial
30
+ };
31
+
32
+ const ALL_SHADER_TYPES = Object.keys(SHADER_MATERIAL_MAP) as ShaderName[];
33
+
34
+ function createMockShader(
35
+ shaderType: ShaderName,
36
+ ): WebGLProgramParametersWithUniforms {
37
+ // Custom ShaderMaterial ("shader") is not in Three.js ShaderLib
38
+ // ShaderLib only contains built-in materials: basic, lambert, phong, standard, physical, points
39
+ // For custom ShaderMaterial, we provide a minimal shader for testing enhancer transformShader()
40
+ if (shaderType === "shader") {
41
+ throw new Error(
42
+ "This test checks if the shader replacement works without any error. ShaderMaterial doesn't need this check.",
43
+ );
44
+ }
45
+
46
+ // For standard Three.js materials, use ShaderLib
47
+ const shaderDef = ShaderLib[shaderType];
48
+ return {
49
+ vertexShader: shaderDef.vertexShader,
50
+ fragmentShader: shaderDef.fragmentShader,
51
+ uniforms: { ...shaderDef.uniforms },
52
+ defines: {},
53
+ } as WebGLProgramParametersWithUniforms;
54
+ }
55
+
56
+ /**
57
+ * Test helper to verify that an enhancer correctly works with its declared shaders.
58
+ *
59
+ * This function creates a test suite that:
60
+ * 1. Tests that all declared shaders and props pairs in availableShaders work without throwing
61
+ * 2. Documents which shaders are intentionally unsupported
62
+ * 3. Verifies all markers exist in their respective transformed shaders
63
+ *
64
+ * @param enhancerName - Name of the enhancer for test description
65
+ * @param createEnhancer - Factory function that takes a material and returns an enhancer
66
+ * @param propsTests - Test cases with props that trigger different shader paths
67
+ * @param markers - Marker constants to verify in the transformed shaders
68
+ */
69
+ export function testShaderCompatibility<
70
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
71
+ E extends MaterialEnhancer<Material, any, any, any, ShaderName[]>,
72
+ >(
73
+ enhancerName: string,
74
+ createEnhancer: (material: Material) => E,
75
+ propsTests: {
76
+ name: string;
77
+ props: InferProps<E>;
78
+ }[],
79
+ markers: ShaderMarkers,
80
+ ): void {
81
+ describe(`${enhancerName} - ShaderLib Compatibility`, () => {
82
+ beforeAll(() => {
83
+ overrideMaterialsForMRT();
84
+ });
85
+
86
+ describe("supported shaders", () => {
87
+ describe.each(ALL_SHADER_TYPES)(
88
+ "should transform %s shader without errors",
89
+ (shaderType) => {
90
+ const testMaterial = new SHADER_MATERIAL_MAP[shaderType]();
91
+ const testEnhancer = createEnhancer(testMaterial);
92
+
93
+ if (!testEnhancer.availableShaders.includes(shaderType)) return;
94
+
95
+ it.each(propsTests)("$name", ({ props }) => {
96
+ const mockShader = createMockShader(shaderType);
97
+
98
+ // Mount
99
+ testEnhancer.mount(props);
100
+ const mountShader = structuredClone(mockShader);
101
+ expect(() => {
102
+ testEnhancer.transformShader(mountShader);
103
+ }).not.toThrow();
104
+
105
+ // Update
106
+ testEnhancer.update(props);
107
+ const updateShader = structuredClone(mockShader);
108
+ expect(() => {
109
+ testEnhancer.transformShader(updateShader);
110
+ }).not.toThrow();
111
+
112
+ // Verify markers exist in transformed shaders
113
+ for (const markerValue of Object.values(markers.vertex)) {
114
+ expect(updateShader.vertexShader).toContain(markerValue);
115
+ }
116
+ for (const markerValue of Object.values(markers.fragment)) {
117
+ expect(updateShader.fragmentShader).toContain(markerValue);
118
+ }
119
+ });
120
+ },
121
+ );
122
+ });
123
+ });
124
+ }
@@ -0,0 +1,95 @@
1
+ import { describe, expect, it } from "vitest";
2
+
3
+ import type { CompositeFeatures } from "../../../tileTexture/types";
4
+
5
+ import {
6
+ composeCompositeContributions,
7
+ compositeFeatureKey,
8
+ createCompositeLayerEnhancers,
9
+ } from "./compose";
10
+
11
+ const OFF: CompositeFeatures = {
12
+ hasHillshade: false,
13
+ hasWater: false,
14
+ hasElevationHeatmap: false,
15
+ hasWatermask: false,
16
+ };
17
+
18
+ const compose = (features: CompositeFeatures, numTextures: number) =>
19
+ composeCompositeContributions(
20
+ createCompositeLayerEnhancers(features),
21
+ numTextures,
22
+ );
23
+
24
+ describe("compositeFeatureKey", () => {
25
+ it("is unique per feature combination", () => {
26
+ const keys = new Set<string>();
27
+ for (let mask = 0; mask < 16; mask++) {
28
+ keys.add(
29
+ compositeFeatureKey({
30
+ hasHillshade: !!(mask & 1),
31
+ hasElevationHeatmap: !!(mask & 2),
32
+ hasWater: !!(mask & 4),
33
+ hasWatermask: !!(mask & 8),
34
+ }),
35
+ );
36
+ }
37
+ expect(keys.size).toBe(16);
38
+ });
39
+ });
40
+
41
+ describe("composeCompositeContributions", () => {
42
+ it("emits no feature GLSL when everything is off", () => {
43
+ const c = compose(OFF, 2);
44
+ expect(c.slotUniformDecls).not.toContain("uniform");
45
+ expect(c.globalUniformDecls).toBe("");
46
+ expect(c.includes).toBe("");
47
+ expect(c.sampleProducer).toBeUndefined();
48
+ expect(c.perSlotPostSample({ k: 0, absSlot: 0, isVector: false })).toBe("");
49
+ expect(c.perSlotOnWinner({ k: 0, absSlot: 0, isVector: false })).toBe("");
50
+ });
51
+
52
+ it("orders slot uniform declarations hillshade → elevation → water", () => {
53
+ const c = compose(
54
+ {
55
+ hasHillshade: true,
56
+ hasElevationHeatmap: true,
57
+ hasWater: true,
58
+ hasWatermask: false,
59
+ },
60
+ 2,
61
+ );
62
+ const hill = c.slotUniformDecls.indexOf("uIsHillshades");
63
+ const elev = c.slotUniformDecls.indexOf("uIsElevationHeatmaps");
64
+ const water = c.slotUniformDecls.indexOf("uWaters");
65
+ expect(hill).toBeGreaterThanOrEqual(0);
66
+ expect(hill).toBeLessThan(elev);
67
+ expect(elev).toBeLessThan(water);
68
+ });
69
+
70
+ it("orders the post-loop blocks hillshade before watermask", () => {
71
+ const c = compose({ ...OFF, hasHillshade: true, hasWatermask: true }, 1);
72
+ const hill = c.postLoop.indexOf("hillshadeNormal");
73
+ const mask = c.postLoop.indexOf("uWatermask");
74
+ expect(hill).toBeGreaterThanOrEqual(0);
75
+ expect(hill).toBeLessThan(mask);
76
+ });
77
+
78
+ it("only the elevation heatmap overrides the per-slot sampler", () => {
79
+ expect(compose(OFF, 1).sampleProducer).toBeUndefined();
80
+ const c = compose({ ...OFF, hasElevationHeatmap: true }, 1);
81
+ expect(c.sampleProducer).toBeDefined();
82
+ expect(c.sampleProducer?.({ k: 0, absSlot: 0, isVector: false })).toContain(
83
+ "sampleElevationBilinear",
84
+ );
85
+ expect(c.includes).toContain("sampleElevationBilinear");
86
+ });
87
+
88
+ it("writes the per-slot water flag only when water is on", () => {
89
+ const ctx = { k: 1, absSlot: 1, isVector: false };
90
+ expect(compose(OFF, 2).perSlotOnWinner(ctx)).toBe("");
91
+ expect(
92
+ compose({ ...OFF, hasWater: true }, 2).perSlotOnWinner(ctx),
93
+ ).toContain("isWater = uWaters[1]");
94
+ });
95
+ });
@@ -0,0 +1,112 @@
1
+ import type {
2
+ CompositeFeatures,
3
+ CompositeGlobals,
4
+ CompositeLayer,
5
+ } from "../../../tileTexture/types";
6
+
7
+ import type { CompositeShaderContributions } from "./tileCompositeBaseEnhancer";
8
+ import { createTileElevationHeatmapEnhancer } from "./tileElevationHeatmapEnhancer";
9
+ import { createTileHillshadeEnhancer } from "./tileHillshadeEnhancer";
10
+ import { createTileWaterEnhancer } from "./tileWaterEnhancer";
11
+ import { createTileWatermaskEnhancer } from "./tileWatermaskEnhancer";
12
+ import type { CompositeLayerEnhancer } from "./types";
13
+
14
+ /**
15
+ * Build the ordered composite layer enhancer chain for a feature set —
16
+ * inactive expressions return undefined and drop out. Order is significant: it
17
+ * fixes how per-slot uniform declarations and post-loop blocks concatenate
18
+ * (hillshade, elevation, water for slot uniforms; hillshade then watermask for
19
+ * the post-loop). A new expression is added by writing an enhancer and slotting
20
+ * it in here.
21
+ */
22
+ export function createCompositeLayerEnhancers(
23
+ features: CompositeFeatures,
24
+ ): CompositeLayerEnhancer[] {
25
+ return [
26
+ createTileHillshadeEnhancer(features.hasHillshade),
27
+ createTileElevationHeatmapEnhancer(features.hasElevationHeatmap),
28
+ createTileWaterEnhancer(features.hasWater),
29
+ createTileWatermaskEnhancer(features.hasWatermask),
30
+ ].filter((e): e is CompositeLayerEnhancer => e !== undefined);
31
+ }
32
+
33
+ /**
34
+ * Derive the active feature set from the planned layers and tile globals. Each
35
+ * per-slot expression is active iff a layer of that kind is present; watermask
36
+ * is a global. Driving the feature set off the active layers means the shader
37
+ * never declares uniforms or runs code for a flag that no compact slot uses.
38
+ */
39
+ export function deriveCompositeFeatures(
40
+ layers: readonly CompositeLayer[],
41
+ globals: CompositeGlobals,
42
+ ): CompositeFeatures {
43
+ return {
44
+ hasHillshade: layers.some((l) => l.kind === "hillshade"),
45
+ hasElevationHeatmap: layers.some((l) => l.kind === "elevationHeatmap"),
46
+ hasWater: layers.some((l) => l.kind === "raster" && l.water),
47
+ hasWatermask: globals.watermask != null,
48
+ };
49
+ }
50
+
51
+ /**
52
+ * Material cache key for a feature set. Stringifying the whole CompositeFeatures
53
+ * object keeps the key unambiguous as flags are added — no hand-maintained
54
+ * per-flag encoding to collide.
55
+ */
56
+ export function compositeFeatureKey(features: CompositeFeatures): string {
57
+ return JSON.stringify(features);
58
+ }
59
+
60
+ /**
61
+ * Fold the enhancer chain into the base enhancer's contribution bundle. Each
62
+ * hook is collected from every enhancer that defines it, in chain order:
63
+ * - decl/include/postLoop blocks join with "\n" (an enhancer that leaves the
64
+ * hook undefined simply drops out of that block),
65
+ * - per-slot transforms concatenate (they target the same texColor / attr),
66
+ * - sampleProducer takes the last active overrider (only the heatmap sets it).
67
+ */
68
+ /** Collect the defined values of one hook across the chain, in chain order. */
69
+ function collect<T>(
70
+ enhancers: readonly CompositeLayerEnhancer[],
71
+ pick: (e: CompositeLayerEnhancer) => T | undefined,
72
+ ): T[] {
73
+ const out: T[] = [];
74
+ for (const e of enhancers) {
75
+ const v = pick(e);
76
+ if (v !== undefined) out.push(v);
77
+ }
78
+ return out;
79
+ }
80
+
81
+ export function composeCompositeContributions(
82
+ enhancers: readonly CompositeLayerEnhancer[],
83
+ numTextures: number,
84
+ ): CompositeShaderContributions {
85
+ // Last active overrider wins (only the heatmap sets one).
86
+ const sampleProducers = collect(enhancers, (e) => e.sampleProducer);
87
+ const sampleProducer = sampleProducers[sampleProducers.length - 1];
88
+
89
+ return {
90
+ slotUniformDecls: collect(enhancers, (e) => e.slotUniformDecls)
91
+ .map((fn) => fn(numTextures))
92
+ .join("\n"),
93
+ globalUniformDecls: collect(enhancers, (e) => e.globalUniformDecls)
94
+ .map((fn) => fn())
95
+ .join("\n"),
96
+ includes: collect(enhancers, (e) => e.includes)
97
+ .map((fn) => fn())
98
+ .join("\n"),
99
+ sampleProducer,
100
+ perSlotPostSample: (ctx) =>
101
+ collect(enhancers, (e) => e.perSlotPostSample)
102
+ .map((fn) => fn(ctx))
103
+ .join(""),
104
+ perSlotOnWinner: (ctx) =>
105
+ collect(enhancers, (e) => e.perSlotOnWinner)
106
+ .map((fn) => fn(ctx))
107
+ .join(""),
108
+ postLoop: collect(enhancers, (e) => e.postLoop)
109
+ .map((fn) => fn(numTextures))
110
+ .join("\n"),
111
+ };
112
+ }
@@ -0,0 +1,23 @@
1
+ export {
2
+ buildCompositeFragmentShader,
3
+ compositeSlotMarker,
4
+ createCoreUniformMutates,
5
+ COMPOSITE_VERTEX_SHADER,
6
+ } from "./tileCompositeBaseEnhancer";
7
+ export type {
8
+ CompositeShaderContributions,
9
+ CompositeSlotContext,
10
+ CompositeUniformTarget,
11
+ CoreUniformMutates,
12
+ } from "./tileCompositeBaseEnhancer";
13
+ export type { CompositeLayerEnhancer } from "./types";
14
+ export {
15
+ composeCompositeContributions,
16
+ compositeFeatureKey,
17
+ createCompositeLayerEnhancers,
18
+ deriveCompositeFeatures,
19
+ } from "./compose";
20
+ export { createTileHillshadeEnhancer } from "./tileHillshadeEnhancer";
21
+ export { createTileElevationHeatmapEnhancer } from "./tileElevationHeatmapEnhancer";
22
+ export { createTileWaterEnhancer } from "./tileWaterEnhancer";
23
+ export { createTileWatermaskEnhancer } from "./tileWatermaskEnhancer";
@@ -0,0 +1,11 @@
1
+ export {
2
+ buildCompositeFragmentShader,
3
+ compositeSlotMarker,
4
+ COMPOSITE_VERTEX_SHADER,
5
+ } from "./shader";
6
+ export { createCoreUniformMutates } from "./mutates";
7
+ export type { CompositeUniformTarget, CoreUniformMutates } from "./mutates";
8
+ export type {
9
+ CompositeShaderContributions,
10
+ CompositeSlotContext,
11
+ } from "./types";
@@ -0,0 +1,132 @@
1
+ import { Color, Uniform, Vector2, Vector4, type Texture } from "three";
2
+
3
+ import type { CompositeLayer } from "../../../../tileTexture/types";
4
+
5
+ /** Shader uniform dictionary the composite ShaderMaterial is built from. */
6
+ export type CompositeUniformTarget = Record<string, Uniform>;
7
+
8
+ const WHITE = new Color(1, 1, 1);
9
+
10
+ /** atan(sinh(PI)) — the WebMercator max latitude (~85.051°). */
11
+ const WM_MAX_LAT = Math.atan(Math.sinh(Math.PI));
12
+
13
+ /**
14
+ * Owns the core per-slot uniforms (shows/colors/opacities/textures/uv) of the
15
+ * composite material. Refs live in this closure so binds mutate the same
16
+ * objects three.js holds. Mirrors the MaterialEnhancer mutates pattern: create
17
+ * + attach once, then sync per compact slot from the planned layers.
18
+ */
19
+ export type CoreUniformMutates = {
20
+ attachUniforms: (
21
+ target: CompositeUniformTarget,
22
+ numTextures: number,
23
+ placeholder: Texture,
24
+ ) => void;
25
+ /** Sync slot `compactSlot` from the layer occupying it (or clear it). */
26
+ bindSlot: (compactSlot: number, layer: CompositeLayer | undefined) => void;
27
+ };
28
+
29
+ export function createCoreUniformMutates(): CoreUniformMutates {
30
+ const refs = {
31
+ uShows: new Uniform<number[]>([]),
32
+ uOpacities: new Uniform<number[]>([]),
33
+ uColors: new Uniform<Color[]>([]),
34
+ uTextures: new Uniform<Texture[]>([]),
35
+ uLayerUvOffset: new Uniform<Vector2[]>([]),
36
+ uLayerUvScale: new Uniform<Vector2[]>([]),
37
+ // Per-slot Mercator reprojection: uReproject[k] = 1 means sample this slot's
38
+ // texture using the latitude reprojection driven by uReprojectTerrainLat[k]
39
+ // (the terrain tile's [south, north] latitude in radians).
40
+ uReproject: new Uniform<number[]>([]),
41
+ uReprojectTerrainLat: new Uniform<Vector2[]>([]),
42
+ // CPU-precomputed per-slot reprojection constants consumed by the shader:
43
+ // (mRs, mDen, clampTopEdge, clampBottomEdge). See bindSlot for the math.
44
+ uReprojectMerc: new Uniform<Vector4[]>([]),
45
+ };
46
+ let placeholderTexture: Texture | null = null;
47
+
48
+ return {
49
+ attachUniforms: (target, numTextures, placeholder) => {
50
+ placeholderTexture = placeholder;
51
+ refs.uShows.value = new Array<number>(numTextures).fill(0);
52
+ refs.uOpacities.value = new Array<number>(numTextures).fill(1);
53
+ refs.uColors.value = Array.from(
54
+ { length: numTextures },
55
+ () => new Color(),
56
+ );
57
+ refs.uTextures.value = new Array<Texture>(numTextures).fill(placeholder);
58
+ refs.uLayerUvOffset.value = Array.from(
59
+ { length: numTextures },
60
+ () => new Vector2(0, 0),
61
+ );
62
+ refs.uLayerUvScale.value = Array.from(
63
+ { length: numTextures },
64
+ () => new Vector2(1, 1),
65
+ );
66
+ refs.uReproject.value = new Array<number>(numTextures).fill(0);
67
+ refs.uReprojectTerrainLat.value = Array.from(
68
+ { length: numTextures },
69
+ () => new Vector2(0, 0),
70
+ );
71
+ refs.uReprojectMerc.value = Array.from(
72
+ { length: numTextures },
73
+ () => new Vector4(0, 0, 0, 0),
74
+ );
75
+ target.uShows = refs.uShows;
76
+ target.uOpacities = refs.uOpacities;
77
+ target.uColors = refs.uColors;
78
+ target.uTextures = refs.uTextures;
79
+ target.uLayerUvOffset = refs.uLayerUvOffset;
80
+ target.uLayerUvScale = refs.uLayerUvScale;
81
+ target.uReproject = refs.uReproject;
82
+ target.uReprojectTerrainLat = refs.uReprojectTerrainLat;
83
+ target.uReprojectMerc = refs.uReprojectMerc;
84
+ },
85
+
86
+ bindSlot: (k, layer) => {
87
+ refs.uShows.value[k] = layer ? 1 : 0;
88
+ refs.uTextures.value[k] =
89
+ layer?.texture ?? placeholderTexture ?? refs.uTextures.value[k];
90
+ // Color only matters for raster slots; hillshade is zeroed and elevation
91
+ // reads the colormap, so reset others to white to drop stale values.
92
+ if (layer && layer.kind === "raster") {
93
+ refs.uColors.value[k].copy(layer.color);
94
+ } else {
95
+ refs.uColors.value[k].copy(WHITE);
96
+ }
97
+ refs.uOpacities.value[k] =
98
+ layer && "opacity" in layer ? layer.opacity : 1;
99
+ if (layer) {
100
+ refs.uLayerUvOffset.value[k].copy(layer.uvOffset);
101
+ refs.uLayerUvScale.value[k].copy(layer.uvScale);
102
+ } else {
103
+ refs.uLayerUvOffset.value[k].set(0, 0);
104
+ refs.uLayerUvScale.value[k].set(1, 1);
105
+ }
106
+
107
+ const reproject =
108
+ layer && layer.kind === "raster" ? layer.reproject : undefined;
109
+ if (reproject && layer) {
110
+ const [Ts, Tn] = reproject;
111
+ // Recover the source tile's latitude band [Rs, Rn] from the affine y
112
+ // mapping, then its Mercator-space start (mRs) and span (mDen). These are
113
+ // constant per slot, so the shader reads them instead of evaluating
114
+ // log/tan per fragment — only the shared per-fragment mLat stays on GPU.
115
+ const span = (Tn - Ts) / layer.uvScale.y;
116
+ const Rs = Ts - layer.uvOffset.y * span;
117
+ const Rn = Rs + span;
118
+ const mRs = Math.log(Math.tan(Math.PI * 0.25 + Rs * 0.5));
119
+ const mRn = Math.log(Math.tan(Math.PI * 0.25 + Rn * 0.5));
120
+ // Polar cap: clamp the overshoot onto the band-edge texel when this tile's
121
+ // north/south edge sits on the WebMercator latitude limit.
122
+ const clampTop = Rn >= WM_MAX_LAT - 1e-4 ? 1 : 0;
123
+ const clampBottom = Rs <= -WM_MAX_LAT + 1e-4 ? 1 : 0;
124
+ refs.uReproject.value[k] = 1;
125
+ refs.uReprojectTerrainLat.value[k].set(Ts, Tn);
126
+ refs.uReprojectMerc.value[k].set(mRs, mRn - mRs, clampTop, clampBottom);
127
+ } else {
128
+ refs.uReproject.value[k] = 0;
129
+ }
130
+ },
131
+ };
132
+ }