Проблема со стеклом в воксельном движке

Я попробовал добавить стекло в воксельный движок из этого урока: https://github.com/StanislavPetrovV/Minecraft. Для этого переделал шейдер и код в chunk_mesh_builder. Но стекло работает нормально только если смотреть на его верхнюю, переднюю и правую стороны. Проблема в chunk_mesh_builder? Или же где-то дальше? glass1 glass2
glass3

    from settings import *
    from numba import uint8
@njit
    def get_ao(local_pos, world_pos, world_voxels, plane):
        x, y, z = local_pos
        wx, wy, wz = world_pos
    
        if plane == 'Y':
            a = is_void((x    , y, z - 1), (wx    , wy, wz - 1), world_voxels)
            b = is_void((x - 1, y, z - 1), (wx - 1, wy, wz - 1), world_voxels)
            c = is_void((x - 1, y, z    ), (wx - 1, wy, wz    ), world_voxels)
            d = is_void((x - 1, y, z + 1), (wx - 1, wy, wz + 1), world_voxels)
            e = is_void((x    , y, z + 1), (wx    , wy, wz + 1), world_voxels)
            f = is_void((x + 1, y, z + 1), (wx + 1, wy, wz + 1), world_voxels)
            g = is_void((x + 1, y, z    ), (wx + 1, wy, wz    ), world_voxels)
            h = is_void((x + 1, y, z - 1), (wx + 1, wy, wz - 1), world_voxels)
    
        elif plane == 'X':
            a = is_void((x, y    , z - 1), (wx, wy    , wz - 1), world_voxels)
            b = is_void((x, y - 1, z - 1), (wx, wy - 1, wz - 1), world_voxels)
            c = is_void((x, y - 1, z    ), (wx, wy - 1, wz    ), world_voxels)
            d = is_void((x, y - 1, z + 1), (wx, wy - 1, wz + 1), world_voxels)
            e = is_void((x, y    , z + 1), (wx, wy    , wz + 1), world_voxels)
            f = is_void((x, y + 1, z + 1), (wx, wy + 1, wz + 1), world_voxels)
            g = is_void((x, y + 1, z    ), (wx, wy + 1, wz    ), world_voxels)
            h = is_void((x, y + 1, z - 1), (wx, wy + 1, wz - 1), world_voxels)
    
        else:  # Z plane
            a = is_void((x - 1, y    , z), (wx - 1, wy    , wz), world_voxels)
            b = is_void((x - 1, y - 1, z), (wx - 1, wy - 1, wz), world_voxels)
            c = is_void((x    , y - 1, z), (wx    , wy - 1, wz), world_voxels)
            d = is_void((x + 1, y - 1, z), (wx + 1, wy - 1, wz), world_voxels)
            e = is_void((x + 1, y    , z), (wx + 1, wy    , wz), world_voxels)
            f = is_void((x + 1, y + 1, z), (wx + 1, wy + 1, wz), world_voxels)
            g = is_void((x    , y + 1, z), (wx    , wy + 1, wz), world_voxels)
            h = is_void((x - 1, y + 1, z), (wx - 1, wy + 1, wz), world_voxels)
    
        ao = (a + b + c), (g + h + a), (e + f + g), (c + d + e)
        return ao
    
    
    @njit
    def pack_data(x, y, z, voxel_id, face_id, ao_id, flip_id):
        # x: 6bit  y: 6bit  z: 6bit  voxel_id: 8bit  face_id: 3bit  ao_id: 2bit  flip_id: 1bit
        a, b, c, d, e, f, g = x, y, z, voxel_id, face_id, ao_id, flip_id
    
        b_bit, c_bit, d_bit, e_bit, f_bit, g_bit = 6, 6, 8, 3, 2, 1
        fg_bit = f_bit + g_bit
        efg_bit = e_bit + fg_bit
        defg_bit = d_bit + efg_bit
        cdefg_bit = c_bit + defg_bit
        bcdefg_bit = b_bit + cdefg_bit
    
        packed_data = (
            a << bcdefg_bit |
            b << cdefg_bit |
            c << defg_bit |
            d << efg_bit |
            e << fg_bit |
            f << g_bit | g
        )
        return packed_data
    
    
    @njit
    def get_chunk_index(world_voxel_pos):
        wx, wy, wz = world_voxel_pos
        cx = wx // CHUNK_SIZE
        cy = wy // CHUNK_SIZE
        cz = wz // CHUNK_SIZE
        if not (0 <= cx < WORLD_W and 0 <= cy < WORLD_H and 0 <= cz < WORLD_D):
            return -1
    
        index = cx + WORLD_W * cz + WORLD_AREA * cy
        return index
    
    
    @njit
    def is_void(local_voxel_pos, world_voxel_pos, world_voxels):
        chunk_index = get_chunk_index(world_voxel_pos)
        if chunk_index == -1:
            return False
        chunk_voxels = world_voxels\[chunk_index\]
    
        x, y, z = local_voxel_pos
        voxel_index = (x % CHUNK_SIZE + z % CHUNK_SIZE * CHUNK_SIZE + y % CHUNK_SIZE * CHUNK_AREA)
    
        if chunk_voxels\[voxel_index\]:
            if chunk_voxels\[voxel_index\] == Z:
                return True
            else:
                return False
        return True
    
    @njit
    def add_data(vertex_data, index, *vertices):
        for vertex in vertices:
            vertex_data\[index\] = vertex
            index += 1
        return index
    
    
    @njit
    def build_chunk_mesh(chunk_voxels, format_size, chunk_pos, world_voxels):
        vertex_data = np.empty(CHUNK_VOL * 36 * format_size, dtype='uint32')
        index = 0
    
        for x in range(CHUNK_SIZE):
            for y in range(CHUNK_SIZE):
                for z in range(CHUNK_SIZE):
                    voxel_id = chunk_voxels\[x + CHUNK_SIZE * z + CHUNK_AREA * y\]
    
                    if not voxel_id:
                        continue
    
                    # voxel world position
                    cx, cy, cz = chunk_pos
                    wx = x + cx * CHUNK_SIZE
                    wy = y + cy * CHUNK_SIZE
                    wz = z + cz * CHUNK_SIZE
    
                    # top face
                    if is_void((x, y + 1, z), (wx, wy + 1, wz), world_voxels):
                        # get ao values
                        ao = get_ao((x, y + 1, z), (wx, wy + 1, wz), world_voxels, plane='Y')
                        flip_id = ao\[1\] + ao\[3\] > ao\[0\] + ao\[2\]
    
                        # format: x, y, z, voxel_id, face_id, ao_id, flip_id
                        v0 = pack_data(x, y + 1, z, voxel_id, 0, ao\[0\], flip_id)
                        v1 = pack_data(x + 1, y + 1, z, voxel_id, 0, ao\[1\], flip_id)
                        v2 = pack_data(x + 1, y + 1, z + 1, voxel_id, 0, ao\[2\], flip_id)
                        v3 = pack_data(x, y + 1, z + 1, voxel_id, 0, ao\[3\], flip_id)
    
                        if flip_id:
                            index = add_data(vertex_data, index, v1, v0, v3, v1, v3, v2)
                        else:
                            index = add_data(vertex_data, index, v0, v3, v2, v0, v2, v1)
    
                    # bottom face
                    if is_void((x, y - 1, z), (wx, wy - 1, wz), world_voxels):
                        ao = get_ao((x, y - 1, z), (wx, wy - 1, wz), world_voxels, plane='Y')
                        flip_id = ao\[1\] + ao\[3\] > ao\[0\] + ao\[2\]
    
                        v0 = pack_data(x, y, z, voxel_id, 1, ao\[0\], flip_id)
                        v1 = pack_data(x + 1, y, z, voxel_id, 1, ao\[1\], flip_id)
                        v2 = pack_data(x + 1, y, z + 1, voxel_id, 1, ao\[2\], flip_id)
                        v3 = pack_data(x, y, z + 1, voxel_id, 1, ao\[3\], flip_id)
    
                        if flip_id:
                            index = add_data(vertex_data, index, v1, v3, v0, v1, v2, v3)
                        else:
                            index = add_data(vertex_data, index, v0, v2, v3, v0, v1, v2)
    
                    # right face
                    if is_void((x + 1, y, z), (wx + 1, wy, wz), world_voxels):
                        ao = get_ao((x + 1, y, z), (wx + 1, wy, wz), world_voxels, plane='X')
                        flip_id = ao\[1\] + ao\[3\] > ao\[0\] + ao\[2\]
    
                        v0 = pack_data(x + 1, y, z, voxel_id, 2, ao\[0\], flip_id)
                        v1 = pack_data(x + 1, y + 1, z, voxel_id, 2, ao\[1\], flip_id)
                        v2 = pack_data(x + 1, y + 1, z + 1, voxel_id, 2, ao\[2\], flip_id)
                        v3 = pack_data(x + 1, y, z + 1, voxel_id, 2, ao\[3\], flip_id)
    
                        if flip_id:
                            index = add_data(vertex_data, index, v3, v0, v1, v3, v1, v2)
                        else:
                            index = add_data(vertex_data, index, v0, v1, v2, v0, v2, v3)
    
                    # left face
                    if is_void((x - 1, y, z), (wx - 1, wy, wz), world_voxels):
                        ao = get_ao((x - 1, y, z), (wx - 1, wy, wz), world_voxels, plane='X')
                        flip_id = ao\[1\] + ao\[3\] > ao\[0\] + ao\[2\]
    
                        v0 = pack_data(x, y, z, voxel_id, 3, ao\[0\], flip_id)
                        v1 = pack_data(x, y + 1, z, voxel_id, 3, ao\[1\], flip_id)
                        v2 = pack_data(x, y + 1, z + 1, voxel_id, 3, ao\[2\], flip_id)
                        v3 = pack_data(x, y, z + 1, voxel_id, 3, ao\[3\], flip_id)
    
                        if flip_id:
                            index = add_data(vertex_data, index, v3, v1, v0, v3, v2, v1)
                        else:
                            index = add_data(vertex_data, index, v0, v2, v1, v0, v3, v2)
    
                    # back face
                    if is_void((x, y, z - 1), (wx, wy, wz - 1), world_voxels):
                        ao = get_ao((x, y, z - 1), (wx, wy, wz - 1), world_voxels, plane='Z')
                        flip_id = ao\[1\] + ao\[3\] > ao\[0\] + ao\[2\]
    
                        v0 = pack_data(x, y, z, voxel_id, 4, ao\[0\], flip_id)
                        v1 = pack_data(x, y + 1, z, voxel_id, 4, ao\[1\], flip_id)
                        v2 = pack_data(x + 1, y + 1, z, voxel_id, 4, ao\[2\], flip_id)
                        v3 = pack_data(x + 1, y, z, voxel_id, 4, ao\[3\], flip_id)
    
                        if flip_id:
                            index = add_data(vertex_data, index, v3, v0, v1, v3, v1, v2)
                        else:
                            index = add_data(vertex_data, index, v0, v1, v2, v0, v2, v3)
    
                    # front face
                    if is_void((x, y, z + 1), (wx, wy, wz + 1), world_voxels):
                        ao = get_ao((x, y, z + 1), (wx, wy, wz + 1), world_voxels, plane='Z')
                        flip_id = ao\[1\] + ao\[3\] > ao\[0\] + ao\[2\]
    
                        v0 = pack_data(x, y, z + 1, voxel_id, 5, ao\[0\], flip_id)
                        v1 = pack_data(x, y + 1, z + 1, voxel_id, 5, ao\[1\], flip_id)
                        v2 = pack_data(x + 1, y + 1, z + 1, voxel_id, 5, ao\[2\], flip_id)
                        v3 = pack_data(x + 1, y, z + 1, voxel_id, 5, ao\[3\], flip_id)
    
                        if flip_id:
                            index = add_data(vertex_data, index, v3, v1, v0, v3, v2, v1)
                        else:
                            index = add_data(vertex_data, index, v0, v2, v1, v0, v3, v2)
    
    
        return vertex_data\[:index + 1\][1]

