Rendering large terrains
pheelicks.com
pheelicks.com
Frostbite goes a bit further (they stream in the height-map etc.) but the bare method used is this. His reaction to me sharing this was quite funny:
> Cool! But… Javascript??! It’s like writing the bible (or your religious equivalent) in glitter and kids crayons… Loses something.
You just can't get oldschool developers away from their beloved languages :).
[1]: http://dice.se/wp-content/uploads/GDC12_Terrain_in_Battlefie...
If I ever do anything 3D, it will probably be WebGL. Some industry veterans have reservations against it, but so long as it doesn't look like poop smeared origami, it's OK.
sort(1,10,5,3)
1, 10, 3, 5
Then there is this.
null == false //false
!null //true
> The default sort order is lexicographic (not numeric).
Works as documented.
Popping: it "naturally" happens with all dynamic LOD systems (back in '98 it would have been Real-time Adaptive Optimized Meshes). It happens when something changes from one detail level to another (and hence more details "pops" into view). If you spend more time on your renderer you will generally morph those vertices between the lower detail position and the higher over a very small amount of time. This means that the pop happens over a longer duration and humans are bad at noticing stuff like that.
Incorrect Heuristics: a heuristic is used to determine how far away from the camera you need to be in order to not see the difference between four triangles and two (this has a lot to do with Nyquist-associated theorems) because "the difference is less than a pixel." If you get it wrong you could present too little detail for a pixel and change the apparent shape of the terrain (obviously intentionally presenting too little detail increases framerate).
I'd love to hear a comparison of the two by someone knowledgeable about the subject.
Did you also consider using some more advanced geometry representation of terrain other than heightfields, such as triangulated irregular networks? That would allow you to choose an error threshold for each LOD and seamlessly join neighboring patches together without the need to use vertex shaders for it.
I did my own "Google Earth"-alike using a modified BDAM algorithm a couple of years ago. It required Hadoop preprocessing of detailed input data (resolution in meters), parallel terrain simplification using quadric error metrics and edge collapses and produced a set of layers at different LODs.
The cool thing about it was that you could have chosen the desired screen-space error and fetch only those LODs that were fitting - usually these had far smaller size than regular heightfields of the same resoultion/error. You could have also incorporated roads, rivers, buildings, bridges, tunnels straight into your terrain geometry, as well as different textures for each sub-part of it.
The tessellation was a bit funky (BDAM uses triangular patches instead of tiles) however there are also variants that utilize rectangular tiles. Vertex shader was then used to simulate 64-bit precision, giving uniform rendering detail in centimeters for the whole Solar system. Geometry shader could add more detail into it and overall it was very snappy online as the size of downloaded data was smaller than with regular meshes.
Yes, the project was completed and working fine though it ended up buried deep within my former employer's R&D lab and I have no update if they are using parts of it anywhere. They got acquired and another office was aggressively taking over, getting rid of internal competing technologies. I also had a prior experience in adding dynamic 3D cities and vector maps into NASA's World Wind, and therefore writing a completely own globe from the scratch was a joy ;-)
I am thinking about doing similar apps in WebGL and Qt and writing some tutorials on how to do it as I progress, so perhaps we can inspire each other then. First I need to finish some tutorials for advanced 2D geometry and Bezier curves though (Illustrator-class algorithms with JavaScript + HTML5 live examples).
Thanks for writing this inspiring piece! :)
RE 3D world, I'm already working on something similar. Shoot me an email (see HN profile)?
This is built on the Cesium open source virtual globe http://cesiumjs.org/
Even the real-world does "fogging-out" over distance depending on atmospheric scattering, haze, rain/storm or actual fog conditions. So fogging-out-smoothly, while beneficial as per above, also looks beautifully "realistic" as an added benefit, at least provides a great realism/cost ratio
- insufficient precision of OpenGL 32-bit floats in Earth-scale computations. If you want to render the whole Earth, you'll find that at the ground level your precision is only 16m resulting in jittering as you move. This was usually solved by "zoning" and local coordinate systems, hence it was easier to deal with a smaller set of ground "tiles" and haze out the distant ones. Having said all that, nowadays you can use vertex shaders to simulate 64-bit (or rather 56-bit) precision and get around 1cm resolution at any distance
- the need to have various LODs that include curvature of the Earth with significantly increased error tolerances, which in turn increases memory consumption. Again, nowadays should be no longer an issue given entry-level GPUs having 1GB of RAM and geometry shaders
In fairness, this is also the case of 90+% of real-world flights I partake in..
Terrain rendering is probably one of the things where GPU-based raymarching really is an option nowadays.
http://iquilezles.org/www/articles/terrainmarching/terrainma...
Runs ok (well, 12fps!) here on firefox on an iMac. Just black on my centOS laptop with intel graphics, I admit, but loads of gl things don't run on that.
Recall that Google Earth was the product of an acquisition of a company called Keyhole. Named after the spy satellite, a reference to the recently declassified satellite imagery they were using. Its also interesting to note Al Gore played an important role in declassifying this data. [2]
But to make use of all of this imagery a new efficient algorithm was needed for loading and rendering the data. This is what the Clip Map paper describes and enabled the iconic zoom from space to the surface of the earth with real time rendering of satellite imagery.
According to Michael T. Jones. "Keyhole started by accident. The earliest possible origin of Keyhole actually lies with me. I worked with a company called Silicon Graphics (SGI). One of the companies I worked with had created a program to view satellite imagery where you could zoom in and see the imagery in great detail. It was used in the Bosnia peace talks to draw the border." [3]
"Before its acquisition by Google, Michael was CTO of Keyhole Corporation, the company that developed the technology used today in Google Earth. He was also CEO of Intrinsic Graphics, and earlier, was Director of Advanced Graphics at Silicon Graphics." [4]
It is interesting to note that a German company is now suing Google over Google earth and possibly this very technique. [5] Are ART+COM and Terravison the company and software Michael Jones was speaking of?
The real power of this technique is that it allows you to pre-page the data in tiles that can be easily loaded over the web and are sized specifically to live graphics memory. It optimizes both the IO this way and off-loads the mesh creation process from CPU to the GPU. In 2004 Microsoft research published an expansion of the of the Clip Map technique that does just that. [6]
A basic demo and source in C++ available [7] and I have also found SpiderGL uses this technique [8]
One thing I have not found yet is a good discussion of implementing collision detection in conjunction with this technique if anyone has found any resources on this I would be grateful.
[1]: http://www.cs.virginia.edu/~gfx/courses/2002/BigData/papers/...
[2]: http://www.realityprime.com/blog/2006/07/notes-on-the-origin...
[3]: http://geospatialworld.net/FirstPerson/ArticleView.aspx?aid=...
[4]: http://www.uoc.edu/portal/en/sala-de-premsa/actualitat/notic...
[5]: http://www.eweek.com/cloud/google-sued-for-alleged-google-ea...
[6]: http://research.microsoft.com/en-us/um/people/hoppe/gpugcm.p...
[7]: http://filougk.blogspot.com/2007/03/gpu-geometry-clipmaps-so...
Though not published in a journal, I developed a near-identical concept and implementation as a senior high-school project from '97 to '98.
This after realized the difficulty of implementing the more general triangle-subdivision strategy for terrain LOD driven by a computational-cost/visual-benefit algorithm.
http://www.gavanw.com/uploads/9/5/4/0/9540564/8069858_orig.pnghttp://www.youtube.com/watch?feature=player_detailpage&v=J2T...
In Trigger Rally, there are additional vertices being added to the lower LOD chunk side of the seam to avoid T-junctions in the mesh topology.
In the OP demo, the vertices on the higher LOD side of the seam are morphed so that they will be flat with the lower LOD side of the seam. This should also help reduce "snapping" when moving to higher LOD levels.
Or am I missing something?
http://sea-of-memes.com/LetsCode28/LetsCode28.html
Edit: just for some additional information, the idea is of course a lot older