I'm trying to use Perlin Noise to paint landscapes on a sphere. So far I've been able to make this:
(the quad is just to get a more flat vision of the height map)
I'm not influencing the mesh vertices height yet, but I am creating the noise map from the CPU and passing it to the GPU as a texture, which is what you see above.
I've got 2 issues though:
Issue #1
If I get a bit close to the sphere, the detail in the landscapes look bad. I'm aware that I can't get too close, but I also feel that I should be able to get better quality at the distance I show above. The detail in the texture looks blurry and stretched...it just looks bad. I'm not sure what I can do to improve it.
Issue #2
I believe I know why the second issue occurs, but don't know how to solve it. If I rotate the sphere, you'll notice something. Click on the image for a better look:
What I think is going on is that some land/noise reaches the end of the uv/texture and since the sphere texture is pretty much like if you wrap paper around the sphere, the beginning and end of the texture map connect, and both sides have different patterns.
Solutions I have in mind for Issue #2:
A) Maybe limiting the noise within a certain bounding box, make sure "land" isn't generated around the borders or poles of the texture. Think Islands. I just have no idea how to do that.
B) Finding a way to make the the noise draw at the beginning of the uv/texture once it reaches the end of it. That way the beginning and ends connect seamlessly, but again, I have no idea how to do that.
I'm kind of rooting for the solution a though. I would be able to make islands that way. Hope I was able to explain myself. If anybody needs anymore information, let me know. I'll share the function in charge of making this noise below. The shader isn't doing anything special but drawing the texture. Thanks!
CPU Noise Texture:
const width = 100;
const depth = 100;
const scale = 30.6;
const pixels = new Uint8Array(4 * width * depth);
let i = 0;
for (let z = 0; z < depth; z += 1) {
for (let x = 0; x < width; x += 1) {
const octaves = 8;
const persistance = 0.5;
const lacunarity = 2.0;
let frequency = 1.0;
let amplitude = 1.0;
let noiseHeight = 0.0;
for (let i = 0; i < octaves; i += 1) {
const sampleX = x / scale * frequency;
const sampleZ = z / scale * frequency;
let n = perlin2(sampleX, sampleZ);
noiseHeight += n * amplitude;
amplitude *= persistance;
frequency *= lacunarity;
}
pixels[i] = noiseHeight * 255;
pixels[i+1] = noiseHeight * 255;
pixels[i+2] = noiseHeight * 255;
pixels[i+3] = 255;
i += 4;
}
}
GPU GLSL:
void main () {
vec3 diffusemap = texture(texture0, uvcoords).rgb;
color = vec4(diffusemap, 1.0);
}