"Google-Earth" style engine for Unity

Hi Guys-

I’m wrapping up core development of my terrain engine for Unity, and I’ve posted a short informal video showing some real world data from USGS.

You can run the actual database live in the webplayer here:

http://www.freeterrainviewer.com/BirminghamWebPlayer.html

General info and game-style webplayer demo can be seen here:

www.freeterrainviewer.com

NOTE: The webplayer version pulls data from ftp (vs. local disk) so bandwidth can be an issue. I’m using a downsampled version for the test (and video), the high res version runs great in standalone mode but I don’t have the server space to host it all (it’s 20+GB).


This runs in Unity 4 or 5 (standard or pro), I’ll be releasing this commercially in the near future (possibly the asset store), and/or partnering with others for continued development.

If you would like to be considered for early beta testing (and/or have large datasets to share), feel free to PM me and let me know me what you’re working on, I can deal with a limited number of people directly so if you have monster terrain data and/or testing setup I can customize/test with your feedback (in some cases).

Any thoughts/comments are welcome and appreciated (positive or negative), if you’re interested in running large terrains I would be glad to hear from you.

Thanks for your time :slight_smile:
-MM

Good to see some more people working on a terrain engine. One thing I would say is to use a proper screen recorder to record videos. That will do your work far more justice.

Some questions:

-How do you handle floating point limitations? Do you use some sort of origin reset system of both the camera and the tiles, as described here?
https://unity3d.com/learn/resources/gis-terrain-unity

-My dataset is local but huge nevertheless (worldwide). Can it manage zero stuttering when loading new tiles when flying at airliner speed?

-Can procedurally generate textures using height maps (snow, grass blending etc.) instead of using satellite pictures? Storing satellite pictures of the entire earth locally is not an option. Heightmaps are ok though.

-Does it support terrain collision?

Edit:
-Does it supports a hands off workflow? Touching the mouse or keyboard for even one tile is not an option if you are dealing with the entire world. This is where 100% of the terrain assets currently fall short.

-Can it cache terrain generation of places you already went?

-Does it use the Unity terrain engine or does it use a regular mesh?

-Does it support PBR shaders?

-Is the mesh generated entirely on the GPU like with Scrawk’s Proland port?

-Until which altitude, viewing horizontally, can you see the terrain without fog required?

-Can you post a video of the LOD system in action (hopefully it has smooth LOD transitions)?

-Does it use DX11 or does it work on DX9 also?

1 Like

Elecman, I will be posting some workflow videos going from World Machine to Unity using this tool in the near future.

And there will be proper screen captures and more info as well :wink:

I’ll let MM answer the rest of your questions.

Like Elecman interested in how this handles very large global sized data sets.
Would need to be stutter free and not suffer from unity floating point problems.

The floating point problem is not Unity’s fault by the way. All game engines suffer from that.

I will answer the ones I know…

Yes. It is up to the shader applied.

Yes.

You don’t have to manually do anything to the tiles. I hate dealing with terrain tiles.

MM can answer this one.

Nope and nope. MM can give more details. It was one of his frustrations.

If you can write one, yes.

MM can take this one.

MM can take this.

I think I can, I will make the video of it in action and if MM says OK, he will post it.

MM can take this one too. :slight_smile:

John G, what is considered “large”?

Well, I will process a short video now… hopefully will be ready in the morning. It is really nice to see in motion… when it’s not a cell phone grab :wink: (Sorry MM, I had to rib you on that one…)

Ok, the forums won’t let me post my response because it is spam-like, I attached a file. I tried chopping it up in various ways to appease the auto-filter, but no.

2118362–139144–5_18_2015_ForumReply.txt (9.77 KB)

Now I will try adding it in sections:

Hi Guys-

I’ll hit all these at once, I appreciate the questions and comments:

    • Floating Point Limitations:

I’ve seen this with procedural data when you go way, way, way out, but it’s not been a practical issue for me so far.

I did run into some issues tiling out the Birmingham data, so used doubles for intermediate calculations in a few places. For the runtime engine, it’s not been a problem with real-world data, the BHam set is about 1143 square miles and coordinates are not a problem.

Infinite procedural background has a definite limitation, but for the real world data it hasn’t been an issue (so far).

    • Zero Stuttering:

