Showing posts with label Noise. Show all posts
Showing posts with label Noise. Show all posts

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.

02 December 2009

BLAS

Yes, better do the job with the right tools. Actually, dealing with 3D stuff without using a neat set of types and operators for linear algebra, such as in GLSL, would be an endless pain writing, improving, debugging, everything. You will bloat your code, make it prone to errors, missing to notice the meaning of what you are doing, perhaps the beauty, and of course the ways to improve it and invent something new.

Java is a neat easy language. It's a pleasure programming Java. It is like coming back to Basic but with Objects.. Ok but, must say the truth, when it comes up to tougher tasks, you can touch how Java is still confined to dumb toys. It is much limited in performance and still limited in abstraction in a manner that is not acceptable.

Look at this:

vec3 fBm( vec2 point, int octaves, float persistence, mat2 lacunarity )
{
    vec3 value = 0;
    float magnitude = 0;
    float amplitude = 1;
    mat2 frequency = mat2(1);

    for( int i=0; i<octaves; i++ )
    {
        vec3 signal = amplitude * dnoise( frequency*point );
        signal.xy *= frequency;

        value += signal;
        magnitude += amplitude;

        amplitude *= persistence;
        frequency *= lacunarity;
    }

    return value/magnitude;
}


GLSL? Well, it is. But it's not. It is actually a scrap of plain C++ code. You still see C++ and some new C++ types, and operators, properly forged to mimic GLSl. The right tools...

If you know what I'm talking about, you will see how this code is concise and clean. This fBm speaks in GLSL. dnoise returns a vec3 where z holds the 2D value noise and xy (a vec2 type) holds the derivatives dx and dy. Then all of them can be weighted, added, normalized, by using a neat fair expression. It is now painless, natural, elegant coping with vectors and matrices, just like those were scalars, just like in GLSL or Mathlab. Also it is so natural to raise the frequency concept to a domain transformation concept, and then apply the transformation to derivatives as well, according to the fact that

D[ f(g(x)) ] = g'(x) f'(g(x))

Ok, this is correct only when the trasformation is a rotation matrix, so that the transpose would give it self back. Otherwise we would have to put up with a Jacobian matrix. But this is not worrying anymore since this library features all GLSL functions and some nice more. Now I can write code intended for CPU using the same expressivity given by GLSL.

See this:

vec3 forward = vec3( -cos(a.x)*sin(a.z), cos(a.x)*cos(a.z), sin(a.x) );
vec3 strafe = vec3( -cos(a.z), -sin(a.z), 0 );
camera.position += forward*(key('W')? +speed: key('S')? -speed: 0)
                  + strafe*(key('A')? +speed: key('D')? -speed: 0);

Or this:

vec3 sky_color = vec3(0,1/3,1) * dot( normalize(sun_dir), upvector );
glFogfv( GL_FOG_COLOR, (sky_color+albedo.rgb).array );

Couldn't avoid of making this library as much GLSL compliant as possible because I will move pieces of code to GPU and back to CPU at will. Though it also turns out a bit embarrassing when you wonder which side you are working on, whether CPU or GPU. I even have set up a mechanism for coding GLSL shaders just like C++ classes. Definitely the two worlds are so tight in gdevice, even without CUDA..

Anyway, why writing yet another BLAS library? There are so many out there, well suited, well performing... Simply I wanted to learn coding my own, perhaps GLSL compliant, performing at best (with SSE2 optimizations). Also, I must to say, I didn't like what I saw inspecting their code, I could not accept to waste all that code, making the whole so confusing and not properly performing like it must be. Above all I expected that types (and operators) had to descend from these two, just like is thought in algebra:

template <typename T, int N> class vec;
template <typename T, int N, int M=N> class mat;

But again I got disappointed so in the end I did my own..

By the way, I still like playing with Java when prototyping new algorithms. It is relaxing :)

Thanks to IƱigo Quilez for sharing the idea of derivatives calculated together with value noise.

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.