I am currently working on a voxel terrain that uses the marching cubes algorithm for polygonizing the scalar field of voxels. I am using a triplanar texturing shader for texturing. say I have a grass texture set to the Y axis and a dirt texture for both the X and Z axes. Now, when my player digs downwards, it still appears as grass. How would I make it to appear as dirt? I have been thinking about this for a while, and the only thing I can think of to make this effect, would be to mark vertices that have been dug with a certain vertex color. When it has that vertex color, the shader would apply that dirt texture to the vertices marked. Is there a better method?
2 Answers
Yep, that's what Ken Silverman's VoxLap Engine did; by today's standard's you're typically better off (re)calculating voxel data as and when you need it, than consuming memory by pregenerating things you don't need right now. Although the data structure used was RLE, each voxel was in essence "born equal". It was only when something was exposed (i.e. when it became a surface voxel) that it had to be assigned a new colour... given the limitations at that time, I've little doubt this also reduced the size of the active surface voxel set and so enormously reduced memory consumption which was at a premium.
...Though Silverman's was a "pure" RLE voxel engine as found in the NovaLogic games, not the expensive, polygon driven kind we see everywhere today. But many of the same challenges apply... like this one.
-
\$\begingroup\$ But how are you supposed to (re)calculate voxel data and check if it is above or below the terrain surface, if the terrain surface isn't flat? \$\endgroup\$ Oct 29, 2012 at 13:25
-
\$\begingroup\$ @DantheMan Well, first, what are the conditions under which a voxel is considered to be a surface voxel? \$\endgroup\$– EngineerOct 29, 2012 at 14:08
-
-
\$\begingroup\$ @DantheMan How do you know when you've been buried alive? It's the same answer. I'm not asking this to annoy you, but because working with voxel worlds requires you to have a particular way of thinking. \$\endgroup\$– EngineerOct 29, 2012 at 14:13
-
1\$\begingroup\$ @DantheMan Almost: On ALL sides. That is, you need to perform a check for 6-connectedness. Provided all 6 checks turn up true, the current voxel is NOT a surface voxel. What's key is that you need to perform these checks only in the region of where a terrain change has just occurred (this being during generation time, where a great many such checks will occur, and at runtime, any time the player or something else affects the world). For this reason, one must be very careful never to change too much at once; any voxel op occurs in an AABB, and the cost goes up drastically with side length. \$\endgroup\$– EngineerOct 29, 2012 at 14:18
off the top of my head, I can think of a few possible solutions;
My implementation assigns a colour to each vertex, and can blend between 4 different sets of tri-planar maps. Each voxel has a material type, and I blend the colours based on that.
In your case I could use one material as dirt with grass, and one as plain dirt. When generating my voxels I could to a surface check to see if dirt is exposed, and set it to grass-dirt.
Digging would produce dirt surface.
This also allows you to have other material types - trivially 4 material types, but with a little work, you can extend that further too.
Or, perhaps create a top-down projection map, and use localized splat mapping.