@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,19 @@
1
+ import type { ShaderMarkers } from "../../ShaderReplacer";
2
+ import { createShaderReplacer } from "../../ShaderReplacer";
3
+
4
+ /**
5
+ * Shader markers for the sdfText base enhancer.
6
+ * These markers are placed in the shader code to allow composing enhancers to inject their own code.
7
+ */
8
+ export const SDF_TEXT_BASE_SHADER_MARKERS = {
9
+ vertex: {},
10
+ fragment: {},
11
+ } as const satisfies ShaderMarkers;
12
+
13
+ /**
14
+ * Factory function to create a ShaderReplacer restricted to sdfText base markers.
15
+ * Used by composing enhancers to safely modify shaders.
16
+ */
17
+ export function createSdfTextBaseShaderReplacer(source: string) {
18
+ return createShaderReplacer<typeof SDF_TEXT_BASE_SHADER_MARKERS>(source);
19
+ }
@@ -0,0 +1,35 @@
1
+ import { ShaderMaterial } from "three";
2
+ import { describe, expect, it } from "vitest";
3
+
4
+ import { updateMaterialProps } from "./material";
5
+
6
+ describe("sdfTextBaseEnhancer/material", () => {
7
+ describe("updateMaterialProps", () => {
8
+ it("should not update properties when props are undefined", () => {
9
+ const material = new ShaderMaterial();
10
+ material.depthTest = false;
11
+ material.transparent = true;
12
+
13
+ updateMaterialProps(material, {});
14
+
15
+ expect(material.depthTest).toBe(false);
16
+ expect(material.transparent).toBe(true);
17
+ });
18
+
19
+ it("should update depthTest when provided", () => {
20
+ const material = new ShaderMaterial();
21
+ material.depthTest = true;
22
+
23
+ updateMaterialProps(material, { depthTest: false });
24
+ expect(material.depthTest).toBe(false);
25
+ });
26
+
27
+ it("should update transparent when provided", () => {
28
+ const material = new ShaderMaterial();
29
+ material.transparent = false;
30
+
31
+ updateMaterialProps(material, { transparent: true });
32
+ expect(material.transparent).toBe(true);
33
+ });
34
+ });
35
+ });
@@ -0,0 +1,32 @@
1
+ import { ShaderMaterial } from "three";
2
+
3
+ import type { ShaderName } from "../../MaterialEnhancer";
4
+
5
+ import type { SdfTextBaseProps } from "./types";
6
+
7
+ /**
8
+ * Shaders that the sdfText base enhancer supports.
9
+ * SdfText uses ShaderMaterial with custom shaders.
10
+ */
11
+ export const AVAILABLE_SHADERS = ["shader"] satisfies ShaderName[];
12
+
13
+ /**
14
+ * Material types that the sdfText base enhancer supports.
15
+ */
16
+ export type SupportedMaterial = ShaderMaterial;
17
+
18
+ /**
19
+ * Update material properties that affect the Three.js material directly.
20
+ * These properties are not handled by shader uniforms.
21
+ */
22
+ export function updateMaterialProps(
23
+ material: SupportedMaterial,
24
+ props: SdfTextBaseProps,
25
+ ): void {
26
+ if (props.depthTest !== undefined) {
27
+ material.depthTest = props.depthTest;
28
+ }
29
+ if (props.transparent !== undefined) {
30
+ material.transparent = props.transparent;
31
+ }
32
+ }
@@ -0,0 +1,381 @@
1
+ import { type DataTexture, Color, Matrix4 } from "three";
2
+ import { describe, expect, it, vi } from "vitest";
3
+
4
+ import type { ShaderUniforms } from "../../MaterialEnhancer";
5
+
6
+ import { createBaseMutates } from "./mutates";
7
+ import { DEFAULT_BASE_STATE } from "./state";
8
+ import type { SdfTextBaseState } from "./types";
9
+
10
+ vi.mock("@navaramap/engine-api", () => ({
11
+ encodePosition: (_x: number, _y: number, _z: number) => ({
12
+ high: { x: 1000, y: 2000, z: 3000 },
13
+ low: { x: 0.5, y: 0.25, z: 0.125 },
14
+ }),
15
+ }));
16
+
17
+ describe("sdfTextBaseEnhancer/mutates", () => {
18
+ describe("update syncs refs from state", () => {
19
+ it("should sync core refs from state", () => {
20
+ const state: SdfTextBaseState = {
21
+ ...DEFAULT_BASE_STATE,
22
+ color: new Color(0xff0000),
23
+ fontSize: 24,
24
+ center: [0.5, 0.5],
25
+ sizeInMeters: true,
26
+ addHeight: 50,
27
+ offsetDepth: false,
28
+ outlineWidth: 0.1,
29
+ outlineColor: new Color(0x00ff00),
30
+ outlineOpacity: 0.8,
31
+ showBackground: true,
32
+ backgroundColor: new Color(0x0000ff),
33
+ backgroundOutlineColor: new Color(0xffff00),
34
+ backgroundOutlineWidth: 0.2,
35
+ pickable: true,
36
+ };
37
+ const mutates = createBaseMutates(false);
38
+ mutates.update(state);
39
+
40
+ const uniforms: ShaderUniforms = {};
41
+ mutates.updateUniforms(uniforms, state);
42
+
43
+ expect(uniforms.uColor?.value.getHex()).toBe(0xff0000);
44
+ expect(uniforms.uFontSize?.value).toBe(24);
45
+ expect(uniforms.uCenter?.value.x).toBe(0.5);
46
+ expect(uniforms.uCenter?.value.y).toBe(0.5);
47
+ expect(uniforms.uSizeInMeters?.value).toBe(true);
48
+ expect(uniforms.uAddHeight?.value).toBe(50);
49
+ expect(uniforms.uOffsetDepth?.value).toBe(false);
50
+ expect(uniforms.uOutlineWidth?.value).toBe(0.1);
51
+ expect(uniforms.uOutlineColor?.value.getHex()).toBe(0x00ff00);
52
+ expect(uniforms.uOutlineOpacity?.value).toBe(0.8);
53
+ expect(uniforms.uShowBackground?.value).toBe(true);
54
+ expect(uniforms.uBackgroundColor?.value.getHex()).toBe(0x0000ff);
55
+ expect(uniforms.uBackgroundOutlineColor?.value.getHex()).toBe(0xffff00);
56
+ expect(uniforms.uBackgroundOutlineWidth?.value).toBe(0.2);
57
+ expect(uniforms.nvr_uPickable?.value).toBe(1.0);
58
+ });
59
+ });
60
+
61
+ describe("RTC center", () => {
62
+ it("should initialize uRTCCenter from constructor args", () => {
63
+ const state: SdfTextBaseState = { ...DEFAULT_BASE_STATE };
64
+ const mutates = createBaseMutates(false, [10, 20, 30]);
65
+ mutates.update(state);
66
+
67
+ const uniforms: ShaderUniforms = {};
68
+ mutates.updateUniforms(uniforms, state);
69
+
70
+ expect(uniforms.uRTCCenter?.value.x).toBe(10);
71
+ expect(uniforms.uRTCCenter?.value.y).toBe(20);
72
+ expect(uniforms.uRTCCenter?.value.z).toBe(30);
73
+ });
74
+ });
75
+
76
+ describe("RTE position refs", () => {
77
+ it("should create RTE position uniforms when useRTE=true", () => {
78
+ const state: SdfTextBaseState = {
79
+ ...DEFAULT_BASE_STATE,
80
+ useRTE: true,
81
+ };
82
+ const mutates = createBaseMutates(true);
83
+ mutates.update(state);
84
+
85
+ const uniforms: ShaderUniforms = {};
86
+ mutates.updateUniforms(uniforms, state);
87
+
88
+ expect(uniforms.uRTEPositionLOW).toBeDefined();
89
+ expect(uniforms.uRTEPositionHIGH).toBeDefined();
90
+ expect(uniforms.uRTCPosition).toBeUndefined();
91
+ });
92
+
93
+ it("should create RTC position uniform when useRTE=false", () => {
94
+ const state: SdfTextBaseState = { ...DEFAULT_BASE_STATE };
95
+ const mutates = createBaseMutates(false);
96
+ mutates.update(state);
97
+
98
+ const uniforms: ShaderUniforms = {};
99
+ mutates.updateUniforms(uniforms, state);
100
+
101
+ expect(uniforms.uRTCPosition).toBeDefined();
102
+ expect(uniforms.uRTEPositionLOW).toBeUndefined();
103
+ expect(uniforms.uRTEPositionHIGH).toBeUndefined();
104
+ });
105
+ });
106
+
107
+ describe("atlas texture ref", () => {
108
+ it("should update uAtlas value without replacing uniform ref", () => {
109
+ const state: SdfTextBaseState = { ...DEFAULT_BASE_STATE };
110
+ const mutates = createBaseMutates(false);
111
+ mutates.update(state);
112
+
113
+ const uniforms: ShaderUniforms = {};
114
+ mutates.updateUniforms(uniforms, state);
115
+ const initialAtlasUniform = uniforms.uAtlas;
116
+ expect(initialAtlasUniform).toBeDefined();
117
+ expect(initialAtlasUniform?.value).toBeNull();
118
+
119
+ const nextTexture = {
120
+ image: { width: 256, height: 256, data: new Uint8Array(256 * 256) },
121
+ } as unknown as DataTexture;
122
+
123
+ mutates.setAtlasTexture({ value: nextTexture });
124
+
125
+ expect(uniforms.uAtlas).toBe(initialAtlasUniform);
126
+ expect(uniforms.uAtlas?.value).toBe(nextTexture);
127
+ });
128
+ });
129
+
130
+ describe("updateAtlasSizes", () => {
131
+ it("should sync uSdfAtlasSize and uColorAtlasSize from bound texture images", () => {
132
+ const state: SdfTextBaseState = { ...DEFAULT_BASE_STATE };
133
+ const mutates = createBaseMutates(false);
134
+ mutates.update(state);
135
+
136
+ const sdfTex = {
137
+ image: { width: 1024, height: 2048, data: new Uint8Array(1) },
138
+ } as unknown as DataTexture;
139
+ const colorTex = {
140
+ image: { width: 4096, height: 4096, data: new Uint8Array(1) },
141
+ } as unknown as DataTexture;
142
+
143
+ mutates.setAtlasTexture({ value: sdfTex });
144
+ mutates.setColorAtlasTexture({ value: colorTex });
145
+ mutates.updateAtlasSizes();
146
+
147
+ const uniforms: ShaderUniforms = {};
148
+ mutates.updateUniforms(uniforms, state);
149
+
150
+ expect(uniforms.uSdfAtlasSize?.value.x).toBe(1024);
151
+ expect(uniforms.uSdfAtlasSize?.value.y).toBe(2048);
152
+ expect(uniforms.uColorAtlasSize?.value.x).toBe(4096);
153
+ expect(uniforms.uColorAtlasSize?.value.y).toBe(4096);
154
+ });
155
+
156
+ it("should pick up new dimensions after the atlas grows", () => {
157
+ const state: SdfTextBaseState = { ...DEFAULT_BASE_STATE };
158
+ const mutates = createBaseMutates(false);
159
+ mutates.update(state);
160
+
161
+ const sdfTex = {
162
+ image: { width: 2048, height: 2048, data: new Uint8Array(1) },
163
+ } as unknown as DataTexture;
164
+ mutates.setAtlasTexture({ value: sdfTex });
165
+ mutates.updateAtlasSizes();
166
+
167
+ const uniforms: ShaderUniforms = {};
168
+ mutates.updateUniforms(uniforms, state);
169
+ expect(uniforms.uSdfAtlasSize?.value.x).toBe(2048);
170
+ expect(uniforms.uSdfAtlasSize?.value.y).toBe(2048);
171
+
172
+ // Simulate the SDFAtlas growing — the image dims on the same texture
173
+ // change, and updateAtlasSizes() must propagate them to the uniform.
174
+ sdfTex.image = {
175
+ width: 4096,
176
+ height: 4096,
177
+ data: new Uint8Array(1),
178
+ } as DataTexture["image"];
179
+ mutates.updateAtlasSizes();
180
+
181
+ expect(uniforms.uSdfAtlasSize?.value.x).toBe(4096);
182
+ expect(uniforms.uSdfAtlasSize?.value.y).toBe(4096);
183
+ });
184
+
185
+ it("should leave atlas size uniforms unchanged when textures are null", () => {
186
+ const state: SdfTextBaseState = { ...DEFAULT_BASE_STATE };
187
+ const mutates = createBaseMutates(false);
188
+ mutates.update(state);
189
+
190
+ // Both uAtlas and uColorAtlas default to null.
191
+ mutates.updateAtlasSizes();
192
+
193
+ const uniforms: ShaderUniforms = {};
194
+ mutates.updateUniforms(uniforms, state);
195
+
196
+ // Defaults set in createBaseMutates: (1, 1) to avoid divide-by-zero.
197
+ expect(uniforms.uSdfAtlasSize?.value.x).toBe(1);
198
+ expect(uniforms.uSdfAtlasSize?.value.y).toBe(1);
199
+ expect(uniforms.uColorAtlasSize?.value.x).toBe(1);
200
+ expect(uniforms.uColorAtlasSize?.value.y).toBe(1);
201
+ });
202
+
203
+ it("should leave atlas size uniforms unchanged when image has zero dimensions", () => {
204
+ const state: SdfTextBaseState = { ...DEFAULT_BASE_STATE };
205
+ const mutates = createBaseMutates(false);
206
+ mutates.update(state);
207
+
208
+ const sdfTex = {
209
+ image: { width: 0, height: 0, data: new Uint8Array(0) },
210
+ } as unknown as DataTexture;
211
+ mutates.setAtlasTexture({ value: sdfTex });
212
+ mutates.updateAtlasSizes();
213
+
214
+ const uniforms: ShaderUniforms = {};
215
+ mutates.updateUniforms(uniforms, state);
216
+
217
+ expect(uniforms.uSdfAtlasSize?.value.x).toBe(1);
218
+ expect(uniforms.uSdfAtlasSize?.value.y).toBe(1);
219
+ });
220
+ });
221
+
222
+ describe("updatePerFrame", () => {
223
+ it("should update camera uniforms", () => {
224
+ const state: SdfTextBaseState = { ...DEFAULT_BASE_STATE };
225
+ const mutates = createBaseMutates(false);
226
+ mutates.update(state);
227
+
228
+ mutates.updatePerFrame(1.5, 1080, 10000, 0, 0, 0, new Matrix4(), state);
229
+
230
+ const uniforms: ShaderUniforms = {};
231
+ mutates.updateUniforms(uniforms, state);
232
+
233
+ expect(uniforms.uFovRad?.value).toBe(1.5);
234
+ expect(uniforms.uScreenHeightPx?.value).toBe(1080);
235
+ expect(uniforms.uFarPlane?.value).toBe(10000);
236
+ });
237
+
238
+ it("should update RTE eye uniforms when useRTE=true", () => {
239
+ const state: SdfTextBaseState = {
240
+ ...DEFAULT_BASE_STATE,
241
+ useRTE: true,
242
+ };
243
+ const mutates = createBaseMutates(true);
244
+ mutates.update(state);
245
+
246
+ mutates.updatePerFrame(
247
+ 1.0,
248
+ 1080,
249
+ 1000,
250
+ 100,
251
+ 200,
252
+ 300,
253
+ new Matrix4(),
254
+ state,
255
+ );
256
+
257
+ const uniforms: ShaderUniforms = {};
258
+ mutates.updateUniforms(uniforms, state);
259
+
260
+ const eyeHigh = uniforms.uEyeRTEHigh?.value;
261
+ const eyeLow = uniforms.uEyeRTELow?.value;
262
+ expect(eyeHigh).toBeDefined();
263
+ expect(eyeLow).toBeDefined();
264
+ // Values come from the mocked encodePosition
265
+ expect(eyeHigh?.x).toBe(1000);
266
+ expect(eyeLow?.x).toBe(0.5);
267
+ });
268
+
269
+ it("should not update RTE eye uniforms when useRTE=false", () => {
270
+ const state: SdfTextBaseState = { ...DEFAULT_BASE_STATE };
271
+ const mutates = createBaseMutates(false);
272
+ mutates.update(state);
273
+
274
+ mutates.updatePerFrame(
275
+ 1.0,
276
+ 1080,
277
+ 1000,
278
+ 100,
279
+ 200,
280
+ 300,
281
+ new Matrix4(),
282
+ state,
283
+ );
284
+
285
+ const uniforms: ShaderUniforms = {};
286
+ mutates.updateUniforms(uniforms, state);
287
+
288
+ expect(uniforms.uEyeRTEHigh?.value.x).toBe(0);
289
+ expect(uniforms.uEyeRTEHigh?.value.y).toBe(0);
290
+ expect(uniforms.uEyeRTEHigh?.value.z).toBe(0);
291
+ });
292
+
293
+ it("should transform the RTC center into view space when useRTE=false", () => {
294
+ const state: SdfTextBaseState = { ...DEFAULT_BASE_STATE };
295
+ const mutates = createBaseMutates(false, [6_400_000, 0, 0]);
296
+ mutates.update(state);
297
+
298
+ // View matrix cancels the center's large X so it lands near the origin.
299
+ const viewInverse = new Matrix4().makeTranslation(-6_400_000, 0, 0);
300
+ mutates.updatePerFrame(1.0, 1080, 1000, 0, 0, 0, viewInverse, state);
301
+
302
+ const uniforms: ShaderUniforms = {};
303
+ mutates.updateUniforms(uniforms, state);
304
+
305
+ expect(uniforms.uRTCCenterView?.value.x).toBeCloseTo(0, 3);
306
+ expect(uniforms.uRTCCenterView?.value.y).toBeCloseTo(0, 3);
307
+ expect(uniforms.uRTCCenterView?.value.z).toBeCloseTo(0, 3);
308
+ });
309
+ });
310
+
311
+ describe("updateTextDimensions", () => {
312
+ it("should update text dimension uniforms", () => {
313
+ const state: SdfTextBaseState = { ...DEFAULT_BASE_STATE };
314
+ const mutates = createBaseMutates(false);
315
+ mutates.update(state);
316
+
317
+ mutates.updateTextDimensions(5.0, 1.0, -0.2, 0.8);
318
+
319
+ const uniforms: ShaderUniforms = {};
320
+ mutates.updateUniforms(uniforms, state);
321
+
322
+ expect(uniforms.uTextWidth?.value).toBe(5.0);
323
+ expect(uniforms.uTextHeight?.value).toBe(1.0);
324
+ expect(uniforms.uBgYBounds?.value.x).toBe(-0.2);
325
+ expect(uniforms.uBgYBounds?.value.y).toBe(0.8);
326
+ });
327
+ });
328
+
329
+ describe("setPosition", () => {
330
+ it("should set RTE position uniforms", () => {
331
+ const state: SdfTextBaseState = {
332
+ ...DEFAULT_BASE_STATE,
333
+ useRTE: true,
334
+ };
335
+ const mutates = createBaseMutates(true);
336
+ mutates.update(state);
337
+
338
+ const high = new Float32Array([100, 200, 300]);
339
+ const low = new Float32Array([0.1, 0.2, 0.3]);
340
+ mutates.setPosition({ high, low }, true);
341
+
342
+ const uniforms: ShaderUniforms = {};
343
+ mutates.updateUniforms(uniforms, state);
344
+
345
+ expect(uniforms.uRTEPositionHIGH?.value.x).toBe(100);
346
+ expect(uniforms.uRTEPositionLOW?.value.x).toBeCloseTo(0.1);
347
+ });
348
+
349
+ it("should set RTC position uniforms", () => {
350
+ const state: SdfTextBaseState = { ...DEFAULT_BASE_STATE };
351
+ const mutates = createBaseMutates(false);
352
+ mutates.update(state);
353
+
354
+ const pos = new Float32Array([10, 20, 30]);
355
+ mutates.setPosition(pos, false, [100, 200, 300]);
356
+
357
+ const uniforms: ShaderUniforms = {};
358
+ mutates.updateUniforms(uniforms, state);
359
+
360
+ expect(uniforms.uRTCPosition?.value.x).toBe(10);
361
+ expect(uniforms.uRTCPosition?.value.y).toBe(20);
362
+ expect(uniforms.uRTCCenter?.value.x).toBe(100);
363
+ expect(uniforms.uRTCCenter?.value.y).toBe(200);
364
+ });
365
+ });
366
+
367
+ describe("setBatchId", () => {
368
+ it("should update nvr_uBatchId value", () => {
369
+ const state: SdfTextBaseState = { ...DEFAULT_BASE_STATE };
370
+ const mutates = createBaseMutates(false);
371
+ mutates.update(state);
372
+
373
+ mutates.setBatchId(42);
374
+
375
+ const uniforms: ShaderUniforms = {};
376
+ mutates.updateUniforms(uniforms, state);
377
+
378
+ expect(uniforms.nvr_uBatchId?.value).toBe(42);
379
+ });
380
+ });
381
+ });
@@ -0,0 +1,232 @@
1
+ import { encodePosition } from "@navaramap/engine-api";
2
+ import { Color, DataTexture, type Matrix4, Vector2, Vector3 } from "three";
3
+
4
+ import type { UniformValue } from "../../../types";
5
+
6
+ import type {
7
+ SdfTextBaseMutates,
8
+ SdfTextBaseRefs,
9
+ SdfTextBaseState,
10
+ } from "./types";
11
+
12
+ /**
13
+ * Create mutation functions for the sdfText base enhancer.
14
+ * Refs are created internally and captured via closure.
15
+ *
16
+ * @param useRTE - Whether RTE positioning is enabled
17
+ * @param rtcCenter - The RTC center position [x, y, z]
18
+ * @param batchId - Batch ID for picking
19
+ */
20
+ export const createBaseMutates = (
21
+ useRTE: boolean,
22
+ rtcCenter?: [number, number, number],
23
+ batchId?: number,
24
+ ): SdfTextBaseMutates => {
25
+ const refs: SdfTextBaseRefs = {
26
+ uColor: { value: new Color(1, 1, 1) },
27
+ uOpacity: { value: 1.0 },
28
+ uFontSize: { value: 16.0 },
29
+ uCenter: { value: new Vector2(0.5, 0.0) },
30
+ uSizeInMeters: { value: true },
31
+ uAddHeight: { value: 0.0 },
32
+ uOffsetDepth: { value: true },
33
+ uSdfThreshold: { value: 0.5 },
34
+ uOutlineWidth: { value: 0.0 },
35
+ uOutlineColor: { value: new Color(1, 0, 0) },
36
+ uOutlineOpacity: { value: 1.0 },
37
+ uShowBackground: { value: false },
38
+ uBackgroundColor: { value: new Color(1, 0, 0) },
39
+ uBackgroundOutlineColor: { value: new Color(1, 0, 0) },
40
+ uBackgroundOutlineWidth: { value: 0.1 },
41
+ uFovRad: { value: 1.0 },
42
+ uScreenHeightPx: { value: 1080.0 },
43
+ uFarPlane: { value: 1000.0 },
44
+ uTextWidth: { value: 0.0 },
45
+ uTextHeight: { value: 0.0 },
46
+ uBgYBounds: { value: new Vector2(0.0, 1.0) },
47
+ uRTCCenter: {
48
+ value: new Vector3(
49
+ rtcCenter?.[0] ?? 0,
50
+ rtcCenter?.[1] ?? 0,
51
+ rtcCenter?.[2] ?? 0,
52
+ ),
53
+ },
54
+ uRTCCenterView: { value: new Vector3(0, 0, 0) },
55
+ uEyeRTELow: { value: new Vector3(0, 0, 0) },
56
+ uEyeRTEHigh: { value: new Vector3(0, 0, 0) },
57
+ nvr_uBatchId: { value: batchId ?? 0 },
58
+ nvr_uPickable: { value: 0.0 },
59
+ uAtlas: { value: null },
60
+ uColorAtlas: { value: null },
61
+ // Default to 1.0 to avoid divide-by-zero in the shader before a texture
62
+ // is bound; UVs are unused until glyph quads exist anyway.
63
+ uSdfAtlasSize: { value: new Vector2(1, 1) },
64
+ uColorAtlasSize: { value: new Vector2(1, 1) },
65
+ };
66
+
67
+ // Conditional position uniforms based on RTE mode
68
+ if (useRTE) {
69
+ refs.uRTEPositionLOW = { value: new Vector3(0, 0, 0) };
70
+ refs.uRTEPositionHIGH = { value: new Vector3(0, 0, 0) };
71
+ } else {
72
+ refs.uRTCPosition = { value: new Vector3(0, 0, 0) };
73
+ }
74
+
75
+ return {
76
+ update: (state: SdfTextBaseState) => {
77
+ refs.uColor.value.set(state.color);
78
+ refs.uOpacity.value = state.opacity;
79
+ refs.uFontSize.value = state.fontSize;
80
+ refs.uCenter.value.set(state.center[0], state.center[1]);
81
+ refs.uSizeInMeters.value = state.sizeInMeters;
82
+ refs.uAddHeight.value = state.addHeight;
83
+ refs.uOffsetDepth.value = state.offsetDepth;
84
+ refs.uOutlineWidth.value = state.outlineWidth;
85
+ refs.uOutlineColor.value.set(state.outlineColor);
86
+ refs.uOutlineOpacity.value = state.outlineOpacity;
87
+ refs.uShowBackground.value = state.showBackground;
88
+ refs.uBackgroundColor.value.set(state.backgroundColor);
89
+ refs.uBackgroundOutlineColor.value.set(state.backgroundOutlineColor);
90
+ refs.uBackgroundOutlineWidth.value = state.backgroundOutlineWidth;
91
+ refs.nvr_uPickable.value = state.pickable ? 1.0 : 0.0;
92
+ },
93
+
94
+ updateUniforms: (uniforms) => {
95
+ uniforms.uColor = refs.uColor;
96
+ uniforms.uOpacity = refs.uOpacity;
97
+ uniforms.uFontSize = refs.uFontSize;
98
+ uniforms.uCenter = refs.uCenter;
99
+ uniforms.uSizeInMeters = refs.uSizeInMeters;
100
+ uniforms.uAddHeight = refs.uAddHeight;
101
+ uniforms.uOffsetDepth = refs.uOffsetDepth;
102
+ uniforms.uSdfThreshold = refs.uSdfThreshold;
103
+ uniforms.uOutlineWidth = refs.uOutlineWidth;
104
+ uniforms.uOutlineColor = refs.uOutlineColor;
105
+ uniforms.uOutlineOpacity = refs.uOutlineOpacity;
106
+ uniforms.uShowBackground = refs.uShowBackground;
107
+ uniforms.uBackgroundColor = refs.uBackgroundColor;
108
+ uniforms.uBackgroundOutlineColor = refs.uBackgroundOutlineColor;
109
+ uniforms.uBackgroundOutlineWidth = refs.uBackgroundOutlineWidth;
110
+ uniforms.uFovRad = refs.uFovRad;
111
+ uniforms.uScreenHeightPx = refs.uScreenHeightPx;
112
+ uniforms.uFarPlane = refs.uFarPlane;
113
+ uniforms.uTextWidth = refs.uTextWidth;
114
+ uniforms.uTextHeight = refs.uTextHeight;
115
+ uniforms.uBgYBounds = refs.uBgYBounds;
116
+ uniforms.uRTCCenter = refs.uRTCCenter;
117
+ uniforms.uRTCCenterView = refs.uRTCCenterView;
118
+ uniforms.uEyeRTELow = refs.uEyeRTELow;
119
+ uniforms.uEyeRTEHigh = refs.uEyeRTEHigh;
120
+ uniforms.nvr_uBatchId = refs.nvr_uBatchId;
121
+ uniforms.nvr_uPickable = refs.nvr_uPickable;
122
+ uniforms.uAtlas = refs.uAtlas;
123
+ uniforms.uColorAtlas = refs.uColorAtlas;
124
+ uniforms.uSdfAtlasSize = refs.uSdfAtlasSize;
125
+ uniforms.uColorAtlasSize = refs.uColorAtlasSize;
126
+
127
+ if (refs.uRTEPositionLOW) {
128
+ uniforms.uRTEPositionLOW = refs.uRTEPositionLOW;
129
+ }
130
+ if (refs.uRTEPositionHIGH) {
131
+ uniforms.uRTEPositionHIGH = refs.uRTEPositionHIGH;
132
+ }
133
+ if (refs.uRTCPosition) {
134
+ uniforms.uRTCPosition = refs.uRTCPosition;
135
+ }
136
+ },
137
+
138
+ updatePerFrame: (
139
+ fovRad: number,
140
+ screenHeightPx: number,
141
+ farPlane: number,
142
+ cameraX: number,
143
+ cameraY: number,
144
+ cameraZ: number,
145
+ viewMatrix: Matrix4,
146
+ state: SdfTextBaseState,
147
+ ) => {
148
+ refs.uFovRad.value = fovRad;
149
+ refs.uScreenHeightPx.value = screenHeightPx;
150
+ refs.uFarPlane.value = farPlane;
151
+
152
+ if (state.useRTE) {
153
+ const encoded = encodePosition(cameraX, cameraY, cameraZ);
154
+ refs.uEyeRTELow.value.set(encoded.low.x, encoded.low.y, encoded.low.z);
155
+ refs.uEyeRTEHigh.value.set(
156
+ encoded.high.x,
157
+ encoded.high.y,
158
+ encoded.high.z,
159
+ );
160
+ } else {
161
+ // Transform the RTC center into view space here (JS numbers are
162
+ // float64), so the shader receives a small, precise value instead of
163
+ // doing `viewMatrix * uRTCCenter` where both operands are ~6.4e6 in
164
+ // float32 — the source of the jitter.
165
+ refs.uRTCCenterView.value
166
+ .copy(refs.uRTCCenter.value)
167
+ .applyMatrix4(viewMatrix);
168
+ }
169
+ },
170
+
171
+ updateTextDimensions: (
172
+ textWidth: number,
173
+ textHeight: number,
174
+ bgMinY: number,
175
+ bgMaxY: number,
176
+ ) => {
177
+ refs.uTextWidth.value = textWidth;
178
+ refs.uTextHeight.value = textHeight;
179
+ refs.uBgYBounds.value.set(bgMinY, bgMaxY);
180
+ },
181
+
182
+ setAtlasTexture: (texture: UniformValue<DataTexture | null>) => {
183
+ refs.uAtlas.value = texture.value;
184
+ },
185
+
186
+ setColorAtlasTexture: (texture: UniformValue<DataTexture | null>) => {
187
+ refs.uColorAtlas.value = texture.value;
188
+ },
189
+
190
+ updateAtlasSizes: () => {
191
+ const sdfImg = refs.uAtlas.value?.image;
192
+ if (sdfImg && sdfImg.width > 0 && sdfImg.height > 0) {
193
+ refs.uSdfAtlasSize.value.set(sdfImg.width, sdfImg.height);
194
+ }
195
+ const colorImg = refs.uColorAtlas.value?.image;
196
+ if (colorImg && colorImg.width > 0 && colorImg.height > 0) {
197
+ refs.uColorAtlasSize.value.set(colorImg.width, colorImg.height);
198
+ }
199
+ },
200
+
201
+ setPosition: (
202
+ position: Float32Array | { high: Float32Array; low: Float32Array },
203
+ posUseRTE: boolean,
204
+ posRtcCenter?: [number, number, number],
205
+ ) => {
206
+ if (posUseRTE) {
207
+ const p = position as { high: Float32Array; low: Float32Array };
208
+ refs.uRTEPositionLOW?.value.set(p.low[0], p.low[1], p.low[2] ?? 0.0);
209
+ refs.uRTEPositionHIGH?.value.set(
210
+ p.high[0],
211
+ p.high[1],
212
+ p.high[2] ?? 0.0,
213
+ );
214
+ } else {
215
+ const p = position as Float32Array;
216
+ refs.uRTCPosition?.value.set(p[0], p[1], p[2] ?? 0.0);
217
+
218
+ if (posRtcCenter) {
219
+ refs.uRTCCenter.value.set(
220
+ posRtcCenter[0],
221
+ posRtcCenter[1],
222
+ posRtcCenter[2],
223
+ );
224
+ }
225
+ }
226
+ },
227
+
228
+ setBatchId: (id: number) => {
229
+ refs.nvr_uBatchId.value = id;
230
+ },
231
+ };
232
+ };