Fake planetary terrain LOD

Greetings fellas! In my attempt to get as much terrain detail on a planetary body, I decided to use vertex displacement shader from Martinsh ‘advanced ocean shader’, the CGcap’s version.I just set time to 0 so that it’s static. This one allows a more subdivided area of the object to track the camera’s position. If I could change the script in order for it to track an object’s position, but on a sphere surface, it would be it!
The effect I want can be simulated on the editor mode only with a displace modifier. This is just to illustrate here!

The idea is to concentrate as much polies as possible in the areas next to the player.
Can some one give me a hand?

I asked both Martinsh and CGcap for help, but they seem quite busy…

Ok, so no one read this, like, why should anyone read it anyways?

Regardless, a few steps have been made, so this is a good beginning!
CGcap made the first step. The script “works” and the idea seam plausible, but needs a lot of tweaking.
Here’s the blend: test2

So the idea is the following:

LOD works with a object with different levels of subdivision. The most subdivided area is the space the player will occupy. The rest of the the mesh can be as low poly as possible. A vertex displacement shader is used to displace the mesh, but it used another object as reference for mapping. So, displacement, diffuse and normal maps are relative to a reference object’s UV. This way, as the LOD mesh tracks to the camera, the displacement and texture will not (hopefully), giving us an effective LOD (I think).
Edit: I’m using the ocean shader because is the only vertex displacement shader I found on the forum. I want to use it as terrain shader, so if some one can split it in 2:
one for ocean LOD and anothe for terrain without all the waves and timer part, and with a ‘object UV map’, no reflections or fresnel, just a diffuse, displace and normal maps.
Thanks for reading.


I am not sure if I understood completely what you were trying to do. A vertex shader can only displace vertices, but not add or delete vertices. To vary the number of vertices of the mesh according to the geometry-to-camera distance, you’ll need to use a geometry shader.

Or maybe you can try to use something like an offset mapping technique to fake height by using a fragment shader: http://blenderartists.org/forum/showthread.php?t=186213

Sorry I never noticed this reply (I swear this forum is updated every minute). I want indeed a vertex shader, to just displace the vertices. However, the displacement map is not UV projected on that geometry, It’s more like global, or object map. The number of vertices if fixed, since the displacement geometry tracks to the camera, the movement must look seamless though.

Or maybe you can try to use something like an offset mapping technique to fake height by using a fragment shader: http://blenderartists.org/forum/showthread.php?t=186213

My first idea was to use that, but since I need to ‘‘walk’’ on the surface of the object, heights need to be real (relief mapping shows artifacts on an horizontal angle, besides, the apparent height goes from the surface of the object in, so it can only be seen from above).
If you tested the example, I just want to replace the displacement modifier by a vertex displacement shader, the rest need to react exactly the same way in realtime. The example is again here: test
Thank you for replying! I was getting sad for being ignored!

I’m not sure if a shader really helps you with LOD. You still need to load and process all the data. The renderer might not render that much faces, but I’m not sure if this is not eating more processing time than it would save.

Anyway, I can’t help you with GLSL.

Thanks professor Monster.
However, what I’m trying to do is “Fake LOD”, I nearly accomplished with Martinsh’ Ocean Shader. I set the time to 0 and changed the displacement map. Then used CGcap’s adaptation and it works, I get infinite terrain (with fresnel and normal map though, I want diffuse instead).
CGcap tried at me request to make it work on a sphere and here’s how far he got: test 2
If you could replace the ocean shader with a simpler vertex displacement with just 2 maps HM and DM… The problem is with the Height map projection, I don’t need anything new on GLSL.
Here’s a example of simpler Vertex displacement shader:

uniform sampler2D displacementMap;

void main(void)
    vec4 newVertexPos;
    vec4 dv;
    float df;
    gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;
    dv = texture2D( displacementMap, gl_MultiTexCoord0.xy );
    df = 0.30*dv.x + 0.59*dv.y + 0.11*dv.z;
    newVertexPos = vec4(gl_Normal * df * 100.0, 0.0) + gl_Vertex;
    gl_Position = gl_ModelViewProjectionMatrix * newVertexPos;


uniform sampler2D colorMap;

void main(void)
   gl_FragColor = texture2D(colorMap, gl_TexCoord[0].xy);

As for processing consumption, I can change the rate at which the shader is called…

I will be annoying for once and persist in asking you WHY you would want to do something like this. It doesn’t improve performance nor visual quality.

As for the shader, you’ll probably have to do a bilinear lookup, a simple texel read will probably give a lot of artifact.

As for bilinear filtering, here you go:

#define textureSize 256.0
#define texelSize 1.0 / 256.0

vec4 texture2D_bilinear( uniform sampler2D tex, vec2 uv )
	vec2 f = fract( uv.xy * textureSize );
	vec4 t00 = texture2D( tex, uv );
	vec4 t10 = texture2D( tex, uv + vec2( texelSize, 0.0 ));
	vec4 tA = mix( t00, t10, f.x );
	vec4 t01 = texture2D( tex, uv + vec2( 0.0, texelSize ) );
	vec4 t11 = texture2D( tex, uv + vec2( texelSize, texelSize ) );
	vec4 tB = mix( t01, t11, f.x );
	return mix( tA, tB, f.y );

Code taken from ozone3D.net

Why would I do this instead of a cheaper method?

  1. The ocean shader seems to work pretty nicely, so the concept works. At higher details, it slows down considerably, but then again, there’s extra rendering involved. As for CGgap’s version, the maths might be taking a bit of calculi as well.

  2. Depending on the size of the displacement maps, I can have highly detailed surfaces (I mean at least mountains and basins) at reasonable frames (I believe it since the shader is only applied to a small surface [about 10X10BU]). Also if there is a way to map it (the D map) according to another object, instead of using expensive maths to accomplish the effect…

  3. Why not? It might just be a nice way to fake terrain LOD! I’m trying as many techniques as I can think of to accomplish high detail on planet surfaces. It saves game space as well a high detail DM is cheaper in size than a high detail mesh. I wanted to go as far as asking procedural heigh maps (like the ones on the realtime procedural clouds demo by Martinsh) but, I really need to control the collision structure…

Thank you very much for your valuable opinions!

As a proof of concept, here is the converted ocean shader into terrain. If the texture was seamless, I could have an unnoticeable infinite terrain…

CGgap’s modified.

CGgaps’ with above shader

The last one has got no diffuse texture (I couldn’t get it to work…) but is way faster than the first one!

I could see how to use this. I am working on a space trader/flight sim similar to escape velocity+freelancer, and it would be awesome if you could fly into the planets atmosphere and see greater geometric detail on the planets surface.

Yes, I’m also working on a space game, and the action happens on the planet’s surface, I want players to seamlessly fly about the planets. Using just geometry is a killer: It takes too much space in the HDD, it causes a lot of lag due physics on multiple polies, it takes more space with LOD meshes, etc.
Yes, I believe this technique - which will require only 3 meshes: the Low level backgroud mesh, the collision mesh(low-poly not rendered) and the vertex displaced mesh; is worth working on.

Hmmm. I am wondering about this as well. This effect is used very well in Spore on the planets. If someone could figure this out, it would be a great asset.