nasa-ammos / 3dtilesrendererjs Goto Github PK
View Code? Open in Web Editor NEWRenderer for 3D Tiles in Javascript using three.js
Home Page: https://nasa-ammos.github.io/3DTilesRendererJS/example/bundle/mars.html
License: Apache License 2.0
Renderer for 3D Tiles in Javascript using three.js
Home Page: https://nasa-ammos.github.io/3DTilesRendererJS/example/bundle/mars.html
License: Apache License 2.0
Right now error is calculated for every camera even if that tile isn't in the cameras frustum. Camera error should only be considered for tiles that are in that cameras frustum, though.
There should be an active tile at least always available for every part of the tile tree. It doesn't seem to be working as expected at the moment. Add a debug view for the active tiles, too.
When prioritizing the download and parsing of tiles they're sorted by 1 / depth
, meaning that coarser tiles load in first before higher detail tiles. However, when the camera is near the terrain parent tiles can have an apparent error of Infinity
because the camera is inside the bounding box meaning the tile won't render (due to the skipTraversal
phase) while its children will. However the children will always be deeper than the parent -- this means that distant tiles that are shallower will always be loaded and parsed before these children tiles which are actually closer to the camera leaving a gap in the foreground until the far tiles have resolved.
It would be best if at least these first renderable child tiles could be loaded with some priority so there isn't a gap in the terrain for so long.
Sort by 1 / distance_to_furthest_rendered_parent
Render with priority of 1
if no parent tiles are to be rendered
The issue is that this means that the priorities will now change based on camera movement and the priority queues will have to be resorted every frame.
Related to #31
It belongs in a separate object like TilesRendererHelper
:
const helper = new TilesRendererHelper( tilesRenderer );
helper.update();
This is because of the skipTraversal
step. Instead we should continue to render a parent if it was already rendered and children haven't full loaded, yet. Sort of the inverse of #29.
Unloading the LRUCache when tiles are no longer needed can wind up taking between 5 to 10ms even on a more powerful machine to unload the cache, which includes deleting data from maps and disposing of the geometry and materials.
Unload amount
The logic to calculate the amount of nodes to unload seems flawed:
3DTilesRendererJS/src/utilities/LRUCache.js
Lines 117 to 119 in 4ece3c5
Instead we should try to unload a fixed amount every frame until the unused list is emptied:
const excess = itemList.length - targetSize;
let nodesToUnload = Math.min( excess, targetSize * unloadPercent );
In this case maybe it's best to not model the unload amount as a fixed size rather than a percentage? The amount unloaded should also be reduced so we don't unload so many at once. Or maybe it should be a ratio relative to the excess in the cache?
Material key iteration
When unloading textures / materials we iterate over all keys in the material to find textures:
3DTilesRendererJS/src/three/TilesRenderer.js
Lines 431 to 446 in 4ece3c5
This is 64+ keys most of which won't have textures. It might be best to cache the textures
in a separate array on load so we don't have to iterate over so many key unnecessarily on unload.
Add a sphere helper to display where the sphere bounds are.
And whether or not it's currently visible -- fixing #29 meant that some children could display before the parent is ready but we still want to load that child before the parent.
Should this be baked into the loader? It's a big file to require people to include. Besides how does loading the draco assembly work with general build processes?
Looks like we should also set the website to scale properly and work with mobile:
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
This is likely due to parent tiles no longer meeting the errorthreshold value when zooming in. Another option could be to render the parent tile if it's loaded already and the children aren't ready yet. The complexity here is that we want to know if the children are ready recursively down to the leaf nodes, not just shallow.
1. Raycasting does not work on the root tile.
2. Depth value is not consistent
See
3DTilesRendererJS/src/three/TilesRenderer.js
Lines 413 to 430 in b9fb5f7
Shallow tiles should be unloaded last
Regions should be specified in the local frame of the group treating the group as the WGS84 coordinate frame.
Example data here.
Spec here.
More information in CesiumGS/3d-tiles#445
See example files here.
Right now every tile gets its own function created but you should be able to set it per cache object:
const cache = new LRUCache();
cache.unloadCallback = tile => {
// ...
};
Add a method to update all meshes with a custom material so the terrain can be displayed with custom shaders.
Some ideas:
tiles = new TilesRenderer( url );
tiles.forEachLoadedModel( scene => {
scene.traverse( c => {
// set the material
} );
} );
tiles.onModelLoaded = scene => {
// set the material
};
https://github.com/CesiumGS/3d-tiles-samples
It looks like the 3d tile sets at the link require a legacy version of GLTFLoader to work.
renderer
from signature and allow for providing a resolution fieldImageBitmap
includes a close
function which allows for immediately discarding of image data when it's no longer needed. We could at least call this on disposeTile if not sooner. It should not be called earlier than first render, though, because it cannot be closed before upload to GPU. If the renderer is being used in multiple WebGLRenderers then it shouldn't ever be discarded until the tile is disposed.
Specifically with first hit. See here.
New arrays and objects are created every frame to sort and iterate over
There is a set of tiles with SSE above "errorThreshold" that never gets loaded (or gets unloaded) when the camera is zoomed far into the terrain. When zooming back out though those tiles start to meet the screen space error requirements causing it to jump back to a coarse level of detail.
Current Behavior
If a tile meets the SSE requirement load and render it. Once loaded load and render all children. Only render children if they're all ready.
New Behavior
If a tile meets the SSE requirement load and render it if a child tile was not rendered the previous frame. If a child was rendered previously or if this tile is loaded then load and render all children. Only render children if they're all ready.
TODO
Places to Improve
Easiest option is to repurpose and constrain OrbitControls to achieve the first person controls.
When fly controls is enabled:
Related to #37
See example tileset here:
https://github.com/CesiumGS/3d-tiles-samples/tree/master/tilesets/TilesetWithRequestVolume
Including loader examples.
Example data for each format available here:
Requires app integration with the NASA-AMMOS project.
Right now it's expected that all cameras are rendering to the same resolution which is incorrect.
Some options:
Maintain a separate list of resolutions
const tiles = new TilesRenderer( url );
tiles.camera = camera;
tiles.resolution.set( ... );
// or
tiles.cameras = [ camera, camera, camera ];
tiles.resolutions = [ res, res, res ];
Add an API to set it:
const tiles = new TilesRenderer( url );
tiles.addCamera( camera );
tiles.setCameraResolution( camera, vec2 );
tiles.setCameraResolution( camera, renderer );
tiles.removeCamera( camera );
New functions are created for queues, caches, and promises which will create a new function with a new scope. It's best to avoid though it might not be a huge deal because it's not necessarily happening every frame. Reference:
https://stackoverflow.com/a/7451336/9838891
Possible improvements:
See https://github.com/gkjohnson/urdf-loaders for reference
Make sure the expected tiles are showing up based on the cameras frustum
The way it's being used now:
3DTilesRendererJS/src/TilesRenderer.js
Line 227 in 07f7b3b
Means that as errorTarget approaches 0 the requirement to be rendered becomes 0. However the intent is that we allow for more tiles to be rendered as the lower level ones get loaded. Maybe it should be something more like errorTarget + errorThreshold
? Or ( errorTarget + 1 ) * errorThreshold
?
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.