Terrain4J_Experimental_branch/resources/EngineResources/VoxelComputeShaders/voxelGenerationShared.glsl

144 lines
No EOL
4.7 KiB
GLSL

#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 islandheight = 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 - 15;
float height = 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;
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 < 1.5) {
voxelType = 1u; // Grass/topsoil
} else if (depthBelowSurface < 5.0) {
voxelType = 2u; // Dirt
} else {
voxelType = 3u; // Stone
}
}
if(float(worldPos.y) <= height2 && float(worldPos.y) >= islandheight2){
float depthBelowSurface = height2 - float(worldPos.y);
if (depthBelowSurface < 1.5) {
voxelType = 1u; // Grass/topsoil
} else if (depthBelowSurface < 5.0) {
voxelType = 2u; // Dirt
} 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;
}