@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,89 @@
|
|
|
1
|
+
import type { Texture } from "three";
|
|
2
|
+
|
|
3
|
+
import type { UniformValue } from "../../../types";
|
|
4
|
+
|
|
5
|
+
import type { ModelWaterMutates, ModelWaterRefs } from "./types";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Default refs with initial values.
|
|
9
|
+
* These are cloned in createWaterMutates and synced from state via update().
|
|
10
|
+
* Note: timeUniform and tSkyEnvMap are external refs assigned via setters (identity doesn't change).
|
|
11
|
+
*/
|
|
12
|
+
const DEFAULT_WATER_REFS: Omit<ModelWaterRefs, "uTime" | "tSkyEnvMap"> = {
|
|
13
|
+
reflectivity: { value: 0 },
|
|
14
|
+
uWaterNormalMap: { value: null },
|
|
15
|
+
cachedWaterNormalMap: { value: null },
|
|
16
|
+
uWaterScaleNormal: { value: 0 },
|
|
17
|
+
uWaterSpeed: { value: 0 },
|
|
18
|
+
uShininess: { value: 0 },
|
|
19
|
+
uSpecularStrength: { value: 0 },
|
|
20
|
+
uApplyWaterNormal: { value: 0 },
|
|
21
|
+
uSpecular: { value: false },
|
|
22
|
+
uIor: { value: 1.33333 },
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Create mutation functions for the water enhancer.
|
|
27
|
+
* Refs are created internally and captured via closure.
|
|
28
|
+
*/
|
|
29
|
+
export const createWaterMutates = (): ModelWaterMutates => {
|
|
30
|
+
// Clone defaults so each enhancer instance gets independent ref objects
|
|
31
|
+
// timeUniform and tSkyEnvMap are external refs assigned via setters (identity doesn't change)
|
|
32
|
+
const refs: ModelWaterRefs = structuredClone(DEFAULT_WATER_REFS);
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
update: (state) => {
|
|
36
|
+
// Sync refs from state
|
|
37
|
+
refs.reflectivity.value = state.reflectivity;
|
|
38
|
+
refs.uWaterNormalMap.value = state.useWater
|
|
39
|
+
? refs.cachedWaterNormalMap.value
|
|
40
|
+
: null;
|
|
41
|
+
refs.uWaterScaleNormal.value = state.waterScaleNormal;
|
|
42
|
+
refs.uWaterSpeed.value = state.waterSpeed;
|
|
43
|
+
refs.uShininess.value = state.shininess;
|
|
44
|
+
refs.uSpecularStrength.value = state.specularStrength;
|
|
45
|
+
// Cast boolean to number for shader uniform
|
|
46
|
+
refs.uApplyWaterNormal.value = state.applyWaterNormal ? 1 : 0;
|
|
47
|
+
refs.uSpecular.value = state.specular;
|
|
48
|
+
refs.uIor.value = state.ior;
|
|
49
|
+
},
|
|
50
|
+
updateUniforms: (uniforms) => {
|
|
51
|
+
// Assign water uniform refs to shader.uniforms
|
|
52
|
+
uniforms.reflectivity = refs.reflectivity;
|
|
53
|
+
uniforms.uWaterNormalMap = refs.uWaterNormalMap;
|
|
54
|
+
uniforms.uWaterScaleNormal = refs.uWaterScaleNormal;
|
|
55
|
+
uniforms.uWaterSpeed = refs.uWaterSpeed;
|
|
56
|
+
uniforms.uShininess = refs.uShininess;
|
|
57
|
+
uniforms.uSpecularStrength = refs.uSpecularStrength;
|
|
58
|
+
uniforms.uApplyWaterNormal = refs.uApplyWaterNormal;
|
|
59
|
+
uniforms.uSpecular = refs.uSpecular;
|
|
60
|
+
uniforms.uIor = refs.uIor;
|
|
61
|
+
if (refs.uTime) {
|
|
62
|
+
uniforms.uTime = refs.uTime;
|
|
63
|
+
}
|
|
64
|
+
if (refs.tSkyEnvMap) {
|
|
65
|
+
uniforms.tSkyEnvMap = refs.tSkyEnvMap;
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
setWaterNormalMap: (
|
|
69
|
+
waterNormalMapUniform: UniformValue<Texture | null>,
|
|
70
|
+
useWater: boolean,
|
|
71
|
+
): void => {
|
|
72
|
+
// Assign external ref object (identity doesn't change after mount)
|
|
73
|
+
refs.cachedWaterNormalMap = waterNormalMapUniform;
|
|
74
|
+
refs.uWaterNormalMap.value = useWater
|
|
75
|
+
? refs.cachedWaterNormalMap.value
|
|
76
|
+
: null;
|
|
77
|
+
},
|
|
78
|
+
setTimeUniform: (timeUniform: UniformValue<number>): void => {
|
|
79
|
+
// Assign external ref object (identity doesn't change after mount)
|
|
80
|
+
refs.uTime = timeUniform;
|
|
81
|
+
},
|
|
82
|
+
setSkyEnvMapUniform: (
|
|
83
|
+
skyEnvMapUniform: UniformValue<Texture | null>,
|
|
84
|
+
): void => {
|
|
85
|
+
// Assign external ref object (identity doesn't change after mount)
|
|
86
|
+
refs.tSkyEnvMap = skyEnvMapUniform;
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { testShaderCompatibility } from "../../test-utils/shaderCompatibility";
|
|
2
|
+
import {
|
|
3
|
+
MODEL_BASE_SHADER_MARKERS,
|
|
4
|
+
createModelBaseEnhancer,
|
|
5
|
+
} from "../modelBaseEnhancer";
|
|
6
|
+
|
|
7
|
+
import { createModelWaterEnhancer, type SupportedMaterial } from ".";
|
|
8
|
+
|
|
9
|
+
testShaderCompatibility(
|
|
10
|
+
"modelWaterEnhancer",
|
|
11
|
+
(material) =>
|
|
12
|
+
createModelWaterEnhancer(
|
|
13
|
+
createModelBaseEnhancer(material as SupportedMaterial),
|
|
14
|
+
),
|
|
15
|
+
[
|
|
16
|
+
{
|
|
17
|
+
name: "With water",
|
|
18
|
+
props: {
|
|
19
|
+
water: {
|
|
20
|
+
water: true,
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: "Without water",
|
|
26
|
+
props: {
|
|
27
|
+
water: {
|
|
28
|
+
water: false,
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
MODEL_BASE_SHADER_MARKERS,
|
|
34
|
+
);
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import WaterParsFragment from "@shaders/glsl/chunks/water_pars_fragment.glsl?raw";
|
|
2
|
+
import type { WebGLProgramParametersWithUniforms } from "three";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
MODEL_BASE_SHADER_MARKERS,
|
|
6
|
+
createModelBaseShaderReplacer,
|
|
7
|
+
} from "../modelBaseEnhancer/markers";
|
|
8
|
+
|
|
9
|
+
import type { ModelWaterMutates, ModelWaterState } from "./types";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Transform shader with water-specific modifications.
|
|
13
|
+
* Uniform assignment is handled by mutates.updateUniforms().
|
|
14
|
+
*/
|
|
15
|
+
export const transformWaterShader = (
|
|
16
|
+
shader: WebGLProgramParametersWithUniforms,
|
|
17
|
+
state: ModelWaterState,
|
|
18
|
+
mutates: ModelWaterMutates,
|
|
19
|
+
): void => {
|
|
20
|
+
const { useWater } = state;
|
|
21
|
+
|
|
22
|
+
// Derive shader defines from semantic state flags
|
|
23
|
+
shader.defines ??= {};
|
|
24
|
+
if (useWater) {
|
|
25
|
+
shader.defines.WATER = 1;
|
|
26
|
+
if (state.skyEnvMap) {
|
|
27
|
+
shader.defines.USE_SKY_ENVMAP = "1";
|
|
28
|
+
}
|
|
29
|
+
} else {
|
|
30
|
+
delete shader.defines.WATER;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Assign water uniform refs to shader.uniforms via mutates
|
|
34
|
+
mutates.updateUniforms(shader.uniforms, state);
|
|
35
|
+
|
|
36
|
+
// Insert WaterParsFragment before the computeSpecular function (non-marker-based)
|
|
37
|
+
const computeSpecularMarker = "vec3 computeSpecular(";
|
|
38
|
+
const specularIdx = shader.fragmentShader.indexOf(computeSpecularMarker);
|
|
39
|
+
if (specularIdx !== -1) {
|
|
40
|
+
const beforeSpecular = shader.fragmentShader.substring(0, specularIdx);
|
|
41
|
+
const afterSpecular = shader.fragmentShader.substring(specularIdx);
|
|
42
|
+
shader.fragmentShader =
|
|
43
|
+
beforeSpecular + WaterParsFragment + "\n\n" + afterSpecular;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
shader.fragmentShader = createModelBaseShaderReplacer(shader.fragmentShader)
|
|
47
|
+
// Add water uniform declarations after base's UNIFORM_END
|
|
48
|
+
.insertAfter(
|
|
49
|
+
MODEL_BASE_SHADER_MARKERS.fragment.UNIFORM_END,
|
|
50
|
+
`uniform sampler2D uWaterNormalMap;
|
|
51
|
+
uniform samplerCube tSkyEnvMap;
|
|
52
|
+
uniform float uWaterScaleNormal;
|
|
53
|
+
uniform float uWaterSpeed;
|
|
54
|
+
uniform float uShininess;
|
|
55
|
+
uniform float uSpecularStrength;
|
|
56
|
+
uniform float uApplyWaterNormal;
|
|
57
|
+
uniform bool uSpecular;
|
|
58
|
+
uniform float uIor;
|
|
59
|
+
uniform float uTime;`,
|
|
60
|
+
)
|
|
61
|
+
// Replace normal block with water/non-water specular computation
|
|
62
|
+
.replaceBlock(
|
|
63
|
+
{
|
|
64
|
+
start: MODEL_BASE_SHADER_MARKERS.fragment.NORMAL_START,
|
|
65
|
+
end: MODEL_BASE_SHADER_MARKERS.fragment.NORMAL_END,
|
|
66
|
+
},
|
|
67
|
+
`vec3 origNormal = normal;
|
|
68
|
+
vec3 specular;
|
|
69
|
+
|
|
70
|
+
#ifdef WATER
|
|
71
|
+
specular = computeWaterSpecularSimple(
|
|
72
|
+
uWaterNormalMap,
|
|
73
|
+
vPosition.xy * uWaterScaleNormal,
|
|
74
|
+
uTime * uWaterSpeed,
|
|
75
|
+
vViewPosition,
|
|
76
|
+
uShininess,
|
|
77
|
+
uSpecularStrength,
|
|
78
|
+
diffuseColor.rgb,
|
|
79
|
+
normal
|
|
80
|
+
);
|
|
81
|
+
#else
|
|
82
|
+
if(uSpecular) {
|
|
83
|
+
specular = computeSpecular(
|
|
84
|
+
vViewPosition,
|
|
85
|
+
origNormal,
|
|
86
|
+
uShininess,
|
|
87
|
+
uSpecularStrength,
|
|
88
|
+
uIor
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
#include <normal_fragment_maps>
|
|
92
|
+
#endif`,
|
|
93
|
+
)
|
|
94
|
+
// Replace outgoing light block with env map + specular
|
|
95
|
+
.insertAfter(
|
|
96
|
+
MODEL_BASE_SHADER_MARKERS.fragment.OUTGOING_LIGHT_END,
|
|
97
|
+
`#if defined(WATER) && defined(USE_SKY_ENVMAP)
|
|
98
|
+
vec3 envColor = getSkyEnv(geometryNormal, tSkyEnvMap, vPosition);
|
|
99
|
+
outgoingLight += envColor * reflectivity;
|
|
100
|
+
#endif
|
|
101
|
+
outgoingLight += specular;`,
|
|
102
|
+
)
|
|
103
|
+
// Replace final normal block with water normal mixing
|
|
104
|
+
.replaceBlock(
|
|
105
|
+
{
|
|
106
|
+
start: MODEL_BASE_SHADER_MARKERS.fragment.FINAL_NORMAL_START,
|
|
107
|
+
end: MODEL_BASE_SHADER_MARKERS.fragment.FINAL_NORMAL_END,
|
|
108
|
+
},
|
|
109
|
+
`vec3 finalNormal = mix(origNormal, normalize(origNormal * 0.7 + normal), uApplyWaterNormal);`,
|
|
110
|
+
).source;
|
|
111
|
+
};
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { Texture } from "three";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
|
|
4
|
+
import { DEFAULT_WATER_STATE, updateWaterState } from "./state";
|
|
5
|
+
import type { ModelWaterState } from "./types";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Helper to create expected water state by merging with defaults.
|
|
9
|
+
*/
|
|
10
|
+
const createExpectedState = (
|
|
11
|
+
overrides: Partial<ModelWaterState> = {},
|
|
12
|
+
): ModelWaterState => ({
|
|
13
|
+
...DEFAULT_WATER_STATE,
|
|
14
|
+
...overrides,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
describe("modelWaterEnhancer/state", () => {
|
|
18
|
+
describe("updateWaterState", () => {
|
|
19
|
+
it("returns default state when given empty props", () => {
|
|
20
|
+
const result = updateWaterState({}, DEFAULT_WATER_STATE);
|
|
21
|
+
expect(result).toEqual(createExpectedState());
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("applies all props", () => {
|
|
25
|
+
const mockSkyEnvMap = new Texture();
|
|
26
|
+
|
|
27
|
+
const result = updateWaterState(
|
|
28
|
+
{
|
|
29
|
+
water: true,
|
|
30
|
+
waterScaleNormal: 0.5,
|
|
31
|
+
waterSpeed: 1.0,
|
|
32
|
+
shininess: 30,
|
|
33
|
+
specularStrength: 0.8,
|
|
34
|
+
applyWaterNormal: true,
|
|
35
|
+
specular: true,
|
|
36
|
+
ior: 1.5,
|
|
37
|
+
reflectivity: 0.6,
|
|
38
|
+
skyEnvMap: mockSkyEnvMap,
|
|
39
|
+
},
|
|
40
|
+
DEFAULT_WATER_STATE,
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
expect(result).toEqual(
|
|
44
|
+
createExpectedState({
|
|
45
|
+
useWater: true,
|
|
46
|
+
waterScaleNormal: 0.5,
|
|
47
|
+
waterSpeed: 1.0,
|
|
48
|
+
shininess: 30,
|
|
49
|
+
specularStrength: 0.8,
|
|
50
|
+
applyWaterNormal: true,
|
|
51
|
+
specular: true,
|
|
52
|
+
ior: 1.5,
|
|
53
|
+
reflectivity: 0.6,
|
|
54
|
+
skyEnvMap: mockSkyEnvMap,
|
|
55
|
+
}),
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("falls back to currentState for missing props", () => {
|
|
60
|
+
const currentState: ModelWaterState = {
|
|
61
|
+
...DEFAULT_WATER_STATE,
|
|
62
|
+
useWater: true,
|
|
63
|
+
waterScaleNormal: 0.3,
|
|
64
|
+
shininess: 25,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const result = updateWaterState({ waterSpeed: 5.0 }, currentState);
|
|
68
|
+
|
|
69
|
+
expect(result.useWater).toBe(true);
|
|
70
|
+
expect(result.waterScaleNormal).toBe(0.3);
|
|
71
|
+
expect(result.shininess).toBe(25);
|
|
72
|
+
expect(result.waterSpeed).toBe(5.0);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it("keeps applyWaterNormal as boolean in state", () => {
|
|
76
|
+
// Boolean values stay as boolean in state (cast to number only in refs)
|
|
77
|
+
const result1 = updateWaterState(
|
|
78
|
+
{ applyWaterNormal: true },
|
|
79
|
+
DEFAULT_WATER_STATE,
|
|
80
|
+
);
|
|
81
|
+
expect(result1.applyWaterNormal).toBe(true);
|
|
82
|
+
|
|
83
|
+
const result2 = updateWaterState(
|
|
84
|
+
{ applyWaterNormal: false },
|
|
85
|
+
DEFAULT_WATER_STATE,
|
|
86
|
+
);
|
|
87
|
+
expect(result2.applyWaterNormal).toBe(false);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it("converts numeric applyWaterNormal to boolean (truthy check)", () => {
|
|
91
|
+
// Numeric values are converted to boolean via !!
|
|
92
|
+
const result1 = updateWaterState(
|
|
93
|
+
{ applyWaterNormal: 0.5 },
|
|
94
|
+
DEFAULT_WATER_STATE,
|
|
95
|
+
);
|
|
96
|
+
expect(result1.applyWaterNormal).toBe(true); // truthy → true
|
|
97
|
+
|
|
98
|
+
const result2 = updateWaterState(
|
|
99
|
+
{ applyWaterNormal: 0 },
|
|
100
|
+
DEFAULT_WATER_STATE,
|
|
101
|
+
);
|
|
102
|
+
expect(result2.applyWaterNormal).toBe(false); // falsy → false
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
});
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { ModelWaterOnlyProps, ModelWaterState } from "./types";
|
|
2
|
+
|
|
3
|
+
export const DEFAULT_WATER_PROPS: Required<ModelWaterOnlyProps> = {
|
|
4
|
+
water: false,
|
|
5
|
+
waterScaleNormal: 0,
|
|
6
|
+
waterSpeed: 0,
|
|
7
|
+
shininess: 0,
|
|
8
|
+
specularStrength: 0,
|
|
9
|
+
applyWaterNormal: false,
|
|
10
|
+
specular: false,
|
|
11
|
+
ior: 1.33333,
|
|
12
|
+
reflectivity: 0,
|
|
13
|
+
skyEnvMap: null,
|
|
14
|
+
waterNormalMap: { value: null },
|
|
15
|
+
timeUniform: { value: 0 },
|
|
16
|
+
skyEnvMapUniform: { value: null },
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/** Default state derived from DEFAULT_WATER_PROPS */
|
|
20
|
+
export const DEFAULT_WATER_STATE: ModelWaterState = {
|
|
21
|
+
useWater: DEFAULT_WATER_PROPS.water,
|
|
22
|
+
skyEnvMap: DEFAULT_WATER_PROPS.skyEnvMap,
|
|
23
|
+
reflectivity: DEFAULT_WATER_PROPS.reflectivity,
|
|
24
|
+
waterScaleNormal: DEFAULT_WATER_PROPS.waterScaleNormal,
|
|
25
|
+
waterSpeed: DEFAULT_WATER_PROPS.waterSpeed,
|
|
26
|
+
shininess: DEFAULT_WATER_PROPS.shininess,
|
|
27
|
+
specularStrength: DEFAULT_WATER_PROPS.specularStrength,
|
|
28
|
+
applyWaterNormal: !!DEFAULT_WATER_PROPS.applyWaterNormal,
|
|
29
|
+
specular: DEFAULT_WATER_PROPS.specular,
|
|
30
|
+
ior: DEFAULT_WATER_PROPS.ior,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Update immutable state from props.
|
|
35
|
+
* Props override currentState values; missing props fall back to currentState.
|
|
36
|
+
* Pass DEFAULT_WATER_STATE as currentState for initial mount.
|
|
37
|
+
*
|
|
38
|
+
* @param props - The props to apply
|
|
39
|
+
* @param currentState - The current state to use as fallback (use DEFAULT_WATER_STATE for mount)
|
|
40
|
+
*/
|
|
41
|
+
export const updateWaterState = (
|
|
42
|
+
props: ModelWaterOnlyProps,
|
|
43
|
+
currentState: ModelWaterState,
|
|
44
|
+
): ModelWaterState => ({
|
|
45
|
+
useWater: props.water ?? currentState.useWater,
|
|
46
|
+
skyEnvMap: props.skyEnvMap ?? currentState.skyEnvMap,
|
|
47
|
+
reflectivity: props.reflectivity ?? currentState.reflectivity,
|
|
48
|
+
waterScaleNormal: props.waterScaleNormal ?? currentState.waterScaleNormal,
|
|
49
|
+
waterSpeed: props.waterSpeed ?? currentState.waterSpeed,
|
|
50
|
+
shininess: props.shininess ?? currentState.shininess,
|
|
51
|
+
specularStrength: props.specularStrength ?? currentState.specularStrength,
|
|
52
|
+
// Keep boolean in state - cast to number only in refs
|
|
53
|
+
applyWaterNormal:
|
|
54
|
+
props.applyWaterNormal !== undefined
|
|
55
|
+
? !!props.applyWaterNormal
|
|
56
|
+
: currentState.applyWaterNormal,
|
|
57
|
+
specular: props.specular ?? currentState.specular,
|
|
58
|
+
ior: props.ior ?? currentState.ior,
|
|
59
|
+
});
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import type { Texture } from "three";
|
|
2
|
+
|
|
3
|
+
import type { UniformValue } from "../../../types";
|
|
4
|
+
import type { Mutates } from "../../MaterialEnhancer";
|
|
5
|
+
import type {
|
|
6
|
+
ModelBaseMutates,
|
|
7
|
+
ModelBaseProps,
|
|
8
|
+
ModelBaseState,
|
|
9
|
+
} from "../modelBaseEnhancer";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Water-only props (excluding base props).
|
|
13
|
+
*/
|
|
14
|
+
export type ModelWaterOnlyProps = {
|
|
15
|
+
water?: boolean;
|
|
16
|
+
waterScaleNormal?: number;
|
|
17
|
+
waterSpeed?: number;
|
|
18
|
+
shininess?: number;
|
|
19
|
+
specularStrength?: number;
|
|
20
|
+
applyWaterNormal?: number | boolean;
|
|
21
|
+
specular?: boolean;
|
|
22
|
+
ior?: number;
|
|
23
|
+
reflectivity?: number;
|
|
24
|
+
|
|
25
|
+
// Sky environment map texture value
|
|
26
|
+
skyEnvMap?: Texture | null;
|
|
27
|
+
|
|
28
|
+
// Water normal map texture (value-based, not ref-based)
|
|
29
|
+
// This ref identity doesn't change, so we assign the ref object itself
|
|
30
|
+
waterNormalMap?: UniformValue<Texture | null>;
|
|
31
|
+
|
|
32
|
+
// External uniform ref (ref-based, shared with CommonUniforms)
|
|
33
|
+
// This ref identity doesn't change, so we assign the ref object itself
|
|
34
|
+
timeUniform?: UniformValue<number>;
|
|
35
|
+
|
|
36
|
+
// External uniform ref for sky env map cubemap
|
|
37
|
+
skyEnvMapUniform?: UniformValue<Texture | null>;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Combined props for the model water enhancer.
|
|
42
|
+
* Props are explicitly separated into base and water sections for clarity.
|
|
43
|
+
*/
|
|
44
|
+
export type ModelWaterProps = {
|
|
45
|
+
base?: ModelBaseProps;
|
|
46
|
+
water?: ModelWaterOnlyProps;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Immutable state for the water enhancer.
|
|
51
|
+
* This state is always replaced as a whole (never mutated).
|
|
52
|
+
* Returned directly via states() - refresh after updates.
|
|
53
|
+
*/
|
|
54
|
+
export type ModelWaterState = Readonly<{
|
|
55
|
+
useWater: boolean;
|
|
56
|
+
skyEnvMap: Texture | null;
|
|
57
|
+
reflectivity: number;
|
|
58
|
+
waterScaleNormal: number;
|
|
59
|
+
waterSpeed: number;
|
|
60
|
+
shininess: number;
|
|
61
|
+
specularStrength: number;
|
|
62
|
+
applyWaterNormal: boolean;
|
|
63
|
+
specular: boolean;
|
|
64
|
+
ior: number;
|
|
65
|
+
}>;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Combined state for the model water enhancer.
|
|
69
|
+
* Includes both base state and water-specific state.
|
|
70
|
+
*/
|
|
71
|
+
export type ModelWaterCombinedStates = {
|
|
72
|
+
readonly base: ModelBaseState;
|
|
73
|
+
readonly water: ModelWaterState;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Combined mutation functions for the model water enhancer.
|
|
78
|
+
*/
|
|
79
|
+
export type ModelWaterCombinedMutates = {
|
|
80
|
+
readonly base: ModelBaseMutates;
|
|
81
|
+
readonly water: ModelWaterMutates;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Mutable references (uniforms) for the water enhancer.
|
|
86
|
+
*
|
|
87
|
+
* These are shared references with shader.uniforms and can be mutated directly
|
|
88
|
+
* for efficient GPU uniform updates without shader recompilation.
|
|
89
|
+
* Internal type - not exposed externally.
|
|
90
|
+
*/
|
|
91
|
+
export type ModelWaterRefs = {
|
|
92
|
+
// Internal refs (value-based updates)
|
|
93
|
+
reflectivity: UniformValue<number>;
|
|
94
|
+
uWaterNormalMap: UniformValue<Texture | null>;
|
|
95
|
+
cachedWaterNormalMap: UniformValue<Texture | null>;
|
|
96
|
+
uWaterScaleNormal: UniformValue<number>;
|
|
97
|
+
uWaterSpeed: UniformValue<number>;
|
|
98
|
+
uShininess: UniformValue<number>;
|
|
99
|
+
uSpecularStrength: UniformValue<number>;
|
|
100
|
+
uApplyWaterNormal: UniformValue<number>;
|
|
101
|
+
uSpecular: UniformValue<boolean>;
|
|
102
|
+
uIor: UniformValue<number>;
|
|
103
|
+
|
|
104
|
+
// External uniform refs (assigned as ref object, identity doesn't change)
|
|
105
|
+
uTime?: UniformValue<number>;
|
|
106
|
+
tSkyEnvMap?: UniformValue<Texture | null>;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
export type ModelWaterUniforms = Partial<
|
|
110
|
+
Omit<ModelWaterRefs, "cachedWaterNormalMap">
|
|
111
|
+
>;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Mutation functions for the water enhancer (internal only).
|
|
115
|
+
*/
|
|
116
|
+
export type ModelWaterMutates = Mutates<
|
|
117
|
+
ModelWaterState,
|
|
118
|
+
ModelWaterUniforms,
|
|
119
|
+
{
|
|
120
|
+
/**
|
|
121
|
+
* Set the water normal map uniform ref.
|
|
122
|
+
* Assigns the external ref object (identity doesn't change after mount).
|
|
123
|
+
*/
|
|
124
|
+
setWaterNormalMap: (
|
|
125
|
+
waterNormalMapUniform: UniformValue<Texture | null>,
|
|
126
|
+
useWater: boolean,
|
|
127
|
+
) => void;
|
|
128
|
+
/**
|
|
129
|
+
* Set the time uniform ref.
|
|
130
|
+
* Assigns the external ref object (identity doesn't change after mount).
|
|
131
|
+
*/
|
|
132
|
+
setTimeUniform: (timeUniform: UniformValue<number>) => void;
|
|
133
|
+
/**
|
|
134
|
+
* Set the sky env map uniform ref.
|
|
135
|
+
* Assigns the external ref object (identity doesn't change after mount).
|
|
136
|
+
*/
|
|
137
|
+
setSkyEnvMapUniform: (
|
|
138
|
+
skyEnvMapUniform: UniformValue<Texture | null>,
|
|
139
|
+
) => void;
|
|
140
|
+
}
|
|
141
|
+
>;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { PointsMaterial } from "three";
|
|
2
|
+
import { beforeEach, describe, expect, it } from "vitest";
|
|
3
|
+
|
|
4
|
+
import { createPntsEnhancer } from ".";
|
|
5
|
+
|
|
6
|
+
describe("pntsEnhancer", () => {
|
|
7
|
+
let enhancer: ReturnType<typeof createPntsEnhancer>;
|
|
8
|
+
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
enhancer = createPntsEnhancer(new PointsMaterial());
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
describe("lifecycle", () => {
|
|
14
|
+
it("states() should throw if called before mount", () => {
|
|
15
|
+
const freshEnhancer = createPntsEnhancer(new PointsMaterial());
|
|
16
|
+
expect(() => freshEnhancer.states()).toThrow(
|
|
17
|
+
"mount() must be called before states",
|
|
18
|
+
);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it("mutates() should throw if called before mount", () => {
|
|
22
|
+
const freshEnhancer = createPntsEnhancer(new PointsMaterial());
|
|
23
|
+
expect(() => freshEnhancer.mutates()).toThrow(
|
|
24
|
+
"mount() must be called before mutates",
|
|
25
|
+
);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("update() should throw if called before mount", () => {
|
|
29
|
+
const freshEnhancer = createPntsEnhancer(new PointsMaterial());
|
|
30
|
+
expect(() => freshEnhancer.update({})).toThrow(
|
|
31
|
+
"mount() must be called before update",
|
|
32
|
+
);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
describe("mount", () => {
|
|
37
|
+
it("should initialize state with provided props", () => {
|
|
38
|
+
enhancer.mount({
|
|
39
|
+
height: 100,
|
|
40
|
+
geodeticNormal: { x: 0.1, y: 0.2, z: 0.3 },
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const state = enhancer.states();
|
|
44
|
+
expect(state.height).toBe(100);
|
|
45
|
+
expect(state.geodeticNormal).toEqual({ x: 0.1, y: 0.2, z: 0.3 });
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("should use defaults for missing props", () => {
|
|
49
|
+
enhancer.mount({});
|
|
50
|
+
|
|
51
|
+
const state = enhancer.states();
|
|
52
|
+
expect(state.height).toBe(0);
|
|
53
|
+
expect(state.geodeticNormal).toEqual({ x: 0, y: 0, z: 0 });
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe("update", () => {
|
|
58
|
+
it("should update state with new props", () => {
|
|
59
|
+
enhancer.mount({ height: 50 });
|
|
60
|
+
enhancer.update({ height: 200 });
|
|
61
|
+
|
|
62
|
+
const state = enhancer.states();
|
|
63
|
+
expect(state.height).toBe(200);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("should preserve state for missing props", () => {
|
|
67
|
+
enhancer.mount({
|
|
68
|
+
height: 100,
|
|
69
|
+
geodeticNormal: { x: 1, y: 0, z: 0 },
|
|
70
|
+
});
|
|
71
|
+
enhancer.update({ height: 200 });
|
|
72
|
+
|
|
73
|
+
const state = enhancer.states();
|
|
74
|
+
expect(state.height).toBe(200);
|
|
75
|
+
expect(state.geodeticNormal).toEqual({ x: 1, y: 0, z: 0 });
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe("programCacheKey", () => {
|
|
80
|
+
it("should return empty string (no shader-affecting state)", () => {
|
|
81
|
+
enhancer.mount({});
|
|
82
|
+
expect(enhancer.programCacheKey()).toBe("");
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("should return same key regardless of state", () => {
|
|
86
|
+
enhancer.mount({ height: 100 });
|
|
87
|
+
const key1 = enhancer.programCacheKey();
|
|
88
|
+
|
|
89
|
+
const enhancer2 = createPntsEnhancer(new PointsMaterial());
|
|
90
|
+
enhancer2.mount({ height: 200 });
|
|
91
|
+
const key2 = enhancer2.programCacheKey();
|
|
92
|
+
|
|
93
|
+
expect(key1).toBe(key2);
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
});
|