@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,110 @@
1
+ import { defaults } from "lodash-es";
2
+ import type { WebGLProgramParametersWithUniforms } from "three";
3
+ import invariant from "tiny-invariant";
4
+
5
+ import type { MaterialEnhancer } from "../../MaterialEnhancer";
6
+
7
+ import { AVAILABLE_SHADERS, type SupportedMaterial } from "./material";
8
+ import { updateMaterialProps } from "./material";
9
+ import { createBaseMutates } from "./mutates";
10
+ import { transformShader } from "./shader";
11
+ import { DEFAULT_BASE_PROPS, DEFAULT_BASE_STATE, updateState } from "./state";
12
+ import type { ModelBaseMutates, ModelBaseProps, ModelBaseState } from "./types";
13
+
14
+ /**
15
+ * Factory function to create a model base enhancer.
16
+ *
17
+ * This enhancer handles:
18
+ * - Basic material properties (color, metalness, roughness, emissive)
19
+ * - Height (addHeight uniform)
20
+ * - Picking
21
+ * - Batch texture support
22
+ * - SelectiveEffect uniforms (effectIdsMask, uEmissiveIntensity) and emissive/emissiveIntensity material syncing
23
+ * - Shadow map depth shader
24
+ *
25
+ * Supports Standard and Physical materials.
26
+ *
27
+ * @param material - The Three.js material to enhance
28
+ */
29
+ export function createModelBaseEnhancer(
30
+ material: SupportedMaterial,
31
+ ): MaterialEnhancer<
32
+ SupportedMaterial,
33
+ ModelBaseProps,
34
+ ModelBaseState,
35
+ ModelBaseMutates,
36
+ typeof AVAILABLE_SHADERS
37
+ > {
38
+ // Internal state - immutable, always replaced as a whole
39
+ let state: ModelBaseState | null = null;
40
+ // Internal mutates object (refs are hidden inside)
41
+ let mutates: ModelBaseMutates | null = null;
42
+
43
+ return {
44
+ material,
45
+ availableShaders: AVAILABLE_SHADERS,
46
+
47
+ transformShader: (shader: WebGLProgramParametersWithUniforms): void => {
48
+ invariant(
49
+ state && mutates,
50
+ "mount() must be called before transformShader",
51
+ );
52
+ transformShader(shader, state, mutates, material);
53
+ },
54
+
55
+ mount: (props: ModelBaseProps): void => {
56
+ const mergedProps = defaults({}, props, DEFAULT_BASE_PROPS);
57
+ state = updateState(mergedProps, DEFAULT_BASE_STATE);
58
+ // Create mutates (refs are created inside with default values)
59
+ mutates = createBaseMutates();
60
+ mutates.update(state);
61
+ // Handle external refs that are passed through props
62
+ if (props.batchDataTexture) {
63
+ mutates.setBatchDataTexture(props.batchDataTexture);
64
+ }
65
+ updateMaterialProps(material, mergedProps);
66
+ },
67
+
68
+ update: (props: ModelBaseProps): void => {
69
+ invariant(state && mutates, "mount() must be called before update");
70
+ state = updateState(props, state);
71
+ mutates.update(state);
72
+ // Handle external refs that are passed through props
73
+ if (props.batchDataTexture) {
74
+ mutates.setBatchDataTexture(props.batchDataTexture);
75
+ }
76
+ updateMaterialProps(material, props);
77
+ },
78
+
79
+ states: (): ModelBaseState => {
80
+ invariant(state, "mount() must be called before states");
81
+ return state;
82
+ },
83
+
84
+ mutates: (): ModelBaseMutates => {
85
+ invariant(mutates, "mount() must be called before mutates");
86
+ return mutates;
87
+ },
88
+
89
+ programCacheKey: (): string => {
90
+ invariant(state, "mount() must be called before programCacheKey");
91
+ // Return cache key based on state that affects shader defines
92
+ return JSON.stringify({
93
+ useBatchTexture: state.useBatchTexture,
94
+ useBatchColorShow: state.useBatchColorShow,
95
+ });
96
+ },
97
+ };
98
+ }
99
+
100
+ // Re-export public types
101
+ export type { ModelBaseMutates, ModelBaseProps, ModelBaseState };
102
+
103
+ // Re-export SupportedMaterial for use by water enhancer
104
+ export type { SupportedMaterial } from "./material";
105
+
106
+ // Re-export marker types for composing enhancers
107
+ export {
108
+ MODEL_BASE_SHADER_MARKERS,
109
+ createModelBaseShaderReplacer,
110
+ } from "./markers";
@@ -0,0 +1,27 @@
1
+ import { type ShaderMarkers, createShaderReplacer } from "../../ShaderReplacer";
2
+
3
+ export const MODEL_BASE_SHADER_MARKERS = {
4
+ vertex: {},
5
+ fragment: {
6
+ /** Start of model uniform declarations. */
7
+ UNIFORM_START: "// NVR_MODEL_BASE_UNIFORM_START",
8
+ /** End of model uniform declarations. */
9
+ UNIFORM_END: "// NVR_MODEL_BASE_UNIFORM_END",
10
+ /** Start of normal computation block. */
11
+ NORMAL_START: "// NVR_MODEL_BASE_NORMAL_START",
12
+ /** End of normal computation block. */
13
+ NORMAL_END: "// NVR_MODEL_BASE_NORMAL_END",
14
+ /** Start of outgoing light additions block. */
15
+ OUTGOING_LIGHT_START: "// NVR_MODEL_BASE_OUTGOING_LIGHT_START",
16
+ /** End of outgoing light additions block. */
17
+ OUTGOING_LIGHT_END: "// NVR_MODEL_BASE_OUTGOING_LIGHT_END",
18
+ /** Start of the final normal assignment block (used for MRT output). */
19
+ FINAL_NORMAL_START: "// NVR_MODEL_BASE_FINAL_NORMAL_START",
20
+ /** End of the final normal assignment block (used for MRT output). */
21
+ FINAL_NORMAL_END: "// NVR_MODEL_BASE_FINAL_NORMAL_END",
22
+ },
23
+ } as const satisfies ShaderMarkers;
24
+
25
+ export function createModelBaseShaderReplacer(source: string) {
26
+ return createShaderReplacer<typeof MODEL_BASE_SHADER_MARKERS>(source);
27
+ }
@@ -0,0 +1,66 @@
1
+ import { MeshStandardMaterial } from "three";
2
+ import { describe, expect, it } from "vitest";
3
+
4
+ import { updateMaterialProps } from "./material";
5
+
6
+ describe("modelBaseEnhancer/material", () => {
7
+ describe("updateMaterialProps", () => {
8
+ it("should not update properties when props are undefined", () => {
9
+ const material = new MeshStandardMaterial();
10
+ material.color.set(0xff0000);
11
+ material.metalness = 0.5;
12
+ material.roughness = 0.3;
13
+
14
+ updateMaterialProps(material, {});
15
+ expect(material.color.getHex()).toBe(0xff0000);
16
+ expect(material.metalness).toBe(0.5);
17
+ expect(material.roughness).toBe(0.3);
18
+ });
19
+
20
+ it("should update color when provided", () => {
21
+ const material = new MeshStandardMaterial();
22
+ updateMaterialProps(material, { color: 0x00ff00 });
23
+ expect(material.color.getHex()).toBe(0x00ff00);
24
+ });
25
+
26
+ it("should update metalness and roughness when provided", () => {
27
+ const material = new MeshStandardMaterial();
28
+ updateMaterialProps(material, { metalness: 0.8, roughness: 0.2 });
29
+ expect(material.metalness).toBe(0.8);
30
+ expect(material.roughness).toBe(0.2);
31
+ });
32
+
33
+ it("should update material emissive when provided", () => {
34
+ const material = new MeshStandardMaterial();
35
+ updateMaterialProps(material, {
36
+ emissiveColor: 0xff0000,
37
+ emissiveIntensity: 0.5,
38
+ });
39
+ expect(material.emissive.getHex()).toBe(0xff0000);
40
+ expect(material.emissiveIntensity).toBe(0.5);
41
+ });
42
+
43
+ it("should update transparent when provided", () => {
44
+ const material = new MeshStandardMaterial();
45
+ material.transparent = false;
46
+
47
+ updateMaterialProps(material, { transparent: true });
48
+ expect(material.transparent).toBe(true);
49
+ });
50
+
51
+ it("should update opacity when provided", () => {
52
+ const material = new MeshStandardMaterial();
53
+ material.opacity = 1.0;
54
+ updateMaterialProps(material, { opacity: 0.5 });
55
+ expect(material.opacity).toBe(0.5);
56
+ });
57
+
58
+ it("should update depthWrite when provided", () => {
59
+ const material = new MeshStandardMaterial();
60
+ material.depthWrite = true;
61
+
62
+ updateMaterialProps(material, { depthWrite: false });
63
+ expect(material.depthWrite).toBe(false);
64
+ });
65
+ });
66
+ });
@@ -0,0 +1,44 @@
1
+ import type { MaterialsFromShaders, ShaderName } from "../../MaterialEnhancer";
2
+
3
+ import type { ModelBaseProps } from "./types";
4
+
5
+ // Shaders this enhancer supports
6
+ export const AVAILABLE_SHADERS = [
7
+ "standard",
8
+ "physical",
9
+ ] satisfies ShaderName[];
10
+ export type SupportedMaterial = MaterialsFromShaders<typeof AVAILABLE_SHADERS>;
11
+
12
+ /**
13
+ * Update Three.js material properties from props.
14
+ * Side effect function - mutates material directly.
15
+ */
16
+ export const updateMaterialProps = (
17
+ material: SupportedMaterial,
18
+ props: ModelBaseProps,
19
+ ): void => {
20
+ if (props.color !== undefined) {
21
+ material.color.set(props.color);
22
+ }
23
+ if (props.metalness !== undefined) {
24
+ material.metalness = props.metalness;
25
+ }
26
+ if (props.roughness !== undefined) {
27
+ material.roughness = props.roughness;
28
+ }
29
+ if (props.emissiveColor !== undefined) {
30
+ material.emissive.set(props.emissiveColor);
31
+ }
32
+ if (props.emissiveIntensity !== undefined) {
33
+ material.emissiveIntensity = props.emissiveIntensity;
34
+ }
35
+ if (props.transparent !== undefined) {
36
+ material.transparent = props.transparent;
37
+ }
38
+ if (props.opacity !== undefined) {
39
+ material.opacity = props.opacity;
40
+ }
41
+ if (props.depthWrite !== undefined) {
42
+ material.depthWrite = props.depthWrite;
43
+ }
44
+ };
@@ -0,0 +1,84 @@
1
+ import { describe, expect, it } from "vitest";
2
+
3
+ import type { ShaderUniforms } from "../../MaterialEnhancer";
4
+
5
+ import { createBaseMutates } from "./mutates";
6
+ import { DEFAULT_BASE_STATE } from "./state";
7
+ import type { ModelBaseState } from "./types";
8
+
9
+ describe("modelBaseEnhancer/mutates", () => {
10
+ describe("update syncs refs from state", () => {
11
+ it("should sync pickable ref from state", () => {
12
+ const state: ModelBaseState = {
13
+ ...DEFAULT_BASE_STATE,
14
+ pickable: true,
15
+ };
16
+ const mutates = createBaseMutates();
17
+ mutates.update(state);
18
+
19
+ const uniforms: ShaderUniforms = {};
20
+ mutates.updateUniforms(uniforms, state);
21
+
22
+ expect(uniforms.nvr_uPickable?.value).toBe(1);
23
+ });
24
+
25
+ it("should set pickable to 0 when false", () => {
26
+ const state: ModelBaseState = {
27
+ ...DEFAULT_BASE_STATE,
28
+ pickable: false,
29
+ };
30
+ const mutates = createBaseMutates();
31
+ mutates.update(state);
32
+
33
+ const uniforms: ShaderUniforms = {};
34
+ mutates.updateUniforms(uniforms, state);
35
+
36
+ expect(uniforms.nvr_uPickable?.value).toBe(0);
37
+ });
38
+ });
39
+
40
+ describe("update syncs selective effect uniforms from state", () => {
41
+ it("should sync effectIdsMask ref from state", () => {
42
+ const state: ModelBaseState = {
43
+ ...DEFAULT_BASE_STATE,
44
+ effectIdsMask: 5, // bits 0 and 2
45
+ };
46
+ const mutates = createBaseMutates();
47
+ mutates.update(state);
48
+
49
+ const uniforms: ShaderUniforms = {};
50
+ mutates.updateUniforms(uniforms, state);
51
+
52
+ expect(uniforms.uEffectIdsMask?.value).toBe(5);
53
+ });
54
+
55
+ it("should sync uEmissiveIntensity ref from state", () => {
56
+ const state: ModelBaseState = {
57
+ ...DEFAULT_BASE_STATE,
58
+ emissiveIntensity: 0.7,
59
+ };
60
+ const mutates = createBaseMutates();
61
+ mutates.update(state);
62
+
63
+ const uniforms: ShaderUniforms = {};
64
+ mutates.updateUniforms(uniforms, state);
65
+
66
+ expect(uniforms.uEmissiveIntensity?.value).toBe(0.7);
67
+ });
68
+ });
69
+
70
+ describe("setBatchDataTexture", () => {
71
+ it("should assign batch data texture ref", () => {
72
+ const mutates = createBaseMutates();
73
+ mutates.update(DEFAULT_BASE_STATE);
74
+
75
+ const textureRef = { value: null };
76
+ mutates.setBatchDataTexture(textureRef);
77
+
78
+ const uniforms: ShaderUniforms = {};
79
+ mutates.updateUniforms(uniforms, DEFAULT_BASE_STATE);
80
+
81
+ expect(uniforms.batchDataTexture).toBe(textureRef);
82
+ });
83
+ });
84
+ });
@@ -0,0 +1,47 @@
1
+ import type { Texture } from "three";
2
+
3
+ import type { UniformValue } from "../../../types";
4
+
5
+ import type { ModelBaseMutates, ModelBaseRefs } from "./types";
6
+
7
+ /**
8
+ * Default refs with initial values.
9
+ * These are cloned in createBaseMutates and synced from state via update().
10
+ */
11
+ const DEFAULT_BASE_REFS: ModelBaseRefs = {
12
+ nvr_uPickable: { value: 0 },
13
+ uEffectIdsMask: { value: 0 },
14
+ uEmissiveIntensity: { value: 0 },
15
+ };
16
+
17
+ /**
18
+ * Create mutation functions for the model base enhancer.
19
+ * Refs are created internally and captured via closure.
20
+ */
21
+ export const createBaseMutates = (): ModelBaseMutates => {
22
+ // Clone defaults so each enhancer instance gets independent ref objects
23
+ const refs = structuredClone(DEFAULT_BASE_REFS) as ModelBaseRefs;
24
+
25
+ return {
26
+ update: (state) => {
27
+ // Sync refs from state
28
+ refs.nvr_uPickable.value = state.pickable ? 1 : 0;
29
+ refs.uEffectIdsMask.value = state.effectIdsMask;
30
+ refs.uEmissiveIntensity.value = state.emissiveIntensity;
31
+ },
32
+ updateUniforms: (uniforms) => {
33
+ // Assign core uniform refs to shader.uniforms
34
+ uniforms.nvr_uPickable = refs.nvr_uPickable;
35
+ uniforms.uEffectIdsMask = refs.uEffectIdsMask;
36
+ uniforms.uEmissiveIntensity = refs.uEmissiveIntensity;
37
+
38
+ // Batch texture
39
+ if (refs.batchDataTexture) {
40
+ uniforms.batchDataTexture = refs.batchDataTexture;
41
+ }
42
+ },
43
+ setBatchDataTexture: (texture: UniformValue<Texture | null>): void => {
44
+ refs.batchDataTexture = texture;
45
+ },
46
+ };
47
+ };
@@ -0,0 +1,24 @@
1
+ import { testShaderCompatibility } from "../../test-utils/shaderCompatibility";
2
+
3
+ import { MODEL_BASE_SHADER_MARKERS } from "./markers";
4
+
5
+ import { createModelBaseEnhancer, type SupportedMaterial } from ".";
6
+
7
+ testShaderCompatibility(
8
+ "modelBaseEnhancer",
9
+ (material) => createModelBaseEnhancer(material as SupportedMaterial),
10
+ [
11
+ {
12
+ name: "Default props",
13
+ props: {},
14
+ },
15
+ {
16
+ name: "With batch texture",
17
+ props: {
18
+ useBatchTexture: true,
19
+ useBatchColorShow: true,
20
+ },
21
+ },
22
+ ],
23
+ MODEL_BASE_SHADER_MARKERS,
24
+ );
@@ -0,0 +1,162 @@
1
+ import BatchTextureParsVertex from "@shaders/glsl/chunks/batch_texture_pars_vertex.glsl";
2
+ import BatchTextureVertex from "@shaders/glsl/chunks/batch_texture_vertex.glsl";
3
+ import Pick from "@shaders/glsl/chunks/pick.glsl";
4
+ import ShadowMapDepthFragment from "@shaders/glsl/chunks/shadowmap_depth_fragment.glsl";
5
+ import ShadowMapDepthParsFragment from "@shaders/glsl/chunks/shadowmap_depth_pars_fragment.glsl";
6
+ import ShadowMapDepthParsVertex from "@shaders/glsl/chunks/shadowmap_depth_pars_vertex.glsl";
7
+ import ShadowMapDepthVertex from "@shaders/glsl/chunks/shadowmap_depth_vertex.glsl";
8
+ import ShowFragment from "@shaders/glsl/chunks/show_fragment.glsl";
9
+ import ShowParsFragment from "@shaders/glsl/chunks/show_pars_fragment.glsl";
10
+ import ShowParsVertex from "@shaders/glsl/chunks/show_pars_vertex.glsl";
11
+ import SpecularParsFragment from "@shaders/glsl/chunks/spucular_pars_fragment.glsl";
12
+ import type { WebGLProgramParametersWithUniforms } from "three";
13
+
14
+ import { createReplacer } from "../../../../utils";
15
+
16
+ import { MODEL_BASE_SHADER_MARKERS } from "./markers";
17
+ import type { SupportedMaterial } from "./material";
18
+ import type { ModelBaseMutates, ModelBaseState } from "./types";
19
+
20
+ /**
21
+ * Transform shader with core model modifications.
22
+ * Uniform assignment is handled by mutates.updateUniforms().
23
+ */
24
+ export const transformShader = (
25
+ shader: WebGLProgramParametersWithUniforms,
26
+ state: ModelBaseState,
27
+ mutates: ModelBaseMutates,
28
+ material: SupportedMaterial,
29
+ ): void => {
30
+ // Set core shader defines
31
+ shader.defines ??= {};
32
+ shader.defines.USE_SELECTIVE_EFFECT = 1;
33
+
34
+ // TODO: Handle batch texture defines in safe way.
35
+ // Merge defines from material.userData.defines (includes batch texture row defines)
36
+ // This is important for batch texture functionality which sets defines like:
37
+ // - BATCHED_TEXTURE_ROW_COLOR_SHOW, BATCHED_TEXTURE_ROW_HEIGHT, etc.
38
+ // - USE_BATCH_TEXTURE, USE_BATCH_COLOR_SHOW, USE_BATCH_HEIGHT, etc.
39
+ if (material.userData.defines) {
40
+ Object.assign(shader.defines, material.userData.defines);
41
+ }
42
+
43
+ // Assign uniform refs to shader.uniforms via mutates
44
+ mutates.updateUniforms(shader.uniforms, state);
45
+
46
+ // Transform vertex shader
47
+ shader.vertexShader = createReplacer(shader.vertexShader)
48
+ .replace(
49
+ "void main() {",
50
+ `
51
+ #include <packing>
52
+
53
+ in float batchId;
54
+ out float nvr_vBatchId;
55
+ out vec3 vPosition;
56
+
57
+ ${ShowParsVertex}
58
+ ${BatchTextureParsVertex}
59
+
60
+ ${ShadowMapDepthParsVertex}
61
+
62
+ void main() {
63
+ nvr_vBatchId = batchId;
64
+ `,
65
+ )
66
+ .replace(
67
+ "#include <color_vertex>",
68
+ `
69
+ #include <color_vertex>
70
+
71
+ ${BatchTextureVertex}
72
+ `,
73
+ )
74
+ .replace(
75
+ "#include <clipping_planes_vertex>",
76
+ `
77
+ #include <clipping_planes_vertex>
78
+ vPosition = (modelMatrix * vec4(transformed, 1.0)).xyz;
79
+ ${ShadowMapDepthVertex}
80
+ `,
81
+ ).source;
82
+
83
+ // Transform fragment shader
84
+ shader.fragmentShader = createReplacer(shader.fragmentShader)
85
+ .replace(
86
+ "void main() {",
87
+ `
88
+ #include <packing>
89
+
90
+ ${MODEL_BASE_SHADER_MARKERS.fragment.UNIFORM_START}
91
+ uniform float nvr_uPickable;
92
+ // uEffectIdsMask is declared by overrideMaterialsForMRT (#ifdef USE_SELECTIVE_EFFECT block)
93
+ ${MODEL_BASE_SHADER_MARKERS.fragment.UNIFORM_END}
94
+
95
+ in float nvr_vBatchId;
96
+
97
+ ${ShowParsFragment}
98
+
99
+ ${Pick}
100
+
101
+ ${ShadowMapDepthParsFragment}
102
+
103
+ void main() {
104
+ ${ShowFragment}
105
+ ${ShadowMapDepthFragment}
106
+ `,
107
+ )
108
+ .replace(
109
+ "#include <color_fragment>",
110
+ `
111
+ #include <color_fragment>
112
+
113
+ #ifdef USE_BATCH_COLOR_SHOW
114
+ diffuseColor.a *= nvr_vOpacity;
115
+ #endif
116
+ `,
117
+ )
118
+ .replace(
119
+ "#include <lights_physical_pars_fragment>",
120
+ `
121
+ #include <lights_physical_pars_fragment>
122
+ ${SpecularParsFragment}
123
+ `,
124
+ )
125
+ .replace(
126
+ "#include <normal_fragment_maps>",
127
+ `
128
+ ${MODEL_BASE_SHADER_MARKERS.fragment.NORMAL_START}
129
+ vec3 origNormal = normal;
130
+ vec3 specular;
131
+ #include <normal_fragment_maps>
132
+ ${MODEL_BASE_SHADER_MARKERS.fragment.NORMAL_END}
133
+ `,
134
+ )
135
+ .replace(
136
+ "vec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;",
137
+ `
138
+ ${MODEL_BASE_SHADER_MARKERS.fragment.OUTGOING_LIGHT_START}
139
+ vec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;
140
+ ${MODEL_BASE_SHADER_MARKERS.fragment.OUTGOING_LIGHT_END}
141
+ `,
142
+ )
143
+ .replace(
144
+ "#include <dithering_fragment>",
145
+ `
146
+ #include <dithering_fragment>
147
+ if (nvr_uPickable > 0.0 && diffuseColor.a > 0.0) {
148
+ vec3 pickColor = nvr_batchIdToColor(nvr_vBatchId);
149
+ gl_FragColor = vec4(pickColor.xyz, 1.0);
150
+ }
151
+ `,
152
+ )
153
+ .replace(
154
+ "normalBuffer = vec4(packNormalToVec2(normal), metalnessFactor, roughnessFactor)",
155
+ `
156
+ ${MODEL_BASE_SHADER_MARKERS.fragment.FINAL_NORMAL_START}
157
+ vec3 finalNormal = normal;
158
+ ${MODEL_BASE_SHADER_MARKERS.fragment.FINAL_NORMAL_END}
159
+ normalBuffer = vec4(packNormalToVec2(finalNormal), metalnessFactor, roughnessFactor)
160
+ `,
161
+ ).source;
162
+ };
@@ -0,0 +1,103 @@
1
+ import { describe, expect, it } from "vitest";
2
+
3
+ import { DEFAULT_BASE_STATE, updateState } from "./state";
4
+ import type { ModelBaseProps, ModelBaseState } from "./types";
5
+
6
+ /**
7
+ * Helper to create expected base state by merging with defaults.
8
+ */
9
+ const createExpectedState = (
10
+ overrides: Partial<ModelBaseState> = {},
11
+ ): ModelBaseState => ({
12
+ ...DEFAULT_BASE_STATE,
13
+ ...overrides,
14
+ });
15
+
16
+ describe("modelBaseEnhancer/state", () => {
17
+ describe("updateState", () => {
18
+ type TestCase = {
19
+ name: string;
20
+ props: ModelBaseProps;
21
+ currentState: ModelBaseState;
22
+ expected: ModelBaseState;
23
+ };
24
+
25
+ const testCases: TestCase[] = [
26
+ {
27
+ name: "returns default state when given empty props",
28
+ props: {},
29
+ currentState: DEFAULT_BASE_STATE,
30
+ expected: createExpectedState(),
31
+ },
32
+ {
33
+ name: "applies all props",
34
+ props: {
35
+ pickable: true,
36
+ batchColorEnabled: true,
37
+ useBatchTexture: true,
38
+ useBatchColorShow: true,
39
+ },
40
+ currentState: DEFAULT_BASE_STATE,
41
+ expected: createExpectedState({
42
+ pickable: true,
43
+ batchColorEnabled: true,
44
+ useBatchTexture: true,
45
+ useBatchColorShow: true,
46
+ }),
47
+ },
48
+ {
49
+ name: "applies pickable only",
50
+ props: {
51
+ pickable: true,
52
+ },
53
+ currentState: DEFAULT_BASE_STATE,
54
+ expected: createExpectedState({
55
+ pickable: true,
56
+ }),
57
+ },
58
+ {
59
+ name: "applies batch flags only",
60
+ props: {
61
+ useBatchTexture: true,
62
+ useBatchColorShow: true,
63
+ },
64
+ currentState: DEFAULT_BASE_STATE,
65
+ expected: createExpectedState({
66
+ useBatchTexture: true,
67
+ useBatchColorShow: true,
68
+ }),
69
+ },
70
+ {
71
+ name: "applies emissive and effectIdsMask",
72
+ props: {
73
+ emissiveColor: 0xff0000,
74
+ emissiveIntensity: 1.5,
75
+ effectIdsMask: 3,
76
+ },
77
+ currentState: DEFAULT_BASE_STATE,
78
+ expected: createExpectedState({
79
+ emissiveColor: 0xff0000,
80
+ emissiveIntensity: 1.5,
81
+ effectIdsMask: 3,
82
+ }),
83
+ },
84
+ ];
85
+
86
+ it.each(testCases)("$name", ({ props, currentState, expected }) => {
87
+ const result = updateState(props, currentState);
88
+ expect(result).toEqual(expected);
89
+ });
90
+
91
+ it("falls back to currentState for missing props", () => {
92
+ const currentState: ModelBaseState = {
93
+ ...DEFAULT_BASE_STATE,
94
+ pickable: true,
95
+ useBatchTexture: true,
96
+ };
97
+ const result = updateState({ batchColorEnabled: true }, currentState);
98
+ expect(result.pickable).toBe(true);
99
+ expect(result.useBatchTexture).toBe(true);
100
+ expect(result.batchColorEnabled).toBe(true);
101
+ });
102
+ });
103
+ });