I am using a simplex 2D noise to generate my worlds so far. This however was never the plan and has the downside that I basically can only generate a heightmap. Instead I want to aim for floating islands scattered in the sky, but I fail to see how I can utilize 3D noise properly for this.
Based on a simplex 3D noise function I am currently generating noise like this:
float
sc_perlin_noise3_ex(const sc_perlin_t *perlin, float x, float y,
float z, int octaves, float persistence,
float base_frequency, float base_amp,
float lacunarity)
{
int i;
float freq = base_frequency;
float amp = base_amp;
float max = 1.0f;
float total = 1.0f;
for (i = 0; i < octaves; i++) {
total += sc_perlin_noise3(perlin, x * freq, y * freq, z * freq) * amp;
max += amp;
freq *= lacunarity;
amp *= persistence;
}
return total / max;
}
Problems start there: first of all I think I got octaves wrong, at least the outcome is very unpredictable. Persistence would be a value smaller 1 that removes the effect of the higher octaves.
Secondly however I have a general problem understanding how 3D noise works. From my understanding a value < -1 could mean air, a value > 1 would be solid and 0 is the thin line between them (the surface). First of all however I get a lot more values below zero than above zero, so I had to flip those two around. That seems odd, do I have the math wrong?
The actual problem however is that I cannot locate "islands" properly. Say I have a container of 256^3 in size and I want to have one large island in there with maybe up to three smaller islands in there I have to ensure that:
- no island is cut off at the edges
- that I only get two even sized islands in my block
- I have some better control of the actual appearance of my island. For instance it would be nice if it had an actual flat-ish surface where I can put a heighmap on top of that for mountains etc.
Based on that I have the feeling I am on the completely wrong track here. Can anyone give me some pointers on where to head now?
Generally speaking I would like to have something that looks like this: floating island
Answer
I went with 3D noise again because it produces much nicer things than I could accomplish with 2D noise. I'm currently using a falloff factor for the general form of my island but unfortunately it still sometimes happens that the island will just be too small.
Generally though it works:
static int
block_is_solid(const sc_worldgen_t *worldgen, float x, float y, float z)
{
float noise, density, center_falloff, plateau_falloff;
/* caves */
if (powf(sc_perlin_noise3_ex(worldgen->perlin, x * 5.0f, y * 5.0f,
z * 5.0f, 3), 3.0f) < -0.5f)
return 0;
/* falloff from the top */
if (y > 0.9f)
return SC_BLOCK_AIR;
else if (y > 0.8f)
plateau_falloff = 1.0f - (y - 0.8f) * 10.0f;
else
plateau_falloff = 1.0f;
/* falloff from center */
center_falloff = 0.1f / (
powf((x - 0.5f) * 1.5f, 2.0f) +
powf((y - 1.0f) * 0.8f, 2.0f) +
powf((z - 0.5f) * 1.5f, 2.0f)
);
/* noise combined density */
noise = sc_perlin_noise3_ex(worldgen->perlin, x, y * 0.5, z, 7);
density = noise * center_falloff * plateau_falloff;
return density > 0.2f ? SC_BLOCK_STONE : SC_BLOCK_AIR;
}
Technique from pyalot.
No comments:
Post a Comment