Check out the live camera fly-through, that is pulling from disk, it’s choppier running from ftp but once the data is streamed into memory, integrating with the runtime engine is very quick. The core is designed to stream in new data from network (or local disk) with minimal delay, you can see this in the live video from the cell phone.

One of the reasons I did the cell phone video was to show how smooth it runs without video capture running, a stand-alone implementation (straight c++/dx) would be much easier to work with, as Unity has some limitations.

There are definite limitations with hardware/memory/bandwidth/etc. but it runs decently enough on my system with BHam, and that’s a good test case.

So, the short answer is, it really depends on the data and hardware, but it has a high performance limit before it craps out.

    • Dealing With Tiles:

The tiles are never touched manually, the only thing needed is the path to the different LODs and the naming convention for the files.

The script code has a client callback to request any tile at XY coordinate, at lodLevel n.

The raw data is a bunch of tiles, downsampled into a pyramid of LODs (so if the first LOD has like 16x16 tiles, the next LOD has 8x8, and so on). So you have to tile out mipmaps (more or less), but it’s just folders of images.

None of that ever has to be loaded into Unity, the critical info is the naming convention for the paths, how many LODs, how many xy tiles in each LOD, expected resolution, things like that.

The webplayer can stream tiles from any ftp so it will be possible to enter in your own path info and stream custom tiles (once I get the GUI in there for that).

NOTE: It’s possible to pre-setup environments using a mix if custom regions and procedural stuff, so you could custom create a terrain using Unity with the other features, however, for the tiling stuff, it just streams the raw imagery (tiled into LODs) and heightmaps, and runs it on the spot.

There are a few ways of getting data into the engine but it’s designed to be as hands-off as possible. Generic images are used for the input data, with no pre-processing required.

    • Cache terrain over areas already gone over

It could save the data, but the memory is reserved for runtime stuff so it doesn’t hang around if not needed. I will be adding some predictive cache stuff in the future (which might hang on to older regions) but for now it just caches as needed and stores only the data required.

The elevations and texture have an internal LOD system so it does store more data than is actually rendered per frame. SO there is a ton of data in the background that might not actually make it to the screen.

    • Mesh Data:

The engine uses a custom mesh, and Unity is a bit slow about vertex buffer access (the mesh basically has to be updated each frame).

I can do the terrain collisions, etc., and there is code for that, but it’s not a pre-baked mesh, it’s always dynamic. It would be nice if Unity provided lower level access to the vertex buffer stuff, but it seems to run ok as is. A standalone c++/dx version doesn’t have those issues.

The mesh data could potentially be generated and save out, and the code interface could be used to generate procedural (mixed with custom) data, but saving the mesh isn’t so critical, it’s a rendering system and not so much of a world-builder.

NOTE: Morphing LODS: The elevation data is constantly being morphed for smooth transitions between LODs, if you check out the gamish-demo on the main site page that will show an example of that.

The LOD settings for geometry are adjustable in script, and whatever data is available (heightfields, etc.) will be filtered through those settings. So you could have high-res data filtered through a low-res terrain mesh, and vice-versa.

    • Mesh on GPU/CPU

The mesh is currently generated on CPU (for collision stuff), I’ve considered doing it in the shader but it hasn’t been a performance issue so far, and I like the CPU-side copy.

I may still add a shader to do the mesh generation entirely on GPU, it would be applicable in some cases and certainly open up the door to higher resolution geometry.

The big downside to that is the smooth morphing LODs, which require some interesting twists and turns (to run fast), so that is the big issue for that. It’s not static data and there are many complex steps to getting the morphing LODs running right.

    • Highest View To Horizon:

Technically, the data is always rendered out to the horizon, provided that the farplane is set high enough. There are problems with depth sorting with a super high farplane (requiring a further nearplane), but technically it could be set out to anything.

In the BHam demo there are places where the entire set is shown, and beyond, but the farplane is set to a finite distance. If I had a large dataset it would extend further (the diminishing LODs mean that far data doesn’t take up so much space).

The elevation data can also be set to a finite (but very large) region, and that is variable, so really, again it depends on the input data and the available hardware.

If you wanted actual miles, etc., I could work out the numbers given available texture memory and desired resolution, Unity has some limits (and there are ways of working around that), but the current implementation can go pretty far. I’ll probably increase that in the future but it works for now.

    • LOD System In Action:

The elevation smooth LOD stuff can be seen in the gamish demo on the main site page, the texture LODs are best seen with BHam.

