diff --git a/src/blocks.zig b/src/blocks.zig index 3680b04d..36dffbb7 100644 --- a/src/blocks.zig +++ b/src/blocks.zig @@ -378,6 +378,7 @@ pub const meshes = struct { // MARK: meshes var reflectivityTextures: main.List(Image) = undefined; var absorptionTextures: main.List(Image) = undefined; var textureFogData: main.List(FogData) = undefined; + pub var textureOcclusionData: main.List(bool) = undefined; var arenaForWorld: main.utils.NeverFailingArenaAllocator = undefined; @@ -427,6 +428,7 @@ pub const meshes = struct { // MARK: meshes reflectivityTextures = .init(main.globalAllocator); absorptionTextures = .init(main.globalAllocator); textureFogData = .init(main.globalAllocator); + textureOcclusionData = .init(main.globalAllocator); arenaForWorld = .init(main.globalAllocator); blockBreakingTextures = .init(main.globalAllocator); } @@ -452,6 +454,7 @@ pub const meshes = struct { // MARK: meshes reflectivityTextures.deinit(); absorptionTextures.deinit(); textureFogData.deinit(); + textureOcclusionData.deinit(); arenaForWorld.deinit(); blockBreakingTextures.deinit(); } @@ -466,6 +469,7 @@ pub const meshes = struct { // MARK: meshes reflectivityTextures.clearRetainingCapacity(); absorptionTextures.clearRetainingCapacity(); textureFogData.clearRetainingCapacity(); + textureOcclusionData.clearRetainingCapacity(); blockBreakingTextures.clearRetainingCapacity(); _ = arenaForWorld.reset(.free_all); } @@ -544,6 +548,7 @@ pub const meshes = struct { // MARK: meshes .fogColor = textureInfoZon.get(u32, "fogColor", 0xffffff), }); } + textureOcclusionData.append(textureInfoZon.get(bool, "hasOcclusion", true)); } pub fn readTexture(_textureId: ?[]const u8, assetFolder: []const u8) !u16 { @@ -630,6 +635,7 @@ pub const meshes = struct { // MARK: meshes reflectivityTextures.clearRetainingCapacity(); absorptionTextures.clearRetainingCapacity(); textureFogData.clearAndFree(); + textureOcclusionData.clearAndFree(); for(textureIDs.items) |path| { readTextureData(path); } diff --git a/src/renderer/chunk_meshing.zig b/src/renderer/chunk_meshing.zig index 15f28be4..3f1a108c 100644 --- a/src/renderer/chunk_meshing.zig +++ b/src/renderer/chunk_meshing.zig @@ -381,7 +381,7 @@ const PrimitiveMesh = struct { // MARK: PrimitiveMesh parent.lightingData[0].lock.lockRead(); parent.lightingData[1].lock.lockRead(); for(completeList) |*face| { - const light = getLight(parent, .{face.position.x, face.position.y, face.position.z}, face.blockAndQuad.quadIndex); + const light = getLight(parent, .{face.position.x, face.position.y, face.position.z}, face.blockAndQuad.texture, face.blockAndQuad.quadIndex); const result = lightMap.getOrPut(light) catch unreachable; if(!result.found_existing) { result.value_ptr.* = @intCast(lightList.items.len/4); @@ -510,8 +510,16 @@ const PrimitiveMesh = struct { // MARK: PrimitiveMesh return result; } - fn getLight(parent: *ChunkMesh, blockPos: Vec3i, quadIndex: u16) [4]u32 { + fn getLight(parent: *ChunkMesh, blockPos: Vec3i, textureIndex: u16, quadIndex: u16) [4]u32 { const normal = models.quads.items[quadIndex].normal; + if(!blocks.meshes.textureOcclusionData.items[textureIndex]) { // No ambient occlusion (→ no smooth lighting) + const fullValues = getLightAt(parent, blockPos[0], blockPos[1], blockPos[2]); + var rawVals: [6]u5 = undefined; + for(0..6) |i| { + rawVals[i] = std.math.lossyCast(u5, fullValues[i]/8); + } + return packLightValues(.{rawVals} ** 4); + } if(models.extraQuadInfos.items[quadIndex].hasOnlyCornerVertices) { // Fast path for simple quads. var rawVals: [4][6]u5 = undefined; for(0..4) |i| {