Showing posts with label Terrain. Show all posts
Showing posts with label Terrain. Show all posts

10 September 2011

Behind the engine

I don’t even remember when it actually started, maybe many years ago, when I still was a student and covered the distance from the village to the city by train. The landscape that flowed beyond the window made me always fantasize, from the perspective of a 3D graphics programmer, about rendering of huge open spaces.

On late 2007, and in my very spare time, I started to place the first seeds of a framework for 3D rendering and some time later started to play with mesh and level of details. I had to face a number of subjects and every little door opened into new worlds to explore. Also, as the framework grew, in place of answers, some new questions about OOP effectivity, reusing or reinventing, scrum in R&D etc., rised up in my mind.

The idea for a level-of-detail algorithm for terrains came on late 2008 and has been tested together with the algorithm to generate the terrain itself on 2009. There I also started to leave some messages in a bottle by means of this blog and some videos on youtube/vimeo, but nothing. The world seems to be crowded by pioneers of procedural generation, some of notable excellence, but all working as isolated cells into their own procedural worlds.

Since 2010 I could no longer work on gdevice, except for some bug fixing, minor changes, making a couple of new videos. What’s happening? Hard to explain. Crysis (?) turned jobs harsher and squeezing. And also, it seems that in my area there is no money to hire senior programmers. Nice. Anyway..

What is currently in gdevice?

A number of components in embryonal form that are common to frameworks for 3D rendering. To name a few: windowing system (like GLFW), GLSL compliant BLAS (like GLM), scene graph management (like OSG), a 3D engine (aka graphic engine), a piece of code that eases procedural generation of assets and that I wanted to name "procedural engine". And so worth.
Everything has been rewritten from the ground up, everything is neat, compact, fast, but nothing that stands out. Except maybe for one thing:

Gdevice is OpenGL SC compatible

Most (if not all) LOD mechanics for terrain, that won’t precompute and won’t sandbox the world, and thus are suitable for continuous streamlined real-time applications (such as SVS), take advantage of pipeline programmability. That explains why 2000s were so proliferous of new LOD algorithms for terrains. However those algorithms won’t generally fit very well into an OpenGL 1 fixed function.

I can tell, only after having read lots of related literature, that the algorithm used in gdevice somewhat resembles the well known Geometry Clipmaps, with some critical modifications, the major of which is that the whole terrain tiles are in place of the quads and this fact gives worse visual poppings, better performances (VBO and imposters affinity) and, above all, it gives OpenGL 1 compliance, and thus it can apply to resource-constrained devices, embedded devices and military devices (most of which still must use OpenGL SC).

The video

At that time gdevice had the first version of the algorithm with its main defects: cracks and visual poppings.



In the video above, you’ve watched the rendering of a huge and dense terrain in realtime, on OpenGL 1 profile, on a very modest hardware (a laptop equipped with old Intel GMA graphics card).

How huge and how dense is this terrain?

The observer is in the middle point of a squared scene that is, according to textures, about 32km sized (so you have a 16km distance view) and every squared meter contains 1024 samples of terrain. That would mean 1012 samples. Considering that each sample comes with vertex position, normal, color, material params, it’d be an enormous amount of data that wouldn’t fit in any storage device nowaday.

While the observer moves, new stripes of terrain enter into the scene and some corresponding stripes at the opposite side get discarded. The cool thing is that these stripes of terrain are procedural generated at runtime, either height maps and texture maps. A few minutes of exploration (say by flight) can make the engine to generate (and discard) several tens of gigabytes of terrain data.
At this point I can state that gdevice turns explicitly meant for procedural generation of assets and rendering itself is rather an accessory feature so far.
Another cool thing is that the executable is made by uncompressed 64KB and there are not any dependencies except for opengl.dll and libc. Think at it like a sort of demoscene product.

Why the terrain is procedural generated?

Because once setup the graphic engine, I soon realized that I could feed it with over 1 million of vertices and still keep the average frame rate above 20 per second and on the very modest hardware. So I needed data. Where to find terrain data? There are lots of maps out there actually, some detailed, some others more detailed if one can afford to pay them. I considered that, in case I get one of these, then I have to convert those formats to gdevice formats and someway supply the missing data.

I've found convenient to write a procedural terrain generator instead. That is simply a formula z = f(x,y) that returns the altitude z at the location x,y. The artwork of making this generated terrain as much as possible believable, together with the power of formulas to hold (compress?) all this fine information, became soon a ground of interest for my mind.

