#version 460 layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in; const int CHUNK_SIZE = 16; const int CHUNK_AREA = CHUNK_SIZE * CHUNK_SIZE; // A 1D storage buffer representing a flat 3D array of voxel IDs layout(std430, binding = 0) buffer VoxelData { uint voxels[]; }; layout(push_constant) uniform ChunkInfo { ivec3 chunkPos; int slot; uint faceOffset; uint unused0; uint indirectCommandIndex; uint padding0; }; vec3 random3(vec3 st) { return fract(sin(vec3( dot(st, vec3(127.1, 311.7, 74.7)), dot(st, vec3(269.5, 183.3, 246.1)), dot(st, vec3(113.5, 271.9, 124.6)) )) * 43758.5453123); } float random3to1(vec3 st) { return fract(sin(dot(st, vec3(127.1, 311.7, 74.7))) * 43758.5453123); } float interpolate(float a, float b, float c, float d, float x) { float p = (d - c) - (a - b); return x * (x * (x * p + ((a - b) - p)) + (c - a)) + b; } float sampleX(vec3 at) { float floored = floor(at.x); return interpolate( random3to1(vec3(floored - 1.0, at.yz)), random3to1(vec3(floored, at.yz)), random3to1(vec3(floored + 1.0, at.yz)), random3to1(vec3(floored + 2.0, at.yz)), at.x - floored) * 0.5 + 0.25; } float sampleY(vec3 at) { float floored = floor(at.y); return interpolate( sampleX(vec3(at.x, floored - 1.0, at.z)), sampleX(vec3(at.x, floored, at.z)), sampleX(vec3(at.x, floored + 1.0, at.z)), sampleX(vec3(at.x, floored + 2.0, at.z)), at.y - floored); } float cubicNoise(vec3 at) { float floored = floor(at.z); return interpolate( sampleY(vec3(at.xy, floored - 1.0)), sampleY(vec3(at.xy, floored)), sampleY(vec3(at.xy, floored + 1.0)), sampleY(vec3(at.xy, floored + 2.0)), at.z - floored); } float rand(vec2 co) { return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453123); } float valueNoise(vec2 st) { vec2 i = floor(st); vec2 f = fract(st); float a = rand(i); float b = rand(i + vec2(1.0, 0.0)); float c = rand(i + vec2(0.0, 1.0)); float d = rand(i + vec2(1.0, 1.0)); vec2 u = f * f * (3.0 - 2.0 * f); return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y; } bool isCave(vec3 worldPos) { vec3 X = vec3(worldPos); X = mat3( 0.788675134594813, -0.211324865405187, -0.577350269189626, -0.211324865405187, 0.788675134594813, -0.577350269189626, 0.577350269189626, 0.577350269189626, 0.577350269189626) * X; float n = cubicNoise(X); return n > 0.5; } void main() { ivec3 localPos = ivec3(gl_GlobalInvocationID.xyz); ivec3 worldPos = chunkPos * CHUNK_SIZE + localPos; float YZone = floor(worldPos.y/150.0)*150.0; float islandheight = valueNoise(vec2(worldPos.x + YZone * 2, worldPos.z + YZone * 2) * 0.005) * 100 + valueNoise(vec2(worldPos.x + YZone * 2, worldPos.z + YZone * 2) * 0.1) * 20 + valueNoise(vec2(worldPos.x + YZone * 2, worldPos.z + YZone * 2) * 0.1) * 5+ valueNoise(vec2(worldPos.x + YZone * 2, worldPos.z + YZone * 2)) * 0.5 - 15 + YZone; float height = valueNoise(vec2(worldPos.x + YZone * 2, worldPos.z + YZone * 2) * 0.005) * 100 + valueNoise(vec2(worldPos.x + YZone * 2, worldPos.z + YZone * 2) * 0.01) * 10 + valueNoise(vec2(worldPos.x + YZone * 2, worldPos.z + YZone * 2) * 0.1) * 5+ valueNoise(vec2(worldPos.x + YZone * 2, worldPos.z + YZone * 2)) * 0.5 + YZone; float YZone2 = floor(worldPos.y/75.0)*75.0; float islandheight2 = valueNoise(vec2(worldPos.x - YZone2 * 2, worldPos.z -YZone2 * 2) * 0.005) * 60 + valueNoise(vec2(worldPos.x + YZone2 * 2, worldPos.z + YZone2 * 2) * 0.1) * 20 + valueNoise(vec2(worldPos.x + YZone2 * 2, worldPos.z + YZone2 * 2) * 0.1) * 10+ valueNoise(vec2(worldPos.x + YZone2 * 2, worldPos.z + YZone2 * 2)) * 0.5 - 5 + YZone2; float height2 = valueNoise(vec2(worldPos.x + YZone2 * 2, worldPos.z + YZone2 * 2) * 0.005) * 50 + valueNoise(vec2(worldPos.x + YZone2 * 2, worldPos.z + YZone2 * 2) * 0.01) * 10 + valueNoise(vec2(worldPos.x + YZone2 * 2, worldPos.z + YZone2 * 2) * 0.1) * 5+ valueNoise(vec2(worldPos.x + YZone2 * 2, worldPos.z + YZone2 * 2)) * 0.5 + YZone2; float grassNoise = valueNoise(vec2(worldPos.z + YZone * 2, worldPos.x + YZone * 2)); //float height2 = valueNoise(vec2(-worldPos.x, -worldPos.z) * 0.005) * 100 + valueNoise(vec2(-worldPos.x, -worldPos.z) * 0.01) * 10 + valueNoise(vec2(-worldPos.x, -worldPos.z) * 0.1) * 5+ valueNoise(vec2(-worldPos.x, -worldPos.z)) * 0.5 + 100; //float islandheight2 = 100 + valueNoise(vec2(-worldPos.z, -worldPos.x) * 0.005) * 100 + valueNoise(vec2(-worldPos.x, -worldPos.z) * 0.1) * 20 + valueNoise(vec2(worldPos.x, worldPos.z) * 0.1) * 5+ valueNoise(vec2(worldPos.x, worldPos.z)) * 0.5 - 5; //height = clamp(height, 4.0, 28.0); uint voxelType = 0u; if (float(worldPos.y) <= height && float(worldPos.y) >= islandheight) { float depthBelowSurface = height - float(worldPos.y); if (depthBelowSurface < 0.5) { if(grassNoise < 0.65) voxelType = 4u; // Grass foliage else voxelType = 0u; }else if (depthBelowSurface < 2.5) { voxelType = 1u; // Grass } else if (depthBelowSurface < 6.0) { voxelType = 2u; // Dirt(also stone rn) } else { voxelType = 3u; // Stone } } else if (float(worldPos.y) <= height2 && float(worldPos.y) >= islandheight2) { float depthBelowSurface = height2 - float(worldPos.y); if (depthBelowSurface < 0.5) { if(grassNoise < 0.65) voxelType = 4u; // Grass foliage else voxelType = 0u; }else if (depthBelowSurface < 1.5) { voxelType = 1u; // Grass } else if (depthBelowSurface < 6.0) { voxelType = 2u; // Dirt(also stone rn) } else { voxelType = 3u; // Stone } } if (voxelType != 0u) { if (isCave(vec3(worldPos*0.05))) { voxelType = 0u; } } uint index = uint((localPos.x * CHUNK_AREA) + (localPos.y * CHUNK_SIZE) + localPos.z); voxels[index] = voxelType; }