From 0008d7f1faf7a7a48ba50dd1a084175bc9918054 Mon Sep 17 00:00:00 2001 From: IntegratedQuantum Date: Mon, 20 Nov 2023 13:03:28 +0100 Subject: [PATCH] Test how well a sparse 3d texture would work for storing and interpolating light data. --- assets/cubyz/shaders/chunks/chunk_fragment.fs | 76 ++++++++++ assets/cubyz/shaders/chunks/chunk_vertex.vs | 16 +- .../shaders/chunks/transparent_fragment.fs | 68 +++++++++ .../shaders/chunks/voxel_model_fragment.fs | 68 +++++++++ src/chunk.zig | 143 ++++++++++++++++-- src/graphics.zig | 6 +- src/gui/windows/debug.zig | 8 +- 7 files changed, 353 insertions(+), 32 deletions(-) diff --git a/assets/cubyz/shaders/chunks/chunk_fragment.fs b/assets/cubyz/shaders/chunks/chunk_fragment.fs index d3cdfef0..01018be8 100644 --- a/assets/cubyz/shaders/chunks/chunk_fragment.fs +++ b/assets/cubyz/shaders/chunks/chunk_fragment.fs @@ -2,6 +2,7 @@ in vec3 mvVertexPos; in vec3 light; +in vec3 chunkPos; flat in int blockType; flat in int faceNormal; flat in int modelIndex; @@ -15,6 +16,9 @@ in vec3 direction; uniform sampler2DArray texture_sampler; uniform sampler2DArray emissionSampler; +uniform uint chunkDataIndex; +uniform vec3 ambientLight; +uniform int voxelSize; layout(location = 0) out vec4 fragColor; @@ -31,6 +35,69 @@ layout(std430, binding = 1) buffer _textureData TextureData textureData[]; }; +struct ChunkData { + uint lightMapPtrs[6*6*6]; +}; + +struct LightData { + int values[8*8*8]; +}; + +layout(std430, binding = 7) buffer _chunkData +{ + ChunkData chunkData[]; +}; +layout(std430, binding = 8) buffer _lightData +{ + LightData lightData[]; +}; + +vec3 sampleLight(ivec3 pos) { + pos += 8; + ivec3 rough = pos/8; + int roughIndex = (rough.x*6 + rough.y)*6 + rough.z; + ivec3 fine = pos&7; + int fineIndex = (fine.x*8 + fine.y)*8 + fine.z; + int lightValue = lightData[chunkData[chunkDataIndex].lightMapPtrs[roughIndex]].values[fineIndex]; + vec3 sunLight = vec3( + lightValue >> 25 & 31, + lightValue >> 20 & 31, + lightValue >> 15 & 31 + ); + vec3 blockLight = vec3( + lightValue >> 10 & 31, + lightValue >> 5 & 31, + lightValue >> 0 & 31 + ); + return max(sunLight*ambientLight, blockLight)/32; +} + +vec3 sCurve(vec3 x) { + return (3*x - 2*x*x)*x; +} + +vec3 getLight(vec3 pos, vec3 normal) { + pos += normal/2; + pos -= vec3(0.5, 0.5, 0.5); + ivec3 start = ivec3(floor(pos)); + vec3 diff = sCurve(pos - start); + vec3 invDiff = 1 - diff; + + vec3 state = vec3(0); + for(int dx = 0; dx < 2; dx++) { + for(int dy = 0; dy < 2; dy++) { + for(int dz = 0; dz < 2; dz++) { + ivec3 delta = ivec3(dx, dy, dz); + vec3 light = sampleLight(start + delta); + bvec3 isOne = bvec3(notEqual(delta, ivec3(0))); + vec3 interpolation = mix(invDiff, diff, isOne); + state += light*interpolation.x*interpolation.y*interpolation.z; + } + } + } + return state; +} + const float[6] normalVariations = float[6]( 1.0, //vec3(0, 1, 0), @@ -40,6 +107,14 @@ const float[6] normalVariations = float[6]( 0.96, //vec3(0, 0, 1), 0.88 //vec3(0, 0, -1) ); +const vec3[6] normals = vec3[6]( + vec3(0, 1, 0), + vec3(0, -1, 0), + vec3(1, 0, 0), + vec3(-1, 0, 0), + vec3(0, 0, 1), + vec3(0, 0, -1) +); float ditherThresholds[16] = float[16] ( 1/17.0, 9/17.0, 3/17.0, 11/17.0, @@ -82,6 +157,7 @@ void main() { uint textureIndex = textureData[blockType].textureIndices[faceNormal]; float normalVariation = normalVariations[faceNormal]; vec3 textureCoords = vec3(getTextureCoordsNormal(startPosition/16, faceNormal), textureIndex); + vec3 light = getLight(chunkPos + startPosition/16.0/voxelSize, normals[faceNormal]); fragColor = texture(texture_sampler, textureCoords)*vec4(light*normalVariation, 1); if(!passDitherTest(fragColor.a)) discard; diff --git a/assets/cubyz/shaders/chunks/chunk_vertex.vs b/assets/cubyz/shaders/chunks/chunk_vertex.vs index 8ab1aefb..7c453e9c 100644 --- a/assets/cubyz/shaders/chunks/chunk_vertex.vs +++ b/assets/cubyz/shaders/chunks/chunk_vertex.vs @@ -2,6 +2,7 @@ out vec3 mvVertexPos; out vec3 light; +out vec3 chunkPos; flat out int blockType; flat out int modelIndex; flat out int faceNormal; @@ -22,7 +23,6 @@ uniform vec3 modelPosition; struct FaceData { int encodedPositionAndNormalsAndPermutation; int blockAndModel; - int light[4]; }; layout(std430, binding = 3) buffer _faceData { @@ -131,18 +131,7 @@ void main() { int vertexID = gl_VertexID%4; int encodedPositionAndNormalsAndPermutation = faceData[faceID].encodedPositionAndNormalsAndPermutation; int blockAndModel = faceData[faceID].blockAndModel; - int fullLight = faceData[faceID].light[vertexID]; - vec3 sunLight = vec3( - fullLight >> 25 & 31, - fullLight >> 20 & 31, - fullLight >> 15 & 31 - ); - vec3 blockLight = vec3( - fullLight >> 10 & 31, - fullLight >> 5 & 31, - fullLight >> 0 & 31 - ); - light = max(sunLight*ambientLight, blockLight)/32; + light = vec3(1, 1, 1); isBackFace = encodedPositionAndNormalsAndPermutation>>19 & 1; int oldNormal = (encodedPositionAndNormalsAndPermutation >> 20) & 7; mat3 permutationMatrix = permutationMatrices[(encodedPositionAndNormalsAndPermutation >> 23) & 7]; @@ -158,6 +147,7 @@ void main() { encodedPositionAndNormalsAndPermutation >> 5 & 31, encodedPositionAndNormalsAndPermutation >> 10 & 31 ); + chunkPos = vec3(position) - normals[normal]; int octantIndex = (position.x >> 4) | (position.y >> 4)<<1 | (position.z >> 4)<<2; if((visibilityMask & 1<> 25 & 31, + lightValue >> 20 & 31, + lightValue >> 15 & 31 + ); + vec3 blockLight = vec3( + lightValue >> 10 & 31, + lightValue >> 5 & 31, + lightValue >> 0 & 31 + ); + return max(sunLight*ambientLight, blockLight)/32; +} + +vec3 sCurve(vec3 x) { + return (3*x - 2*x*x)*x; +} + +vec3 getLight(vec3 pos, vec3 normal) { + pos += normal/2; + pos -= vec3(0.5, 0.5, 0.5); + ivec3 start = ivec3(floor(pos)); + vec3 diff = sCurve(pos - start); + vec3 invDiff = 1 - diff; + + vec3 state = vec3(0); + for(int dx = 0; dx < 2; dx++) { + for(int dy = 0; dy < 2; dy++) { + for(int dz = 0; dz < 2; dz++) { + ivec3 delta = ivec3(dx, dy, dz); + vec3 light = sampleLight(start + delta); + bvec3 isOne = bvec3(notEqual(delta, ivec3(0))); + vec3 interpolation = mix(invDiff, diff, isOne); + state += light*interpolation.x*interpolation.y*interpolation.z; + } + } + } + return state; +} + const float[6] normalVariations = float[6]( 1.0, //vec3(0, 1, 0), @@ -142,6 +209,7 @@ void main() { float fogDistance = calculateFogDistance(dist, textureData[blockType].fogDensity*densityAdjustment); float airFogDistance = calculateFogDistance(dist, fog.density*densityAdjustment); vec3 fogColor = unpackColor(textureData[blockType].fogColor); + vec3 light = getLight(chunkPos + startPosition/16.0/voxelSize, normals[faceNormal]); vec4 textureColor = texture(texture_sampler, textureCoords)*vec4(light*normalVariation, 1); if(isBackFace == 0) { textureColor.rgb *= textureColor.a; diff --git a/assets/cubyz/shaders/chunks/voxel_model_fragment.fs b/assets/cubyz/shaders/chunks/voxel_model_fragment.fs index 8f5021ab..0d3b1b2f 100644 --- a/assets/cubyz/shaders/chunks/voxel_model_fragment.fs +++ b/assets/cubyz/shaders/chunks/voxel_model_fragment.fs @@ -1,6 +1,7 @@ #version 450 in vec3 mvVertexPos; +in vec3 chunkPos; in vec3 light; // TODO: This doesn't work here. flat in int blockType; flat in int faceNormal; @@ -15,6 +16,8 @@ in vec3 direction; uniform sampler2DArray texture_sampler; uniform sampler2DArray emissionSampler; +uniform uint chunkDataIndex; +uniform vec3 ambientLight; layout(location = 0) out vec4 fragColor; @@ -43,6 +46,69 @@ layout(std430, binding = 4) buffer _voxelModels VoxelModel voxelModels[]; }; +struct ChunkData { + uint lightMapPtrs[6*6*6]; +}; + +struct LightData { + int values[8*8*8]; +}; + +layout(std430, binding = 7) buffer _chunkData +{ + ChunkData chunkData[]; +}; +layout(std430, binding = 8) buffer _lightData +{ + LightData lightData[]; +}; + +vec3 sampleLight(ivec3 pos) { + pos += 8; + ivec3 rough = pos/8; + int roughIndex = (rough.x*6 + rough.y)*6 + rough.z; + ivec3 fine = pos&7; + int fineIndex = (fine.x*8 + fine.y)*8 + fine.z; + int lightValue = lightData[chunkData[chunkDataIndex].lightMapPtrs[roughIndex]].values[fineIndex]; + vec3 sunLight = vec3( + lightValue >> 25 & 31, + lightValue >> 20 & 31, + lightValue >> 15 & 31 + ); + vec3 blockLight = vec3( + lightValue >> 10 & 31, + lightValue >> 5 & 31, + lightValue >> 0 & 31 + ); + return max(sunLight*ambientLight, blockLight)/32; +} + +vec3 sCurve(vec3 x) { + return (3*x - 2*x*x)*x; +} + +vec3 getLight(vec3 pos, vec3 normal) { + pos += normal/2; + pos -= vec3(0.5, 0.5, 0.5); + ivec3 start = ivec3(floor(pos)); + vec3 diff = sCurve(pos - start); + vec3 invDiff = 1 - diff; + + vec3 state = vec3(0); + for(int dx = 0; dx < 2; dx++) { + for(int dy = 0; dy < 2; dy++) { + for(int dz = 0; dz < 2; dz++) { + ivec3 delta = ivec3(dx, dy, dz); + vec3 light = sampleLight(start + delta); + bvec3 isOne = bvec3(notEqual(delta, ivec3(0))); + vec3 interpolation = mix(invDiff, diff, isOne); + state += light*interpolation.x*interpolation.y*interpolation.z; + } + } + } + return state; +} + const float[6] normalVariations = float[6]( 1.0, //vec3(0, 1, 0), @@ -229,6 +295,8 @@ void main() { float normalVariation = normalVariations[result.normal]; float lod = getLod(result.voxelPosition, result.normal, direction, variance); ivec2 textureCoords = getTextureCoords(result.voxelPosition, result.textureDir); + vec3 pos = chunkPos + vec3(result.voxelPosition)/16.0 + 1.0/32.0; + vec3 light = getLight(pos, normals[result.normal]); fragColor = mipMapSample(texture_sampler, textureCoords, textureIndex, lod)*vec4(light*normalVariation, 1); if(!passDitherTest(fragColor.a)) discard; diff --git a/src/chunk.zig b/src/chunk.zig index 09ff6ed5..4936cbcc 100644 --- a/src/chunk.zig +++ b/src/chunk.zig @@ -411,6 +411,7 @@ pub const meshing = struct { voxelSize: c_int, zNear: c_int, zFar: c_int, + chunkDataIndex: c_int, }; pub var uniforms: UniformStruct = undefined; pub var voxelUniforms: UniformStruct = undefined; @@ -419,6 +420,8 @@ pub const meshing = struct { var vbo: c_uint = undefined; var faces: std.ArrayList(u32) = undefined; pub var faceBuffer: graphics.LargeBuffer(FaceData) = undefined; + pub var chunkBuffer: graphics.LargeBuffer(ChunkData) = undefined; + pub var lightBuffer: graphics.LargeBuffer(LightData) = undefined; pub var quadsDrawn: usize = 0; pub var transparentQuadsDrawn: usize = 0; @@ -442,6 +445,11 @@ pub const meshing = struct { faces = try std.ArrayList(u32).initCapacity(main.globalAllocator, 65536); try faceBuffer.init(main.globalAllocator, 1 << 20, 3); + try chunkBuffer.init(main.globalAllocator, 1 << 10, 7); + try lightBuffer.init(main.globalAllocator, 1 << 10, 8); + var allocation: graphics.SubAllocation = .{.start = undefined, .len = 0}; + try lightBuffer.uploadData(&.{.{.values = .{0}**(8*8*8)}}, &allocation); + std.debug.assert(allocation.start == 0); // Reserve 0 for null } pub fn deinit() void { @@ -451,14 +459,20 @@ pub const meshing = struct { c.glDeleteBuffers(1, &vbo); faces.deinit(); faceBuffer.deinit(); + chunkBuffer.deinit(); + lightBuffer.deinit(); } pub fn beginRender() !void { try faceBuffer.beginRender(); + try chunkBuffer.beginRender(); + try lightBuffer.beginRender(); } pub fn endRender() void { faceBuffer.endRender(); + chunkBuffer.endRender(); + lightBuffer.endRender(); } fn bindCommonUniforms(locations: *UniformStruct, projMatrix: Mat4f, ambient: Vec3f) void { @@ -519,7 +533,15 @@ pub const meshing = struct { typ: u16, modelIndex: u16, }, - light: [4]u32 = .{0, 0, 0, 0}, + //light: [4]u32 = .{0, 0, 0, 0}, + }; + + pub const ChunkData = extern struct { + lightMapPtrs: [6*6*6]u32, + }; + + pub const LightData = extern struct { + values: [8*8*8]u32, }; const PrimitiveMesh = struct { @@ -577,7 +599,20 @@ pub const meshing = struct { i += neighborFaces.items.len; } for(self.completeList) |*face| { - face.light = getLight(parent, face.position.x, face.position.y, face.position.z, face.position.normal); + if(face.blockAndModel.modelIndex != 0 or true) { // Non-cube model: Add all light data. + for(&[_]i32{-1, 1}) |dx| { + for(&[_]i32{-1, 1}) |dy| { + for(&[_]i32{-1, 1}) |dz| { + const x = @divFloor((face.position.x -% Neighbors.relX[face.position.normal] +% dx) +% 8, 8); + const y = @divFloor((face.position.y -% Neighbors.relY[face.position.normal] +% dy) +% 8, 8); + const z = @divFloor((face.position.z -% Neighbors.relZ[face.position.normal] +% dz) +% 8, 8); + parent.needsLightData[@intCast((x*6 + y)*6 + z)] = true; + } + } + } + } else { // TODO: Simpler/Faster approach for cube models. + + } } try self.uploadData(); } @@ -754,6 +789,9 @@ pub const meshing = struct { lastTransparentUpdatePos: Vec3i = Vec3i{0, 0, 0}, refCount: std.atomic.Atomic(u32) = std.atomic.Atomic(u32).init(1), needsNeighborUpdate: bool = false, + chunkData: ChunkData, + chunkDataAllocation: graphics.SubAllocation = .{.start = 0, .len = 0}, + needsLightData: [6*6*6]bool = undefined, chunkBorders: [6]BoundingRectToNeighborChunk = [1]BoundingRectToNeighborChunk{.{}} ** 6, @@ -770,10 +808,21 @@ pub const meshing = struct { .transparentMesh = .{}, .chunk = chunk, .lightingData = lightingData, + .chunkData = .{.lightMapPtrs = .{0}**(6*6*6)}, }; } pub fn deinit(self: *ChunkMesh) void { + chunkBuffer.free(self.chunkDataAllocation) catch |err| { + std.log.err("Error while freeing mesh data: {s}", .{@errorName(err)}); + }; + for(self.chunkData.lightMapPtrs) |ptr| { + if(ptr != 0) { + lightBuffer.free(.{.start = @intCast(ptr), .len = 1}) catch |err| { + std.log.err("Error while freeing mesh data: {s}", .{@errorName(err)}); + }; + } + } std.debug.assert(self.refCount.load(.Monotonic) == 0); self.opaqueMesh.deinit(); self.voxelMesh.deinit(); @@ -991,15 +1040,11 @@ pub const meshing = struct { } } if(neighborMesh != self) { - try neighborMesh.opaqueMesh.finish(neighborMesh); - try neighborMesh.voxelMesh.finish(neighborMesh); - try neighborMesh.transparentMesh.finish(neighborMesh); + try neighborMesh.finish(); } } self.chunk.blocks[getIndex(x, y, z)] = newBlock; - try self.opaqueMesh.finish(self); - try self.voxelMesh.finish(self); - try self.transparentMesh.finish(self); + try self.finish(); } pub inline fn constructFaceData(block: Block, normal: u3, x: i32, y: i32, z: i32, comptime backFace: bool) FaceData { @@ -1010,6 +1055,77 @@ pub const meshing = struct { }; } + fn getValues(mesh: *ChunkMesh, wx: i32, wy: i32, wz: i32) [6]u8 { + const x = (wx >> mesh.chunk.voxelSizeShift) & chunkMask; + const y = (wy >> mesh.chunk.voxelSizeShift) & chunkMask; + const z = (wz >> mesh.chunk.voxelSizeShift) & chunkMask; + const index = getIndex(x, y, z); + return .{ + mesh.lightingData.*[0].data[index], + mesh.lightingData.*[1].data[index], + mesh.lightingData.*[2].data[index], + mesh.lightingData.*[3].data[index], + mesh.lightingData.*[4].data[index], + mesh.lightingData.*[5].data[index], + }; + } + + fn getLightAt(self: *ChunkMesh, x: i32, y: i32, z: i32) [6]u8 { + const wx = self.pos.wx +% x*self.pos.voxelSize; + const wy = self.pos.wy +% y*self.pos.voxelSize; + const wz = self.pos.wz +% z*self.pos.voxelSize; + if(x == x & chunkMask and y == y & chunkMask and z == z & chunkMask) { + return self.getValues(wx, wy, wz); + } + const neighborMesh = renderer.RenderStructure.getMeshFromAnyLodFromRenderThread(wx, wy, wz, self.pos.voxelSize) orelse return .{0, 0, 0, 0, 0, 0}; + // TODO: If the neighbor mesh has a higher lod the transition isn't seamless. + return neighborMesh.getValues(wx, wy, wz); + } + + fn getCompressedLightAt(self: *ChunkMesh, x: i32, y: i32, z: i32) u32 { + const light = self.getLightAt(x, y, z); + return ( + @as(u32, light[0]) << 25 | + @as(u32, light[1]) << 20 | + @as(u32, light[2]) << 15 | + @as(u32, light[3]) << 10 | + @as(u32, light[4]) << 5 | + @as(u32, light[5]) << 0 + ); + } + + fn finish(self: *ChunkMesh) !void { + @memset(&self.needsLightData, false); + try self.opaqueMesh.finish(self); + try self.voxelMesh.finish(self); + try self.transparentMesh.finish(self); + for(0..6) |x| { + for(0..6) |y| { + for(0..6) |z| { + const index = (x*6 + y)*6 + z; + if(!self.needsLightData[index]) continue; + var map: LightData = undefined; + for(0..8) |dx| { + for(0..8) |dy| { + for(0..8) |dz| { + map.values[(dx*8 + dy)*8 + dz] = self.getCompressedLightAt(@as(i32, @intCast(x*8 + dx)) - 8, @as(i32, @intCast(y*8 + dy)) - 8, @as(i32, @intCast(z*8 + dz)) - 8); + } + } + } + + var allocation: graphics.SubAllocation = .{.start = undefined, .len = 0}; + if(self.chunkData.lightMapPtrs[index] != 0) { + allocation.start = @intCast(self.chunkData.lightMapPtrs[index]); + allocation.len = 1; + } + try lightBuffer.uploadData(&.{map}, &allocation); + self.chunkData.lightMapPtrs[index] = allocation.start; + } + } + } + try chunkBuffer.uploadData(&.{self.chunkData}, &self.chunkDataAllocation); + } + pub fn uploadDataAndFinishNeighbors(self: *ChunkMesh) !void { for(Neighbors.iterable) |neighbor| { const nullNeighborMesh = renderer.RenderStructure.getNeighborFromRenderThread(self.pos, self.pos.voxelSize, neighbor); @@ -1080,9 +1196,7 @@ pub const meshing = struct { } } } - try neighborMesh.opaqueMesh.finish(neighborMesh); - try neighborMesh.voxelMesh.finish(neighborMesh); - try neighborMesh.transparentMesh.finish(neighborMesh); + try neighborMesh.finish(); continue; } // lod border: @@ -1149,9 +1263,7 @@ pub const meshing = struct { } } } - try self.opaqueMesh.finish(self); - try self.voxelMesh.finish(self); - try self.transparentMesh.finish(self); + try self.finish(); } pub fn render(self: *ChunkMesh, playerPosition: Vec3d) void { @@ -1164,6 +1276,7 @@ pub const meshing = struct { ); c.glUniform1i(uniforms.visibilityMask, self.visibilityMask); c.glUniform1i(uniforms.voxelSize, self.pos.voxelSize); + c.glUniform1ui(uniforms.chunkDataIndex, self.chunkDataAllocation.start); quadsDrawn += self.opaqueMesh.vertexCount/6; c.glDrawElementsBaseVertex(c.GL_TRIANGLES, self.opaqueMesh.vertexCount, c.GL_UNSIGNED_INT, null, self.opaqueMesh.bufferAllocation.start*4); } @@ -1178,6 +1291,7 @@ pub const meshing = struct { ); c.glUniform1i(voxelUniforms.visibilityMask, self.visibilityMask); c.glUniform1i(voxelUniforms.voxelSize, self.pos.voxelSize); + c.glUniform1ui(voxelUniforms.chunkDataIndex, self.chunkDataAllocation.start); quadsDrawn += self.voxelMesh.vertexCount/6; c.glDrawElementsBaseVertex(c.GL_TRIANGLES, self.voxelMesh.vertexCount, c.GL_UNSIGNED_INT, null, self.voxelMesh.bufferAllocation.start*4); } @@ -1279,6 +1393,7 @@ pub const meshing = struct { ); c.glUniform1i(transparentUniforms.visibilityMask, self.visibilityMask); c.glUniform1i(transparentUniforms.voxelSize, self.pos.voxelSize); + c.glUniform1ui(transparentUniforms.chunkDataIndex, self.chunkDataAllocation.start); transparentQuadsDrawn += self.culledSortingCount; c.glDrawElementsBaseVertex(c.GL_TRIANGLES, self.culledSortingCount*6, c.GL_UNSIGNED_INT, null, self.transparentMesh.bufferAllocation.start*4); } diff --git a/src/graphics.zig b/src/graphics.zig index 2d1a3c80..8b8c9586 100644 --- a/src/graphics.zig +++ b/src/graphics.zig @@ -1332,7 +1332,7 @@ pub fn LargeBuffer(comptime Entry: type) type { try self.fencedFreeLists[self.activeFence].append(allocation); } - pub fn uploadData(self: *Self, data: []Entry, allocation: *SubAllocation) !void { + pub fn uploadData(self: *Self, data: []const Entry, allocation: *SubAllocation) !void { try self.free(allocation.*); if(data.len == 0) { allocation.len = 0; @@ -1854,9 +1854,7 @@ pub fn generateBlockTexture(blockType: u16) !Texture { faceData[faces + 1] = main.chunk.meshing.ChunkMesh.constructFaceData(block, main.chunk.Neighbors.dirUp, 1, 1+1, 1, false); faceData[faces + 2] = main.chunk.meshing.ChunkMesh.constructFaceData(block, main.chunk.Neighbors.dirPosZ, 1, 1, 1+1, false); faces += 3; - for(faceData[0..faces]) |*face| { - @memset(&face.light, ~@as(u32, 0)); - } + // TODO: Lighting var allocation: SubAllocation = .{.start = 0, .len = 0}; try main.chunk.meshing.faceBuffer.uploadData(faceData[0..faces], &allocation); diff --git a/src/gui/windows/debug.zig b/src/gui/windows/debug.zig index 1974e974..1297c086 100644 --- a/src/gui/windows/debug.zig +++ b/src/gui/windows/debug.zig @@ -41,7 +41,13 @@ fn flawedRender() !void { try draw.print("Queue size: {}", .{main.threadPool.queueSize()}, 0, y, 8, .left); y += 8; const faceDataSize = @sizeOf(main.chunk.meshing.FaceData); - try draw.print("ChunkMesh memory: {} MiB / {} MiB (fragmentation: {})", .{main.chunk.meshing.faceBuffer.used*faceDataSize >> 20, main.chunk.meshing.faceBuffer.capacity*faceDataSize >> 20, main.chunk.meshing.faceBuffer.freeBlocks.items.len}, 0, y, 8, .left); + try draw.print("Chunk Face memory: {} MiB / {} MiB (fragmentation: {})", .{main.chunk.meshing.faceBuffer.used*faceDataSize >> 20, main.chunk.meshing.faceBuffer.capacity*faceDataSize >> 20, main.chunk.meshing.faceBuffer.freeBlocks.items.len}, 0, y, 8, .left); + y += 8; + const chunkDataSize = @sizeOf(main.chunk.meshing.ChunkData); + try draw.print("Chunk memory: {} MiB / {} MiB (fragmentation: {})", .{main.chunk.meshing.chunkBuffer.used*chunkDataSize >> 20, main.chunk.meshing.chunkBuffer.capacity*chunkDataSize >> 20, main.chunk.meshing.chunkBuffer.freeBlocks.items.len}, 0, y, 8, .left); + y += 8; + const lightDataSize = @sizeOf(main.chunk.meshing.LightData); + try draw.print("Chunk light memory: {} MiB / {} MiB (fragmentation: {})", .{main.chunk.meshing.lightBuffer.used*lightDataSize >> 20, main.chunk.meshing.lightBuffer.capacity*lightDataSize >> 20, main.chunk.meshing.lightBuffer.freeBlocks.items.len}, 0, y, 8, .left); y += 8; try draw.print("Biome: {s}", .{main.game.world.?.playerBiome.load(.Monotonic).id}, 0, y, 8, .left); y += 8;