@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.
- package/LICENSE +8 -0
- package/dist/assets/atmosphere/README.md +1 -0
- package/dist/assets/atmosphere/higher_order_scattering.bin +0 -0
- package/dist/assets/atmosphere/higher_order_scattering.exr +0 -0
- package/dist/assets/atmosphere/irradiance.bin +0 -0
- package/dist/assets/atmosphere/irradiance.exr +0 -0
- package/dist/assets/atmosphere/scattering.bin +0 -0
- package/dist/assets/atmosphere/scattering.exr +0 -0
- package/dist/assets/atmosphere/single_mie_scattering.bin +0 -0
- package/dist/assets/atmosphere/single_mie_scattering.exr +0 -0
- package/dist/assets/atmosphere/stars.bin +0 -0
- package/dist/assets/atmosphere/transmittance.bin +0 -0
- package/dist/assets/atmosphere/transmittance.exr +0 -0
- package/dist/assets/cloud/README.md +1 -0
- package/dist/assets/cloud/local_weather.png +0 -0
- package/dist/assets/cloud/shape.bin +1 -0
- package/dist/assets/cloud/shape_detail.bin +1 -0
- package/dist/assets/cloud/turbulence.png +0 -0
- package/dist/assets/fontWorker-CEJEfRpb.js +2 -0
- package/dist/assets/fontWorker-CEJEfRpb.js.map +1 -0
- package/dist/assets/index-BUB-ijMO.js +12 -0
- package/dist/assets/index-BUB-ijMO.js.map +1 -0
- package/dist/assets/navara_wasm_font_worker_bg-665OLxjy.wasm +0 -0
- package/dist/assets/navara_wasm_worker_bg-BXhKC5bE.wasm +0 -0
- package/dist/assets/noise/README.md +1 -0
- package/dist/assets/noise/stbn.bin +0 -0
- package/dist/assets/water/README.md +3 -0
- package/dist/assets/water/waternormals.jpg +0 -0
- package/dist/index.d.ts +10114 -0
- package/dist/index.js +34481 -0
- package/dist/index.js.map +1 -0
- package/dist/index.umd.cjs +6345 -0
- package/dist/index.umd.cjs.map +1 -0
- package/package.json +95 -0
- package/src/Color.ts +111 -0
- package/src/ShadowMapViewers.ts +49 -0
- package/src/atmosphere.test.ts +76 -0
- package/src/atmosphere.ts +364 -0
- package/src/bufferView.ts +90 -0
- package/src/camera.ts +182 -0
- package/src/concurrency.ts +15 -0
- package/src/constants/assets.ts +30 -0
- package/src/constants/decoder.ts +7 -0
- package/src/constants/index.ts +2 -0
- package/src/core/BaseDesc.ts +142 -0
- package/src/core/BaseHandle.ts +126 -0
- package/src/core/DescRegistry.ts +88 -0
- package/src/core/EffectDesc.ts +343 -0
- package/src/core/EffectDescRegistry.ts +31 -0
- package/src/core/InstancedMeshDesc.ts +413 -0
- package/src/core/LightDesc.ts +216 -0
- package/src/core/LightDescRegistry.ts +32 -0
- package/src/core/MeshDesc.ts +457 -0
- package/src/core/MeshDescRegistry.ts +32 -0
- package/src/core/MeshDescWithSelectiveEffect.ts +129 -0
- package/src/core/Registries.ts +59 -0
- package/src/core/SelectiveEffectRegistry.ts +90 -0
- package/src/core/ViewContext.ts +235 -0
- package/src/core/errors.ts +16 -0
- package/src/core/index.ts +50 -0
- package/src/device.ts +414 -0
- package/src/effects/CustomEffectPass.ts +28 -0
- package/src/effects/copy.ts +10 -0
- package/src/effects/effect.ts +87 -0
- package/src/effects/index.ts +4 -0
- package/src/effects/render.ts +10 -0
- package/src/evaluations/FeatureEvaluator.ts +529 -0
- package/src/evaluations/index.ts +1 -0
- package/src/event/HillshadeContext.test.ts +232 -0
- package/src/event/HillshadeContext.ts +299 -0
- package/src/event/context.ts +279 -0
- package/src/event/feature.ts +357 -0
- package/src/event/featureEvent.ts +81 -0
- package/src/event/features/billboard.ts +30 -0
- package/src/event/features/model.ts +192 -0
- package/src/event/features/modelGpuBytes.test.ts +69 -0
- package/src/event/features/modelGpuBytes.ts +87 -0
- package/src/event/features/point.ts +25 -0
- package/src/event/features/polygon.ts +23 -0
- package/src/event/features/polygonOutline.ts +19 -0
- package/src/event/features/polyline.ts +19 -0
- package/src/event/features/text.ts +71 -0
- package/src/event/hillshade.test.ts +842 -0
- package/src/event/hillshade.ts +588 -0
- package/src/event/index.ts +700 -0
- package/src/event/loaders.ts +53 -0
- package/src/event/tile.ts +19 -0
- package/src/event/worker.ts +999 -0
- package/src/event/workerTaskSettlement.test.ts +243 -0
- package/src/event/workerTaskSettlement.ts +128 -0
- package/src/inMemoryBufferStore.test.ts +60 -0
- package/src/inMemoryBufferStore.ts +67 -0
- package/src/index.iife.ts +11 -0
- package/src/index.ts +2556 -0
- package/src/input.ts +144 -0
- package/src/layer.ts +183 -0
- package/src/layers/effect/FinalCopyEffectDesc.ts +29 -0
- package/src/layers/effect/MRTPassEffectDesc.ts +105 -0
- package/src/layers/effect/README.md +9 -0
- package/src/layers/effect/SelectiveEffectDesc.ts +113 -0
- package/src/layers/effect/SkyEnvMapEffectDesc.ts +58 -0
- package/src/layers/effect/TransparentPassEffectDesc.ts +62 -0
- package/src/layers/effect/index.ts +5 -0
- package/src/layers/index.ts +1 -0
- package/src/layersManager.ts +63 -0
- package/src/light.ts +15 -0
- package/src/loaders/AbortableImageLoader.ts +203 -0
- package/src/loaders/AbortableTextureLoader.ts +74 -0
- package/src/loaders/index.ts +5 -0
- package/src/material/enhancer/DESIGN.md +300 -0
- package/src/material/enhancer/MaterialEnhancer.ts +112 -0
- package/src/material/enhancer/ShaderReplacer.test.ts +114 -0
- package/src/material/enhancer/ShaderReplacer.ts +97 -0
- package/src/material/enhancer/batchTexture.ts +8 -0
- package/src/material/enhancer/index.ts +46 -0
- package/src/material/enhancer/instancedSprite/index.ts +7 -0
- package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/index.test.ts +214 -0
- package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/index.ts +134 -0
- package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/markers.ts +21 -0
- package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/material.ts +32 -0
- package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/mutates.test.ts +277 -0
- package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/mutates.ts +151 -0
- package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/shader.test.ts +114 -0
- package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/shader.ts +49 -0
- package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/state.test.ts +82 -0
- package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/state.ts +80 -0
- package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/types.ts +146 -0
- package/src/material/enhancer/instancedSprite/instancedSpriteMaterialEnhancer.ts +105 -0
- package/src/material/enhancer/model/index.ts +25 -0
- package/src/material/enhancer/model/modelBaseEnhancer/index.test.ts +74 -0
- package/src/material/enhancer/model/modelBaseEnhancer/index.ts +110 -0
- package/src/material/enhancer/model/modelBaseEnhancer/markers.ts +27 -0
- package/src/material/enhancer/model/modelBaseEnhancer/material.test.ts +66 -0
- package/src/material/enhancer/model/modelBaseEnhancer/material.ts +44 -0
- package/src/material/enhancer/model/modelBaseEnhancer/mutates.test.ts +84 -0
- package/src/material/enhancer/model/modelBaseEnhancer/mutates.ts +47 -0
- package/src/material/enhancer/model/modelBaseEnhancer/shader.test.ts +24 -0
- package/src/material/enhancer/model/modelBaseEnhancer/shader.ts +162 -0
- package/src/material/enhancer/model/modelBaseEnhancer/state.test.ts +103 -0
- package/src/material/enhancer/model/modelBaseEnhancer/state.ts +52 -0
- package/src/material/enhancer/model/modelBaseEnhancer/types.ts +89 -0
- package/src/material/enhancer/model/modelMaterialEnhancer.ts +91 -0
- package/src/material/enhancer/model/modelWaterEnhancer/index.test.ts +71 -0
- package/src/material/enhancer/model/modelWaterEnhancer/index.ts +175 -0
- package/src/material/enhancer/model/modelWaterEnhancer/material.test.ts +48 -0
- package/src/material/enhancer/model/modelWaterEnhancer/material.ts +25 -0
- package/src/material/enhancer/model/modelWaterEnhancer/mutates.test.ts +89 -0
- package/src/material/enhancer/model/modelWaterEnhancer/mutates.ts +89 -0
- package/src/material/enhancer/model/modelWaterEnhancer/shader.test.ts +34 -0
- package/src/material/enhancer/model/modelWaterEnhancer/shader.ts +111 -0
- package/src/material/enhancer/model/modelWaterEnhancer/state.test.ts +105 -0
- package/src/material/enhancer/model/modelWaterEnhancer/state.ts +59 -0
- package/src/material/enhancer/model/modelWaterEnhancer/types.ts +141 -0
- package/src/material/enhancer/model/pntsEnhancer/index.test.ts +96 -0
- package/src/material/enhancer/model/pntsEnhancer/index.ts +82 -0
- package/src/material/enhancer/model/pntsEnhancer/markers.ts +6 -0
- package/src/material/enhancer/model/pntsEnhancer/material.test.ts +37 -0
- package/src/material/enhancer/model/pntsEnhancer/material.ts +21 -0
- package/src/material/enhancer/model/pntsEnhancer/mutates.test.ts +80 -0
- package/src/material/enhancer/model/pntsEnhancer/mutates.ts +29 -0
- package/src/material/enhancer/model/pntsEnhancer/shader.test.ts +32 -0
- package/src/material/enhancer/model/pntsEnhancer/shader.ts +56 -0
- package/src/material/enhancer/model/pntsEnhancer/state.test.ts +87 -0
- package/src/material/enhancer/model/pntsEnhancer/state.ts +29 -0
- package/src/material/enhancer/model/pntsEnhancer/types.ts +38 -0
- package/src/material/enhancer/polygon/index.ts +22 -0
- package/src/material/enhancer/polygon/polygonBaseEnhancer/index.test.ts +101 -0
- package/src/material/enhancer/polygon/polygonBaseEnhancer/index.ts +130 -0
- package/src/material/enhancer/polygon/polygonBaseEnhancer/markers.ts +23 -0
- package/src/material/enhancer/polygon/polygonBaseEnhancer/material.test.ts +19 -0
- package/src/material/enhancer/polygon/polygonBaseEnhancer/material.ts +38 -0
- package/src/material/enhancer/polygon/polygonBaseEnhancer/mutates.test.ts +75 -0
- package/src/material/enhancer/polygon/polygonBaseEnhancer/mutates.ts +122 -0
- package/src/material/enhancer/polygon/polygonBaseEnhancer/shader.test.ts +25 -0
- package/src/material/enhancer/polygon/polygonBaseEnhancer/shader.ts +249 -0
- package/src/material/enhancer/polygon/polygonBaseEnhancer/state.test.ts +102 -0
- package/src/material/enhancer/polygon/polygonBaseEnhancer/state.ts +92 -0
- package/src/material/enhancer/polygon/polygonBaseEnhancer/types.ts +150 -0
- package/src/material/enhancer/polygon/polygonMaterialEnhancer.ts +97 -0
- package/src/material/enhancer/polygon/polygonWaterEnhancer/index.test.ts +72 -0
- package/src/material/enhancer/polygon/polygonWaterEnhancer/index.ts +164 -0
- package/src/material/enhancer/polygon/polygonWaterEnhancer/material.test.ts +48 -0
- package/src/material/enhancer/polygon/polygonWaterEnhancer/material.ts +35 -0
- package/src/material/enhancer/polygon/polygonWaterEnhancer/mutates.ts +61 -0
- package/src/material/enhancer/polygon/polygonWaterEnhancer/shader.test.ts +34 -0
- package/src/material/enhancer/polygon/polygonWaterEnhancer/shader.ts +96 -0
- package/src/material/enhancer/polygon/polygonWaterEnhancer/state.test.ts +98 -0
- package/src/material/enhancer/polygon/polygonWaterEnhancer/state.ts +57 -0
- package/src/material/enhancer/polygon/polygonWaterEnhancer/types.ts +115 -0
- package/src/material/enhancer/polyline/index.ts +7 -0
- package/src/material/enhancer/polyline/polylineBaseEnhancer/index.test.ts +157 -0
- package/src/material/enhancer/polyline/polylineBaseEnhancer/index.ts +154 -0
- package/src/material/enhancer/polyline/polylineBaseEnhancer/markers.ts +19 -0
- package/src/material/enhancer/polyline/polylineBaseEnhancer/material.test.ts +42 -0
- package/src/material/enhancer/polyline/polylineBaseEnhancer/material.ts +38 -0
- package/src/material/enhancer/polyline/polylineBaseEnhancer/mutates.test.ts +120 -0
- package/src/material/enhancer/polyline/polylineBaseEnhancer/mutates.ts +169 -0
- package/src/material/enhancer/polyline/polylineBaseEnhancer/shader.test.ts +67 -0
- package/src/material/enhancer/polyline/polylineBaseEnhancer/shader.ts +75 -0
- package/src/material/enhancer/polyline/polylineBaseEnhancer/state.test.ts +55 -0
- package/src/material/enhancer/polyline/polylineBaseEnhancer/state.ts +91 -0
- package/src/material/enhancer/polyline/polylineBaseEnhancer/types.ts +170 -0
- package/src/material/enhancer/polyline/polylineMaterialEnhancer.ts +102 -0
- package/src/material/enhancer/sdfText/index.ts +7 -0
- package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/index.ts +125 -0
- package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/markers.ts +19 -0
- package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/material.test.ts +35 -0
- package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/material.ts +32 -0
- package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/mutates.test.ts +381 -0
- package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/mutates.ts +232 -0
- package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/shader.ts +36 -0
- package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/state.test.ts +118 -0
- package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/state.ts +107 -0
- package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/types.ts +184 -0
- package/src/material/enhancer/sdfText/sdfTextMaterialEnhancer.ts +100 -0
- package/src/material/enhancer/shadowMap/index.ts +7 -0
- package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/index.ts +97 -0
- package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/markers.ts +10 -0
- package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/material.ts +31 -0
- package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/mutates.ts +8 -0
- package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/shader.test.ts +17 -0
- package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/shader.ts +53 -0
- package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/state.ts +17 -0
- package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/types.ts +26 -0
- package/src/material/enhancer/test-utils/shaderCompatibility.ts +124 -0
- package/src/material/enhancer/tileComposite/compose.test.ts +95 -0
- package/src/material/enhancer/tileComposite/compose.ts +112 -0
- package/src/material/enhancer/tileComposite/index.ts +23 -0
- package/src/material/enhancer/tileComposite/tileCompositeBaseEnhancer/index.ts +11 -0
- package/src/material/enhancer/tileComposite/tileCompositeBaseEnhancer/mutates.ts +132 -0
- package/src/material/enhancer/tileComposite/tileCompositeBaseEnhancer/shader.ts +245 -0
- package/src/material/enhancer/tileComposite/tileCompositeBaseEnhancer/types.ts +43 -0
- package/src/material/enhancer/tileComposite/tileElevationHeatmapEnhancer/index.ts +29 -0
- package/src/material/enhancer/tileComposite/tileElevationHeatmapEnhancer/mutates.ts +68 -0
- package/src/material/enhancer/tileComposite/tileElevationHeatmapEnhancer/shader.ts +24 -0
- package/src/material/enhancer/tileComposite/tileHillshadeEnhancer/index.ts +29 -0
- package/src/material/enhancer/tileComposite/tileHillshadeEnhancer/mutates.ts +34 -0
- package/src/material/enhancer/tileComposite/tileHillshadeEnhancer/shader.ts +36 -0
- package/src/material/enhancer/tileComposite/tileWaterEnhancer/index.ts +23 -0
- package/src/material/enhancer/tileComposite/tileWaterEnhancer/mutates.ts +23 -0
- package/src/material/enhancer/tileComposite/tileWaterEnhancer/shader.ts +8 -0
- package/src/material/enhancer/tileComposite/tileWatermaskEnhancer/index.ts +23 -0
- package/src/material/enhancer/tileComposite/tileWatermaskEnhancer/mutates.ts +34 -0
- package/src/material/enhancer/tileComposite/tileWatermaskEnhancer/shader.ts +13 -0
- package/src/material/enhancer/tileComposite/types.ts +58 -0
- package/src/material/index.ts +3 -0
- package/src/material/macro/index.ts +1 -0
- package/src/material/macro/tileShader.test.ts +136 -0
- package/src/material/macro/tileShader.ts +287 -0
- package/src/material/overrideMaterialsForMRT.ts +439 -0
- package/src/material/selectiveEffectMaterialSetup.test.ts +52 -0
- package/src/material/selectiveEffectMaterialSetup.ts +53 -0
- package/src/material/types/index.ts +1 -0
- package/src/material/types/uniform.ts +1 -0
- package/src/mesh/DrapedMesh.ts +101 -0
- package/src/mesh/batchTexture.test.ts +646 -0
- package/src/mesh/batchTexture.ts +437 -0
- package/src/mesh/batchedFeature.ts +186 -0
- package/src/mesh/batchedSdfText.ts +484 -0
- package/src/mesh/featureMesh.ts +43 -0
- package/src/mesh/index.ts +16 -0
- package/src/mesh/instanced.ts +117 -0
- package/src/mesh/model.ts +483 -0
- package/src/mesh/pickableMesh.ts +55 -0
- package/src/mesh/pickableMeshWrapper.ts +529 -0
- package/src/mesh/polygon.ts +699 -0
- package/src/mesh/polygonOutline.ts +393 -0
- package/src/mesh/polyline.ts +523 -0
- package/src/mesh/releaseGeometryArrays.ts +57 -0
- package/src/mesh/rtcRteHelper.ts +211 -0
- package/src/mesh/sdfText.test.ts +200 -0
- package/src/mesh/sdfText.ts +1019 -0
- package/src/mesh/sprite/billboardAtlas.test.ts +177 -0
- package/src/mesh/sprite/billboardAtlas.ts +210 -0
- package/src/mesh/sprite/billboardAtlasImageLoader.ts +29 -0
- package/src/mesh/sprite/index.ts +1 -0
- package/src/mesh/sprite/instancedSprite.ts +694 -0
- package/src/mesh/tile.test.ts +393 -0
- package/src/mesh/tile.ts +1790 -0
- package/src/object3DEvent.ts +6 -0
- package/src/orchestrators/RenderPassOrchestrator.ts +147 -0
- package/src/orchestrators/index.ts +1 -0
- package/src/passes/AllDepthCopyPass.ts +165 -0
- package/src/passes/CustomRenderPass.ts +279 -0
- package/src/passes/NormalCopyPass.ts +125 -0
- package/src/passes/RenderTargetCopyPass.ts +91 -0
- package/src/passes/SkyEnvMapPass.ts +58 -0
- package/src/passes/index.ts +5 -0
- package/src/pick/pickHelper.ts +273 -0
- package/src/pick/pickTerrain.ts +254 -0
- package/src/plugins/AttributionPlugin/AttributionPlugin.test.ts +210 -0
- package/src/plugins/AttributionPlugin/attribution.test.ts +225 -0
- package/src/plugins/AttributionPlugin/attribution.ts +355 -0
- package/src/plugins/AttributionPlugin/attributionStyles.ts +163 -0
- package/src/plugins/AttributionPlugin/index.ts +702 -0
- package/src/plugins/index.ts +1 -0
- package/src/quality.ts +1 -0
- package/src/renderOrder.ts +3 -0
- package/src/scene.test.ts +164 -0
- package/src/scene.ts +127 -0
- package/src/shaders/index.ts +1 -0
- package/src/solar.test.ts +81 -0
- package/src/solar.ts +101 -0
- package/src/source.ts +80 -0
- package/src/stats.ts +102 -0
- package/src/tasks/computeVertexNormalsAsync.ts +15 -0
- package/src/tasks/constructPolygonBatchedFeature.ts +34 -0
- package/src/tasks/constructPolylineBatchedFeature.ts +27 -0
- package/src/tasks/constructQuantizedMeshTerrainMesh.ts +24 -0
- package/src/tasks/constructTerrainMesh.ts +25 -0
- package/src/tasks/getImageDataFromBlob.ts +13 -0
- package/src/tasks/getImageDataFromImageBitmap.ts +12 -0
- package/src/tasks/parseMvtTile.ts +22 -0
- package/src/tasks/queueTask.ts +19 -0
- package/src/tasks/toCreasedNormalsAsync.ts +18 -0
- package/src/tasks/upsampleQuantizedMeshTerrainMesh.ts +44 -0
- package/src/tasks/upsampleTerrainMesh.ts +39 -0
- package/src/texture.ts +19 -0
- package/src/textures.ts +13 -0
- package/src/tileTexture/CompositeShader.snapshot.test.ts +59 -0
- package/src/tileTexture/CompositeShader.test.ts +168 -0
- package/src/tileTexture/CompositeShader.ts +53 -0
- package/src/tileTexture/SlotPlanner.test.ts +105 -0
- package/src/tileTexture/SlotPlanner.ts +102 -0
- package/src/tileTexture/TileTextureCache.test.ts +227 -0
- package/src/tileTexture/TileTextureCache.ts +192 -0
- package/src/tileTexture/TileTextureCompositor.test.ts +260 -0
- package/src/tileTexture/TileTextureCompositor.ts +421 -0
- package/src/tileTexture/__snapshots__/CompositeShader.snapshot.test.ts.snap +2649 -0
- package/src/tileTexture/index.ts +8 -0
- package/src/tileTexture/types.ts +150 -0
- package/src/type/index.ts +261 -0
- package/src/uniforms.ts +20 -0
- package/src/utils/arraysEqual.ts +9 -0
- package/src/utils/blendModes.ts +80 -0
- package/src/utils/geometry.ts +53 -0
- package/src/utils/hillshadeNormalMapGenerator.ts +193 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/object.test.ts +14 -0
- package/src/utils/object.ts +7 -0
- package/src/utils/replacer.test.ts +42 -0
- package/src/utils/replacer.ts +89 -0
- package/src/utils/screen.ts +29 -0
- package/src/utils/textureFragmentIndex.test.ts +224 -0
- package/src/utils/textureFragmentIndex.ts +97 -0
- package/src/utils/worker.ts +3 -0
- package/src/vite-env.d.ts +2 -0
- package/src/worker/index.ts +13 -0
- package/src/worker/tasks/computeVertexNormals.ts +15 -0
- package/src/worker/tasks/toCreasedNormals.ts +22 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { ModelBaseProps, ModelBaseState } from "./types";
|
|
2
|
+
|
|
3
|
+
export const DEFAULT_BASE_PROPS: Required<
|
|
4
|
+
Omit<ModelBaseProps, "batchDataTexture">
|
|
5
|
+
> = {
|
|
6
|
+
color: 0,
|
|
7
|
+
metalness: 0,
|
|
8
|
+
roughness: 0,
|
|
9
|
+
transparent: false,
|
|
10
|
+
opacity: 1.0,
|
|
11
|
+
depthWrite: true,
|
|
12
|
+
emissiveColor: 0,
|
|
13
|
+
emissiveIntensity: 0,
|
|
14
|
+
pickable: false,
|
|
15
|
+
effectIdsMask: 0,
|
|
16
|
+
batchColorEnabled: false,
|
|
17
|
+
useBatchTexture: false,
|
|
18
|
+
useBatchColorShow: false,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/** Default state derived from DEFAULT_BASE_PROPS */
|
|
22
|
+
export const DEFAULT_BASE_STATE: ModelBaseState = {
|
|
23
|
+
pickable: DEFAULT_BASE_PROPS.pickable,
|
|
24
|
+
emissiveColor: DEFAULT_BASE_PROPS.emissiveColor,
|
|
25
|
+
emissiveIntensity: DEFAULT_BASE_PROPS.emissiveIntensity,
|
|
26
|
+
effectIdsMask: 0,
|
|
27
|
+
batchColorEnabled: DEFAULT_BASE_PROPS.batchColorEnabled,
|
|
28
|
+
useBatchTexture: DEFAULT_BASE_PROPS.useBatchTexture,
|
|
29
|
+
useBatchColorShow: DEFAULT_BASE_PROPS.useBatchColorShow,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Update immutable state from props.
|
|
34
|
+
* Props override currentState values; missing props fall back to currentState.
|
|
35
|
+
* Pass DEFAULT_BASE_STATE as currentState for initial mount.
|
|
36
|
+
*
|
|
37
|
+
* @param props - The props to apply
|
|
38
|
+
* @param currentState - The current state to use as fallback (use DEFAULT_BASE_STATE for mount)
|
|
39
|
+
*/
|
|
40
|
+
export const updateState = (
|
|
41
|
+
props: ModelBaseProps,
|
|
42
|
+
currentState: ModelBaseState,
|
|
43
|
+
): ModelBaseState => ({
|
|
44
|
+
pickable: props.pickable ?? currentState.pickable,
|
|
45
|
+
emissiveColor: props.emissiveColor ?? currentState.emissiveColor,
|
|
46
|
+
emissiveIntensity: props.emissiveIntensity ?? currentState.emissiveIntensity,
|
|
47
|
+
effectIdsMask: props.effectIdsMask ?? currentState.effectIdsMask,
|
|
48
|
+
// Batch flags can only transition from false to true, never back
|
|
49
|
+
batchColorEnabled: props.batchColorEnabled ?? currentState.batchColorEnabled,
|
|
50
|
+
useBatchTexture: props.useBatchTexture ?? currentState.useBatchTexture,
|
|
51
|
+
useBatchColorShow: props.useBatchColorShow ?? currentState.useBatchColorShow,
|
|
52
|
+
});
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { Texture } from "three";
|
|
2
|
+
|
|
3
|
+
import type { UniformValue } from "../../../types";
|
|
4
|
+
import type { BatchTextureFlags } from "../../batchTexture";
|
|
5
|
+
import type { Mutates } from "../../MaterialEnhancer";
|
|
6
|
+
|
|
7
|
+
type ModelBatchTextureFlags = Required<
|
|
8
|
+
Pick<BatchTextureFlags, "useBatchTexture" | "useBatchColorShow">
|
|
9
|
+
>;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Props for the model base enhancer.
|
|
13
|
+
*/
|
|
14
|
+
export type ModelBaseProps = {
|
|
15
|
+
// Basic material props
|
|
16
|
+
color?: number;
|
|
17
|
+
metalness?: number;
|
|
18
|
+
roughness?: number;
|
|
19
|
+
|
|
20
|
+
transparent?: boolean;
|
|
21
|
+
opacity?: number;
|
|
22
|
+
depthWrite?: boolean;
|
|
23
|
+
|
|
24
|
+
// Emissive (for selective effects)
|
|
25
|
+
emissiveColor?: number;
|
|
26
|
+
emissiveIntensity?: number;
|
|
27
|
+
|
|
28
|
+
// Picking
|
|
29
|
+
pickable?: boolean;
|
|
30
|
+
|
|
31
|
+
// Selective Effect
|
|
32
|
+
effectIdsMask?: number;
|
|
33
|
+
|
|
34
|
+
// Batch texture
|
|
35
|
+
batchDataTexture?: UniformValue<Texture | null>;
|
|
36
|
+
|
|
37
|
+
// When batchColorEnabled is true, material.color is set to white and actual colors come from batch texture
|
|
38
|
+
batchColorEnabled?: boolean;
|
|
39
|
+
} & Partial<ModelBatchTextureFlags>;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Immutable state for the model base enhancer.
|
|
43
|
+
* This state is always replaced as a whole (never mutated).
|
|
44
|
+
* Returned directly via states() - refresh after updates.
|
|
45
|
+
*/
|
|
46
|
+
export type ModelBaseState = Readonly<
|
|
47
|
+
{
|
|
48
|
+
pickable: boolean;
|
|
49
|
+
emissiveColor: number;
|
|
50
|
+
emissiveIntensity: number;
|
|
51
|
+
effectIdsMask: number;
|
|
52
|
+
// Batch texture state - when true, material.color is white and colors come from batch texture
|
|
53
|
+
batchColorEnabled: boolean;
|
|
54
|
+
} & ModelBatchTextureFlags
|
|
55
|
+
>;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Mutable references (uniforms) for the model base enhancer.
|
|
59
|
+
*
|
|
60
|
+
* These are shared references with shader.uniforms and can be mutated directly
|
|
61
|
+
* for efficient GPU uniform updates without shader recompilation.
|
|
62
|
+
* Internal type - not exposed externally.
|
|
63
|
+
*/
|
|
64
|
+
export type ModelBaseRefs = {
|
|
65
|
+
nvr_uPickable: UniformValue<number>;
|
|
66
|
+
uEffectIdsMask: UniformValue<number>;
|
|
67
|
+
uEmissiveIntensity: UniformValue<number>;
|
|
68
|
+
|
|
69
|
+
// Optional uniforms
|
|
70
|
+
batchDataTexture?: UniformValue<Texture | null>;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export type ModelBaseUniforms = Partial<ModelBaseRefs>;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Mutation functions for the model base enhancer.
|
|
77
|
+
* Includes `update(state)` to sync refs from state, plus additional methods.
|
|
78
|
+
*/
|
|
79
|
+
export type ModelBaseMutates = Mutates<
|
|
80
|
+
ModelBaseState,
|
|
81
|
+
ModelBaseUniforms,
|
|
82
|
+
{
|
|
83
|
+
/**
|
|
84
|
+
* Set the batch data texture ref.
|
|
85
|
+
* This is needed because batchDataTexture is an external ref passed via props.
|
|
86
|
+
*/
|
|
87
|
+
setBatchDataTexture: (texture: UniformValue<Texture | null>) => void;
|
|
88
|
+
}
|
|
89
|
+
>;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model Material Enhancer - Composed from Base + Water enhancers
|
|
3
|
+
*
|
|
4
|
+
* This module provides the full model material functionality by using
|
|
5
|
+
* the water enhancer factory which internally composes with the base enhancer.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { MaterialEnhancer } from "../MaterialEnhancer";
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
createModelBaseEnhancer,
|
|
12
|
+
type ModelBaseMutates,
|
|
13
|
+
type ModelBaseProps,
|
|
14
|
+
type ModelBaseState,
|
|
15
|
+
} from "./modelBaseEnhancer";
|
|
16
|
+
import {
|
|
17
|
+
createModelWaterEnhancer,
|
|
18
|
+
type ModelWaterCombinedMutates,
|
|
19
|
+
type ModelWaterCombinedStates,
|
|
20
|
+
type ModelWaterOnlyProps,
|
|
21
|
+
type ModelWaterProps,
|
|
22
|
+
type ModelWaterState,
|
|
23
|
+
type AVAILABLE_SHADERS as WATER_AVAILABLE_SHADERS,
|
|
24
|
+
type SupportedMaterial as WaterSupportedMaterial,
|
|
25
|
+
} from "./modelWaterEnhancer";
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Combined props for the model material enhancer.
|
|
29
|
+
* Props are explicitly separated into base and water sections for clarity.
|
|
30
|
+
*/
|
|
31
|
+
export type ModelMaterialProps = {
|
|
32
|
+
base?: ModelBaseProps;
|
|
33
|
+
water?: ModelWaterOnlyProps;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// Shaders this enhancer supports
|
|
37
|
+
type AVAILABLE_SHADERS = typeof WATER_AVAILABLE_SHADERS;
|
|
38
|
+
type SupportedMaterial = WaterSupportedMaterial;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Factory function to create the model material enhancer.
|
|
42
|
+
*
|
|
43
|
+
* This creates a new enhancer instance with its own internal state.
|
|
44
|
+
*
|
|
45
|
+
* @param material - The Three.js material to enhance
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* const material = new MeshStandardMaterial();
|
|
50
|
+
* const enhancer = createModelMaterialEnhancer(material);
|
|
51
|
+
*
|
|
52
|
+
* // Mount with separated base and water props
|
|
53
|
+
* enhancer.mount({
|
|
54
|
+
* base: { color: 0xff0000, metalness: 0.5 },
|
|
55
|
+
* water: { water: true, waterScaleNormal: 0.01 },
|
|
56
|
+
* });
|
|
57
|
+
*
|
|
58
|
+
* // Get state directly via states() - refresh after updates
|
|
59
|
+
* const { base, water } = enhancer.states();
|
|
60
|
+
*
|
|
61
|
+
* // Update props (then call states() again to get fresh state)
|
|
62
|
+
* enhancer.update({ base: { height: 100 } });
|
|
63
|
+
*
|
|
64
|
+
* // Use transformShader for onBeforeCompile
|
|
65
|
+
* material.onBeforeCompile = enhancer.transformShader;
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export function createModelMaterialEnhancer(
|
|
69
|
+
material: SupportedMaterial,
|
|
70
|
+
): MaterialEnhancer<
|
|
71
|
+
SupportedMaterial,
|
|
72
|
+
ModelMaterialProps,
|
|
73
|
+
ModelWaterCombinedStates,
|
|
74
|
+
ModelWaterCombinedMutates,
|
|
75
|
+
AVAILABLE_SHADERS
|
|
76
|
+
> {
|
|
77
|
+
const baseEnhancer = createModelBaseEnhancer(material);
|
|
78
|
+
return createModelWaterEnhancer(baseEnhancer);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Re-export types for convenience
|
|
82
|
+
export type {
|
|
83
|
+
ModelBaseMutates,
|
|
84
|
+
ModelBaseProps,
|
|
85
|
+
ModelBaseState,
|
|
86
|
+
ModelWaterCombinedMutates,
|
|
87
|
+
ModelWaterCombinedStates,
|
|
88
|
+
ModelWaterOnlyProps,
|
|
89
|
+
ModelWaterProps,
|
|
90
|
+
ModelWaterState,
|
|
91
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { MeshStandardMaterial } from "three";
|
|
2
|
+
import { beforeEach, describe, expect, it } from "vitest";
|
|
3
|
+
|
|
4
|
+
import { createModelBaseEnhancer } from "../modelBaseEnhancer";
|
|
5
|
+
|
|
6
|
+
import { createModelWaterEnhancer } from ".";
|
|
7
|
+
|
|
8
|
+
describe("modelWaterEnhancer", () => {
|
|
9
|
+
let enhancer: ReturnType<typeof createModelWaterEnhancer>;
|
|
10
|
+
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
const baseEnhancer = createModelBaseEnhancer(new MeshStandardMaterial());
|
|
13
|
+
enhancer = createModelWaterEnhancer(baseEnhancer);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
describe("lifecycle", () => {
|
|
17
|
+
it("states() should throw if called before mount", () => {
|
|
18
|
+
const freshMaterial = new MeshStandardMaterial();
|
|
19
|
+
const baseEnhancer = createModelBaseEnhancer(freshMaterial);
|
|
20
|
+
const freshEnhancer = createModelWaterEnhancer(baseEnhancer);
|
|
21
|
+
|
|
22
|
+
expect(() => freshEnhancer.states()).toThrow(
|
|
23
|
+
"mount() must be called before states",
|
|
24
|
+
);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
describe("programCacheKey", () => {
|
|
29
|
+
it("should combine base cache key with water-specific state", () => {
|
|
30
|
+
enhancer.mount({
|
|
31
|
+
base: { useBatchTexture: true },
|
|
32
|
+
water: { water: true },
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const cacheKey = enhancer.programCacheKey();
|
|
36
|
+
|
|
37
|
+
expect(cacheKey).toContain('"useBatchTexture":true');
|
|
38
|
+
expect(cacheKey).toContain('"useWater":true');
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("should return different cache keys when useWater differs", () => {
|
|
42
|
+
enhancer.mount({ water: { water: false } });
|
|
43
|
+
const cacheKey1 = enhancer.programCacheKey();
|
|
44
|
+
|
|
45
|
+
const enhancer2 = createModelWaterEnhancer(
|
|
46
|
+
createModelBaseEnhancer(new MeshStandardMaterial()),
|
|
47
|
+
);
|
|
48
|
+
enhancer2.mount({ water: { water: true } });
|
|
49
|
+
const cacheKey2 = enhancer2.programCacheKey();
|
|
50
|
+
|
|
51
|
+
expect(cacheKey1).not.toBe(cacheKey2);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("should return same cache key for same shader-affecting states with different non-affecting states", () => {
|
|
55
|
+
enhancer.mount({
|
|
56
|
+
water: { water: true, waterSpeed: 1.0, shininess: 10 },
|
|
57
|
+
});
|
|
58
|
+
const cacheKey1 = enhancer.programCacheKey();
|
|
59
|
+
|
|
60
|
+
const enhancer2 = createModelWaterEnhancer(
|
|
61
|
+
createModelBaseEnhancer(new MeshStandardMaterial()),
|
|
62
|
+
);
|
|
63
|
+
enhancer2.mount({
|
|
64
|
+
water: { water: true, waterSpeed: 5.0, shininess: 50 },
|
|
65
|
+
});
|
|
66
|
+
const cacheKey2 = enhancer2.programCacheKey();
|
|
67
|
+
|
|
68
|
+
expect(cacheKey1).toBe(cacheKey2);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
});
|
|
@@ -0,0 +1,175 @@
|
|
|
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
|
+
import type {
|
|
7
|
+
ModelBaseMutates,
|
|
8
|
+
ModelBaseProps,
|
|
9
|
+
ModelBaseState,
|
|
10
|
+
SupportedMaterial,
|
|
11
|
+
} from "../modelBaseEnhancer";
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
AVAILABLE_SHADERS,
|
|
15
|
+
type SupportedMaterial as WaterSupportedMaterial,
|
|
16
|
+
} from "./material";
|
|
17
|
+
import { applyWaterMaterialConfig } from "./material";
|
|
18
|
+
import { createWaterMutates } from "./mutates";
|
|
19
|
+
import { transformWaterShader } from "./shader";
|
|
20
|
+
import {
|
|
21
|
+
DEFAULT_WATER_PROPS,
|
|
22
|
+
DEFAULT_WATER_STATE,
|
|
23
|
+
updateWaterState,
|
|
24
|
+
} from "./state";
|
|
25
|
+
import type {
|
|
26
|
+
ModelWaterCombinedMutates,
|
|
27
|
+
ModelWaterCombinedStates,
|
|
28
|
+
ModelWaterMutates,
|
|
29
|
+
ModelWaterOnlyProps,
|
|
30
|
+
ModelWaterProps,
|
|
31
|
+
ModelWaterState,
|
|
32
|
+
} from "./types";
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Factory function to create a model water enhancer.
|
|
36
|
+
*
|
|
37
|
+
* @param baseEnhancer - The base model enhancer to compose with (material is obtained from this)
|
|
38
|
+
* @returns A new MaterialEnhancer with combined base + water functionality
|
|
39
|
+
*/
|
|
40
|
+
export function createModelWaterEnhancer(
|
|
41
|
+
baseEnhancer: MaterialEnhancer<
|
|
42
|
+
SupportedMaterial,
|
|
43
|
+
ModelBaseProps,
|
|
44
|
+
ModelBaseState,
|
|
45
|
+
ModelBaseMutates,
|
|
46
|
+
typeof AVAILABLE_SHADERS
|
|
47
|
+
>,
|
|
48
|
+
): MaterialEnhancer<
|
|
49
|
+
WaterSupportedMaterial,
|
|
50
|
+
ModelWaterProps,
|
|
51
|
+
ModelWaterCombinedStates,
|
|
52
|
+
ModelWaterCombinedMutates,
|
|
53
|
+
typeof AVAILABLE_SHADERS
|
|
54
|
+
> {
|
|
55
|
+
const { material } = baseEnhancer;
|
|
56
|
+
// Internal state - immutable, always replaced as a whole
|
|
57
|
+
let state: ModelWaterState | null = null;
|
|
58
|
+
// Internal mutates object (refs are hidden inside)
|
|
59
|
+
let mutates: ModelWaterMutates | null = null;
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
material: material as WaterSupportedMaterial,
|
|
63
|
+
availableShaders: AVAILABLE_SHADERS,
|
|
64
|
+
|
|
65
|
+
transformShader: (shader: WebGLProgramParametersWithUniforms): void => {
|
|
66
|
+
invariant(
|
|
67
|
+
state && mutates,
|
|
68
|
+
"mount() must be called before transformShader",
|
|
69
|
+
);
|
|
70
|
+
// First apply base transformations
|
|
71
|
+
baseEnhancer.transformShader(shader);
|
|
72
|
+
// Then apply water transformations
|
|
73
|
+
transformWaterShader(shader, state, mutates);
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
mount: (props: ModelWaterProps): void => {
|
|
77
|
+
// Mount base enhancer first with base props
|
|
78
|
+
baseEnhancer.mount(props.base ?? {});
|
|
79
|
+
|
|
80
|
+
// Initialize water state and mutates with water props
|
|
81
|
+
const waterProps = props.water ?? {};
|
|
82
|
+
const mergedWaterProps = defaults({}, waterProps, DEFAULT_WATER_PROPS);
|
|
83
|
+
state = updateWaterState(mergedWaterProps, DEFAULT_WATER_STATE);
|
|
84
|
+
// Create mutates (refs are created inside with default values)
|
|
85
|
+
mutates = createWaterMutates();
|
|
86
|
+
mutates.update(state);
|
|
87
|
+
// Handle external refs (identity doesn't change after mount)
|
|
88
|
+
if (waterProps.waterNormalMap) {
|
|
89
|
+
mutates.setWaterNormalMap(waterProps.waterNormalMap, state.useWater);
|
|
90
|
+
}
|
|
91
|
+
if (waterProps.timeUniform) {
|
|
92
|
+
mutates.setTimeUniform(waterProps.timeUniform);
|
|
93
|
+
}
|
|
94
|
+
if (waterProps.skyEnvMapUniform) {
|
|
95
|
+
mutates.setSkyEnvMapUniform(waterProps.skyEnvMapUniform);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Apply material configuration (side effect)
|
|
99
|
+
applyWaterMaterialConfig(
|
|
100
|
+
material as WaterSupportedMaterial,
|
|
101
|
+
state,
|
|
102
|
+
false,
|
|
103
|
+
);
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
update: (props: ModelWaterProps): void => {
|
|
107
|
+
// Update base enhancer first with base props
|
|
108
|
+
if (props.base) {
|
|
109
|
+
baseEnhancer.update(props.base);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
invariant(state && mutates, "mount() must be called before update");
|
|
113
|
+
|
|
114
|
+
// Update water state and refs with water props
|
|
115
|
+
if (props.water) {
|
|
116
|
+
const prevUseWater = state.useWater;
|
|
117
|
+
state = updateWaterState(props.water, state);
|
|
118
|
+
mutates.update(state);
|
|
119
|
+
// Handle external refs (identity doesn't change, only set once)
|
|
120
|
+
if (props.water.timeUniform) {
|
|
121
|
+
mutates.setTimeUniform(props.water.timeUniform);
|
|
122
|
+
}
|
|
123
|
+
if (props.water.skyEnvMapUniform) {
|
|
124
|
+
mutates.setSkyEnvMapUniform(props.water.skyEnvMapUniform);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Apply material configuration (side effect)
|
|
128
|
+
applyWaterMaterialConfig(
|
|
129
|
+
material as WaterSupportedMaterial,
|
|
130
|
+
state,
|
|
131
|
+
prevUseWater,
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
states: (): ModelWaterCombinedStates => {
|
|
137
|
+
invariant(state, "mount() must be called before states");
|
|
138
|
+
return {
|
|
139
|
+
base: baseEnhancer.states(),
|
|
140
|
+
water: state,
|
|
141
|
+
};
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
mutates: (): ModelWaterCombinedMutates => {
|
|
145
|
+
invariant(mutates, "mount() must be called before mutates");
|
|
146
|
+
return {
|
|
147
|
+
base: baseEnhancer.mutates(),
|
|
148
|
+
water: mutates,
|
|
149
|
+
};
|
|
150
|
+
},
|
|
151
|
+
|
|
152
|
+
programCacheKey: (): string => {
|
|
153
|
+
invariant(state, "mount() must be called before programCacheKey");
|
|
154
|
+
// Combine base cache key with water-specific state
|
|
155
|
+
return (
|
|
156
|
+
baseEnhancer.programCacheKey() +
|
|
157
|
+
JSON.stringify({
|
|
158
|
+
useWater: state.useWater,
|
|
159
|
+
})
|
|
160
|
+
);
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Re-export public types
|
|
166
|
+
export type {
|
|
167
|
+
ModelWaterCombinedMutates,
|
|
168
|
+
ModelWaterCombinedStates,
|
|
169
|
+
ModelWaterMutates,
|
|
170
|
+
ModelWaterOnlyProps,
|
|
171
|
+
ModelWaterProps,
|
|
172
|
+
ModelWaterState,
|
|
173
|
+
AVAILABLE_SHADERS,
|
|
174
|
+
SupportedMaterial,
|
|
175
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { MeshStandardMaterial } from "three";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
|
|
4
|
+
import { applyWaterMaterialConfig } from "./material";
|
|
5
|
+
import { DEFAULT_WATER_STATE } from "./state";
|
|
6
|
+
import type { ModelWaterState } from "./types";
|
|
7
|
+
|
|
8
|
+
describe("modelWaterEnhancer/material", () => {
|
|
9
|
+
describe("applyWaterMaterialConfig", () => {
|
|
10
|
+
it("should trigger material.needsUpdate when water flag changes", () => {
|
|
11
|
+
const material = new MeshStandardMaterial();
|
|
12
|
+
const state: ModelWaterState = {
|
|
13
|
+
...DEFAULT_WATER_STATE,
|
|
14
|
+
useWater: true,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
let needsUpdateCalled = false;
|
|
18
|
+
Object.defineProperty(material, "needsUpdate", {
|
|
19
|
+
set: (value: boolean) => {
|
|
20
|
+
if (value) needsUpdateCalled = true;
|
|
21
|
+
},
|
|
22
|
+
configurable: true,
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
applyWaterMaterialConfig(material, state, false);
|
|
26
|
+
expect(needsUpdateCalled).toBe(true);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("should not trigger material.needsUpdate when water flag stays the same", () => {
|
|
30
|
+
const material = new MeshStandardMaterial();
|
|
31
|
+
const state: ModelWaterState = {
|
|
32
|
+
...DEFAULT_WATER_STATE,
|
|
33
|
+
useWater: true,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
let needsUpdateCalled = false;
|
|
37
|
+
Object.defineProperty(material, "needsUpdate", {
|
|
38
|
+
set: (value: boolean) => {
|
|
39
|
+
if (value) needsUpdateCalled = true;
|
|
40
|
+
},
|
|
41
|
+
configurable: true,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
applyWaterMaterialConfig(material, state, true);
|
|
45
|
+
expect(needsUpdateCalled).toBe(false);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { MaterialsFromShaders, ShaderName } from "../../MaterialEnhancer";
|
|
2
|
+
|
|
3
|
+
import type { ModelWaterState } 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
|
+
* Apply water-related material configuration.
|
|
14
|
+
* Side effect function - mutates material directly.
|
|
15
|
+
*/
|
|
16
|
+
export const applyWaterMaterialConfig = (
|
|
17
|
+
material: SupportedMaterial,
|
|
18
|
+
state: ModelWaterState,
|
|
19
|
+
prevUseWater: boolean,
|
|
20
|
+
): void => {
|
|
21
|
+
// Trigger shader recompilation if water flag changed
|
|
22
|
+
if (state.useWater !== prevUseWater) {
|
|
23
|
+
material.needsUpdate = true;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { Texture } from "three";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
|
|
4
|
+
import type { ShaderUniforms } from "../../MaterialEnhancer";
|
|
5
|
+
|
|
6
|
+
import { createWaterMutates } from "./mutates";
|
|
7
|
+
import { DEFAULT_WATER_STATE } from "./state";
|
|
8
|
+
import type { ModelWaterState } from "./types";
|
|
9
|
+
|
|
10
|
+
describe("modelWaterEnhancer/mutates", () => {
|
|
11
|
+
describe("setWaterNormalMap", () => {
|
|
12
|
+
it("should set uWaterNormalMap when useWater is true", () => {
|
|
13
|
+
const mutates = createWaterMutates();
|
|
14
|
+
const mockTexture = {} as Texture;
|
|
15
|
+
const waterNormalMapUniform = { value: mockTexture };
|
|
16
|
+
const state: ModelWaterState = { ...DEFAULT_WATER_STATE, useWater: true };
|
|
17
|
+
|
|
18
|
+
mutates.setWaterNormalMap(waterNormalMapUniform, true);
|
|
19
|
+
|
|
20
|
+
const uniforms: ShaderUniforms = {};
|
|
21
|
+
mutates.updateUniforms(uniforms, state);
|
|
22
|
+
|
|
23
|
+
expect(uniforms.uWaterNormalMap?.value).toBe(mockTexture);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("should set uWaterNormalMap to null when useWater is false", () => {
|
|
27
|
+
const mutates = createWaterMutates();
|
|
28
|
+
const mockTexture = {} as Texture;
|
|
29
|
+
const waterNormalMapUniform = { value: mockTexture };
|
|
30
|
+
const state: ModelWaterState = {
|
|
31
|
+
...DEFAULT_WATER_STATE,
|
|
32
|
+
useWater: false,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
mutates.setWaterNormalMap(waterNormalMapUniform, false);
|
|
36
|
+
|
|
37
|
+
const uniforms: ShaderUniforms = {};
|
|
38
|
+
mutates.updateUniforms(uniforms, state);
|
|
39
|
+
|
|
40
|
+
expect(uniforms.uWaterNormalMap?.value).toBe(null);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
describe("update", () => {
|
|
45
|
+
it("should keep uWaterNormalMap when useWater is true", () => {
|
|
46
|
+
const mutates = createWaterMutates();
|
|
47
|
+
const mockTexture = {} as Texture;
|
|
48
|
+
const waterNormalMapUniform = { value: mockTexture };
|
|
49
|
+
|
|
50
|
+
// First set the water normal map with useWater false
|
|
51
|
+
mutates.setWaterNormalMap(waterNormalMapUniform, false);
|
|
52
|
+
|
|
53
|
+
// Then update with useWater true
|
|
54
|
+
const state: ModelWaterState = {
|
|
55
|
+
...DEFAULT_WATER_STATE,
|
|
56
|
+
useWater: true,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const uniforms: ShaderUniforms = {};
|
|
60
|
+
mutates.updateUniforms(uniforms, state);
|
|
61
|
+
|
|
62
|
+
mutates.update(state);
|
|
63
|
+
|
|
64
|
+
expect(uniforms.uWaterNormalMap?.value).toBe(mockTexture);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("should clear uWaterNormalMap when useWater becomes false", () => {
|
|
68
|
+
const mutates = createWaterMutates();
|
|
69
|
+
const mockTexture = {} as Texture;
|
|
70
|
+
const waterNormalMapUniform = { value: mockTexture };
|
|
71
|
+
|
|
72
|
+
// First set the water normal map with useWater true
|
|
73
|
+
mutates.setWaterNormalMap(waterNormalMapUniform, true);
|
|
74
|
+
|
|
75
|
+
// Then update with useWater false
|
|
76
|
+
const state: ModelWaterState = {
|
|
77
|
+
...DEFAULT_WATER_STATE,
|
|
78
|
+
useWater: false,
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const uniforms: ShaderUniforms = {};
|
|
82
|
+
mutates.updateUniforms(uniforms, state);
|
|
83
|
+
|
|
84
|
+
mutates.update(state);
|
|
85
|
+
|
|
86
|
+
expect(uniforms.uWaterNormalMap?.value).toBe(null);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
});
|