When you want to compute a heightmap and use for 3d voxel binary, it's easy.

solid are maybe 1, and air are 0, easy.

But in my case I would like to have a smooth terrain, so the solution is the floating point value. But now I cannot say "Hey, it's 1 so it's solid !" because when I use 1 or -1 with a threshold to 0. It's will work, sure, but look like blocky, not smooth.

When you compute a 3d noise, it's easy you just have to set the computed value (scaled from -1 to 1, threshold to 0). It's will look nice. But for 2d noise...

Let's say, 0 is the minHeight and 500 maxHeight. The 2d noise function is scaled between 0 and 1.

At x:0, y:0, let's say the final value of the height is 250, that the middle. (noise output 0.5 scaled from 0/1 to 0/500)

But for each height, what I am supposed to set ? In binary case, solid are 1, air 0. But in floating point case, what should be the value ?

I tried to apply the noise result (0 to 1), and where y > computedHeight (computedHeight=250) the value is -1.

It's look blocky (That normal) but I don't have the right solution.

So what I am supposed to set to each y voxel ?

Ok my question look confusing, sorry for that.

I can easily get a smooth terrain based on heightmap value. Here is a screenshot.

voxel layer ground, cave and both together

As you can see, when I combine it with 3d layer, there is a problem, cave is blocky.

Why this problem, I guess it because the cave value are between -1 to 0, nice. But the ground layer that computeNoise*maxHeight-y which give nice result but the value is wrong ! And I'm looking for a better way to compute the heightmap (ground layer) to have correct value and get a smooth cave. :)

Here is my pseudo code of how I generate my voxel array.

for (var x = 0; x < sizeXz + 1; x++) {
    for (var z = 0; z < sizeXz + 1; z++) {
        var compute = Biome.ComputeXz(voxelX, voxelZ);
        for (var y = 0; y < sizeY + 1; y++) {
            data[x, y, z] = Biome.GetY(compute, voxelX, voxelY, voxelZ);


public ... GetY(...){
    var computedHeight = Scale(compute.value, 0, maxHeight, 0, 1); //Scale noise 0-1 to 0-MaxHeight
    var currentValue = computedHeight-pos.y;
    var currentType = BlockType.Rock;
    if(pos.y > computedHeight)
        currentType = BlockType.Air;
    return new Block(currentType, currentValue);

This work, this look nice (see ground layer image), but the value are wrong because if you lower, you'll get some value like -82.28389, because of the -y to the currentValue which means further you are from the threshold further from 0 the value will be.

And the cave layer which is a raw output from the noise function (so a value between -1 and 1).

As you know Marching cube do a interpolation between each voxel so I let you imagine why the result is so blocky between the cave which output value like 0.0x and ground output like xx.x

Sorry for the long post.

  • \$\begingroup\$ The obvious answer to this question would be to use a smoothing algorithm like marching cubes. But the question mentions that the author already know about that algorithm, but not why it isn't applicable to the problem. That makes me wonder what exactly is the problem here. \$\endgroup\$
    – Philipp
    Jan 1, 2018 at 4:22
  • \$\begingroup\$ The question is not about how to use the smooth marching cube 'cause as the two layer alone are smooth. But when combined they aren't anymore. The question is how to play with the value on each voxel when we merge two layer. Even 1 year later I still don't know. \$\endgroup\$
    – Alaanor
    Jan 1, 2018 at 9:35
  • \$\begingroup\$ I'm trying to understand the question. You have 2 objects. A surface generated from a heightmap, and a volume generated by a binary 3d matrix. How are you combining these 2 objects? Are you trying to combine them by converting the surface to a binary 3d matrix and interpolate between them? \$\endgroup\$
    – Kyy13
    Aug 16, 2018 at 18:37

1 Answer 1


That's up to you. You have to define a limit (in your case between 0 and 1) which determines which positions are in or out of your terrain. So let's say your values go from 0 to 1, you define 0.5 as the limit, then you can interpret it as every position with a value below 0.5 is outside of your terrain, while every value over 0.5 is inside of your terrain.

You can then change this value and influence how much of your terrain is actually visible.

  • \$\begingroup\$ Its called marching cubes, works on 3d noise and you use a float for the voxel value in place of a bool. Changing the ISO value controls at what density the voxels become air. Would up vote if you talked about the algorithm a bit more. \$\endgroup\$ Jan 23, 2017 at 12:15
  • \$\begingroup\$ I'm using marching cubes. This answer doesn't reply my question sorry. Look at my screenshot: prntscr.com/dz89s7 . Left is computed value for solid block and -1 for air, right is (computed value*maxHeight) + y value. The right solution look like I want, but the value is wrong, and when I want to apply other 3d layer, that a problem. \$\endgroup\$
    – Alaanor
    Jan 23, 2017 at 12:36
  • 1
    \$\begingroup\$ I am not sure I understand, sry. Marching cubes calculates an interpolated position, this is where you place your vertex. If you only get the blocky look there seems to be something wrong with your MC implementation. \$\endgroup\$
    – ElDuderino
    Jan 23, 2017 at 15:48
  • \$\begingroup\$ Did you just look at the screenshot ? These are computed by the same algorithm. I'm trying to said that not my problem, I already pass this step. Now my problem is to understand why the result is so blocky and this is so blocky because of my algorithm that set value on each voxel. (see my previous comment). I'm here to know how I'm supposed to generate a smooth heightmap on 3d float array which be used by marching cube algorithm to render it. \$\endgroup\$
    – Alaanor
    Jan 23, 2017 at 15:57
  • 1
    \$\begingroup\$ I'll try to improve the quality of my question. \$\endgroup\$
    – Alaanor
    Jan 23, 2017 at 16:01

You must log in to answer this question.

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