Archive for the ‘noise’ Category

13
Jun

Few Experiments

   Posted by: Foxtox

Played around with a few methods for modifying the terrain, so far just doing simple
modifications to the fractional part of the noise input.

The input is from 0.0-1.0, so to keep the terrain continuous it helps if the output also is
(more or less); but at first I was getting terrain with boxy shapes because I wasn’t doing this
correctly.

One very interesting result was this: A world composed out the outline of boxes.

Modification:
_mu = _mu*2.0*1.33134 -1.33134;
_mu = cos(_mu*_mu*_mu*_mu);
tinker.jpg

Where they grow..
Tinker toys

Another example where the signal is not smooth…
Cool but pattern can be seen

Realized what I was doing wrong, fixed it, and implemented a sin filter; it only looks
subtly different from the standard appearance so I won’t bother posting a picture.

More interesting was a sin(x^2) filter:

_mu *= 1.2533141373155002512078826424054;
_mu = sin(_mu*_mu)

Lots of poker type things appeared…
Poke

And some odd looking rounded shapes occasionally..

Smooth

Dark twisted area I’m posting for no particular reason.
darks


Super Shape?

I saw this about Super Shapes and thought I might see if they could be made to
work within my generation process– but the results aren’t so great, and it is also rather
slow since it involves a great many calls to sin/cos.
Not so Super
-Problem being the super shape function expects as input angles, and returns positions;
but I already have a position & just want to modify the density. What I did was calculate an
angle based on an arbitrary center point, and then use the returned position to modify
the existing density dependent upon how far it was from the real position… but
it tended to blob together and stretch/tear in ways that the proper super shapes don’t.

Point Rendering:

Awhile back I was reading the Atom journal and began wondering if points might
be a nice solution for my terrain.

Good:
+ Would greatly reduce memory usage since index buffers wouldn’t be necessary.
+ The poor triangulation MC generates could be avoided and likely point interpolation
would look superior.
+ Could skip most of the MC steps altogether for faster generation
Bad:
– Could be issues if points aren’t dense enough
– The hole filling step doesn’t sound particularly fast, and I would have to do this
multiple times(shadow maps too).
– Might not work so great with occlusion culling

Here is the terrain rendered using points(looks kinda crap from jpg compression)
point cloud

Visual Studio 2010
Also download the VS2010 beta 1, it supports lamba functions and
various other new C++ features, but mainly what I noticed was:

1) Unresponsive UI — often around a 1 second delay
2) It crashed within the first 5 minutes
3) Intellisense can’t compete with visual assist, though it does have some new
abilities I have not seen before(red squiggle lines under things it doesn’t understand;
hover over said items and it actually says in English why).

I look forward to the new C++ language features, but MS really needs to improving
the UI responsiveness; considering I’m running an i7 there is no reason
for it to be so slow.

Bindless Graphics
Also tested out NVidia’s new bindless graphics extensions, but for whatever reason
this resulted in crashes once enough terrain chunks had been generated.
An Nvidia guy told me it was a driver bug, so hopefully I can re-enable this down the road.
Using occlusion culling also seemed to anger it greatly as any attempt to run with OC
enabled would result in a crash within seconds of startup.

I’d like to start using dx11(or 10) more, OGL is just getting old.

4
Oct

Precision

   Posted by: Foxtox

Dealing with precision loss:

GPU precision:
In order to actually display a large scale terrain system I had to address the issue of precision loss, originally I was translating the camera around like it is done in most games, but when the camera was very near the surface the more detailed chunks would start to jitter about.

To combat this I am now subtracting the camera’s position from each object’s position prior to rendering said object. In the shader I only need to rotate the object, and now everything is relative to the origin of (0,0,0) and precision loss is minimized. On the CPU side I could use doubles, but as of yet it has not been necessary, and the jitter is completely gone.

Noise precision:
Another place where precision has become an issue is in the generation of the noise data.
Essentially noise assigns random values to points in space and then interpolate between them
to create a smooth signal. By adding these octaves/signals together you can create something
that looks like a mountain range etc. I am using many octaves for my noise, each using a
higher frequency and lower amplitude then the previous.

In order to create a spherical planet I am running a short post process algorithm on the
noise results which alters the signal based on its distance from the surface of a
perfect sphere, points under the surface have their density increased and points above
have their density decreased. I was using SSE to process 32bitx4 floats, since the
process involves a square root(I could use distance squared, and may switch to it at
some point, but it was less stable when I tested it out; the drop off from solid->air
was exponential instead of linear).

SSE, unlike x86, which has 80 bits internally, really only has 32 bits of precision so
as the camera descended toward the planets surface some visible stair step effects
could eventually been seen.

I have switched to using SSE2 64bitx2 doubles during the “make spherical” step,
and happily the stair step effect is gone.

Here is the inner loop in SSE2, this gives me chance to test out posting of source
code…(sorry the syntax highlighting is terrible.. and the spacing..this thing
fails at understanding tabs..)

