i did a little memory optimisation (19GB of VRAM -> 2.6GB of VRAM), lost some FPS in vertex rendering as a result but i'll figure it out

This commit is contained in:
Halbear 2026-09-16 20:38:37 +01:00
parent bf9af81f38
commit ce7051d8ca
21 changed files with 766 additions and 592 deletions

View file

@ -6,261 +6,72 @@ const int CHUNK_SIZE = 16;
const int CHUNK_AREA = CHUNK_SIZE * CHUNK_SIZE;
const int VOXEL_COUNT = CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE;
const uint FLOATS_PER_VERTEX = 14u;
const uint VERTICES_PER_FACE = 4u;
const uint INDICES_PER_FACE = 6u;
const uint MAX_VISIBLE_FACES_PER_CHUNK = uint(CHUNK_SIZE * CHUNK_SIZE * 12);
const uint MAX_VERTICES = MAX_VISIBLE_FACES_PER_CHUNK * VERTICES_PER_FACE;
const uint MAX_INDICES = MAX_VISIBLE_FACES_PER_CHUNK * INDICES_PER_FACE;
const uint VERTICES_PER_FACE = 6u;
const uint MAX_VISIBLE_FACES_PER_CHUNK = uint(CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE * 6);
layout(std430, binding = 0) readonly buffer VoxelData {
uint voxels[];
};
layout(std430, binding = 1) buffer VertexBuffer {
float vertices[];
};
layout(std430, binding = 2) buffer IndexBuffer {
uint indices[];
layout(std430, binding = 1) buffer FaceBuffer {
uint faces[];
};
struct DrawCommand {
uint indexCount;
uint vertexCount;
uint instanceCount;
uint firstIndex;
int vertexOffset;
uint firstVertex;
uint firstInstance;
};
layout(std430, binding = 3) buffer DrawCommands {
layout(std430, binding = 2) buffer DrawCommands {
DrawCommand drawCmds[];
};
layout(std430, binding = 3) buffer Counters {
uint faceCount;
} counters;
layout(push_constant) uniform ChunkInfo {
ivec3 chunkPos;
int slot;
uint vertexFloatOffset;
uint indexOffset;
uint faceOffset;
uint unused0;
uint indirectCommandIndex;
uint padding0;
};
layout(std430, binding = 4) buffer Counters {
uint vertexCount;
uint indexCount;
} counters;
uint flatten(ivec3 pos) {
return uint((pos.x * CHUNK_AREA) + (pos.y * CHUNK_SIZE) + pos.z);
}
uint getVoxel(ivec3 pos) {
if (pos.x < 0 || pos.x >= CHUNK_SIZE) return 0;
if (pos.y < 0 || pos.y >= CHUNK_SIZE) return 0;
if (pos.z < 0 || pos.z >= CHUNK_SIZE) return 0;
if (pos.x < 0 || pos.x >= CHUNK_SIZE) return 0u;
if (pos.y < 0 || pos.y >= CHUNK_SIZE) return 0u;
if (pos.z < 0 || pos.z >= CHUNK_SIZE) return 0u;
return voxels[flatten(pos)];
}
void writeVertex(uint vertexIndex, vec3 position, vec3 normal, vec3 tangent, vec3 bitangent, vec2 uv) {
uint base = vertexFloatOffset + vertexIndex * FLOATS_PER_VERTEX;
vertices[base + 0u] = position.x;
vertices[base + 1u] = position.y;
vertices[base + 2u] = position.z;
vertices[base + 3u] = normal.x;
vertices[base + 4u] = normal.y;
vertices[base + 5u] = normal.z;
vertices[base + 6u] = tangent.x;
vertices[base + 7u] = tangent.y;
vertices[base + 8u] = tangent.z;
vertices[base + 9u] = bitangent.x;
vertices[base + 10u] = bitangent.y;
vertices[base + 11u] = bitangent.z;
vertices[base + 12u] = uv.x;
vertices[base + 13u] = uv.y;
uint packFace(uvec3 voxelPos, uint faceIndex, uint materialId, uint ao) {
return (voxelPos.x & 0x1Fu) |
((voxelPos.y & 0x1Fu) << 5u) |
((voxelPos.z & 0x1Fu) << 10u) |
((faceIndex & 0x7u) << 15u) |
((materialId & 0xFFu) << 18u) |
((ao & 0x3u) << 26u);
}
void emitFace(ivec3 voxelPos, int faceIndex, uint VoxelType) {
uint localBaseVertex = atomicAdd(counters.vertexCount, VERTICES_PER_FACE);
uint localBaseIndex = atomicAdd(counters.indexCount, INDICES_PER_FACE);
void emitFace(ivec3 voxelPos, uint faceIndex, uint voxelType) {
uint localFace = atomicAdd(counters.faceCount, 1u);
if (localBaseVertex + VERTICES_PER_FACE > MAX_VERTICES ||
localBaseIndex + INDICES_PER_FACE > MAX_INDICES) {
if (localFace >= MAX_VISIBLE_FACES_PER_CHUNK) {
return;
}
uint baseVertex = localBaseVertex;
uint baseIndex = indexOffset + localBaseIndex;
faces[faceOffset + localFace] = packFace(uvec3(voxelPos), faceIndex, voxelType, 0u);
vec3 p = vec3(chunkPos * CHUNK_SIZE + voxelPos);
vec3 normal;
vec3 tangent;
vec3 bitangent;
vec3 v0;
vec3 v1;
vec3 v2;
vec3 v3;
vec2 uv0;
vec2 uv1;
vec2 uv2;
vec2 uv3;
if (faceIndex == 0) {
// Top +Y
normal = vec3(0.0, 1.0, 0.0);
tangent = vec3(1.0, 0.0, 0.0);
bitangent = vec3(0.0, 0.0, 1.0);
v0 = p + vec3(0.0, 1.0, 0.0);
v1 = p + vec3(0.0, 1.0, 1.0);
v2 = p + vec3(1.0, 1.0, 1.0);
v3 = p + vec3(1.0, 1.0, 0.0);
if(VoxelType == 1) {
uv0 = vec2(0.0, 0.5);
uv1 = vec2(0.0, 1.0);
uv2 = vec2(0.5, 1.0);
uv3 = vec2(0.5, 0.5);
} else{
uv0 = vec2(0.5, 0.0);
uv1 = vec2(0.5, 0.5);
uv2 = vec2(1.0, 0.5);
uv3 = vec2(1.0, 0.0);
}
} else if (faceIndex == 1) {
// Bottom -Y
normal = vec3(0.0, -1.0, 0.0);
tangent = vec3(1.0, 0.0, 0.0);
bitangent = vec3(0.0, 0.0, -1.0);
v0 = p + vec3(0.0, 0.0, 0.0);
v1 = p + vec3(1.0, 0.0, 0.0);
v2 = p + vec3(1.0, 0.0, 1.0);
v3 = p + vec3(0.0, 0.0, 1.0);
uv0 = vec2(0.5, 0.0);
uv1 = vec2(0.5, 0.5);
uv2 = vec2(1.0, 0.5);
uv3 = vec2(1.0, 0.0);
} else if (faceIndex == 2) {
// Right +X
normal = vec3(1.0, 0.0, 0.0);
tangent = vec3(0.0, 0.0, -1.0);
bitangent = vec3(0.0, 1.0, 0.0);
v0 = p + vec3(1.0, 0.0, 0.0);
v1 = p + vec3(1.0, 1.0, 0.0);
v2 = p + vec3(1.0, 1.0, 1.0);
v3 = p + vec3(1.0, 0.0, 1.0);
if(VoxelType == 1) {
uv2 = vec2(0.0, 0.0);
uv3 = vec2(0.0, 0.5);
uv0 = vec2(0.5, 0.5);
uv1 = vec2(0.5, 0.0);
} else{
uv0 = vec2(0.5, 0.0);
uv1 = vec2(0.5, 0.5);
uv2 = vec2(1.0, 0.5);
uv3 = vec2(1.0, 0.0);
}
} else if (faceIndex == 3) {
// Left -X
normal = vec3(-1.0, 0.0, 0.0);
tangent = vec3(0.0, 0.0, 1.0);
bitangent = vec3(0.0, 1.0, 0.0);
v0 = p + vec3(0.0, 0.0, 0.0);
v1 = p + vec3(0.0, 0.0, 1.0);
v2 = p + vec3(0.0, 1.0, 1.0);
v3 = p + vec3(0.0, 1.0, 0.0);
if(VoxelType == 1) {
uv3 = vec2(0.0, 0.0);
uv0 = vec2(0.0, 0.5);
uv1 = vec2(0.5, 0.5);
uv2 = vec2(0.5, 0.0);
} else{
uv0 = vec2(0.5, 0.0);
uv1 = vec2(0.5, 0.5);
uv2 = vec2(1.0, 0.5);
uv3 = vec2(1.0, 0.0);
}
} else if (faceIndex == 4) {
// Front +Z
normal = vec3(0.0, 0.0, 1.0);
tangent = vec3(1.0, 0.0, 0.0);
bitangent = vec3(0.0, 1.0, 0.0);
v0 = p + vec3(0.0, 0.0, 1.0);
v1 = p + vec3(1.0, 0.0, 1.0);
v2 = p + vec3(1.0, 1.0, 1.0);
v3 = p + vec3(0.0, 1.0, 1.0);
if(VoxelType == 1) {
uv3 = vec2(0.0, 0.0);
uv0 = vec2(0.0, 0.5);
uv1 = vec2(0.5, 0.5);
uv2 = vec2(0.5, 0.0);
} else{
uv0 = vec2(0.5, 0.0);
uv1 = vec2(0.5, 0.5);
uv2 = vec2(1.0, 0.5);
uv3 = vec2(1.0, 0.0);
}
} else {
// Back -Z
normal = vec3(0.0, 0.0, -1.0);
tangent = vec3(-1.0, 0.0, 0.0);
bitangent = vec3(0.0, 1.0, 0.0);
v0 = p + vec3(0.0, 0.0, 0.0);
v1 = p + vec3(0.0, 1.0, 0.0);
v2 = p + vec3(1.0, 1.0, 0.0);
v3 = p + vec3(1.0, 0.0, 0.0);
if(VoxelType == 1) {
uv2 = vec2(0.0, 0.0);
uv3 = vec2(0.0, 0.5);
uv0 = vec2(0.5, 0.5);
uv1 = vec2(0.5, 0.0);
} else{
uv0 = vec2(0.5, 0.0);
uv1 = vec2(0.5, 0.5);
uv2 = vec2(1.0, 0.5);
uv3 = vec2(1.0, 0.0);
}
}
writeVertex(baseVertex + 0u, v0, normal, tangent, bitangent, uv0);
writeVertex(baseVertex + 1u, v1, normal, tangent, bitangent, uv1);
writeVertex(baseVertex + 2u, v2, normal, tangent, bitangent, uv2);
writeVertex(baseVertex + 3u, v3, normal, tangent, bitangent, uv3);
indices[baseIndex + 0u] = baseVertex + 0u;
indices[baseIndex + 1u] = baseVertex + 1u;
indices[baseIndex + 2u] = baseVertex + 2u;
indices[baseIndex + 3u] = baseVertex + 0u;
indices[baseIndex + 4u] = baseVertex + 2u;
indices[baseIndex + 5u] = baseVertex + 3u;
atomicAdd(drawCmds[indirectCommandIndex].indexCount, INDICES_PER_FACE);
atomicAdd(drawCmds[indirectCommandIndex].vertexCount, VERTICES_PER_FACE);
}
void main() {
@ -276,10 +87,10 @@ void main() {
return;
}
if (getVoxel(pos + ivec3( 0, 1, 0)) == 0u) emitFace(pos, 0,current);
if (getVoxel(pos + ivec3( 0, -1, 0)) == 0u) emitFace(pos, 1,current);
if (getVoxel(pos + ivec3( 1, 0, 0)) == 0u) emitFace(pos, 2,current);
if (getVoxel(pos + ivec3(-1, 0, 0)) == 0u) emitFace(pos, 3,current);
if (getVoxel(pos + ivec3( 0, 0, 1)) == 0u) emitFace(pos, 4,current);
if (getVoxel(pos + ivec3( 0, 0, -1)) == 0u) emitFace(pos, 5,current);
if (getVoxel(pos + ivec3( 0, 1, 0)) == 0u) emitFace(pos, 0u, current);
if (getVoxel(pos + ivec3( 0, -1, 0)) == 0u) emitFace(pos, 1u, current);
if (getVoxel(pos + ivec3( 1, 0, 0)) == 0u) emitFace(pos, 2u, current);
if (getVoxel(pos + ivec3(-1, 0, 0)) == 0u) emitFace(pos, 3u, current);
if (getVoxel(pos + ivec3( 0, 0, 1)) == 0u) emitFace(pos, 4u, current);
if (getVoxel(pos + ivec3( 0, 0, -1)) == 0u) emitFace(pos, 5u, current);
}