I've recently been working on a hobby voxel world recently.

I'm currently interested in ideas or solutions which would enable me to basically step up and down the Y-axis 1 horizontal block slice at a time, effectively making all upper horizontal slices transparent so that I can see objects/terrain/units under the earth.

[A quick visual attempt at describing the problem] Voxel World Horizontal Slice I've done a bit of googling on the subject but perhaps I'm not describing the problem set correctly because I'm unable to find anything satisfactory.

Goals :
1.) I dont' want to have to recreate the chunk meshes across the entire world everytime I step up and down the Y-axis blocks. It would destroy performance and probably crash Unity.
2.) Reasonably optimized quick stepping up and down the Y-axis i.e. no perf drops.

I know that a few options must be out there as I've seen examples in other engines and games (Byte56's Age of Goblins tech demo and Gnomoria etc). I'm guessing an algorithm via some magic shader math would be perfect.

All ideas greatly appreciated!


1 Answer 1


When I implemented this, I had hoped to do it all via the shaders. I planned on just passing a global Y coordinate into the shader and having the geometry shader just flatten all the terrain geometry above that Y coordinate to flatness. This works great if your game doesn't have any overhangs or caves, though this is unlikely with a voxel terrain.

What I ended up doing was a combination of shader and new geometry. I used the shader to remove all the vertices above the "slice level". This leaves a hole in the terrain wherever terrain has been removed, which is where the new geometry comes in. Like you I didn't want to have to rebuild chunks, so I just built a cap. Each chunk was responsible for building a terrain cap at the slice level. This was much faster than recomputing and building a whole chunk since it only needs to happen at one layer.

The two steps are:

  1. Use geometry shader to discard all geometry vertices above your slice point.
  2. Build a new mesh for each chunk that caps the sliced terrain.

Additionally, in my case I didn't want the player to see caves that hadn't been discovered yet. I implemented a feature where only 'air' cubes that were connected to the outside world would be visible. This was done at terrain generation time. I'd walk all the cubes connected to sky and mark them as 'found' along with any solid cubes touching that air. Whenever mining happened I'd start a new walk from that location to see if it reviled any 'hidden' pockets (like caves).

Any cubes that were not found show up as a black void texture. Where the found cubes would have the texture appropriate to their material type.

This was all done with a custom build engine. I haven't used shaders in Unity so I'm not sure what pointers to give you for implementing this in Unity.

  • \$\begingroup\$ Cheers for the very detailed and prompt answer. I was hoping you would respond to this question as I really liked and took inspiration from your implementation in your AoG youtube vidoes. Your shader + geometry mesh cap per chunk is interesting indeed. I'm familiar with GLSL and have just spend the day digging into Unity shaders so hopefully I can get something working! \$\endgroup\$
    – DanoThom
    Commented Jan 31, 2015 at 18:52
  • \$\begingroup\$ Sure thing, though I might suggest not accepting this answer yet, you might get a better answer! Accepting too soon discourages further answers. \$\endgroup\$
    – House
    Commented Jan 31, 2015 at 20:00
  • \$\begingroup\$ Good point. I'll leave it open for a bit longer to entice some different opinions. I've just discovered that I can't seem to compile geometry shaders in the latest Unity, even if use #pragma target 5.0 etc. So I'll have to hack around with alpha blending and transparency - which is probably going to cause more eventual issues. \$\endgroup\$
    – DanoThom
    Commented Feb 1, 2015 at 10:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .