Terrrain LOD [UPDATE: dynamic shadows !!] huge open world for all (glsl shader)

Here is my “LODShader”

This shader handle the terrain LOD. It uses real-time displacement in order to display more polygons near the camera, and less polygons far way. This allow you to make huge open world for your games! Or at least, big background for your games.
It’s still in developpement, but I hope it already could be useful :slight_smile:

EDIT: Update 2013/02/28 ============================

There is now a fully working physic system that allow on-foot gameplay (FPS, TPS, race game, vehicles, etc.).


Current features:

  • fast and efficient LOD via real-time displacement.
  • unobtrusive and easy to setup, highly ajustable.
  • multilayer shading with 4 materials
  • colormap, normalmap and specularmap for each of these 4 materials
  • stencil maps to mix different materials
  • 2-steps fog (2 colors and 2 distance)
  • baked shadows map support

What it can’t do:
- cast and receive dynamic shadows (you have to bake them)

  • have collision (but you can use an invisible collision mesh)

    UPDATE : dynamic shadow and collisions are now possible !

In what kind of game I can use it:

  • All of them, except a game where the collision with the player and the ground are too visible. This is the big weakness, for now.

Where to download it:

How to use it:
As I said before, it’s easy to setup. Easy, but not obvious… that’s why I made this little tutorial…

1 Like

How to use it

0. Import the shader in your blend file.

1. Create a plane. Unwrap the UVs, then subdivide the plane. Subdivide the center many times to get something like this:

2. Create the following games properties on this object:
They will make the LOD to work properly

  • uvX and uvY : leave them to zero
  • height : define the height of the terrain.
  • cell size and cell number: What I call a “cell” is one of the biggest quads of your mesh, in the lower density area (look at the picture below). The cells number is the number of cells in the width of you terrain. The cell size is the width of one cell, in blender unit, and have to be an integer.
    (If your cells width is not an exact number of blender units, scale your mesh to make this match to an integer value… For example : my mesh have 64 cells in the width, I put the dimensions to 128… The cell size is 2, and cell number is 64! easy)
  • LODcenter: simply put the name of the object that the LOD will follow. By default put the active camera name.

3. Setup the logic like this (it will call the shader):

4. Setup the textures.

First create your textures. You can use these textures:

  • height map of the terrain (needed, in gray shade)
  • normal map of the terrain (needed)
  • lightmap of the therrain (optional, use pure white instead)
    And for each the 4 materials:
  • color (optional, use any solid color instead)
  • normal map (optionnal, use solid color instead with R=127 G=127 B=255, or R=0.5 G=0.5 B=1.0)
  • specular map (gray shade, optionnal, use pure black instead)
  • stencil map (for 3 materials only, gray shade)

As you can see, you don’t have to use all of them, but if you don’t, you have to provide something instead to the shader, otherwise it won’t work at all.

Now you have your textures, we have to give them to the shader. This is the tricky part, but don’t panic, it’s very easy. Custom glsl shader does not accept a lot of textures. In order to make this shader the most compatible possible (with GPUs), we put all these textures in 4 files.

Create a new material, and place your files in the texture panel in this exact order:

  • height map : this file contains the normal map of the terrain in the R,G,B channels and the heightmap in the Alpha channel.

  • textures: this file contains color, specular and normal of each material, they’re placed like this on a 4*4 pattern:

  • stencils: the three stencils are placed in different channls of the same picture:
  • material 2 stencil on the BLUE channel
  • material 3 stencil on the RED channel
  • material 4 stencil on the GREEN channel
    (be aware that material1 is below others, material2 is over material1, material3 is over these, and material 4 is over all)

  • lightmap: put baked shadows and/or ambient occlusion here. Take care that non-shadowed areas are pure white otherwise everything can be too darkenned.

Adjsut the material in the shader.
Go to the text windows, open the shader, find the “variables to tweak” area.

Most of the parameters speak by themself. If some are unclear, change values and you will see the changes. All the values are float so take care to write “4.0” and not “4”.
Only the “margin” value may not be obvious. Because all the material textures are placed on the same file, tiling artifact may appear. To avoid this, place margin around your textures, like this:

In this example, I choose 0.6 as a value, but you can basically scale your texture like you want.
I suggest you first not to make any margin around your texture, and then change the “margin” value directly in the shader (from 1.0, decreasing step by step) until artifacts disappear. Then scale your textures acording to the value you found.

6. Run the game and enjoy :slight_smile:

Please feel free to ask if I am unclear!

Feel free to use the shader, share it, improve it !

And please let me know and see if you use it for an actual game :]

