Saturday, January 28, 2012

Textured Procedural Planet

…aka back to square one albeit the terrain is round this time, so back to round one? I added some textures to the planet, generated on the GPU, they look ok but still lots of work to do. First some outtakes, looked like a load of shite at the start…

JellyEngineXna 2012-01-27 19-15-05-88JellyEngineXna 2012-01-27 19-15-16-54

… then a bit like an old leather ball…

JellyEngineXna 2012-01-27 19-23-18-91JellyEngineXna 2012-01-27 19-26-42-21

… then all contoury …

JellyEngineXna 2012-01-27 19-30-04-16JellyEngineXna 2012-01-27 19-29-49-84

… (which is actually not too bad looking) then it started to come together a bit …

JellyEngineXna 2012-01-27 19-35-58-32

The problem with this though is that the source texture is applied at the same scale for each patch so there’s a noticeable jump when changing levels, a higher level might show a rock but when it subdivides there are 4 rocks. This gif shows the gifferences when approaching, it looks like the centre patch uses a completely different texture.

texturemonoscaleprob

So it made sense to scale them according to the level (texCoords *= pow(2, maxlevels – patchlevel)), but this introduced some pretty nasty artefacts when zoomed out due to tiling the same texture over and over. Applying mipmapping to the texture I was using helped a bit but it’s still very obvious.

JellyEngineXna 2012-01-28 00-26-54-35

The transitions looked very layered so I added a bit of noise:

JellyEngineXna 2012-01-28 12-51-12-78JellyEngineXna 2012-01-28 12-51-43-54

All in all it’s not bad for a first go but could be a lot better. I was having fun flying about the place so I made a little video:

 

…then noticed a problem I had neglected from before that’s obvious in lines going through the brown pit on the right at 0:34.

JellyEngineXna 2012-01-28 12-19-10-78

I thought it was cracking at first because it only seemed to occur when creating other patches but investigating it further it wasn’t cracking, but something to do with textures. Another gif to show the gifferences…

pointlinearclampproblem

The points are fine, it’s the texture on top that’s creating the artefact. What it ended up being was a leftover setting from creating patches. In order to get the heights from the GPU I draw the noise for each vertex in a patch to an image and read them back to reset the vertices. In order for neighbouring patches to have the same height values I draw it as a point-clamped list of lines. When this was happening a subsequent draw would use the point-clamped sampler and create the artefact. Looking for how to fix led to some good advice, don’t assume sampler states when drawing, explicitly set them every time you need them.

I’ve found a few other very impressive procedural planet projects so I might trawl their blogs to see if they mention how to do textures so well. So for next time…

  • Adding noise to the texture isn’t great, needs a good bit of tweaking. I could try to do a look-up table & incorporate slope as in this old post from Ysaneya (Infinity).
  • I need to hide tiling somehow, it occurs and is dealt with in the old post from Ysaneya above but the description is just “lighting, shadowing, other effects”.
  • I’ll need a better noise algo, the one I’m using is very homogenous (“samey”). This project called lithosphere might help find a good one quickly.
  • The FPS are struggling whenever creating patches & I’m not showing that many polys so I might need to do some optimisation. I pass data around a lot between CPU and GPU so I think these articles by Shawn Hargreaves might help find out if I’m CPU or GPU bound and try to balance both.

Lots to do!

Tuesday, January 17, 2012

Less Abnormal…

This problem took me MONTHS to resolve. First I had to laze about and ignore it for about 6 months until a new year’s resolution made me look at it again. The problem is that each patch is created independently (i.e. it might not have any neighbours yet), so when calculating the normal vectors at the edges the normal calculation is biased towards itself. It’s kinda hard to explain in words so hopefully a diagram will help:

image

A normal is a normalised vector perpendicular to the surface at a certain point, it might help if you imagine walking on the surface, at peaks and troughs you’ll be upright but on slopes you’ll have to compensate by leaning in (or fall over whatever floats your boat). In this example, I’m trying to work out what the normals are for the green “patch” (the green V) and I don’t yet have the blue or the red patch. So I have to calculate a normal (pink arrows) for each of the 3 points in the green patch using just those 3 points.

I can work out the centre normal fully using the 2 adjacent points to the left and the right. However the left and right normals only have 2 points available (left & centre for the left normal, right & centre for the right normal) for normal calculation and so they end up perpendicular to the left and right vectors. When the red patch comes along it happens to work out well, the normal on the right indicates a slope. Unfortunately when the blue patch comes along it  will look wrong. The left normal should be pointing straight up because it’s a peak, not a slope. If that wasn’t enough, to make matters worse when the blue patch works out its right normal it will look like a slope in the opposite direction so lighting will shade the slopes with a very sharp divide at the top.

In order to solve I could redo neighbouring normals whenever a new patch is generated but this would cause lots of rewriting the vertex buffer & would be visually obvious until the neighbouring patch was created. The way I opted for was to extend the patch area by one cell (equivalent to getting the middle point of the blue and red patches) and work out normals for all the inner points (same number of points as in the unextended patch). It worked out pretty well, here’s a before and after shot where latitude lines disappear:

JellyEngineXna 2012-01-17 21-35-20-06

JellyEngineXna 2012-01-17 21-35-25-64

And a close up with pink normals. On the peak in the before shot there’s divergence with normals at the same point going different directions. In the after shot the normals on the peak look like one normal but really they are 4 different normals all pointing in the same direction:

JellyEngineXna 2012-01-17 21-40-58-54

JellyEngineXna 2012-01-17 21-41-10-70

It’s a bit less obvious but on the mountain side you can see some lines caused by divergent normals where patches meet in the before shot disappear in the after. I made a gif to show gifferences but the 256 colour palette isn’t the best:

peak

I think I’ll have a little look at texturing next, to get the planet looking like the terrain I had SEVERAL years ago… pretty shameful thinking this is progressing so slow but sure I’ll keep tapping away at it, one day at a time*.

*time may be anything from 6 months to a year or two!