davenquinn / cesium-martini Goto Github PK
View Code? Open in Web Editor NEWOn-the-fly meshing of raster elevation tiles for the CesiumJS virtual globe
License: MIT License
On-the-fly meshing of raster elevation tiles for the CesiumJS virtual globe
License: MIT License
@davenquinn In your post:
https://community.cesium.com/t/hillshade-using-cesium-terrain/9590/2
you mention that you were able to generate client-side hillshade using Terrain RGB tiles.
I'm trying to do the same thing you are, but in my case I'd like to generate both a hillshare and also a high-res slope rendering from the rgb tiles. From your post I gather that you created a custom Cesium ImageryProvider and did not do it in the cesium-martini code. Is that effort something you have open sourced (I can't find it in your repo list) or plan on doing so at some point? If not, I would be so thankful if you could point me in the right direction as to what it took for you to code this?
Thank you!
-Martin
Cesium's requestRenderMode
is an opt-in that dramatically reduces CPU use when viewing static content. This usually works just fine, but when this TerrainProvider is enabled, it is broken for some reason, and Cesium targets 60 fps in all cases. This can be seen by toggling requestRenderMode
in the examples.
This terrain provider should provide support for upsampling tiles to use the maximum resolution of high-scale data. This could be rendered as a standalone tile cache, using Cesium's built-in utilities, or sharing a backend with Maplibre GL JS. The latter could potentially allow efficient cooperation between this layer and hillshading utilities.
One major element of this terrain provider that is lacking currently is the fact that there are enormous holes at the poles. This is true of all tiled terrain providers from Cesium that use the web mercator tiling scheme. Cesium's own CesiumTerrainProvider
does not suffer from this issue, because tiles extend to the poles. We need to figure out how to add caps to the globe in order to make low zooms not look jarring. One possibility would be to just extend the northernmost tile to the pole. I think imagery would stretch atop it to make the globe look relatively seamless.
When trying to include @macrostrat/cesium-martini
in a bare bones Vite project the following error occurs:
browser-external:path:9 Module "path" has been externalized for browser compatibility. Cannot access "path.join" in client code.
get @ browser-external:path:9
18:12:23.384 index.cjs:14 Uncaught ReferenceError: __dirname is not defined
at node_modules/cesium/index.cjs (index.cjs:14:3)
at __require2 (chunk-7FP5O474.js?v=6ac06d1a:10:50)
at node_modules/@macrostrat/cesium-martini/dist/index.js (index.cjs:16:1)
at __require2 (chunk-7FP5O474.js?v=6ac06d1a:10:50)
at dep:@macrostrat_cesium-martini:1:16
You can see this in a very basic repro here (check your browser's dev console):
https://stackblitz.com/edit/vitejs-vite-pqnxx6?file=package.json,src%2FApp.jsx&terminal=dev
By hacking the cesium module to import the cesium module directly to bypass the error (import cesium using cesium/Build/Cesium/Cesium
instead of cesium
), then I see this error:
Uncaught ReferenceError: regeneratorRuntime is not defined
at worker-farm.ts:52:3
at worker-farm.ts:52:3
at node_modules/@macrostrat/cesium-martini/dist/index.js (worker-farm.ts:52:3)
at __require2 (chunk-7FP5O474.js?v=4361fb93:10:50)
at dep:@macrostrat_cesium-martini:1:16
It seems like I can workaround that with this - yarn add -D regenerator-runtime
then:
import 'regenerator-runtime/runtime';
// import cesium-martini module here
note: using the @vitejs/plugin-legacy
didn't appear to work
I think this can be resolved by adding @babel/plugin-transform-runtime
to your project's babelrc
Requests are not appropriately canceled when executing large movements, leading to a lot of effort spent loading tiles that are no longer relevant. This may just be a networking issue, but it's quite noticeable on slower networks.
@davenquinn We've been happily updating Cesium versions, and cesium-martini happily run against all the versions until two weeks ago, when cesium 1.104.0 came out.
Seems like Cesium finally made a breaking change. The errors below come from running the commands below on a clean pull from this git repo. Do you have any immediate insights from the errors that might help address cesium breaking backwards compatibility for cesium-martini? Your library has been crucial for our development, as I'm sure it's been for many others.
Note: The example UI in this repo actually stopped working on Cesium v 0.97.0, but our application kept working with with the dist files of cesium-martini compiled with Cesium 0.97. That is, when we used your library compiled against 0.97.0 we could keep updating Cesium in our application (up to 0.103.0 - we can't move to 0.104.0 regardless how we compile cesium-martini now).
Errors when we run:
rm -rf node_modules;npm install; npm run build; npm run dev
are:
ERROR in ./node_modules/@cesium/engine/Source/Scene/Model/B3dmLoader.js 142:30
Module parse failed: Unexpected token (142:30)
File was processed with these loaders:
* ./node_modules/source-map-loader/index.js
You may need an additional loader to handle the result of these loaders.
| texturesLoaded: {
| get: function () {
> return this._gltfLoader?.texturesLoaded;
| },
| },
@ ./node_modules/@cesium/engine/index.js 925:0-75 925:0-75
@ ./node_modules/cesium/Source/Cesium.js
@ ./examples/simple/index.ts
ERROR in ./node_modules/@cesium/engine/Source/Scene/Model/I3dmLoader.js 150:30
Module parse failed: Unexpected token (150:30)
File was processed with these loaders:
* ./node_modules/source-map-loader/index.js
You may need an additional loader to handle the result of these loaders.
| texturesLoaded: {
| get: function () {
> return this._gltfLoader?.texturesLoaded;
| },
| },
@ ./node_modules/@cesium/engine/index.js 938:0-75 938:0-75
@ ./node_modules/cesium/Source/Cesium.js
@ ./examples/simple/index.ts
ERROR in ./node_modules/@cesium/engine/Source/DataSources/ModelVisualizer.js 161:28
Module parse failed: Unexpected token (161:28)
File was processed with these loaders:
* ./node_modules/source-map-loader/index.js
You may need an additional loader to handle the result of these loaders.
|
| if (!defined(modelData) || resource.url !== modelData.url) {
> if (defined(modelData?.modelPrimitive)) {
| primitives.removeAndDestroy(modelData.modelPrimitive);
| delete modelHash[entity.id];
@ ./node_modules/@cesium/engine/index.js 97:0-85 97:0-85
@ ./node_modules/cesium/Source/Cesium.js
@ ./examples/simple/index.ts
ERROR in ./node_modules/@cesium/engine/Source/Scene/Cesium3DTilesVoxelProvider.js 438:37
Module parse failed: Unexpected token (438:37)
File was processed with these loaders:
* ./node_modules/source-map-loader/index.js
You may need an additional loader to handle the result of these loaders.
| function addAttributeInfo(provider, metadata, className) {
| const { schema, statistics } = metadata;
> const classStatistics = statistics?.classes[className];
| const properties = schema.classes[className].properties;
|
@ ./node_modules/@cesium/engine/index.js 518:0-101 518:0-101
@ ./node_modules/cesium/Source/Cesium.js
@ ./examples/simple/index.ts
ERROR in ./node_modules/@cesium/engine/Source/Scene/Model/MetadataPipelineStage.js 86:29
Module parse failed: Unexpected token (86:29)
File was processed with these loaders:
* ./node_modules/source-map-loader/index.js
You may need an additional loader to handle the result of these loaders.
| const { shaderBuilder, model } = renderResources;
| const { structuralMetadata = {}, content } = model;
> const statistics = content?.tileset.metadataExtension?.statistics;
|
| const propertyAttributesInfo = getPropertyAttributesInfo(
@ ./node_modules/@cesium/engine/index.js 944:0-97 944:0-97
@ ./node_modules/cesium/Source/Cesium.js
@ ./examples/simple/index.ts
Hello I tried to use this library but I am receiving this error in the browser. How could I fix?
index.cjs:14 Uncaught ReferenceError: __dirname is not defined
at node_modules/@macrostrat/cesium-martini/node_modules/cesium/index.cjs (index.cjs:14:3)
at __require2 (chunk-OZI5HTJH.js?v=df6a9d37:15:50)
at node_modules/@macrostrat/cesium-martini/dist/index.js (index.cjs:16:2)
at __require2 (chunk-OZI5HTJH.js?v=df6a9d37:15:50)
at terrain-provider.ts:315:52
Tiles at low zoom levels must to respond to the curvature of the Earth, while their minimal scaled topographic range often yields only two triangles covering the entire tile. For zoom levels less than 5, we currently fall back to a basic height field, but we should ideally have a method that subdivides triangles to densify the mesh to a certain threshold size.
First as a little background, I've been working on some similar terrain projects with deck.gl a 3D-capable geospatial rendering engine, which now has support for extruded terrain. I've found that using Martini to generate the mesh client-side has good, but not necessarily great, performance. So I'm testing out an alternative approach: to run Martini and generate a Quantized Mesh format in a serverless function in AWS Lambda. This should be fast and relatively cheap, maybe ~$10 per million tile requests.
Regardless, I'm tackling essentially the same problem you are: running Martini and generating a Quantized Mesh-compliant tile, just that I'm doing it in Node and you're doing it client side. My WIP Quantized Mesh encoder and the WIP lambda function to take a heightmap, run Martini on it, and then encode into quantized mesh.
A few notes:
BoundingSphere
, HorizonOcclusionPoint
cesium-martini/src/terrain-provider.ts
Lines 152 to 162 in be4c1e9
I think these might be wrong. First, the BoundingSphere
is the minimal bounding sphere of the tile not of the earth. It's used to prevent rendering unnecessary tiles. Second, the HorizonOcclusionPoint
is defined as a point where if the point is not visible, then no portion of the tile is visible. Here's an image from Cesium; P
is the horizon occlusion point, which by definition must be "above" the tile in 3D space.
cesium-martini/src/terrain-provider.ts
Lines 204 to 209 in be4c1e9
Why inside the if
block? This seems like an ideal way to create the bounding sphere for all tiles.
A couple helpful references if you haven't seen them:
Free Terrarium heightmap tiles
You're currently pulling Mapbox's Terrain RGB tiles, but you can also use AWS Terrain Tiles for free. Just note that they use a different encoding.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.