NOTE: All the input(position/radius) was scaled down prior to running this code in order
to increase the range from 100% solid to 100% air.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
for(int i = 0;i<8;++i)
{
   for(int j =0;j<8;++j)
   {
	zyPosSqrDist = (zSqrBuf[i] + ySqrBuf[j]);   //Sum square Z and Y positions
	SquareDistZY = _mm_set1_pd((zyPosSqrDist));
 
	for(int m = 0;m<4;m+=2,bufOffset+=4)
	{
 
		CurBufferValue = _mm_load_ps(&buffer[bufOffset]); //Load the 4 32bit noise values
 
		SurfaceVal =_mm_sub_pd(Radius,	        //Subtract distance from planets radius
				 _mm_sqrt_pd(			//sqrt to get real distance
				 _mm_add_pd(SquareDistZY,	//Add ZY square to X square to get distance squared
			           xSqrBufSSE[m]))) ;	        //X square distance for this row
 
		LowerBuf = _mm_cvtpd_ps(SurfaceVal); //Set lower 2 spherical offsets
 
		SurfaceVal =_mm_sub_pd(Radius,	                //Subtract distance from planets radius
				_mm_sqrt_pd(				//sqrt to get real distance
				_mm_add_pd(SquareDistZY,	        //Add ZY square to X square to get distance squared
				xSqrBufSSE[m+1]))) ;	                //X square distance for this row
 
		UpperBuf = _mm_cvtpd_ps(SurfaceVal); //Set upper  2 spherical offsets
 
		OutBuffer = _mm_movelh_ps(LowerBuf,UpperBuf);	//pack them together
 
		//Add the 4 spherical offsets to the 4 noise values
		CurBufferValue = _mm_add_ps(CurBufferValue,OutBuffer); 
 
		//Now write back to buffer
		_mm_store_ps(&buffer[bufOffset],CurBufferValue);
 
	}
   }
}

There is still a very faint darkened line that appears when the camera is extremely
close to the surface, basically when the near plane is intersecting with it.
I need to investigate further but I suspect it may caused by the extremely
small intervals which are being interpolated in the noise once ~15 octaves has
been reached.

The terrain normals are currently just 3x8bit normals, which so far has
worked surprisingly well, but I may switch to something along the lines of 10/11bits
for X/Y and packing the sign of Z into the leftover bits. More work in the shader
to decompress it but possibly worth the processing time.

Terrain Improvements:

Sliver removal: Marching cubes tends to generate many small triangles,
some so small they contribute nothing to the overall model, and in truth make it look
worse as they create shimmering when the camera moves. So I am now processing
the chunks to remove all sliver triangles. The process is controlled by a float
specifying the relative minimum allowed distance between vertices from 0.0-1.0.
At a moderate setting it removes around 20%-30% of the triangles and I cannot
really see any reduction in the quality of the terrain.

And finally..

Balancing the amplitude of each octave so that it doesn’t introduce more information to the signal than the visuals can support is turning out to be very important. This greatly reduces the amount of “floaters” and other unsightly looking problems found in the image.

In the following screens I’ve found a much better balance then in any of the previous screens
I have posted, though a few small floaters are visible and the sharp edge issue is still present.

improvedwithlight.jpg

Again, after the light has been moved.
improvedallbright.jpg

This shot was taken prior to the precision fix(actually they all were), if you zoom in
on the lower right corner you can see some ugly tearing/stair step starting to show.
torch.jpg

22
Sep

More Terrain

   Posted by: Foxtox

I’ve worked on various aspects of the terrain system since last time.

Level of Detail:

The LOD system determines when a chunk should split, but I can’t just let every chunk split just because it is close enough to the camera to do so, as this would result in a whole lot of chunks trying to generate at once, and create a massive stall. Instead I assign a score to each chunk that wishes to split-the score is based its depth in the quad tree, how close it is to the split point, and if it is visible-and send off only the best scoring chunks to be split. This generation runs in a threaded job system so it scales to however many cores are available.

Here is a screenshot of the terrain, with each LOD colored differently.
lod.jpg

Performance

Performance wise I also discovered that the data type I had been using in the vertex format for my terrain normals was quite slow, apparently using signed uchars/ushorts with normalize set to true (using glVertexAttribPointer() ) is not the fast path, instead I’ve switched to using unsigned uchars/ushorts and just subtracting 0.5 in the vertex shader. This one change basically doubled my FPS. It would be really great if the drivers would actually give some indication of this instead of having to resort to trial and error(and for all I know this is just a problem found only on my 6800..).

Randomness

I was originally using 256 element look up table for the random gradient, as is used in perlin 3D noise(except I used 3 of them, one for each axis), and although I couldn’t really visible see the repetition, it still seemed prudent to try and reduce the repetition as much as possible so I fiddled around with some various integer hash functions.
Integer Hash: this site had some nice integer hashes.
At the moment I’m using a mix of integer hash and perlin LUT by offsetting the hash by the value in the LUT. I probably need to go over this again at some point, but believe the terrain does look more “random”.

Lighting & Marching Cubes Issue

Another thing I’ve been playing with is the lighting of the terrain; I’ve tested out a whole bunch of ways to generate the terrain normals, and in general it seems to be a tradeoff between smoothness and detail. Using sobel filter type methods I can get extremely smooth normals, but they lack fine details, while using central difference the detail is better but some sharp edges on the terrain appear jagged. This jagged edge effect is a result of my current implementation of marching cubes, which is based on marching cubes 33. MC33 solves the ambiguity problems in MC but does not allow for sharp edges(it creates rather ugly zigzags where sharp edges exist). Since I’m largely using ridged noise which is all about sharp edges to generate my terrain, the result is plenty of zigzags are visible on the terrain.

Thankfully there are a couple of newer, improved marching cubes algorithms which solve the
sharp edge problem. Unfortunately they are quite abit more complex then standard MC.

Cubical Marching Squares: This one apparently solves the sharp edge problem by further subdivision, not sure that is what I want..

Dual Marching Cubes: This is a much nicer paper, the algorithm is explained well enough and I think I will try and implement it at some point. As a bonus it would drastically reduce my triangle count since it removes triangles in flat areas.

I’ve implemented a few different lighting models, originally I was just using Blinn, but I was curious how some of the other models would look for terrain. So far I’ve only tried OrenNayar & CookTorrance, since I don’t currently have tangent information available in the shader (I’ll eventually add it for normal maps I expect) as is require by some of the models. The two screen posted below use Oren & Cook respectively.

Terrain Formation:

I also fiddled around with some alternative algorithms for generating the terrain to try and create some different looking shapes. So far I’ve found methods for creating…

Blockworld: Looks like a bunch of chipped stone slabs all stacked on each other. This could possibly be used to create a cracked/slab like appearance for some stone shapes near the surface.

Mounds&Craters: One of the algorithms I made creates irregular shaped mounds mixed in with craters/lakes. I’ve mixed this in with some ridged noise and it seems to work fairly well, although not terribly realistic it does add some variety to the terrain. I’m not really focused on creating realistic terrain, I just want something that looks interesting, so I’m alright with the lakes not having rivers leading into them…and rivers are close to impossible with procedural methods.

Here is a screenshot showing a Mound like shape mixed in with multi-fractal ridged noise. This is also using OrenNayar lighting so supposedly it should look clay-like. I have the normals set to detailed as apposed to smooth so some zigzags are visible.
irregularshape.jpg

And here is a shot taken using the CookTorrance model, supposed to be nice and glossy which obviously doesn’t suit terrain but whatever. Also very jagged as the normals are set to detailed & this shot has many would-be sharp edges.
torrancecook.jpg

7
Sep

Development Journal

   Posted by: Foxtox Tags: , ,

I’m going to try and keep a short dev journal here, hopefully it should help to keep my motivation up and serve as a nice method of keeping track of my own progress. My current project, which is just one part of larger game, is a volumetric terrain system, and I’ve been working on it on and off throughout the summer.

By volumetric I mean that unlike most terrain systems which use heightfields, and are essentially just 2D, thought they have been extruded to appear 3D, mine is actually 3D. The advantage of being volumetric is you can have features you don’t normally find in a terrain system, such as overhangs, caves, and tunnels. Additionally shear cliff walls are not stretched as is common in heightfield based methods.

There are some pretty sever disadvantages though; the implementation complexity is increased, and the time required to generate the terrain is much higher. Many heightfield methods use 2D images as a source to guide the terrain, alternatively noise can be used, or even mixed in, to add detail to the terrain.

Storing a 3D image, as would be required for volumetric terrain is very impractical(would quickly exceed available storage), so I use noise to generate 3D volumes at run time. I do this on the CPU using a highly optimized version of 3D noise I wrote specifically for this task(implementations of noise available on the net are far to slow). Once the volume is generated I use a marching cubes derivative to create the mesh.

Now obviously if I want to create an entire planet or even something small like a valley I cannot afford to process every point in space for the volume, so I use a system very similar to ChunkedLOD, based on a octree, which hierarchically creates nodes, determines if they contain anything visible within them, and if so(once the camera is near enough) generates each child of the parent node dependent upon whether any triangles were contained in that quadrant(octant?) of the parent. The same octree is also used to frustum culling(though I can shrink the bounding box to match the actual verts found within the nodes volume for greater accuracy).

I’m going to have to cover some basics of the system in more detail, but I’ll leave that for later post.

Here are some early screens of the volumetric terrain.

NOTE:
-I have not yet added skirts(to hide the gaps between the different LOD’s) so some “green lines” are visible(green because my background is set to green).
-The terrain is currently not textured at all and is only using vertex normals.
- I’ve noticed it is hard to gauge depth in these still pictures, though it is quite easy when the camera is moving, I believe this is a result of there being no visible atmosphere(fogging/horizon fading) or textures to disguise the self similar nature of the noise.
-The terrain pictured here is using very simple noise algorithms(Fmb | Ridged), eventually I will make it much more complex and varied.

Looking through an arch down into a valley
Arch

Rolling Ridges

This is the same planet that the above “Arch” picture was taken from.
From “space”