spherical fractal heightmaps

Started by
8 comments, last by swiftcoder 18 years, 10 months ago
Ok, so I have a Level-of-Detail planet renderer all set up and working, but driving this with a fractal heightmap is not seeming very easy at the moment. Basically, I am trying to do two things: 1) retrieve a height value for any point on the planet, which is generated by passing in a normalized vector containing the direction for which I need the height. and 2) to generate textures for each tile, where each pixel is found by passing in the normalized direction vector to that point. I have 1 running, just by feeding the normal into a 3-dimensional perlin noise generator, but the results are a little unpredictable, to say the least ;) and when I tried texturing the same way, things looked even worse, very distorted looking, as if it was a bad texture mapping. I would be very grateful if anyone had any advice on ways to generate spherical noise, or a better way to map to the noise. Haven't had much luck searching the net, most people making fractal planets seem to be ray-tracing, not sub-dividing triangles. Thanks in advance, SwiftCoder

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Advertisement
3D Perlin noise has worked fine for me for both raytracing and triangle meshes. As the texturing depends on the altitude of the point I used the same noise function for both...

Your problems are probably in the specific implementation. For example, if the noise is too high-frequency compared to the mesh density, then the results won't look smooth. Also the way you map the textures onto the sphere will produce various distortions. Is this a tesselated icosahedron, or a sphere constructed of latitude rings, or an inflated cube or...?
I agree with the previous poster.
IMPORTANT! Make sure you use a terrain based on 3D noise.

For example I use the ridged perlin terrain texture from Musgrave.
Applying this on a sphere with different radius will give you
smaller or larger features.

Good Luck
You are doing it right I think.
But try to multiply your normalized vector with some radius for example 20
and see if things don't look better.

Otherwise please send an image on what you get and maybe it's easier to see what is wrong.

Cheers
LOL, thanks for the help.
Turns out it was a stupid typo, which caused the planet to use a 2-dimensional perlin noise generator instead.
Someday I am going to kill whoever invented auto-completing code editors.

Now for the next problem, everything works fine, except I am getting seams at the texture edges, even between tiles at the same LOD. Any ideas why this is happening?
I will try to post a picture:


Thanks,

SwiftCoder

[Edited by - swiftcoder on June 23, 2005 2:21:14 AM]

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

That looks like a texture filtering artifact. If your UV coordinates go from 0.0 to 1.0, you'll see a thin sliver of the bottom of the texture at the "top" of the terrain patch, and the same for left/right. You can either limit your texture coordinates so that they start half a pixel inward from each edge, or use texture clamping to automatically stop the color bleeding. (In openGL this would be GL_CLAMP_TO_EDGE)
Thanks Fingers_, GL_CLAMP did half the trick. Now my next problem is with the kind of filtering, here are a couple of pictures with low-res textures, and different filtering:


The first uses GL_NEAREST filtering, and the second uses GL_LINEAR. Obviously, the GL_LINEAR looks a lot nicer, but introduces filtering artifacts at the texture edges (especially noticeable on the rather corny skybox test).
Perhaps I should make the texture a pixel wider on each side than I am actually going to use? or is there a simpler way?

Thanks,

SwiftCoder

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Try setting the texture coordinates to 0.5/N resp. 1-0.5/N instead of 0 and 1
on the boundary, where N is the resolution of the texture.
GL_CLAMP causes the black borders you're seeing (it displays whatever you've set as the "border color" outside the texture, the default being black). GL_CLAMP_TO_EDGE will actually clamp it to within the texture so there shouldn't be any visible borders at all.

If your hardware/drivers don't support edge clamping then the half-pixel offset will be the only way... I don't really like this method myself because it has problems with mip-mapping. You'd have to include something like 8 pixels of border along the edges of each texture to make it look good with the first three mip levels.
Many thanks, I hadn't realized GL_CLAMP_TO_EDGE was any different to GL_CLAMP.
Works perfectly with edge clamping:



Thanks again,

SwiftCoder

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

This topic is closed to new replies.

Advertisement