From 109d666eb85f9040a2543a51042eb57574cf80e0 Mon Sep 17 00:00:00 2001 From: catangent Date: Sun, 3 Aug 2025 17:54:28 +0100 Subject: [PATCH] fix literally fucking everything --- resources/images/ambient_occlusion.png | Bin 0 -> 75586 bytes resources/images/tiles.png | Bin 2843 -> 2811 bytes resources/images/tiles.png~ | Bin 2807 -> 2843 bytes .../ambient_occlusion_texture_generator.py | 100 +++++++++++++++ resources/shaders/tiling.fs | 57 ++++++--- resources/shaders/tiling.vs | 2 +- src/lib_helpers/raylib_helper.zig | 3 + src/main.zig | 31 +++-- src/world/chunk.zig | 117 ++++++++++-------- 9 files changed, 235 insertions(+), 75 deletions(-) create mode 100644 resources/images/ambient_occlusion.png create mode 100644 resources/scripts/ambient_occlusion_texture_generator.py diff --git a/resources/images/ambient_occlusion.png b/resources/images/ambient_occlusion.png new file mode 100644 index 0000000000000000000000000000000000000000..9b56dcfa69c432e6d2adb264d7ac8b70bb96b59d GIT binary patch literal 75586 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 y4g}?q7X)+Q=Y)}O2D1SN0R)l 0 and square & (1 << 4) > 0: + square = square | (1 << 5) + if square & (1 << 4) > 0 and square & (1 << 2) > 0: + square = square | (1 << 3) + if square & (1 << 2) > 0 and square & (1 << 0) > 0: + square = square | (1 << 1) + if square & (1 << 0) > 0 and square & (1 << 6) > 0: + square = square | (1 << 7) + + # check if we've already done the task in a rotated variation + instance_found = False + for rotation in range(4): # clockwise rotations by pi/2 + rotated_square = (square >> (rotation * 2)) | ((square & ((1 << rotation*2)-1)) << 2*(4 - rotation)) + if rotated_square in calculated_squares: + square_id_from = calculated_squares[rotated_square] + print(f"already calculated at {square_id_from}") + + box_from = (SQUARE_SIZE*square_id_from, 0, SQUARE_SIZE*(square_id_from+1), SQUARE_SIZE) + box_to = (SQUARE_SIZE*square_id, 0, SQUARE_SIZE*(square_id+1), SQUARE_SIZE) + region = im.crop(box_from) + if rotation == 1: + region = region.transpose(Image.Transpose.ROTATE_270) + if rotation == 2: + region = region.transpose(Image.Transpose.ROTATE_180) + if rotation == 3: + region = region.transpose(Image.Transpose.ROTATE_90) + im.paste(region, box_to) + + instance_found = True + break + if instance_found: + continue + + # actually calculate the occlusion + obscured = [i for c, i in enumerate(COORDS) if (square >> c) & 1 == 1] + for x in range(SQUARE_SIZE): + for y in range(SQUARE_SIZE): + point_coord = ((x+0.5)/SQUARE_SIZE-0.5, (y+0.5)/SQUARE_SIZE-0.5, 0) + count = 0 + for i in range(ITERATIONS_PER_PIXEL): + point = random_point_on_sphere() + point[0] += point_coord[0] + point[1] += point_coord[1] + rounded_point = (round(point[0]), round(point[1])) + if rounded_point in obscured: + count += 1 + result_color = 255-255*count//ITERATIONS_PER_PIXEL + px[x+square_id*SQUARE_SIZE, y] = (result_color, result_color, result_color, 255) + calculated_squares[square] = square_id + + # smooth it + box = (SQUARE_SIZE*square_id, 0, SQUARE_SIZE*(square_id+1), SQUARE_SIZE) + region = im.crop(box) + region = region.filter(filter=ImageFilter.GaussianBlur(2)) + im.paste(region, box) + + print(f"calculated") + + print(f"total squares calculated: {len(calculated_squares)}") + + # result_side_length = int(SQUARES**0.5) + # with Image.new("RGBA", (SQUARE_SIZE*result_side_length, SQUARE_SIZE*result_side_length), "black") as new_im: + # for i in range(result_side_length): + # box_from = (SQUARE_SIZE*result_side_length*i, 0, SQUARE_SIZE*result_side_length*(i+1), SQUARE_SIZE) + # box_to = (0, SQUARE_SIZE*i, SQUARE_SIZE*result_side_length, SQUARE_SIZE*(i+1)) + # new_im.paste(im.crop(box_from), box_to) + # new_im.show() + # new_im.save("../images/ambient_occlusion.png") + + im.show() + im.save("../images/ambient_occlusion.png") + diff --git a/resources/shaders/tiling.fs b/resources/shaders/tiling.fs index 8da9038..7430751 100644 --- a/resources/shaders/tiling.fs +++ b/resources/shaders/tiling.fs @@ -1,6 +1,7 @@ #version 330 core uniform sampler2D diffuseMap; +uniform sampler2D occlusionMap; uniform vec2 textureTiling; in vec2 fragTexCoord; @@ -17,30 +18,52 @@ flat in int quadWidth; out vec4 outColor; -// this is a shitty approximation of arcsin(x)/pi that gets the tails right and is reasonably close to the actual arcsin(x)/pi curve. -float fakeArcsin(float x) { - x = clamp(x, -1.0, 1.0); - float ax = abs(x); - float sqrtPart = sqrt(1.0 - ax); - float result = 0.5 - sqrtPart * (0.5 - 0.06667 * ax); - return x < 0.0 ? -result : result; +int calculate_ao_square() +{ + ivec2 tileCoord = ivec2(fragTileTexCoord); + int ao_square = 0; + + if(tileCoord.x == quadWidth - 1 && ((occlusionSides.x & uint(1 << tileCoord.y)) > uint(0))) ao_square |= 1 << 0; + + if(tileCoord.x == quadWidth - 1 && tileCoord.y == quadHeight - 1 && bottomRightObscured > 0) ao_square |= 1 << 1; + if(tileCoord.x == quadWidth - 1 && tileCoord.y != quadHeight - 1 && ((occlusionSides.x & uint(1 << (tileCoord.y+1))) > uint(0))) ao_square |= 1 << 1; + if(tileCoord.x != quadWidth - 1 && tileCoord.y == quadHeight - 1 && ((occlusionSides.w & uint(1 << (tileCoord.x+1))) > uint(0))) ao_square |= 1 << 1; + + if(tileCoord.y == quadHeight - 1 && ((occlusionSides.w & uint(1 << tileCoord.x)) > uint(0))) ao_square |= 1 << 2; + + if(tileCoord.x == 0 && tileCoord.y == quadHeight - 1 && bottomLeftObscured > 0) ao_square |= 1 << 3; + if(tileCoord.x == 0 && tileCoord.y != quadHeight - 1 && ((occlusionSides.y & uint(1 << (tileCoord.y+1))) > uint(0))) ao_square |= 1 << 3; + if(tileCoord.x != 0 && tileCoord.y == quadHeight - 1 && ((occlusionSides.w & uint(1 << (tileCoord.x-1))) > uint(0))) ao_square |= 1 << 3; + + if(tileCoord.x == 0 && ((occlusionSides.y & uint(1 << tileCoord.y)) > uint(0))) ao_square |= 1 << 4; + + if(tileCoord.x == 0 && tileCoord.y == 0 && topRightObscured > 0) ao_square |= 1 << 5; + if(tileCoord.x == 0 && tileCoord.y != 0 && ((occlusionSides.y & uint(1 << (tileCoord.y-1))) > uint(0))) ao_square |= 1 << 5; + if(tileCoord.x != 0 && tileCoord.y == 0 && ((occlusionSides.z & uint(1 << (tileCoord.x-1))) > uint(0))) ao_square |= 1 << 5; + + if(tileCoord.y == 0 && ((occlusionSides.z & uint(1 << tileCoord.x)) > uint(0))) ao_square |= 1 << 6; + + if(tileCoord.x == quadWidth - 1 && tileCoord.y == 0 && topLeftObscured > 0) ao_square |= 1 << 7; + if(tileCoord.x == quadWidth - 1 && tileCoord.y != 0 && ((occlusionSides.x & uint(1 << (tileCoord.y-1))) > uint(0))) ao_square |= 1 << 7; + if(tileCoord.x != quadWidth - 1 && tileCoord.y == 0 && ((occlusionSides.z & uint(1 << (tileCoord.x+1))) > uint(0))) ao_square |= 1 << 7; + + return ao_square; } void main() { vec2 texCoord = (floor(fragTexCoord*textureTiling) + fract(fragTileTexCoord)) / textureTiling; + + int ao_square = calculate_ao_square(); + outColor = texture(diffuseMap, texCoord); - - ivec2 floorFragTileTexCoord = ivec2(fragTileTexCoord); - - if(floorFragTileTexCoord.x < 1 && ((occlusionSides.x >> floorFragTileTexCoord.x) & uint(1)) == uint(1)) { - outColor *= 0.5 + fakeArcsin(fragTileTexCoord.x); - } + outColor *= texture(occlusionMap, (vec2(ao_square, 0)+fract(fragTileTexCoord))/vec2(256, 1)); outColor.a = 1; - uint bit = uint(fragTileTexCoord * 32); - outColor.g = (((occlusionSides.x >> bit) & uint(1)) == uint(1)) ? - ((bit % uint(2) == uint(0)) ? 1.0 : 0.8): - ((bit % uint(2) == uint(0)) ? 0.0 : 0.2); + //uint bit = uint(fragTileTexCoord * 32); + //outColor.g = (((uint(quadWidth) >> bit) & uint(1)) == uint(1)) ? + // ((bit % uint(2) == uint(0)) ? 1.0 : 0.8): + // ((bit % uint(2) == uint(0)) ? 0.0 : 0.2); } + diff --git a/resources/shaders/tiling.vs b/resources/shaders/tiling.vs index 0efd713..5fa028f 100644 --- a/resources/shaders/tiling.vs +++ b/resources/shaders/tiling.vs @@ -29,7 +29,7 @@ void main() { gl_Position = mvp*vec4(vertexPosition, 1.0); // metadata 1 parsing - int metadata1W = int(vertexMetadata1.w); + int metadata1W = int(vertexMetadata1.x); topLeftObscured = (metadata1W & 0x1); // Take 0th bit. topRightObscured = (metadata1W & 0x2) >> 1; // Take 1st bits. bottomLeftObscured = (metadata1W & 0x4) >> 2; // Take 2nd bits. diff --git a/src/lib_helpers/raylib_helper.zig b/src/lib_helpers/raylib_helper.zig index 8ad5c5f..c30455f 100644 --- a/src/lib_helpers/raylib_helper.zig +++ b/src/lib_helpers/raylib_helper.zig @@ -33,6 +33,9 @@ pub const v3 = struct { pub inline fn nor(a: raylib.Vector3) raylib.Vector3 { return raylib.Vector3Normalize(a); } + pub inline fn dot(a: raylib.Vector3, b: raylib.Vector3) f32 { + return raylib.Vector3DotProduct(a, b); + } pub inline fn cross(a: raylib.Vector3, b: raylib.Vector3) raylib.Vector3 { return raylib.Vector3CrossProduct(a, b); } diff --git a/src/main.zig b/src/main.zig index 985c06f..a8c6a75 100644 --- a/src/main.zig +++ b/src/main.zig @@ -64,11 +64,13 @@ pub fn main() !void { defer raylib.UnloadTexture(texture); raylib.UnloadImage(tiles); + const ambient_occlusion_image = raylib.LoadImage("resources/images/ambient_occlusion.png"); + const ambient_occlusion_texture = raylib.LoadTextureFromImage(ambient_occlusion_image); + defer raylib.UnloadTexture(ambient_occlusion_texture); + raylib.UnloadImage(ambient_occlusion_image); + const shader = raylib.LoadChunkShader("resources/shaders/tiling.vs", "resources/shaders/tiling.fs"); defer raylib.UnloadShader(shader); - //for (0..32) |i|{ - // std.debug.print("shader loc {}: {}\n", .{i, shader.locs[i]}); - //} raylib.SetShaderValue(shader, raylib.GetShaderLocation(shader, "textureTiling"), &.{ @as(f32, @floatFromInt(tile_columns)), @as(f32, @floatFromInt(tile_rows)) }, raylib.SHADER_UNIFORM_VEC2); var chunk = try chunks.Chunk.init(a7r); @@ -83,7 +85,7 @@ pub fn main() !void { const xf: f32 = @floatFromInt(raw_x); const yf: f32 = @floatFromInt(raw_y); const zf: f32 = @floatFromInt(raw_z); - const tile_type: u32 = if (tile_type_generator.noise3(xf, yf, zf) > 0) 1 else 2; + const tile_type: u32 = if (tile_type_generator.noise3(xf, yf, zf) > 0) 2 else 2; // const height: f32 = (height_generator.noise2(xf, zf) + 1) * 16 + @as(f32, if(x > 24) 4.0 else 0.0) + @as(f32, if(z < 8) 4.0 else 0.0); // if (height >= yf) chunk.setTile(x, y, z, tile_type); if((xf-16)*(xf-16)+(yf-16)*(yf-16)+(zf-16)*(zf-16) < 16*16) chunk.setTile(x, y, z, tile_type); @@ -108,6 +110,13 @@ pub fn main() !void { model.materials[0].maps[raylib.MATERIAL_MAP_DIFFUSE].texture = texture; model.materials[0].shader = shader; + model.materials[0].shader.locs[raylib.SHADER_LOC_MAP_DIFFUSE+1] = raylib.GetShaderLocation(shader, "occlusionMap"); + raylib.SetShaderValueTexture(shader, model.materials[0].shader.locs[raylib.SHADER_LOC_MAP_DIFFUSE+1], ambient_occlusion_texture); model.materials[0].maps[raylib.MATERIAL_MAP_DIFFUSE+1].texture = ambient_occlusion_texture; + + // for (0..32) |i|{ + // std.debug.print("shader loc {}: {}\n", .{i, shader.locs[i]}); + // } + while (!raylib.WindowShouldClose()) { raylib.ClearBackground(raylib.BLACK); @@ -128,10 +137,17 @@ pub fn main() !void { moveCamera(&camera, v3.scl(v3.nor(movement), speed)); const delta = raylib.GetMouseDelta(); - // on the first mouse movement, for some reason mouse delta is completely insane, so we just ignore too large deltas + // on the first mouse movement, for some reason mouse delta is way too large, so we just ignore too large deltas if(delta.x < 1000 and delta.y < 1000 and delta.x > -1000 and delta.y > -1000){ - camera.target = v3.add(camera.position, v3.rotate(v3.sub(camera.target, camera.position), camera.up, -0.005 * delta.x)); - camera.target = v3.add(camera.position, v3.rotate(v3.sub(camera.target, camera.position), right, -0.005 * delta.y)); + var direction = v3.sub(camera.target, camera.position); + direction = v3.rotate(direction, camera.up, -0.005 * delta.x); + const tmp_direction = direction; + direction = v3.rotate(direction, right, -0.005 * delta.y); + if(tmp_direction.x*direction.x+tmp_direction.z*direction.z > 0){ + camera.target = v3.add(camera.position, direction); + } else { + camera.target = v3.add(camera.position, tmp_direction); + } } raylib.BeginDrawing(); @@ -145,6 +161,7 @@ pub fn main() !void { raylib.BeginShaderMode(shader); defer raylib.EndShaderMode(); + raylib.SetShaderValueTexture(shader, raylib.GetShaderLocation(shader, "ambientOcclusionTexture"), ambient_occlusion_texture); raylib.DrawChunkModel(model, model_position, 0.5, raylib.WHITE); } diff --git a/src/world/chunk.zig b/src/world/chunk.zig index 6bb0613..e57c88b 100644 --- a/src/world/chunk.zig +++ b/src/world/chunk.zig @@ -21,6 +21,8 @@ const RawQuad = struct { normal: raylib.Vector3, width: f32, height: f32, + flip_x: bool, + flip_y: bool, top_obscuring_pattern: u32, left_obscuring_pattern: u32, @@ -85,12 +87,12 @@ pub const Chunk = struct { } // This cyclically permutes the x, y, z coordinates at compile time. Useful when iterating over x, y, and z axis. - inline fn getTileRawShifted(self: Chunk, x: u5, y: u5, z: u5, comptime dimention: comptime_int) u32 { - if (dimention % 3 == 0) { + inline fn getTileRawShifted(self: Chunk, x: u5, y: u5, z: u5, comptime dimension: comptime_int) u32 { + if (dimension % 3 == 0) { return self.getTileRaw(x, y, z); - } else if (dimention % 3 == 1) { + } else if (dimension % 3 == 1) { return self.getTileRaw(y, z, x); - } else if (dimention % 3 == 2) { + } else if (dimension % 3 == 2) { return self.getTileRaw(z, x, y); } } @@ -101,12 +103,16 @@ pub const Chunk = struct { y_start: usize, y_end: usize, z_start: usize, z_end: usize, sign: comptime_int, - dimention: comptime_int, + dimension: comptime_int, surface: u32, y_minus_obscuring_pattern: u32, y_plus_obscuring_pattern: u32, z_minus_obscuring_pattern: u32, z_plus_obscuring_pattern: u32, + y_minus_z_minus_obscured: bool, + y_minus_z_plus_obscured: bool, + y_plus_z_plus_obscured: bool, + y_plus_z_minus_obscured: bool, ) RawQuad { const ymin: f32 = @as(f32, @floatFromInt(y_start)) - 0.5; const ymax: f32 = @as(f32, @floatFromInt(y_end)) - 0.5; @@ -117,16 +123,8 @@ pub const Chunk = struct { const zleft: f32 = if (sign == 1) zmin else zmax; const zright: f32 = if (sign == 1) zmax else zmin; - if(dimention == 0 and z_minus_obscuring_pattern == 0b10000){ - std.debug.print("z_minus_obscuring_pattern {b}\n", .{z_minus_obscuring_pattern}); - std.debug.print("dimension {}\n", .{dimention}); - std.debug.print("x {}\n", .{x}); - std.debug.print("y {}-{}\n", .{y_start, y_end}); - std.debug.print("z {}-{}\n", .{z_start, z_end}); - } - var raw_quad: RawQuad = undefined; - switch (dimention) { + switch (dimension) { X_DIRECTION => { raw_quad = .{ .tile = surface, @@ -137,15 +135,17 @@ pub const Chunk = struct { .normal = v3.new(sign, 0, 0), .width = zmax - zmin, .height = ymax - ymin, + .flip_x = sign == -1, + .flip_y = false, - .top_obscuring_pattern = z_plus_obscuring_pattern, + .top_obscuring_pattern = y_plus_obscuring_pattern, .left_obscuring_pattern = z_minus_obscuring_pattern, - .right_obscuring_pattern = y_plus_obscuring_pattern, + .right_obscuring_pattern = z_plus_obscuring_pattern, .bottom_obscuring_pattern = y_minus_obscuring_pattern, - .top_left_obscured = false, - .top_right_obscured = false, - .bottom_right_obscured = false, - .bottom_left_obscured = false, + .top_left_obscured = y_plus_z_minus_obscured, + .top_right_obscured = y_plus_z_plus_obscured, + .bottom_right_obscured = y_minus_z_plus_obscured, + .bottom_left_obscured = y_minus_z_minus_obscured, }; }, Y_DIRECTION => { @@ -158,15 +158,17 @@ pub const Chunk = struct { .normal = v3.new(0, 0, sign), .height = zmax - zmin, .width = ymax - ymin, + .flip_x = sign == 1, + .flip_y = false, - .top_obscuring_pattern = 0, - .left_obscuring_pattern = 0, - .right_obscuring_pattern = 0, - .bottom_obscuring_pattern = 0, - .top_left_obscured = false, - .top_right_obscured = false, - .bottom_right_obscured = false, - .bottom_left_obscured = false, + .top_obscuring_pattern = z_plus_obscuring_pattern, + .left_obscuring_pattern = y_minus_obscuring_pattern, + .right_obscuring_pattern = y_plus_obscuring_pattern, + .bottom_obscuring_pattern = z_minus_obscuring_pattern, + .top_left_obscured = y_minus_z_plus_obscured, + .top_right_obscured = y_plus_z_plus_obscured, + .bottom_right_obscured = y_plus_z_minus_obscured, + .bottom_left_obscured = y_minus_z_minus_obscured, }; }, Z_DIRECTION => { @@ -179,15 +181,17 @@ pub const Chunk = struct { .normal = v3.new(0, sign, 0), .width = zmax - zmin, .height = ymax - ymin, + .flip_x = sign == 1, + .flip_y = true, - .top_obscuring_pattern = 0, - .left_obscuring_pattern = 0, - .right_obscuring_pattern = 0, - .bottom_obscuring_pattern = 0, - .top_left_obscured = false, - .top_right_obscured = false, - .bottom_right_obscured = false, - .bottom_left_obscured = false, + .top_obscuring_pattern = y_plus_obscuring_pattern, + .left_obscuring_pattern = z_minus_obscuring_pattern, + .right_obscuring_pattern = z_plus_obscuring_pattern, + .bottom_obscuring_pattern = y_minus_obscuring_pattern, + .top_left_obscured = y_plus_z_minus_obscured, + .top_right_obscured = y_plus_z_plus_obscured, + .bottom_right_obscured = y_minus_z_plus_obscured, + .bottom_left_obscured = y_minus_z_minus_obscured, }; }, else => unreachable, @@ -201,7 +205,7 @@ pub const Chunk = struct { defer raw_quads.deinit(); // Begin scanning the chunk for tile surfaces to make raw quads. - inline for (0..3) |dimention| { // Iterate over the 3 dimensions, X, Y and Z. + inline for (0..3) |dimension| { // Iterate over the 3 dimensions, X, Y and Z. for (0..32) |raw_x| { const x: u5 = @intCast(raw_x); // Create surface arrays for the +x side of the layer and the -x side. @@ -210,11 +214,11 @@ pub const Chunk = struct { for (0..32) |raw_y| for (0..32) |raw_z| { const y: u5 = @intCast(raw_y); const z: u5 = @intCast(raw_z); - const tile: u32 = chunk.getTileRawShifted(x, y, z, dimention); + const tile: u32 = chunk.getTileRawShifted(x, y, z, dimension); if (tile == 0) continue; // If air, there is no surface. // If either at the edge of the chunk or the tile is exposed, create a tile surface. - if (x == 31 or chunk.getTileRawShifted(x + 1, y, z, dimention) == 0) positive_tile_surfaces[y][z] = tile; - if (x == 0 or chunk.getTileRawShifted(x - 1, y, z, dimention) == 0) negative_tile_surfaces[y][z] = tile; + if (x == 31 or chunk.getTileRawShifted(x + 1, y, z, dimension) == 0) positive_tile_surfaces[y][z] = tile; + if (x == 0 or chunk.getTileRawShifted(x - 1, y, z, dimension) == 0) negative_tile_surfaces[y][z] = tile; }; inline for (.{ -1, 1 }) |sign| { var tile_surfaces = if (sign == 1) positive_tile_surfaces else negative_tile_surfaces; @@ -241,7 +245,7 @@ pub const Chunk = struct { for (y_start..y_end) |raw_y| { const y: u5 = @intCast(raw_y); z_minus_obscuring_pattern <<= 1; - if (chunk.getTileRawShifted(if (sign == 1) x+1 else x-1, y, @intCast(z_start - 1), dimention) != 0) z_minus_obscuring_pattern |= 1; + if (chunk.getTileRawShifted(if (sign == 1) x+1 else x-1, y, @intCast(z_start - 1), dimension) != 0) z_minus_obscuring_pattern |= 1; } } var z_plus_obscuring_pattern: u32 = 0; @@ -249,7 +253,7 @@ pub const Chunk = struct { for (y_start..y_end) |raw_y| { const y: u5 = @intCast(raw_y); z_plus_obscuring_pattern <<= 1; - if (chunk.getTileRawShifted(if (sign == 1) x+1 else x-1, y, @intCast(z_end), dimention) != 0) z_plus_obscuring_pattern |= 1; + if (chunk.getTileRawShifted(if (sign == 1) x+1 else x-1, y, @intCast(z_end), dimension) != 0) z_plus_obscuring_pattern |= 1; } } var y_minus_obscuring_pattern: u32 = 0; @@ -257,7 +261,7 @@ pub const Chunk = struct { for (z_start..z_end) |raw_z| { const z: u5 = @intCast(raw_z); y_minus_obscuring_pattern <<= 1; - if (chunk.getTileRawShifted(if (sign == 1) x+1 else x-1, @intCast(y_start - 1), z, dimention) != 0) y_minus_obscuring_pattern |= 1; + if (chunk.getTileRawShifted(if (sign == 1) x+1 else x-1, @intCast(y_start - 1), z, dimension) != 0) y_minus_obscuring_pattern |= 1; } } var y_plus_obscuring_pattern: u32 = 0; @@ -265,11 +269,22 @@ pub const Chunk = struct { for (z_start..z_end) |raw_z| { const z: u5 = @intCast(raw_z); y_plus_obscuring_pattern <<= 1; - if (chunk.getTileRawShifted(if (sign == 1) x+1 else x-1, @intCast(y_end), z, dimention) != 0) y_plus_obscuring_pattern |= 1; + if (chunk.getTileRawShifted(if (sign == 1) x+1 else x-1, @intCast(y_end), z, dimension) != 0) y_plus_obscuring_pattern |= 1; } } - // std.debug.print("{}\n", .{z_minus_obscuring_pattern}); - const raw_quad = packRawQuad(@floatFromInt(raw_x), y_start, y_end, z_start, z_end, sign, dimention, surface, y_minus_obscuring_pattern, y_plus_obscuring_pattern, z_minus_obscuring_pattern, z_plus_obscuring_pattern); + var y_minus_z_minus_obscured = false; + var y_minus_z_plus_obscured = false; + var y_plus_z_plus_obscured = false; + var y_plus_z_minus_obscured = false; + if(x != (if (sign == 1) 31 else 0) and y_start != 0 and z_start != 0) + y_minus_z_minus_obscured = chunk.getTileRawShifted(if (sign == 1) x+1 else x-1, @intCast(y_start-1), @intCast(z_start-1), dimension) != 0; + if(x != (if (sign == 1) 31 else 0) and y_start != 0 and z_end != 32) + y_minus_z_plus_obscured = chunk.getTileRawShifted(if (sign == 1) x+1 else x-1, @intCast(y_start-1), @intCast(z_end), dimension) != 0; + if(x != (if (sign == 1) 31 else 0) and y_end != 32 and z_end != 32) + y_plus_z_plus_obscured = chunk.getTileRawShifted(if (sign == 1) x+1 else x-1, @intCast(y_end), @intCast(z_end), dimension) != 0; + if(x != (if (sign == 1) 31 else 0) and y_end != 32 and z_start != 0) + y_plus_z_minus_obscured = chunk.getTileRawShifted(if (sign == 1) x+1 else x-1, @intCast(y_end), @intCast(z_start-1), dimension) != 0; + const raw_quad = packRawQuad(@floatFromInt(raw_x), y_start, y_end, z_start, z_end, sign, dimension, surface, y_minus_obscuring_pattern, y_plus_obscuring_pattern, z_minus_obscuring_pattern, z_plus_obscuring_pattern, y_minus_z_minus_obscured, y_minus_z_plus_obscured, y_plus_z_plus_obscured, y_plus_z_minus_obscured); try raw_quads.append(raw_quad); }; } @@ -309,8 +324,10 @@ pub const Chunk = struct { const vertex_corners = .{ raw_quad.top_left, raw_quad.bottom_left, raw_quad.top_right, raw_quad.bottom_right, raw_quad.top_right, raw_quad.bottom_left }; const texcoords_x = .{ left_uv, left_uv, right_uv, right_uv, right_uv, left_uv }; const texcoords_y = .{ top_uv, bottom_uv } ** 3; - const tiletexcoords_x = .{ 0.0, 0.0, raw_quad.width, raw_quad.width, raw_quad.width, 0.0 }; - const tiletexcoords_y = .{ 0.0, raw_quad.height } ** 3; + const tiletexcoords_x = if(raw_quad.flip_x) + .{raw_quad.width, raw_quad.width, 0.0, 0.0, 0.0, raw_quad.width} else + .{ 0.0, 0.0, raw_quad.width, raw_quad.width, raw_quad.width, 0.0 }; + const tiletexcoords_y = if(raw_quad.flip_y) .{ raw_quad.height, 0.0 } ** 3 else .{ 0.0, raw_quad.height } ** 3; inline for (0..6) |corner_id| { vertices[VERTICES_BLOCK_SIZE * i + corner_id * 3 + 0] = vertex_corners[corner_id].x; @@ -332,9 +349,9 @@ pub const Chunk = struct { .quad_height = @intFromFloat(raw_quad.height), .quad_width = @intFromFloat(raw_quad.width), }; - const metadata1_baked: [4]f32 = @bitCast(metadata1); + const metadata1_baked: [4]u32 = @bitCast(metadata1); for (0..4) |k| { - metadata1_packed[24 * i + 4 * j + k] = @bitCast(@as(f32, metadata1_baked[k])); + metadata1_packed[24 * i + 4 * j + k] = metadata1_baked[k]; } }