Vector data: polygons, polylines, and billboards/labels.
For now just a placeholder to gather reading material. More to come.
Last link seems broken, here is the paper http://wscg.zcu.cz/WSCG2007/Papers_2007/journal/B17-full.pdf
And a review here http://vterrain.org/Misc/draping.html
@bagnell can you evaluate volume decals as an approach for polygons/polylines on terrain? Think about performance and precision.
I don't know how to make it fast for polygons; it needs either a convex decomposition (not necessarily as fine-grained as triangulation) or a per-pixel point-in-polygon test (which, if done with a 2D texture of the polygon would have all the drawbacks of just rasterizing a texture as an image layer).
@bagnell here are some notes for the shadow volume approach:
Notes from our discussion on billboards/labels:
x number of labels and not depth test them. This allows us to see labels through terrain, buildings, etc.Also, I expect screen-space approaches (shadow volume, decal, etc.) to be much better for runtime editing than texture and sub-sampling approaches (sub-sampling may be OK, but I expect re-rasterizing the texture, especially if we made a sparse quadtree out of it, would be painfully slow).
Query height from terrain provider.
I'm not sure what the implementation looks like now, but we can do much better than brute force look at each triangle. We can assume the triangle last used will be used next, and also use adjacency information (pre-compute once on the client I guess, or as a quantized-mesh extension) or a quad-tree arrangement inside the tile to find the right triangle.
Have callback for when it refines. Entity layer will update the billboards height.
This could be done on a web worker, e.g., each time we get a new tile, a web worker looks at all the subscribed positions to queue up callbacks (or events). This could be the same worker that processes the tile for visualization or a separate one to decrease the latency for terrain visualization at the cost of delaying the vector data update.
@bagnell perhaps we do polylines last. We can evaluate shadow volumes for them using the corridor geometry and sub-sampling using the infrastructure we'll build for billboards/labels. Chapter 3 of Usability Oriented Visualization Techniques for 3D Navigation Map Display is a nice comparison, but their sub-sampling does exact line-segment/triangle intersections - and still does not get adequate visual quality for high-resolution terrain.
To start, this could be based on the bounding sphere of each (or max height when it is lower), but we could make this much better with a quantized-mesh extension that keeps min/max per node.
Not sure what you mean here. Quantized mesh tiles already know the min and max height of any point within the tile. Is that what you're referring to, or do you need something else? Actually, heightmap tiles do, too, it's just computed at load time.
do you need something else?
No. That will do it. I clearly didn't look at the format.
@bagnell I had more ideas about point-in-volume.
We already discussed:
bounding sphere -> extruded convex hull -> exact testinscribed sphere -> inscribed convex hull -> exact test (actually probably check bounding sphere and extruded convex hull before the exact test)Here's a few more ideas:
Recent paper:
Usability Oriented Visualization Techniques for 3D Navigation Map Display. 2014.
That thing is like a Hitchiker's Guide or something waoww
I only read the abstraction, but this could be interesting:
Deferred vector map visualization
Interactive rendering of large scale vector maps is a key challenge for high-quality geographic visualization software systems. In this paper we present a novel approach for the visualization of large scale vector maps over detailed height-field terrains. Our method uses a deferred line shading approach to render large scale vector maps directly in a screen-space shading stage over a terrain visualization. The fact that there is no traditional geometric polygonal rendering involved allows our algorithm to outperform conventional vector map rendering algorithms for geographic information systems. Our flexible clustered deferred line rendering approach allows a user to interactively customize and apply advanced vector styling methods, as well as the integration into a vector map level-of-detail system.
@likangning93 have a read and let us know what you think.
Dear patrick and others, you might want to consider the journal article to the link above, which contains some more perfomance analysis:
http://onlinelibrary.wiley.com/doi/10.1111/cgf.13294/abstract
Thanks for sharing @Thoenu!
Deferred vector map visualization
https://dl.acm.org/citation.cfm?doid=3002151.3002157
This approach is amazing and terrifying. The crux is that instead of rendering "lines" as geometry, they do a full-screen post process pass that checks each terrain fragment in the current view to see how close it is to a line segment, with all the line segments stored in textures using a uniform grid of BVHs.
Unconfirmed concerns about precision issues aside, is it finally time for me to write a GPU BVH traversal? Is it finally my time?!
[EDIT] okay an actual list of concerns:
I'm falling in love with the idea though, which is dangerous. I wonder how much math we can move to eyespace... and texture partial updates aren't that slow... and storing polylines in float textures at double precision is possible...
A screen-space approach to rendering polylines on terrain
One beef I have with this technique is the requirement to render both a wall and a shadow volume, which seems more expensive for us because WebGL. However, combining this with ideas leveraging the batch table for fragment culling in https://github.com/AnalyticalGraphicsInc/cesium/pull/6393, I wonder if we could:
We'd have to disable early Z I think, for example if the camera's looking down at the volumes very closely so that the "top" of a volume draws over the adjacent volumes. But maybe that's not such a large price to pay to cut this down to a single pass.
We can also maybe modulate the "thickness" of the shadow volume using a normal vertex attribute that gets added to the positions based on camera distance.
Some back of the envelope math for batch table consumption:
The colinearity approach also gives us data that could be vital for doing style stuff.
Question: what's the extent of material support that we want here? There's an awesome development Polyline Color sandcastle and I'm... not sure how to do that when we're working in fragment space.
Something something pass two colors per segment and lerp maybe...
For style, start with color and line width. Then dash. Then textures.
So the "single pass shadow volume for lines" trick above probably has the same problems as a conventional shadow volume algorithm for polylines on terrain, namely, difficulty keeping constant screen space width:
But since it's single-pass and doesn't require any special render state it can possibly still share a draw call with @pjcozzi's wall algorithm, which a conventional shadow volume can't do. So that's still kind of promising.
[EDIT] come to think of it, "Deferred vector map visualization" probably also suffers from smears and edge-on problems because it relies on something like the 2D colinearity technique for checking if a fragment is part of a line segment.
"single pass shadow volume for lines" trick
I think this technique has enough promise that we can start assembling a gameplan. Here's a couple shots of my prototype at various view distances, we should be able to simulate "constant screen space width" reasonably well:
|
|
:-------------------------:|:-------------------------:|:-----------:
near | far | wherever you are
I think through the Primitive API this is going to look something like a custom Geometry type (to be used via a method that builds arrays of GeometryInstances) and a custom Primitive type that will really just be a lightweight wrapper around Primitive but might have to tangle a bit with GroundPrimitive for terrain info.
How should this integrate into the Entity API though? Just something like an onTerrain flag that you can add to polyline entities? I'm reasonably sure that this is going to need its own spaghetti of updaters and batchers under the hood due to the custom Primitive.
It might also be wisest to start off with material support limited to, say, simple colors, but I'll try to have a more concrete idea of how difficult full material support will be soon.
@likangning93 at the entity level, polylines already have a followSurface option that defaults to true. I imagine we would use this as the new default and use PolylineGeometry when followSurface: false or if it's using a material that's unsupported
followSurface option that defaults to true
One thing with this is that the current API lets users define polylines following the planet curve with per-point altitude:
var orangeOutlined = viewer.entities.add({
name : 'Orange line with black outline at height and following the surface',
polyline : {
positions : Cesium.Cartesian3.fromDegreesArrayHeights([-75, 39, 250000,
-125, 39, 250000]),
width : 5,
material : new Cesium.PolylineOutlineMaterialProperty({
color : Cesium.Color.ORANGE,
outlineWidth : 2,
outlineColor : Cesium.Color.BLACK
})
}
});
If anyone's depending on this behavior right now this is going to be a breaking API change, and they're going to have to write their own methods for interpolating between points with altitude. We could just check if any of the points specified are at height 0 above the ellipsoid, but then if users actually want 0 altitude for each point's height they again need to handle point interpolation themselves. Is that niche enough to be ok if we just document it?
I can also see a combination of per-point heights and followTerrain being kind of confusing to Google Earth users since in KML you can specify a line that follows terrain contours at a height above the terrain:
when drawn perpendicular to the gradient of a steep slope and viewed wall-on
Fun idea: we might already have slopes available somewhere because of materials on terrain, and if not we can also compute per-fragment terrain slopes like we do for materials on ground primitives. Wonder if this would be useful for reducing smearing on slopes.
Something to experiment with a little later.
@hpinkos can confirm, but I believe we compute slopes in the material shader and it requires vertexnormals be part of the the terrain data (so they are technically not always available). I'm fine with requiring them, but we may need to either throw an error or provide a fallback (which can be not clamping to terrain).
I believe we compute slopes in the material shader and it requires vertexnormals be part of the the terrain data (so they are technically not always available)
Yep, see https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/?src=Globe%20Materials.html
@likangning93 can we close this?
@pjcozzi :+1: from me
Most helpful comment
I think this technique has enough promise that we can start assembling a gameplan. Here's a couple shots of my prototype at various view distances, we should be able to simulate "constant screen space width" reasonably well:
:-------------------------:|:-------------------------:|:-----------:
near | far |
wherever you areI think through the
PrimitiveAPI this is going to look something like a customGeometrytype (to be used via a method that builds arrays ofGeometryInstances) and a custom Primitive type that will really just be a lightweight wrapper aroundPrimitivebut might have to tangle a bit withGroundPrimitivefor terrain info.How should this integrate into the Entity API though? Just something like an
onTerrainflag that you can add to polyline entities? I'm reasonably sure that this is going to need its own spaghetti of updaters and batchers under the hood due to the customPrimitive.It might also be wisest to start off with material support limited to, say, simple colors, but I'll try to have a more concrete idea of how difficult full material support will be soon.