@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,58 @@
1
+ import type { Texture } from "three";
2
+
3
+ import type {
4
+ CompositeGlobals,
5
+ CompositeLayer,
6
+ } from "../../../tileTexture/types";
7
+
8
+ import type {
9
+ CompositeShaderContributions,
10
+ CompositeSlotContext,
11
+ CompositeUniformTarget,
12
+ } from "./tileCompositeBaseEnhancer";
13
+
14
+ /**
15
+ * A composite layer enhancer owns one expression's contribution to the
16
+ * offscreen composite pass — both its GLSL fragments and its uniforms. The
17
+ * factory returns `undefined` when the expression is inactive, so the composed
18
+ * chain contains only active enhancers and the composer just concatenates what
19
+ * each one provides. Adding a new expression is a new enhancer module + one
20
+ * entry in `createCompositeLayerEnhancers`.
21
+ *
22
+ * Every hook is optional; an enhancer exposes only the ones it participates in.
23
+ */
24
+ export type CompositeLayerEnhancer = {
25
+ /** Per-slot uniform declarations (sized at numTextures). */
26
+ slotUniformDecls?: (numTextures: number) => string;
27
+ /** Slot-independent uniform declarations. */
28
+ globalUniformDecls?: () => string;
29
+ /** GLSL chunks inlined before `main()`. */
30
+ includes?: () => string;
31
+ /** Overrides the per-slot sampler (only the active overrider sets it). */
32
+ sampleProducer?: CompositeShaderContributions["sampleProducer"];
33
+ /** Additive transform on `texColor${k}` after sampling. */
34
+ perSlotPostSample?: (ctx: CompositeSlotContext) => string;
35
+ /** Additive attr update when a slot wins the alpha-over blend. */
36
+ perSlotOnWinner?: (ctx: CompositeSlotContext) => string;
37
+ /** GLSL injected after the slot loop. */
38
+ postLoop?: (numTextures: number) => string;
39
+
40
+ // --- material defines + uniform ownership (active enhancers only) ---
41
+ /** Shader defines this enhancer needs (e.g. USE_ELEVATION_HEATMAP). */
42
+ defines?: Record<string, number>;
43
+ /**
44
+ * Create this enhancer's uniform refs (sized at numTextures) and assign them
45
+ * into the composite material's uniform dict. Refs are held in closure so
46
+ * `bindSlot`/`bindGlobal` mutate the same objects three.js owns. Defined only
47
+ * when the enhancer is active.
48
+ */
49
+ attachUniforms?: (
50
+ target: CompositeUniformTarget,
51
+ numTextures: number,
52
+ placeholder: Texture,
53
+ ) => void;
54
+ /** Sync per-slot refs from the layer occupying compact slot `compactSlot`. */
55
+ bindSlot?: (compactSlot: number, layer: CompositeLayer | undefined) => void;
56
+ /** Sync slot-independent refs from the tile globals. */
57
+ bindGlobal?: (globals: CompositeGlobals) => void;
58
+ };
@@ -0,0 +1,3 @@
1
+ export * from "./enhancer";
2
+ export * from "./macro";
3
+ export * from "./overrideMaterialsForMRT";
@@ -0,0 +1 @@
1
+ export * from "./tileShader";
@@ -0,0 +1,136 @@
1
+ import { describe, expect, it } from "vitest";
2
+
3
+ import {
4
+ generateTileCommonInjection,
5
+ generateTileMapFragment,
6
+ generateTileNormalFragmentMaps,
7
+ TILE_EMISSIVE_EFFECT_BUFFER_REPLACEMENT,
8
+ TILE_NORMAL_BUFFER_REPLACEMENT,
9
+ TILE_PICK_FRAGMENT_OVERRIDE,
10
+ } from "./tileShader";
11
+
12
+ describe("generateTileCommonInjection", () => {
13
+ it("declares the three atlas samplers", () => {
14
+ const src = generateTileCommonInjection(8);
15
+ expect(src).toContain("uniform sampler2D uColorAtlas;");
16
+ expect(src).toContain("uniform sampler2D uAttrAtlas;");
17
+ expect(src).toContain("uniform sampler2D uNormalAtlas;");
18
+ });
19
+
20
+ it("sizes per-slot uniform arrays to the requested slot count", () => {
21
+ const src = generateTileCommonInjection(16);
22
+ expect(src).toContain("uniform float uShininesses[16];");
23
+ expect(src).toContain("uniform vec3 uEmissiveColors[16];");
24
+ expect(src).toContain("uniform float uEffectIdsMasks[16];");
25
+ });
26
+ });
27
+
28
+ describe("generateTileMapFragment", () => {
29
+ const src = generateTileMapFragment(16);
30
+
31
+ it("samples each atlas exactly once", () => {
32
+ const colorMatches = src.match(/texture2D\(uColorAtlas/g) ?? [];
33
+ const attrMatches = src.match(/texture2D\(uAttrAtlas/g) ?? [];
34
+ expect(colorMatches.length).toBe(1);
35
+ expect(attrMatches.length).toBe(1);
36
+ });
37
+
38
+ it("decodes winning slot from attr.a as (n*255) - 1", () => {
39
+ expect(src).toContain("int winIdx = int(round(atlasAttr.a * 255.0)) - 1;");
40
+ });
41
+
42
+ it("masks colour by attr.g and snapshots into nvr_pickColor on picking pass", () => {
43
+ // Raster pixels contribute 0 (no entity); vector pixels keep the pick
44
+ // ID written into atlasColor by the per-layer RT pass. We snapshot the
45
+ // masked value BEFORE the diffuse merge so the dithering-stage override
46
+ // writes it straight to gl_FragColor without lighting/tonemapping/fog
47
+ // corruption.
48
+ expect(src).toContain("if (uPickable > 0.)");
49
+ expect(src).toContain("atlasColor.rgb *= atlasAttr.g;");
50
+ expect(src).toContain("vec3 nvr_pickColor = atlasColor.rgb;");
51
+ });
52
+
53
+ it("indexes per-slot uniforms with winIdx (no loop)", () => {
54
+ expect(src).toContain("uShininesses[winIdx]");
55
+ expect(src).toContain("uReflectivities[winIdx]");
56
+ // Should not loop over slots — the dynamic index is the whole point.
57
+ expect(src).not.toMatch(/for\s*\(/);
58
+ });
59
+
60
+ it("uses premultiplied 'over' blend so transparent atlas keeps base color", () => {
61
+ // src.rgb + dst * (1 - src.a) — NOT mix(dst, src.rgb, src.a). Mixing
62
+ // would double-apply alpha because the composite already premultiplies.
63
+ expect(src).toContain(
64
+ "diffuseColor.rgb = atlasColor.rgb + diffuseColor.rgb * (1.0 - atlasColor.a);",
65
+ );
66
+ expect(src).not.toMatch(/mix\(diffuseColor\.rgb,\s*atlasColor\.rgb/);
67
+ });
68
+ });
69
+
70
+ describe("generateTileNormalFragmentMaps", () => {
71
+ it("omits the hillshade lookup entirely when hasHillshade is off", () => {
72
+ const src = generateTileNormalFragmentMaps({
73
+ hasHillshade: false,
74
+ hasWater: false,
75
+ });
76
+ expect(src).not.toContain("uNormalAtlas");
77
+ expect(src).not.toContain("TBN");
78
+ });
79
+
80
+ it("samples uNormalAtlas exactly once when hasHillshade is on", () => {
81
+ const src = generateTileNormalFragmentMaps({
82
+ hasHillshade: true,
83
+ hasWater: false,
84
+ });
85
+ const matches = src.match(/texture2D\(uNormalAtlas/g) ?? [];
86
+ expect(matches.length).toBe(1);
87
+ expect(src).toContain("atlasNormalSample.a > 0.5");
88
+ expect(src).toContain("uHillshadeExaggeration");
89
+ });
90
+
91
+ it("omits water specular call when hasWater is off", () => {
92
+ const src = generateTileNormalFragmentMaps({
93
+ hasHillshade: false,
94
+ hasWater: false,
95
+ });
96
+ expect(src).not.toContain("computeWaterSpecular");
97
+ expect(src).toContain("computeSpecular(");
98
+ });
99
+
100
+ it("emits computeWaterSpecular when hasWater is on", () => {
101
+ const src = generateTileNormalFragmentMaps({
102
+ hasHillshade: false,
103
+ hasWater: true,
104
+ });
105
+ expect(src).toContain("computeWaterSpecular(");
106
+ });
107
+ });
108
+
109
+ describe("MRT buffer replacements", () => {
110
+ it("writes finalNormal into normalBuffer with reflectivity/roughness packed", () => {
111
+ expect(TILE_NORMAL_BUFFER_REPLACEMENT).toContain("normalBuffer = vec4(");
112
+ expect(TILE_NORMAL_BUFFER_REPLACEMENT).toContain("tileReflectivity");
113
+ expect(TILE_NORMAL_BUFFER_REPLACEMENT).toContain("tileRoughness");
114
+ });
115
+
116
+ it("gates emissive/effect on isTexturizedLayer", () => {
117
+ expect(TILE_EMISSIVE_EFFECT_BUFFER_REPLACEMENT).toContain(
118
+ "if (isTexturizedLayer)",
119
+ );
120
+ expect(TILE_EMISSIVE_EFFECT_BUFFER_REPLACEMENT).toContain(
121
+ "effectIdBuffer = vec4(0.0);",
122
+ );
123
+ });
124
+
125
+ it("pick override writes nvr_pickColor straight to gl_FragColor", () => {
126
+ // Output is the LAST write of the fragment shader so envmap/tonemapping/
127
+ // colorspace/fog can't pollute the pick buffer with lit colours. The
128
+ // value comes from the attr.g-masked atlas (see generateTileMapFragment)
129
+ // — raster pixels become batchId=0 (no entity); vector pixels carry the
130
+ // ID their own per-layer enhancer wrote during the per-layer RT pass.
131
+ expect(TILE_PICK_FRAGMENT_OVERRIDE).toContain("if (uPickable > 0.)");
132
+ expect(TILE_PICK_FRAGMENT_OVERRIDE).toContain(
133
+ "gl_FragColor = vec4(nvr_pickColor, 1.0);",
134
+ );
135
+ });
136
+ });
@@ -0,0 +1,287 @@
1
+ /**
2
+ * Slim TileMesh fragment-shader fragments.
3
+ *
4
+ * The TileMesh main pass used to unroll an N-slot texture loop per fragment
5
+ * (`generateMixOverlaidTexturesMacro`). That cost N TMU fetches × screen
6
+ * pixels every frame, plus another N iterations for `generateHillshadeNormal`.
7
+ *
8
+ * After the refactor, TileTextureCompositor bakes all N source textures into
9
+ * a per-tile MRT atlas (color + attr + normal) only when something is dirty.
10
+ * The main pass then does **at most three** texture lookups per fragment and
11
+ * uses the attr atlas's encoded winning-slot index to dynamically index the
12
+ * per-slot uniform arrays for shininess/specular/emissive/effect/etc.
13
+ *
14
+ * Each function returns a snippet that's spliced into a chunk via the
15
+ * existing `createReplacer` machinery in mesh/tile.ts.
16
+ */
17
+
18
+ export type TileShaderFeatures = {
19
+ /** Atlas has a hillshade normal that should override the default normal. */
20
+ hasHillshade: boolean;
21
+ /** Some layer uses Water material → emit the water specular branch. */
22
+ hasWater: boolean;
23
+ };
24
+
25
+ /**
26
+ * Goes after `#include <common>` in the fragment shader. Declares the three
27
+ * atlas samplers + the per-slot uniform arrays we still index by winning
28
+ * slot. Adds varying for the original UV.
29
+ */
30
+ export function generateTileCommonInjection(numTextures: number): string {
31
+ return `
32
+ uniform sampler2D uColorAtlas;
33
+ uniform sampler2D uAttrAtlas;
34
+ uniform sampler2D uNormalAtlas;
35
+
36
+ // Per-slot uniforms retained because they need full float precision and are
37
+ // indexed once per fragment by the winning slot from attr.a.
38
+ uniform vec3 uColors[${numTextures}];
39
+ uniform float uReflectivities[${numTextures}];
40
+ uniform float uRoughnesses[${numTextures}];
41
+ uniform float uWaterScaleNormals[${numTextures}];
42
+ uniform float uWaterSpeeds[${numTextures}];
43
+ uniform float uShininesses[${numTextures}];
44
+ uniform float uSpecularStrengths[${numTextures}];
45
+ uniform float uApplyWaterNormals[${numTextures}];
46
+ uniform bool uSpeculars[${numTextures}];
47
+ uniform float uEmissiveIntensities[${numTextures}];
48
+ uniform vec3 uEmissiveColors[${numTextures}];
49
+ uniform float uEffectIdsMasks[${numTextures}];
50
+
51
+ uniform sampler2D uWaterNormalMap;
52
+ uniform float uHillshadeExaggeration;
53
+ uniform float uPickable;
54
+ uniform float uIor;
55
+ uniform float uTime;
56
+
57
+ varying vec2 vOrigUv;
58
+ // vPosition is declared by WaterParsFragment when useNormal=true; for the
59
+ // Basic-material path no fragment-side code reads it, so omitting the
60
+ // declaration here avoids a redefinition error when both are present.
61
+ `;
62
+ }
63
+
64
+ /**
65
+ * Goes in place of `#include <map_fragment>`. Reads the three atlas textures
66
+ * once, decodes the winning slot index, and (when present) pulls per-slot
67
+ * precision-sensitive attrs by dynamic indexing. Picking suppresses the
68
+ * raster contribution by masking colour with the attr's isTexturized flag.
69
+ *
70
+ * `texturizedSceneIndexFrom` is captured at material-build time (used by
71
+ * generateTileEmissiveBuffer below to decide what gets written to the
72
+ * emissive/effect MRT attachments).
73
+ */
74
+ export function generateTileMapFragment(maxTextures: number): string {
75
+ return `
76
+ vec4 atlasColor = texture2D(uColorAtlas, vOrigUv);
77
+ vec4 atlasAttr = texture2D(uAttrAtlas, vOrigUv);
78
+
79
+ // attr.a encodes (winningSlot + 1) / 255 — 0 means no contributing slot.
80
+ int winIdx = int(round(atlasAttr.a * 255.0)) - 1;
81
+ // Bound + clamp the decoded index to the valid uniform-array range. A tile drawn
82
+ // BEFORE its composite atlas is initialized samples an undefined attr.a that can
83
+ // decode to an out-of-range winIdx. An out-of-bounds DYNAMIC array index
84
+ // is undefined behavior that HANGS the Apple/iOS GPU with no WebGL error —
85
+ bool hasWinner = winIdx >= 0 && winIdx < ${maxTextures};
86
+ winIdx = clamp(winIdx, 0, ${maxTextures - 1});
87
+
88
+ // Picking: only vector (texturized) layers carry a pickable entity.
89
+ // attr.g is 1.0 on a vector pixel, 0.0 on a raster pixel — masking by
90
+ // attr.g zeroes raster contribution and leaves the vector mesh's own
91
+ // pick-shader output (composited into atlasColor via the per-layer RT
92
+ // path) untouched. We snapshot the masked colour BEFORE the diffuse
93
+ // merge so the final gl_FragColor override (after dithering_fragment)
94
+ // can write the encoded batchId straight through, bypassing envmap,
95
+ // tonemapping, colorspace, and fog — all of which would corrupt the ID.
96
+ if (uPickable > 0.) {
97
+ atlasColor.rgb *= atlasAttr.g;
98
+ }
99
+ vec3 nvr_pickColor = atlasColor.rgb;
100
+
101
+ // atlasColor is premultiplied: the composite pass accumulates with
102
+ // acc = mix(acc, vec4(rgb, 1.0), alpha)
103
+ // which gives acc.rgb = rgb*alpha + prev*(1-alpha) and acc.a tracks total
104
+ // coverage. The "over" operator for a premultiplied source is
105
+ // out = src.rgb + dst * (1 - src.a)
106
+ // — this preserves the globe's base colour where no layer wrote (atlas.a=0)
107
+ // and matches the legacy per-slot mix(diffuse, color, alpha) semantics
108
+ // exactly (verified algebraically for 1 and 2 stacked layers).
109
+
110
+ bool useWater = atlasAttr.r > 0.5;
111
+ bool isTexturizedLayer = atlasAttr.g > 0.5;
112
+
113
+ // Per-slot uniforms indexed by the winner. Dynamic indexing of non-sampler
114
+ // arrays is well-defined in GLSL ES 3.00. Fallbacks keep the default
115
+ // lighting reasonable for fully-transparent pixels.
116
+ float tileReflectivity = hasWinner ? uReflectivities[winIdx] : 0.0;
117
+ float tileRoughness = hasWinner ? uRoughnesses[winIdx] : 0.0;
118
+
119
+ // TODO: Support water material
120
+ float waterScaleNormal = hasWinner ? uWaterScaleNormals[winIdx] : 0.0;
121
+ float waterSpeed = hasWinner ? uWaterSpeeds[winIdx] : 0.0;
122
+ // Per-slot water specular params only exist for vector (texturized) water
123
+ // layers. When useWater comes from the tile-wide quantized-mesh watermask
124
+ // instead, the winning slot is a raster imagery layer (attr.g == 0) that
125
+ // carries no water params — so fall back to the default water appearance,
126
+ // the same one the no-winner open-ocean path uses. Without this a raster tile
127
+ // draped over a watermask would index the raster slot's zeroed params and the
128
+ // water glint would vanish under the imagery.
129
+ bool hasSlotWaterParams = hasWinner && isTexturizedLayer;
130
+ float waterShininess = hasSlotWaterParams ? uShininesses[winIdx] : 50.0;
131
+ float waterSpecularStrength = hasSlotWaterParams ? uSpecularStrengths[winIdx] : 1.0;
132
+ float applyWaterNormals = hasWinner ? uApplyWaterNormals[winIdx] : 0.0;
133
+ // The watermask flags water independently of which slot wins the blend, so its
134
+ // specular must survive a (non-water) raster winner. OR it in rather than
135
+ // letting the winner's own specular flag gate it — otherwise a draped raster
136
+ // imagery slot (uSpeculars == false) suppresses the watermask water entirely.
137
+ bool useSpecular = (!isTexturizedLayer && useWater) || (hasWinner && uSpeculars[winIdx]);
138
+
139
+ float tileEmissiveIntensity = (hasWinner && isTexturizedLayer) ? uEmissiveIntensities[winIdx] : 0.0;
140
+ vec3 tileEmissiveColor = (hasWinner && isTexturizedLayer) ? uEmissiveColors[winIdx] : vec3(0.0);
141
+ float tileEffectIdsMask = (hasWinner && isTexturizedLayer) ? uEffectIdsMasks[winIdx] : 0.0;
142
+
143
+ diffuseColor.rgb = atlasColor.rgb + diffuseColor.rgb * (1.0 - atlasColor.a);
144
+ `;
145
+ }
146
+
147
+ /**
148
+ * Goes in place of `#include <normal_fragment_maps>`. When the atlas carries
149
+ * a hillshade normal, transform it tangent→view via TBN like the legacy
150
+ * unrolled loop did, but with a single normal-atlas read. Then optionally
151
+ * compute water/specular contribution.
152
+ */
153
+ export function generateTileNormalFragmentMaps(
154
+ features: TileShaderFeatures,
155
+ ): string {
156
+ const hillshadeBlock = features.hasHillshade
157
+ ? `
158
+ // attr-atlas normal: .a flags whether a hillshade slot won this pixel.
159
+ vec4 atlasNormalSample = texture2D(uNormalAtlas, vOrigUv);
160
+ if (atlasNormalSample.a > 0.5) {
161
+ vec3 demNormal = atlasNormalSample.rgb * 2.0 - 1.0;
162
+ demNormal = normalize(demNormal);
163
+ demNormal.xy *= uHillshadeExaggeration;
164
+ demNormal = normalize(demNormal);
165
+
166
+ // Build tangent-space basis from the geometric normal (= N).
167
+ vec3 up = vec3(0.0, 0.0, 1.0);
168
+ vec3 T = normalize(cross(up, N));
169
+ if (length(T) < 0.001) T = vec3(1.0, 0.0, 0.0); // pole fallback
170
+ vec3 B = normalize(cross(N, T));
171
+ mat3 TBN = mat3(T, B, N);
172
+
173
+ vec3 worldDemNormal = normalize(TBN * demNormal);
174
+ normal = normalize(mat3(viewMatrix) * worldDemNormal);
175
+ }
176
+ `
177
+ : "";
178
+
179
+ const waterBlock = features.hasWater
180
+ ? `
181
+ if (useSpecular) {
182
+ specular = computeSpecular(
183
+ vViewPosition,
184
+ origNormal,
185
+ waterShininess,
186
+ waterSpecularStrength,
187
+ uIor
188
+ );
189
+ } else if (useWater) {
190
+ specular = computeWaterSpecular(
191
+ uWaterNormalMap,
192
+ (vPosition.xy + vPosition.zy + vPosition.xz) / 3.0 * waterScaleNormal,
193
+ uTime * waterSpeed,
194
+ vViewPosition,
195
+ normalMatrix,
196
+ origNormal,
197
+ waterShininess,
198
+ waterSpecularStrength,
199
+ diffuseColor.rgb,
200
+ normal
201
+ );
202
+ }
203
+ `
204
+ : `
205
+ if (useSpecular) {
206
+ specular = computeSpecular(
207
+ vViewPosition,
208
+ origNormal,
209
+ waterShininess,
210
+ waterSpecularStrength,
211
+ uIor
212
+ );
213
+ }
214
+ `;
215
+
216
+ return `
217
+ #if USE_VERTEX_NORMAL && !USE_HILLSHADE
218
+ // Keep the interpolated per-vertex normal (already in view space via three.js).
219
+ #else
220
+ vec3 N = normalize(vPosition);
221
+ normal = normalize(mat3(viewMatrix) * N);
222
+ #endif
223
+ ${hillshadeBlock}
224
+ vec3 origNormal = vec3(normal);
225
+ vec3 specular = vec3(0.0);
226
+ ${waterBlock}
227
+ `;
228
+ }
229
+
230
+ /**
231
+ * `normalBuffer = …` replacement for the MRT pass. Identical to legacy
232
+ * behaviour: applyWaterNormals mixes the perturbed normal into the geometric
233
+ * one before packing.
234
+ */
235
+ export const TILE_NORMAL_BUFFER_REPLACEMENT = `
236
+ vec3 finalNormal = mix(origNormal, normalize(origNormal * 0.7 + normal), applyWaterNormals);
237
+ normalBuffer = vec4(packNormalToVec2(finalNormal), tileReflectivity, tileRoughness);
238
+ `;
239
+
240
+ /**
241
+ * `effectIdBuffer = …; emissiveBuffer = …;` replacement. Only the
242
+ * texturized-layer pixels write effect/emissive; raster pixels stay 0 so they
243
+ * don't perturb downstream effect-mask passes.
244
+ */
245
+ export const TILE_EMISSIVE_EFFECT_BUFFER_REPLACEMENT = `
246
+ if (isTexturizedLayer) {
247
+ effectIdBuffer = vec4(tileEffectIdsMask, 0.0, 0.0, 1.0);
248
+ emissiveBuffer = vec4(diffuseColor.rgb * tileEmissiveIntensity + tileEmissiveColor, 1.0);
249
+ } else {
250
+ effectIdBuffer = vec4(0.0);
251
+ emissiveBuffer = vec4(0.0);
252
+ }
253
+ `;
254
+
255
+ /**
256
+ * Final-stage pick override. Injected immediately AFTER
257
+ * `#include <dithering_fragment>` (the last chunk in MeshLambert/Basic main()),
258
+ * so the assignment to `gl_FragColor` is the last write of the fragment shader
259
+ * — bypassing envmap, tonemapping, colorspace, and fog, all of which would
260
+ * otherwise corrupt the encoded batchId.
261
+ *
262
+ * Draped vector meshes stay in their TileScene during the pick pass (see
263
+ * PickHelper's TileScene guard) and render their own pick IDs into the
264
+ * per-layer RT in pick mode. The composite atlas then carries those IDs
265
+ * forward; here we write them straight through, masked by attr.g so raster
266
+ * pixels contribute batchId=0 (no entity) instead of polluting the pick
267
+ * buffer. `nvr_pickColor` is set up by `generateTileMapFragment`.
268
+ */
269
+ export const TILE_PICK_FRAGMENT_OVERRIDE = `
270
+ if (uPickable > 0.) {
271
+ gl_FragColor = vec4(nvr_pickColor, 1.0);
272
+ }
273
+ `;
274
+
275
+ /** Vertex-shader injection: passes UV and world-space position through. */
276
+ export const TILE_VERTEX_INJECTIONS = {
277
+ afterCommon: `
278
+ varying vec2 vOrigUv;
279
+ varying vec3 vPosition;
280
+ `,
281
+ afterUvVertex: `
282
+ vOrigUv = vUv;
283
+ `,
284
+ afterEnvmapVertex: `
285
+ vPosition = (modelMatrix * vec4(transformed, 1.0)).xyz;
286
+ `,
287
+ };