fix literally fucking everything
This commit is contained in:
parent
0b7eb66703
commit
109d666eb8
9 changed files with 235 additions and 75 deletions
BIN
resources/images/ambient_occlusion.png
Normal file
BIN
resources/images/ambient_occlusion.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 74 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.7 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.8 KiB |
100
resources/scripts/ambient_occlusion_texture_generator.py
Normal file
100
resources/scripts/ambient_occlusion_texture_generator.py
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
from PIL import Image, ImageFilter
|
||||||
|
import random
|
||||||
|
import math
|
||||||
|
|
||||||
|
SQUARE_SIZE = 32
|
||||||
|
SQUARES = 2**8
|
||||||
|
ITERATIONS_PER_PIXEL = 1000
|
||||||
|
COORDS = [(1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0), (-1, -1), (0, -1), (1, -1)]
|
||||||
|
|
||||||
|
|
||||||
|
def random_point_on_sphere():
|
||||||
|
theta = random.uniform(0, 2 * math.pi)
|
||||||
|
phi = math.acos(random.uniform(-1, 1))
|
||||||
|
x = math.sin(phi) * math.cos(theta)
|
||||||
|
y = math.sin(phi) * math.sin(theta)
|
||||||
|
z = math.cos(phi)
|
||||||
|
return [x, y, z]
|
||||||
|
|
||||||
|
|
||||||
|
calculated_squares = dict()
|
||||||
|
with Image.new("RGBA", (SQUARE_SIZE*SQUARES, SQUARE_SIZE), "black") as im:
|
||||||
|
px = im.load()
|
||||||
|
|
||||||
|
for square_id in range(SQUARES):
|
||||||
|
print(f"square {square_id}: ", end="")
|
||||||
|
square = square_id
|
||||||
|
|
||||||
|
# if 2 side touching tiles are obscuring, then we can assume the corner is obscuring as well
|
||||||
|
if square & (1 << 6) > 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")
|
||||||
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
uniform sampler2D diffuseMap;
|
uniform sampler2D diffuseMap;
|
||||||
|
uniform sampler2D occlusionMap;
|
||||||
uniform vec2 textureTiling;
|
uniform vec2 textureTiling;
|
||||||
|
|
||||||
in vec2 fragTexCoord;
|
in vec2 fragTexCoord;
|
||||||
|
|
@ -17,30 +18,52 @@ flat in int quadWidth;
|
||||||
|
|
||||||
out vec4 outColor;
|
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.
|
int calculate_ao_square()
|
||||||
float fakeArcsin(float x) {
|
{
|
||||||
x = clamp(x, -1.0, 1.0);
|
ivec2 tileCoord = ivec2(fragTileTexCoord);
|
||||||
float ax = abs(x);
|
int ao_square = 0;
|
||||||
float sqrtPart = sqrt(1.0 - ax);
|
|
||||||
float result = 0.5 - sqrtPart * (0.5 - 0.06667 * ax);
|
if(tileCoord.x == quadWidth - 1 && ((occlusionSides.x & uint(1 << tileCoord.y)) > uint(0))) ao_square |= 1 << 0;
|
||||||
return x < 0.0 ? -result : result;
|
|
||||||
|
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()
|
void main()
|
||||||
{
|
{
|
||||||
vec2 texCoord = (floor(fragTexCoord*textureTiling) + fract(fragTileTexCoord)) / textureTiling;
|
vec2 texCoord = (floor(fragTexCoord*textureTiling) + fract(fragTileTexCoord)) / textureTiling;
|
||||||
|
|
||||||
|
int ao_square = calculate_ao_square();
|
||||||
|
|
||||||
outColor = texture(diffuseMap, texCoord);
|
outColor = texture(diffuseMap, texCoord);
|
||||||
|
outColor *= texture(occlusionMap, (vec2(ao_square, 0)+fract(fragTileTexCoord))/vec2(256, 1));
|
||||||
ivec2 floorFragTileTexCoord = ivec2(fragTileTexCoord);
|
|
||||||
|
|
||||||
if(floorFragTileTexCoord.x < 1 && ((occlusionSides.x >> floorFragTileTexCoord.x) & uint(1)) == uint(1)) {
|
|
||||||
outColor *= 0.5 + fakeArcsin(fragTileTexCoord.x);
|
|
||||||
}
|
|
||||||
|
|
||||||
outColor.a = 1;
|
outColor.a = 1;
|
||||||
|
|
||||||
uint bit = uint(fragTileTexCoord * 32);
|
//uint bit = uint(fragTileTexCoord * 32);
|
||||||
outColor.g = (((occlusionSides.x >> bit) & uint(1)) == uint(1)) ?
|
//outColor.g = (((uint(quadWidth) >> bit) & uint(1)) == uint(1)) ?
|
||||||
((bit % uint(2) == uint(0)) ? 1.0 : 0.8):
|
// ((bit % uint(2) == uint(0)) ? 1.0 : 0.8):
|
||||||
((bit % uint(2) == uint(0)) ? 0.0 : 0.2);
|
// ((bit % uint(2) == uint(0)) ? 0.0 : 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ void main() {
|
||||||
gl_Position = mvp*vec4(vertexPosition, 1.0);
|
gl_Position = mvp*vec4(vertexPosition, 1.0);
|
||||||
|
|
||||||
// metadata 1 parsing
|
// metadata 1 parsing
|
||||||
int metadata1W = int(vertexMetadata1.w);
|
int metadata1W = int(vertexMetadata1.x);
|
||||||
topLeftObscured = (metadata1W & 0x1); // Take 0th bit.
|
topLeftObscured = (metadata1W & 0x1); // Take 0th bit.
|
||||||
topRightObscured = (metadata1W & 0x2) >> 1; // Take 1st bits.
|
topRightObscured = (metadata1W & 0x2) >> 1; // Take 1st bits.
|
||||||
bottomLeftObscured = (metadata1W & 0x4) >> 2; // Take 2nd bits.
|
bottomLeftObscured = (metadata1W & 0x4) >> 2; // Take 2nd bits.
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,9 @@ pub const v3 = struct {
|
||||||
pub inline fn nor(a: raylib.Vector3) raylib.Vector3 {
|
pub inline fn nor(a: raylib.Vector3) raylib.Vector3 {
|
||||||
return raylib.Vector3Normalize(a);
|
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 {
|
pub inline fn cross(a: raylib.Vector3, b: raylib.Vector3) raylib.Vector3 {
|
||||||
return raylib.Vector3CrossProduct(a, b);
|
return raylib.Vector3CrossProduct(a, b);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
31
src/main.zig
31
src/main.zig
|
|
@ -64,11 +64,13 @@ pub fn main() !void {
|
||||||
defer raylib.UnloadTexture(texture);
|
defer raylib.UnloadTexture(texture);
|
||||||
raylib.UnloadImage(tiles);
|
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");
|
const shader = raylib.LoadChunkShader("resources/shaders/tiling.vs", "resources/shaders/tiling.fs");
|
||||||
defer raylib.UnloadShader(shader);
|
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);
|
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);
|
var chunk = try chunks.Chunk.init(a7r);
|
||||||
|
|
@ -83,7 +85,7 @@ pub fn main() !void {
|
||||||
const xf: f32 = @floatFromInt(raw_x);
|
const xf: f32 = @floatFromInt(raw_x);
|
||||||
const yf: f32 = @floatFromInt(raw_y);
|
const yf: f32 = @floatFromInt(raw_y);
|
||||||
const zf: f32 = @floatFromInt(raw_z);
|
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);
|
// 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 (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);
|
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].maps[raylib.MATERIAL_MAP_DIFFUSE].texture = texture;
|
||||||
model.materials[0].shader = shader;
|
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()) {
|
while (!raylib.WindowShouldClose()) {
|
||||||
raylib.ClearBackground(raylib.BLACK);
|
raylib.ClearBackground(raylib.BLACK);
|
||||||
|
|
||||||
|
|
@ -128,10 +137,17 @@ pub fn main() !void {
|
||||||
moveCamera(&camera, v3.scl(v3.nor(movement), speed));
|
moveCamera(&camera, v3.scl(v3.nor(movement), speed));
|
||||||
|
|
||||||
const delta = raylib.GetMouseDelta();
|
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){
|
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));
|
var direction = v3.sub(camera.target, camera.position);
|
||||||
camera.target = v3.add(camera.position, v3.rotate(v3.sub(camera.target, camera.position), right, -0.005 * delta.y));
|
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();
|
raylib.BeginDrawing();
|
||||||
|
|
@ -145,6 +161,7 @@ pub fn main() !void {
|
||||||
raylib.BeginShaderMode(shader);
|
raylib.BeginShaderMode(shader);
|
||||||
defer raylib.EndShaderMode();
|
defer raylib.EndShaderMode();
|
||||||
|
|
||||||
|
raylib.SetShaderValueTexture(shader, raylib.GetShaderLocation(shader, "ambientOcclusionTexture"), ambient_occlusion_texture);
|
||||||
raylib.DrawChunkModel(model, model_position, 0.5, raylib.WHITE);
|
raylib.DrawChunkModel(model, model_position, 0.5, raylib.WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ const RawQuad = struct {
|
||||||
normal: raylib.Vector3,
|
normal: raylib.Vector3,
|
||||||
width: f32,
|
width: f32,
|
||||||
height: f32,
|
height: f32,
|
||||||
|
flip_x: bool,
|
||||||
|
flip_y: bool,
|
||||||
|
|
||||||
top_obscuring_pattern: u32,
|
top_obscuring_pattern: u32,
|
||||||
left_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.
|
// 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 {
|
inline fn getTileRawShifted(self: Chunk, x: u5, y: u5, z: u5, comptime dimension: comptime_int) u32 {
|
||||||
if (dimention % 3 == 0) {
|
if (dimension % 3 == 0) {
|
||||||
return self.getTileRaw(x, y, z);
|
return self.getTileRaw(x, y, z);
|
||||||
} else if (dimention % 3 == 1) {
|
} else if (dimension % 3 == 1) {
|
||||||
return self.getTileRaw(y, z, x);
|
return self.getTileRaw(y, z, x);
|
||||||
} else if (dimention % 3 == 2) {
|
} else if (dimension % 3 == 2) {
|
||||||
return self.getTileRaw(z, x, y);
|
return self.getTileRaw(z, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -101,12 +103,16 @@ pub const Chunk = struct {
|
||||||
y_start: usize, y_end: usize,
|
y_start: usize, y_end: usize,
|
||||||
z_start: usize, z_end: usize,
|
z_start: usize, z_end: usize,
|
||||||
sign: comptime_int,
|
sign: comptime_int,
|
||||||
dimention: comptime_int,
|
dimension: comptime_int,
|
||||||
surface: u32,
|
surface: u32,
|
||||||
y_minus_obscuring_pattern: u32,
|
y_minus_obscuring_pattern: u32,
|
||||||
y_plus_obscuring_pattern: u32,
|
y_plus_obscuring_pattern: u32,
|
||||||
z_minus_obscuring_pattern: u32,
|
z_minus_obscuring_pattern: u32,
|
||||||
z_plus_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 {
|
) RawQuad {
|
||||||
const ymin: f32 = @as(f32, @floatFromInt(y_start)) - 0.5;
|
const ymin: f32 = @as(f32, @floatFromInt(y_start)) - 0.5;
|
||||||
const ymax: f32 = @as(f32, @floatFromInt(y_end)) - 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 zleft: f32 = if (sign == 1) zmin else zmax;
|
||||||
const zright: f32 = if (sign == 1) zmax else zmin;
|
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;
|
var raw_quad: RawQuad = undefined;
|
||||||
switch (dimention) {
|
switch (dimension) {
|
||||||
X_DIRECTION => {
|
X_DIRECTION => {
|
||||||
raw_quad = .{
|
raw_quad = .{
|
||||||
.tile = surface,
|
.tile = surface,
|
||||||
|
|
@ -137,15 +135,17 @@ pub const Chunk = struct {
|
||||||
.normal = v3.new(sign, 0, 0),
|
.normal = v3.new(sign, 0, 0),
|
||||||
.width = zmax - zmin,
|
.width = zmax - zmin,
|
||||||
.height = ymax - ymin,
|
.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,
|
.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,
|
.bottom_obscuring_pattern = y_minus_obscuring_pattern,
|
||||||
.top_left_obscured = false,
|
.top_left_obscured = y_plus_z_minus_obscured,
|
||||||
.top_right_obscured = false,
|
.top_right_obscured = y_plus_z_plus_obscured,
|
||||||
.bottom_right_obscured = false,
|
.bottom_right_obscured = y_minus_z_plus_obscured,
|
||||||
.bottom_left_obscured = false,
|
.bottom_left_obscured = y_minus_z_minus_obscured,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
Y_DIRECTION => {
|
Y_DIRECTION => {
|
||||||
|
|
@ -158,15 +158,17 @@ pub const Chunk = struct {
|
||||||
.normal = v3.new(0, 0, sign),
|
.normal = v3.new(0, 0, sign),
|
||||||
.height = zmax - zmin,
|
.height = zmax - zmin,
|
||||||
.width = ymax - ymin,
|
.width = ymax - ymin,
|
||||||
|
.flip_x = sign == 1,
|
||||||
|
.flip_y = false,
|
||||||
|
|
||||||
.top_obscuring_pattern = 0,
|
.top_obscuring_pattern = z_plus_obscuring_pattern,
|
||||||
.left_obscuring_pattern = 0,
|
.left_obscuring_pattern = y_minus_obscuring_pattern,
|
||||||
.right_obscuring_pattern = 0,
|
.right_obscuring_pattern = y_plus_obscuring_pattern,
|
||||||
.bottom_obscuring_pattern = 0,
|
.bottom_obscuring_pattern = z_minus_obscuring_pattern,
|
||||||
.top_left_obscured = false,
|
.top_left_obscured = y_minus_z_plus_obscured,
|
||||||
.top_right_obscured = false,
|
.top_right_obscured = y_plus_z_plus_obscured,
|
||||||
.bottom_right_obscured = false,
|
.bottom_right_obscured = y_plus_z_minus_obscured,
|
||||||
.bottom_left_obscured = false,
|
.bottom_left_obscured = y_minus_z_minus_obscured,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
Z_DIRECTION => {
|
Z_DIRECTION => {
|
||||||
|
|
@ -179,15 +181,17 @@ pub const Chunk = struct {
|
||||||
.normal = v3.new(0, sign, 0),
|
.normal = v3.new(0, sign, 0),
|
||||||
.width = zmax - zmin,
|
.width = zmax - zmin,
|
||||||
.height = ymax - ymin,
|
.height = ymax - ymin,
|
||||||
|
.flip_x = sign == 1,
|
||||||
|
.flip_y = true,
|
||||||
|
|
||||||
.top_obscuring_pattern = 0,
|
.top_obscuring_pattern = y_plus_obscuring_pattern,
|
||||||
.left_obscuring_pattern = 0,
|
.left_obscuring_pattern = z_minus_obscuring_pattern,
|
||||||
.right_obscuring_pattern = 0,
|
.right_obscuring_pattern = z_plus_obscuring_pattern,
|
||||||
.bottom_obscuring_pattern = 0,
|
.bottom_obscuring_pattern = y_minus_obscuring_pattern,
|
||||||
.top_left_obscured = false,
|
.top_left_obscured = y_plus_z_minus_obscured,
|
||||||
.top_right_obscured = false,
|
.top_right_obscured = y_plus_z_plus_obscured,
|
||||||
.bottom_right_obscured = false,
|
.bottom_right_obscured = y_minus_z_plus_obscured,
|
||||||
.bottom_left_obscured = false,
|
.bottom_left_obscured = y_minus_z_minus_obscured,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
|
|
@ -201,7 +205,7 @@ pub const Chunk = struct {
|
||||||
defer raw_quads.deinit();
|
defer raw_quads.deinit();
|
||||||
|
|
||||||
// Begin scanning the chunk for tile surfaces to make raw quads.
|
// 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| {
|
for (0..32) |raw_x| {
|
||||||
const x: u5 = @intCast(raw_x);
|
const x: u5 = @intCast(raw_x);
|
||||||
// Create surface arrays for the +x side of the layer and the -x side.
|
// 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| {
|
for (0..32) |raw_y| for (0..32) |raw_z| {
|
||||||
const y: u5 = @intCast(raw_y);
|
const y: u5 = @intCast(raw_y);
|
||||||
const z: u5 = @intCast(raw_z);
|
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 (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 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 == 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, dimention) == 0) negative_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| {
|
inline for (.{ -1, 1 }) |sign| {
|
||||||
var tile_surfaces = if (sign == 1) positive_tile_surfaces else negative_tile_surfaces;
|
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| {
|
for (y_start..y_end) |raw_y| {
|
||||||
const y: u5 = @intCast(raw_y);
|
const y: u5 = @intCast(raw_y);
|
||||||
z_minus_obscuring_pattern <<= 1;
|
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;
|
var z_plus_obscuring_pattern: u32 = 0;
|
||||||
|
|
@ -249,7 +253,7 @@ pub const Chunk = struct {
|
||||||
for (y_start..y_end) |raw_y| {
|
for (y_start..y_end) |raw_y| {
|
||||||
const y: u5 = @intCast(raw_y);
|
const y: u5 = @intCast(raw_y);
|
||||||
z_plus_obscuring_pattern <<= 1;
|
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;
|
var y_minus_obscuring_pattern: u32 = 0;
|
||||||
|
|
@ -257,7 +261,7 @@ pub const Chunk = struct {
|
||||||
for (z_start..z_end) |raw_z| {
|
for (z_start..z_end) |raw_z| {
|
||||||
const z: u5 = @intCast(raw_z);
|
const z: u5 = @intCast(raw_z);
|
||||||
y_minus_obscuring_pattern <<= 1;
|
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;
|
var y_plus_obscuring_pattern: u32 = 0;
|
||||||
|
|
@ -265,11 +269,22 @@ pub const Chunk = struct {
|
||||||
for (z_start..z_end) |raw_z| {
|
for (z_start..z_end) |raw_z| {
|
||||||
const z: u5 = @intCast(raw_z);
|
const z: u5 = @intCast(raw_z);
|
||||||
y_plus_obscuring_pattern <<= 1;
|
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});
|
var y_minus_z_minus_obscured = false;
|
||||||
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_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);
|
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 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_x = .{ left_uv, left_uv, right_uv, right_uv, right_uv, left_uv };
|
||||||
const texcoords_y = .{ top_uv, bottom_uv } ** 3;
|
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_x = if(raw_quad.flip_x)
|
||||||
const tiletexcoords_y = .{ 0.0, raw_quad.height } ** 3;
|
.{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| {
|
inline for (0..6) |corner_id| {
|
||||||
vertices[VERTICES_BLOCK_SIZE * i + corner_id * 3 + 0] = vertex_corners[corner_id].x;
|
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_height = @intFromFloat(raw_quad.height),
|
||||||
.quad_width = @intFromFloat(raw_quad.width),
|
.quad_width = @intFromFloat(raw_quad.width),
|
||||||
};
|
};
|
||||||
const metadata1_baked: [4]f32 = @bitCast(metadata1);
|
const metadata1_baked: [4]u32 = @bitCast(metadata1);
|
||||||
for (0..4) |k| {
|
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];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue