I recently wrote an article on noise-based procedural (pixel) shaders I created for a project that uses the GPU to both render and edit heightfield terrain.
Besides explaining the Cg code, I also added an FX Composer sample project for anyone to play with.
Project intro + terrain rendering article + nice demo movie: http://www.decarpentier.nl/scape-render Procedural shaders article + FX Composer project: http://www.decarpent...ocedural-basics
Hope some of you find this useful!
I read your article, its really well written and the iq noise is interesting!!!
Thank you, Rouncer, I appreciate it.
I hope to post another article on this in a week or so, covering ways to mix noise on the GPU in even more complex ways
in order to generate (even) more interesting terrain, as demonstrated in the youtube clip.
The IQ noise looks very good, and I love the perp/aligned features brush.
Do you have any examples of how the horizontally projected texture improves appearance?
I do now
Obviously, a single Y projection works fine when slopes are gentle, but when you need proper texturing on steep slopes as well, it's not always enough.
Then again, the terrain in this image is pretty much on the border of what can be done with heightfields, so the technique's advantages in more 'typical' scenarios might be a bit less pronounced.
(The subtle light/dark banding in BOTH images is not a texture projection artefact but the result of using (faster and compacter) vertex normals instead of a normal map).
I hope this clarifies it a bit.
I just wrote another article on this topic, covering two novel procedural algorithms that try to mimick the
look of different types of eroded terrain, without actually doing an erosion simulation.
Two screenshots generated with the aid of these algorithms:
Again, it's accompanied by an FX Composer project that exposes the algorithms as a real-time (pixel shader) effects.
Let me know what you think!
Giliam de Carpentier
That's some fine looking terrain! Now I kind of wish I was still tinkering with terrains, so I could mess around with this myself
For those interested in tech behind the Scape project, I've just written another article on it.
This time, it's mainly about the editing pipeline as a whole, using the CPU and/or GPU to locally edit the terrain through brush strokes.
It also covers directional noise, which generates procedural noise that has its features stretched or compressed at an angle relative to the direction of a brush stroke, creating user-driven effects that would be hard to create otherwise.
I found IQ noise about a year ago, it's stunningly good. A little slow to generate for realtime stuff, but just beautiful.
The one I am really struggling to do at the moment is lunar terrain.
For my needs I use the 3d position of the vertex (on the surface of a unit sphere) as the input to the height generation function, this works really well with iq noise, but for generating craters... pretty awful.
That's a complicated one, as it's less of a fractal landscape in a sense.
I've never tried it but I'd imagine that something like the following might do a decent job:
- Start of with a smooth turbulence function as the base height
- Implement something similar to texture bombing as described here, using a texture height texture of a crater, having has a dark spherical center, a light rim and midgrey edges and do the lookup as follows: height += (0.5 + 0.5*random.w) * amp * (tex2D(imageTex, (1+random.z) * freq * (offset_t - random.xy)).r - 0.5). Alternatively, do this 'lookup' using a procedural function that you like. The (1+random.z) factor is there to randomly scale the radius of the crater between 50% and 100%, while the (0.5 + 0.5+random.w) is there to scale the amplitude between 50% and 100%.
- Call the texture bombing function multiple times per height sample (i.e. vertex), similar to calculating and summing the octaves in the turbulence function, increasing the frequency and decreasing the amplitude with each subsequent octave (for, example: freq *= 1.9, amp *= 0.55).
Alternatively, you could replace the texture lookup with a radial procedural function of your own, of course. But the texture approach might give you more opportunities to tweak the result to your liking (e.g. select one of many non-perfectly-circular variations per bombing). You could also try a little input distortion as discussed and implemented in my third article on Scape to add more variation to the shapes themselves.
In any case, this approach should create randomly placed craters of wildly varying sizes.
And even though I've got no idea on how good the above will already look, it will probably give you an interesting base to experiment and extend from.
Hope this all makes sense.
I tried a similar approach a while ago using cell noise rather than a crater texture. It was dog slow and didn't look very good.
The use of a crater texture will probably improve the looks of the result, but it still will be dog slow as we would need a lot of octaves.
I'm beginning to think this cannot be done as a single shader, I think I'm going to have to get creative.
For those who are interested: I just released the free binary and all of the source code for Scape at www.decarpentier.nl/scape.
Very impressive! Any ways to export the mesh, say, to an OBJ?
No, not directly, but it can export the heightfield as greyscale image, which can probably be used in your favorite modelling tool (blender, max, maya, ...) to displace a plane and just export it from there instead.
Although the feature could be added to Scape, i'd image it wouldn't be used that often, as modelling tools are often just as happy to work with heightfield images, and most game engine require a heightmap input image (instead of mesh) for their terrain system anyway, as they generate the terrain mesh on the fly (based on the exported image) for performance reasons (lod, bandwidth, culling, ...).
I see what you mean, make sense. About the heightfield as greyscale image, is it float based or 0..255 based?
That's a good question.
Different tools support/prefer different formats. That's why Scape can import from and export to a bunch of different formats:
8-bit (0 ... 255): BMP, PGM, PNG, TGA, TIFF, RAW
16-bit integers (0 ... 65536): BMP (using Unreal's color encoding scheme), PGM, PNG, TIFF, RAW
32-bit integers (0 ... 4294967296): TIFF
32-bit floats (0.0 ... 1.0): TIFF, RAW