The procedural engine can (could already 1 year ago actually) generate terrain with several erosion features, as well as water and snow. It is not the best you can find out there but it’s one noticeable thing.
There is an entire world made of continents, flatlands, mountains, snowy peaks, rivers, valleys.. All coming from one single formula and a few dozens of parameters. You change one parameter and the world changes.

What is done, what is to do

At the time that I write, cracks and visual poppings have been solved in a neat, natural way, still preserving performances and compliance to OpenGL 1.
I plan the making of a new video only at the next stage where I wish to show you procedural displacement mapping and procedural bump mapping. The overall architecture will hopefully feature deferred rendering to enable, eventually, shadow mapping, atmospheric phenomena and any sort of post-processing effects. Also procedural generation of content will be switched to GPU instead of CPU. Addictional objects such as vegetation, foliage and human artifacts will be set in a later stage. Can't say when.

19 June 2010

Texture mapping

At last I had to walk my way to texture blending, in order to dress the naked gouraud-shaded thingy. But I wanted to experience a compositing approach to textures where 4 luma-only patterns (say “desaturated” textures) get blended together within a weighted sum, and then colorized. This way less memory is touched (only 3 fetches). It's thus faster, yet enables a variety of materials.
This weird choise is not casual. Indeed I had in mind to stick this stuff into a fixed function configuration, in order to push the old OpenGL API (1.2.1) to its limits and see what I can get. Well, the texture blending I can get is shown in this video:



So now there is another 3D engine in the world, that would look pretty good if it were developed 15 years ago, but is kind of ugly compared with modern today stuff. It is tiny, coarse, fast. It is built around a procedural terrain generator and a LOD algorithm for terrains that doesn't require precomputed data and enables run-time continuous streamlined exploration.

Here are a couple of further videos for the archive:


04 January 2010

Chunked LOD

Some mean wind is still breathing over me resulting in much less spare time and a bad start of the new year. However, during these holidays, I could fulfill a wish expressed on last post: I did implement the new LOD system into gdevice.

I have ported the essential Java code of the prototype and it was quite easy due to the fact that my way to code C++ in gdevice is similar to Java/C# in some key aspect. Anyway, details: there are two threads, one for receiving user input and handling the rendering process, the other one for generating terrain chunks (tiles) by means of fractional Brownian motion processes, still computing derivatives as well.. In a first test with only one single fBm made of 4 octaves, and then with a mild multifractal system, computationally equivalent to a 6 octaves fBm, but still 4 octaves.

Indeed this test is intended to evaluate the new LOD system with terrains. Plausibility of terrain itself is not crucial at this stage. Also there is no texture mapping, no shaders, no occlusion culling, not even frustum culling here.

Watch the video:



The demo ran at 25 fps on my machine, showing a runtime generated terrain made of over 500k vertices shaded with gouraud on a video card with very basic graphics capabilities. Runtime generated means that while camera proceeds a piece of the world is removed from the scene and a new generated piece is added. So you are enabled to roam ad infinitum. I definitely would not try to find periodicity in this function :)

Why chunked? Because without baking VBOs I don't feel to be getting the best from nowaday video cards. Why this chunked LOD? Because I wanted to reduce complexity to O(log(N)) still approaching dynamic geometry data without precomputing anything.
Considerations about the name: this LOD system has no name, not by me, as far as I know. It is similar to Chunked LOD and Geomipmapping, yet it is none of them.

11 November 2009

Yet another discrete level of detail



The picture shows my first attempt on generating a terrain height map. It's a non normalized Fractional Brownian motion applied over Value noise, rendered by using color gradients and fake shadows.
Indeed, this shot comes from an interactive prototype I coded not for generating terrains but for testing an idea for a DLOD system. This is different than previous DLODs I developed before, since this one handles unbound models, doesn't need much precalculation and also performs a nice computational complexity of O(log2(N)). I've also found out that it is someway similar with what is known in literature as Chunked LOD. Though it is in practice quite different than that, I didn't find any valid reason to think at it with a different name, because it is still actually a chunked LOD.
The prototype is a 2D viewer, written in plain Java, fast enough to allow exploration and... roaming around that infinite world, I couldn't avoid of fantasizing about an imaginary procedural doungeon master. Of course missing a number of advisable features. But the terrain it depicts, though still monotonous, has not much to envy to those its human counterparts may conceive. And it's still a prototype.
I have to stuff all this into the engine, in C++, using VBO and shaders, otherwise I won't believe myself either. I will do this right after cleaning up the framework, rearranging those parts I neglected by months.