voxel_id = Z это стекло. Z = 17

#version 330 core

layout (location = 0) out vec4 fragColor;

const vec3 gamma = vec3(2.2);
const vec3 inv_gamma = 1 / gamma;

uniform sampler2DArray u_texture_array_0;
uniform vec3 bg_color;
uniform float water_line;

in vec2 uv;
in float shading;
in vec3 frag_world_pos;

flat in int face_id;
flat in int voxel_id;


void main() {
    vec2 face_uv = uv;
    face_uv.x = uv.x / 3.0 - min(face_id, 2) / 3.0;

    vec3 tex_col = texture(u_texture_array_0, vec3(face_uv, voxel_id)).rgb;
    tex_col = pow(tex_col, gamma);

    vec4 tex_alpha = texture(u_texture_array_0, vec3(face_uv, voxel_id));

    tex_col *= shading;

    // underwater effect
    if (frag_world_pos.y < water_line) tex_col *= vec3(0.0, 0.3, 1.0);

    //fog
    float fog_dist = gl_FragCoord.z / gl_FragCoord.w;
    tex_col = mix(tex_col, bg_color, (1.0 - exp2(-0.00001 * fog_dist * fog_dist)));

    tex_col = pow(tex_col, inv_gamma);


    float alpha;

    if (voxel_id == 17) {
        alpha = clamp(tex_alpha.g, 0.0, 1.0);
    } else {
        alpha = 1;
    }

    fragColor = vec4(tex_col, alpha);
}

Ответы (0 шт):