Some tips:

  • Use only square textures, power of 2 scaled.
  • Once you have your heightmap, create a mesh from it using the “displace” modifier. From this mesh you can bake normal map of the terrain, and lightmap. You can even paint on it to create your stencils maps.
  • You can get the material textures easily from cgtextures.com
  • to put some material only on top of your terrain (for example), use your heigtmap as a stencil, and change the gray shade using curves.
  • to put one material only on the steep areas, use the blue channel of the terrain normal map as a stencil.
  • Use this same mesh to create the collision mesh. You can use the “decimate” modifier to decrease the polygon number of the collision mesh.
  • I suggest you to subdivide the first plane accordingly to the size of your heightmap… To be the most optimized, you should have one vertex per pixel in the center area.
  • for optmization, choose the texture size smartly. Having big texture slow down the shader… Height/normal texture is the biggest because it really needs details. But lightmap can be much smaller. Stencils map can also be a lot smaller. Do some tests…

Okey, then the .blend demo file… HERE (26 Mo, tell me if I forgot to pack something)

Laser blaster also made a version that support multilights: HERE(you may have to tweak some little things in order to make averything works properly, look at posts #41 and #46 if you have some problems with this version)

Let me know if it works for you (what fps?), if not what’s your GPU specs…

I get this

on my older system…but the lod works perfectly and wow at the high steady framerates even on my older system. I want to say over 112+ fps at most points :smiley:

DUAL 2.4 Xeon processors

1 Like

The shader doesn’t work for me at all(everything is transparent). But I’m sure its fixable. It’s probably some miniscule error in your shader code that my gpu driver doesn’t like. I’ve had this problem before. I’m currently going though the code, seeing if I can find any problems.

Thanks for posting this, though.

@ Superflip: Hmmm… I wonder if that’s simply a precision problem with your gpu, or if there’s some sort of compatibility issue at hand.

EDIT: I managed to get the shader to work properly without BGE throwing any errors. However, my poor old relic of a computer just can’t handle the strain. Instead of 30 frames per second, my framerate is more like 30 seconds per frame. It also crashed my computer after a while… I’ll see if I can change anything to improve the situation.

EDIT 2: Okay, I don’t think there are any errors in your code. The problem is my ancient gpu. It’s an Nvidia GeForce 6800, and has limited support for vertex texture fetches. I did a bit of research: (For vertex texture fetch)Gf 6 supports only GL_TEXTURE_2D of format GL_LUMINANCE32F_ARB and GL_RGBA32F_ARB. It doesn’t support any of the other floating point formats or fixed point formats. There is no floating point compressed format.All other formats besides GL_LUMINANCE32F_ARB and GL_RGBA32F_ARB cause the VS to run in software mode.

I assume Blender doesn’t use either of those texture formats, and that’s causing the vertex shader to run in software, thus the massive slowdown.

This is a very nice shader you’ve created. It’s a shame I can’t really use it.

Well I hope it will work at least for someone…
(yes 30 seconds per frame means that CPU is doing the job…:confused: )

It seems that Blender uses GL_ARB_multitexture… (which is already deprecated).

The only thing you can do is to update your GPU driver, but I guess you already did.

@ super flip: nice glitch… I have no idea why ! Maybe code should be changed for ATI card ? Like laserblaster said, its looks like everything works fine except some precision :confused:

Does it work on 2.49?

super flip: nice glitch… I have no idea why ! Maybe code should be changed for ATI card ? Like laserblaster said, its looks like everything works fine except some precision :confused:

I checked my video drivers to make sure they were up-to-date, To my surprise they were not. After upgrading drivers it works perfectly without the glitches. And a smooth 100 + Framerate at any zoom, orientation level even on my ancient machine. Nice Job.

No. If you want the shader to work in 2.49, you’d need to modify the Python script to be compatible.

And if you want the demo file to work, you’ll need a version of Blender that has Bmesh(2.63 and above, I believe).

@superflip : hey im happy to know it works well for you too ! Whats your gpu spec?

@laserblaster : actually the python part of the script is very small, it should be very easy to change for 2.49… I should make a 2.49 compatible file…

Does it work for someone else?

It’s quite beautifull by the way, and it would look even cooler with the day/night cycle skydome.

@superflip : hey im happy to know it works well for you too ! Whats your gpu spec?

its only a ATI RADEON 3650 HD AGP (512), quite a few years old

For me its working very well! I just cant move forward, but that is ok

he did not use A, S, W, D to move the camera, try changing its logic brick

Is the demo-blend supposed to look like this?

edit: Ah, I just realized it doesn’t work when just pressing “p”. Using the standalone-player it works fine.

No, it works fine when you press ‘p’, you just have to make sure your viewport shading is set to ‘Texture’. This is seriously impressive benj. I get a nice steady 60fps with this, even with martinish’s DOF shader running alongside it. Fantastic work. Are there many more improvements to be made with this, or is this almost done?