The BHam webplayer demo is a bit choppy becuase it pulls tiles from ftp vs. disk, I have a higher-res set that won’t fit on my ftp space (it’s 20_GB), and I’m working with Lamont on making videos of that.

The texture LOD transitions can be blended and interpolated so there is no abrupt change anywhere, that’s on my list of things to do but very trivial and easy (so not a huge concern right away).

The morphing LODs for elevations work with any input data, I designed the engine to input raw imagery and heightfields and just “run it” with a minimum of hassle.

    • DX/D9

Technically this should work with pre-DX9 (I’m doing all the hard stuff in code and using the platform as-needed), the core engine generates geometry and sorts textures without using any advanced functionality.

The shaders used are of course limited by DX version, but there’s nothing extra special about them, it’s all in the process, no tricks.

I’ve run the engine in U4 and U5(standard, not pro), and it could be ported to pretty much any other platform. I used to prefer c++/dx/gl but I am now getting spoiled on Unity and c# :slight_smile:


High-res Videos:

Lamont has a better video capture setup than I do, and I’m getting him the high-res version of BHam (the one running in the webplayer, and my demos, is the low-end version).

The high-res version runs decently on my system, from external drive, Lamont will be running it from a local drive and get better video than I can.

The engine itself has other cool options for game-style stuff, but the tiling is the big feature.

BONUSES:

    • No real pre-processing required (just folders of tiled images)
    • Virtually unlimited database (if your server has the tiles, they can go on forever)
    • Easy Integration (the terrain engine plugs into any Unity project)

Setting up a game-style environment gets more in-depth, but for running raw tiled data, it’s very straightforward.

Ideally, I can get people to share their large terrains and make them available from the main site. The end result of that webplayer will be a free public utility for viewing terrain sets, and anyone that has something like BHam (or more) can just run it in the browser.

Lamont is testing with World Machine (the engine supports splat maps for material maps, too, I have a shader for that), that will clarify the workflow for generating artificial terrains.

The BHam data is basically tiled out imagery from USGS, the input format for the engine is just consistent indexing for tiled images at various LODs, and the elevations are handled the same way.


I’ll be running more data in the near future (Lamont got a section of Colorado), and that will clarify how things work with the tiling.

I appreciate the questions and feedback, feel free to add more, I am happy to address whatever is raised :slight_smile:

OK it is the text on alternate shaders that gets flagged as spam-like…Let me Dumb This Down


    • Alternate Shaders:

Main Geometry Can Be Rendered With Any Shader

Underwater Caustics Shader Shown In Gamish Demo On Main Page

Geometry and Textures Sorted By Core Engine, Can Be Rendered In Different Ways

Ok, aside from the bit about alternate shaders (thanks Unity forums) that was it…the PBR shaders aren’t part of the package, but in the end it’s all geometry and sorted texture LOD data., and the core engine makes that available to be rendered in different ways.

The underwater caustics shader will probably be included as a special effect, if you have experience writing shaders the possibilities should be clear with things like that.

Lamont made a video of the engine running in the editor, this shows the geometry cached in (which handles elevations) and the texture view:

BHam is fairly flat but the elevations are in there and adjustable, the smooth morphing LOD is best seen with the gamish demo…I have a Colorado set I am about to start working with, I expect that will have some nice elevations…

NOTE: That video is with the low-res BHam set, I’m having to transfer the full set to Lamont in sections…that should be interesting…

Thanks MM. more detailed than what I could ever say :wink:

A video showing the process from World Machine is in the works. I don’t own a license of any other apps, so I can’t go into those workflows. But WM seems to be the app of choice for people who do this work.

Thanks for your detailed reply.

-Regarding the floating point issue, I think the reason you didn’t see any limitations yet is because of the use case. This isn’t so much of an issue with the terrain itself but with the physics of objects moving through it.

Please have a look at this Unite video and scroll to 4:20 for an example of that.

If you have an object in the scene which uses physics, you will start to notice jittering at about 20 km. Sometimes even as little as 10 km, depending on what you do. Now, this might seems like a big distance but what “far” is, depends on what you do. I want to use it for a flight simulator I am working on, and 20 km is about 4 minutes (!) of flying time in a jet.

So unless you can reset the camera and everything with it, I am afraid that for any descent flight simulator application (where you go from A to B and not stay in the same region), it will not be suitable. I will be happy to beta test it for you and show you an simple example of this limitation.

