Sign in to follow this  
tapped

Marching Cube Holes

Recommended Posts

I have problem generating terrain in marching cubes. My marching cube implementation is in OpenCL. I have 16 * 16 * 16 voxels per block. It works fine when generating a sphere, the only problem is that you can see some small holes between some parts of the sphere. My theory is floating precision, but i dont know.

[url="http://imageshack.us/photo/my-images/833/failsphere.png/"]http://imageshack.us/photo/my-images/833/failsphere.png/[/url]

Another problem occur when i tries to generate terrain, with noise:

[url="http://imageshack.us/a/img689/1146/failterrain.png"]http://imageshack.us...failterrain.png[/url]

As you can see, it does not look well. This was rendered with isolevel 0.9f.

I create the terrain like:
[source lang="cpp"]sampler_t randomVolumeSampler = CLK_NORMALIZED_COORDS_TRUE | CLK_ADDRESS_REPEAT | CLK_FILTER_LINEAR;

density.x = wPos.y;
density.x += read_imagef(randomVolume, randomVolumeSampler, realGridPos).x * 0.25f;[/source]

So i was wondering, if i have implemented marching cube wrong, or if it behaves right, Edited by Tapped

Share this post


Link to post
Share on other sites
I believe your problem is because you are sampling a random volume of finite size, which is not tileable. The crack patterns suggest you are having a discontinuity in your noise volume at regular UV intervals. Do the cracks appear at the edge of each block only? How do you generate randomVolume? Is it done on the CPU? Can we see the noise generation code?

The marching cubes triangulation looks fine - if you screw that up it usually ends up looking like nothing, so your code seems to work in that regard.

Share this post


Link to post
Share on other sites
it depends on how you build your sphere.. with voxels the best test would be a n^3 for loop over the diameter, ie. dx is iterated (x-radius+1 to x+radius-1) etc.
that way you can be sure the sphere is complete
the terrain is unmistakably as the poster above me said, the noise doesn't use world-space coordinates.. or it's just an array you draw 4 times [img]http://public.gamedev.net//public/style_emoticons/default/tongue.png[/img] which is even more wrong Edited by Kaptein

Share this post


Link to post
Share on other sites
Thanks, i generate the noise with glm::perlin. First I create a random 3D vector, which is then being multiplied with the position in the random volume, then i use that as the seed for perlin.

The thing is that my blocks are 2.0 * 2.0 * 2.0 in opengl size. And 32 * 32 * 32 voxels per block, therefore 16 * 16 * 16 voxels per cubic meter(opengl). What you see on the picture is one block, so 4 cracks appear per block. So yeah, i believe it is some problem with the tiling of the random volume. However, how can i create a tileable noise volume. I have tried different techniques which did not fix the cracks, like using the same noise on all edges...

[CODE]
#define RANDOM_VOLUME_EXTENT 16

glm::vec3 randVec(glm::signedRand1<float>(), glm::signedRand1<float>(), glm::signedRand1<float>());
for(int i = 0;i < RANDOM_VOLUME_EXTENT;++i)
{
for(int j = 0;j < RANDOM_VOLUME_EXTENT;++j)
{
for(int k = 0;k < RANDOM_VOLUME_EXTENT;++k)
{
glm::vec3 p(i * randVec.x, j * randVec.y, k * randVec.z);
randBuffer[(i*RANDOM_VOLUME_EXTENT*RANDOM_VOLUME_EXTENT)+(j*RANDOM_VOLUME_EXTENT) + k] = glm::perlin(p);
}
}
[/CODE] Edited by Tapped

Share this post


Link to post
Share on other sites
Nice that you've fixed it (can you give some information or perhaps links for people of the future - hello guys!). I don't know but I'm pretty sure you only need a single seed for perlin noise, and that you then use the world position in the density function to sample the perlin noise directly (with a single seed, it can be sampled from -infinity to +infinity and will never have discontinuities, so you won't have that crack problem).

Share this post


Link to post
Share on other sites
Now i have implemented the information i got from: [url="http://gamedev.stackexchange.com/questions/23625/how-do-you-generate-tileable-perlin-noise"]http://gamedev.stack...le-perlin-noise[/url]
Even if i did that, i still had cracks, but then after a lot of testing of different sample types, i finally got it work. It worked when i used this sampler:
[CODE]
__constant sampler_t randomVolumeSampler = CLK_NORMALIZED_COORDS_TRUE | CLK_ADDRESS_MIRRORED_REPEAT | CLK_FILTER_LINEAR;


float4 realGridPos;
realGridPos.x = gridPos.x * voxelSize;
realGridPos.y = gridPos.y * voxelSize;
realGridPos.z = gridPos.z * voxelSize;

density.x += read_imagef(randomVolume, randomVolumeSampler, realGridPos).x * 0.8f;
[/CODE]

realGridPos is the same as the local position in terms of a block, which in this case range from [0.0, 2.0] for each block.
Here is the result:

[url="http://imageshack.us/a/img823/9383/itworks.png"]http://imageshack.us...383/itworks.png[/url]
Thanks for the help! [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img] Edited by Tapped

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this