Original Post
My engine supports a terrain which can get generated out of voxels (Converted to polygons), so you can make nice caves and mountains as well as flat landscapes pretty easily. For texturing it, we use Triplanar texturing, so the thread title doesn't fit really. My main question is: How can I have different Layers of shader materials on it, like grass, mud and stone.
To make you familiar with that what I'm talking about, here is a picture from our ModDB profile (Pretty old version, the newer are smoothed [smile]):

(http://www.moddb.com/engines/wtech/images/terrain)
The whole terrain is made out of chunks, which are little meshes. I divided it into them because then, the regeneration of the meshes is faster than parsing the whole Voxel-Volume, even at locations which are untouched.
That means, the whole terrain has a large Polygon/Drawcall count.
I've made some thoughts about this, and now I would like to know if there is a better approach, or if someone knows an optimization, or just feedback [smile].
All of my "Algorithms" start with having one Hi-Res voxel-volume for the geometry and for each layer one low-res volume, which look like the main volume, just in a lower resolution (Those volumes aren't very memory friendly)
While the main volume holds the values to smooth the terrain (I won't go further into that), all layer volumes can hold a alpha value for each voxel, in a range of 0..255.
Lets say we have 3 layers, a Grass, a Mud and a Stone layer.
Approach Nr. 1, Layer-Meshes:
Generate as many terrains as we have layers, here 3.
Now, for each vertex in the Layer-Mesh parse the Layer-Volume, find the nearest Voxel to it and assign an alpha value to it. Do this 3 times with 3 meshes and we have 3 meshes which have the alpha values of the layer.
Then render all 3 Layermeshes with different shaders, with the given alpha value, and blend them together.
This would do it, but results in a giant fillrate and draw call count.
Approach Nr. 2, Terrain-Shader:
As I can't use normal UV-Mapping for the textures, there are free places in the vertices. These are: UV (Two channels), Tangent (Three channels) and Binormal (Three channels).
Then, instead of making a mesh for each layer, the alpha value could go into them. This would give us up to 8 layers. Then render it with one shader and let it blend all layers together (. This would only require one render of the terrain, but one shader would have to do everything. And this could get pretty messy and slow. Also the artist who is working with my engine isn't a "shader warrior", and I don't want him to write such complex shaders.
Approach Nr. 3, Deferred Rendering:
Do it like in Nr.2 and put the alpha values into the vertices. Then, render the terrain once with a special shader which writes the Position and Normals (Needed for Triplanar texturing) to rendertargets. Since I have a deferred renderer for the lighting already set up I don't need to do this anymore and I can use this instead. So the Terrain-Shader only needs to write the alpha values to one or two R8G8B8A8 rendertargets, according to how many layers we have (Maximum of 8).
When we have that, render a fullscreen quad for each layer (With the right alpha value), which puts the texture and effects onto the terrain.
This would provide the possibility of using multiple shaders for the layers and I only need to render the terrain once. However, there is a second "Layer-Pass".
What would you advise to me? Or do you maybe have a completely different idea of how to do that? [wink]
[Edited by - mind in a box on July 12, 2010 3:38:02 PM]
To make you familiar with that what I'm talking about, here is a picture from our ModDB profile (Pretty old version, the newer are smoothed [smile]):
(http://www.moddb.com/engines/wtech/images/terrain)
The whole terrain is made out of chunks, which are little meshes. I divided it into them because then, the regeneration of the meshes is faster than parsing the whole Voxel-Volume, even at locations which are untouched.
That means, the whole terrain has a large Polygon/Drawcall count.
I've made some thoughts about this, and now I would like to know if there is a better approach, or if someone knows an optimization, or just feedback [smile].
All of my "Algorithms" start with having one Hi-Res voxel-volume for the geometry and for each layer one low-res volume, which look like the main volume, just in a lower resolution (Those volumes aren't very memory friendly)
While the main volume holds the values to smooth the terrain (I won't go further into that), all layer volumes can hold a alpha value for each voxel, in a range of 0..255.
Lets say we have 3 layers, a Grass, a Mud and a Stone layer.
Approach Nr. 1, Layer-Meshes:
Generate as many terrains as we have layers, here 3.
Now, for each vertex in the Layer-Mesh parse the Layer-Volume, find the nearest Voxel to it and assign an alpha value to it. Do this 3 times with 3 meshes and we have 3 meshes which have the alpha values of the layer.
Then render all 3 Layermeshes with different shaders, with the given alpha value, and blend them together.
This would do it, but results in a giant fillrate and draw call count.
Approach Nr. 2, Terrain-Shader:
As I can't use normal UV-Mapping for the textures, there are free places in the vertices. These are: UV (Two channels), Tangent (Three channels) and Binormal (Three channels).
Then, instead of making a mesh for each layer, the alpha value could go into them. This would give us up to 8 layers. Then render it with one shader and let it blend all layers together (. This would only require one render of the terrain, but one shader would have to do everything. And this could get pretty messy and slow. Also the artist who is working with my engine isn't a "shader warrior", and I don't want him to write such complex shaders.
Approach Nr. 3, Deferred Rendering:
Do it like in Nr.2 and put the alpha values into the vertices. Then, render the terrain once with a special shader which writes the Position and Normals (Needed for Triplanar texturing) to rendertargets. Since I have a deferred renderer for the lighting already set up I don't need to do this anymore and I can use this instead. So the Terrain-Shader only needs to write the alpha values to one or two R8G8B8A8 rendertargets, according to how many layers we have (Maximum of 8).
When we have that, render a fullscreen quad for each layer (With the right alpha value), which puts the texture and effects onto the terrain.
This would provide the possibility of using multiple shaders for the layers and I only need to render the terrain once. However, there is a second "Layer-Pass".
What would you advise to me? Or do you maybe have a completely different idea of how to do that? [wink]
[Edited by - mind in a box on July 12, 2010 3:38:02 PM]