1
\$\begingroup\$

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);
        }
    }
}

Then

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.

\$\endgroup\$
3
  • \$\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 '18 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 '18 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 '18 at 18:37
1
\$\begingroup\$

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.

\$\endgroup\$
5
  • \$\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\$ – Justin William Stanley Bryant Jan 23 '17 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 '17 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 '17 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 '17 at 15:57
  • 1
    \$\begingroup\$ I'll try to improve the quality of my question. \$\endgroup\$ – Alaanor Jan 23 '17 at 16:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.