Some other questions:

-Did you contact Unity about the slow vertex buffer access issue? They seem to be willing to fix stuff if it is doable.

-Is it possible to add airports to the mesh system which I procedurally generate myself? It needs to know the mesh height data so parts of the terrain don’t overlap the runway / taxiway.

-I understand that you are working on a video which shows the LOD in action over a a more mountainous terrain. Can you make the camera face forward also?

1 Like

Hey Elecman-

Thanks for the response, I’ll gloss over these :slight_smile:

Floating Point Issue:

I understand the problem with the motion and physics, that’s more for the wrapper application to handle, my core stuff is all about the terrain itself, and the way the client code uses it can be variable…I do something similar to an origin reset in the code for the terrain (depending on the vantage point), but the host app/simulator decides the actual coordinates and range(for example, the BHam dataset is 35 miles across, but the flight works ok because it’s in a different scale).

The floating point limitations in the terrain are mostly a problem for procedural stuff that is far, far away, but it takes forever to get there, the amount of data that is crammed in between the origin and the failure point can be pretty much anything (the universe could be scaled to within acceptable limits for Unity motion).

This is more of a core plugin for flight-sims and not a flight-sim itself (though I have some basic motion controls), it’s straightforward to add but there are some script-controlled parts that need explicit input, such as camera position, etc.

I’ll be posting docs later this week (still spiffing them up) that describe how that can be used.

Vertex Buffer Woes:

They would have to give me inside access to the vertex buffers, which isn’t really practical for them…it’s not so much of a big as it is a design issue with Unity itself, I searched every post I could find and there is no faster solution for now…it’s not that it’s terribly slow, it’s just faster using straight c++/dx and it would be nice to get to dx directly and bypass the Unity mesh wrapper object.

Adding Custom Areas:

I think you will like the docs, there is an option (and script) to create custom areas anywhere you want, at any fixed height, with or without textures, with or without custom elevations. I use that for custom roadmaps and watermaps, though you could easily stake out a custom region for anything. The elevations can blend into the procedural background, and/or blend into overlapping custom regions.

The tiled dataset is only one type of input (which is just a bunch of indexed images in folders), but the core engine is designed to have infinite procedural background with different custom regions, this allows pretty much any type of base gameplay area to be defined.

I also have a mechanism for auto-placement of objects (like trees) that cache in and out in a custom range as you move, that will be covered in the docs.

Forward-Looking Camera:

www.freeterrainviewer.com

Check out the gamish demo on the main page, that is a Much Older Version but it shows some of the smooth LOD stuff (with cartoony terrain) and the underwater shader…

btw the first video at the top of that page shows a fly-through of BHam with the forward facing camera, you’ll probably want to see that first…


I’ll be putting together the official release with all that info real soon, if you can PM your details about your terrain I’d like to see what data you have and the best way to get it running.

There are a few ways of doing it, I designed the engine to load and incorporate plain imagery with a minimum of pre-processing so if you have images for everything that is best.

If the terrain engine has some sort of API which allows a coordinate reset done manually, that would be fine. Of course resetting the camera is easy but the terrain has to somehow move with it. I just want to make sure the engine can support that. I would love to try that API out it out if that is possible.

I will gather some of the terrain data I have and pm you.

Anyway, I am excited about this and can’t wait to give it a go.

John, Elecman,

Before I start rendering out these terrain tiles, I would like to know what is big? What is your average/target database size in distance/pixel density? Altitude you want to see it at? Speed?

Bear in mind that the full-resolution set for Birmingham, if it was a single texture, would be:

169,908 x 156,821

That is 3 samples per meter, or roughly 1ft pixels in world space…depending on world scale, LODs, elevations, memory, etc., the absolute limits can be worked out for any scenario…I could give a theoretical maximum but that really depends on texture memory and how many rendering passes (if more than one is needed)…

In my case, the definition of “big” is the entire earth. Like google earth. But for a flight simulator. Only height maps are stored locally though. Satellite images are not used, only for some specific areas.

Floating point issues are going to be a problem, I am sure.

Not sure what the heightmap pixel density is, will look it up. Either way, the resolution is not too much of an issue in my case, just global coverage which requires the terrain to be reset to the origin at some point.

The speed required is the typical speed a jet airliner flies at. A maximum ground speed of 600 kts will do.