perovskite_client 0.2.0

Multiplayer voxel game written in Rust - Game client
Documentation
#version 460
#define SKIP_MASK 4u
#include "raytracer_frag_common.glsl"

layout(input_attachment_index = 0, set = 1, binding = 3) uniform subpassInput f_depth_in;
layout(location = 0) out vec4 f_color;
layout(location = 1) out vec4 deferred_specular_strength;
layout(location = 2) out uvec4 deferred_specular_ray_dir;

void main() {
    deferred_specular_strength = vec4(0);
    deferred_specular_ray_dir = uvec4(0);

    if (RAYTRACE_DEBUG) {
        vec2 pix3 = gl_FragCoord.xy / (16.0 * supersampling);
        int ix3 = int(pix3.x);
        int iy3 = int(pix3.y);

        if (iy3 == 1) {
            if (ix3 <= 160 && ix3 >= 1) {
                int idx = ix3 - 1;
                int idx0 = idx >> 5;
                uint dbg_data;
                if (idx0 == 0) {
                    dbg_data = n_minus_one;
                }
                if (idx0 == 1) {
                    dbg_data = mxc;
                }
                if (idx0 == 2) {
                    dbg_data = k.x;
                }
                if (idx0 == 3) {
                    dbg_data = k.y;
                }
                if (idx0 == 4) {
                    dbg_data = k.z;
                }
                uint idx1 = uint(idx & 31);
                uint bit = dbg_data & (1u << idx1);
                if (bit != 0) {
                    f_color = vec4(1.0, 0.0, 0.0, 1.0);
                    return;
                } else {
                    f_color = vec4(0.0, 0.0, 0.0, 1.0);
                    return;
                }
            }
        }
        if (iy3 == 2) {
            if (ix3 <= 160 && ix3 >= 1) {
                int idx = ix3 - 1;
                int idx0 = idx >> 5;
                if (idx0 == 0) {
                    f_color = vec4(1.0, 0.0, 0.0, 1.0);
                    return;
                } else if (idx0 == 1) {
                    f_color = vec4(1.0, 1.0, 0.0, 1.0);
                    return;
                } else if (idx0 == 2) {
                    f_color = vec4(0.0, 1.0, 0.0, 1.0);
                    return;
                } else if (idx0 == 3) {
                    f_color = vec4(0.0, 0.0, 1.0, 1.0);
                    return;
                } else if (idx0 == 4) {
                    f_color = vec4(1.0, 1.0, 0.0, 1.0);
                    return;
                }
            }
        }

        if (iy3 == 3) {
            if (ix3 <= 160 && ix3 >= 1) {
                int idx = ix3 - 1;
                if ((idx % 2) == 0) {
                    f_color = vec4(0.2, 1.0, 0.4, 1.0);
                    return;
                }
                else {
                    f_color = vec4(1.0, 1.0, 0.0, 1.0);
                    return;
                }
            }
        }
        vec2 pix_fine = gl_FragCoord.xy / (2 * supersampling);
        int ixp = int(pix_fine.x);
        int iyp = int(pix_fine.y) - 64;
        uint rows = (n_minus_one + 1) / 1024;
        if (iyp >= 0 && iyp < rows) {
            if (ixp < 1024) {
                uint slot = iyp * 1024 + ixp;
                uint slot_base = slot * 4;

                if ((chunks[slot_base] & 1) == 0) {
                    f_color = vec4(0, 0, 0, 1);
                    return;
                }
                uvec3 putative = uvec3(chunks[slot_base + 1], chunks[slot_base + 2], chunks[slot_base + 3]);
                uvec3 products = putative * k;
                uint sum = products.x + products.y + products.z;
                uint try_slot = (sum % 1610612741) & n_minus_one;
                if (try_slot == slot) {
                    f_color = vec4(0, 1, 0, 1);
                    return;
                } else {
                    f_color = vec4(1, 1, 0, 1);
                    return;
                }
            }
        }
    }// if (RAYTRACE_DEBUG)

    f_color = vec4(0);
    vec3 facedir_world = normalize(facedir_world_in);
    float prev_depth = subpassLoad(f_depth_in).r;

    // There are some fixups done between the raster and raytrace pipelines:
    // All raster geometry, as well as non-rendering calcs, assume that blocks have
    // their *centers* at integer coordinates.
    // However, we have the *edges* as integer-aligned in this code.
    // Note that this shader works in world space, with Y up throughout.
    // The Y axis orientation has been flipped in the calculation of facedir_world.
    vec2 t_min_max = t_range(fine_pos, facedir_world);

    if (t_min_max.x > t_min_max.y) {
        return;
    }

    vec3 g0 = fine_pos + (t_min_max.x * facedir_world);
    vec3 g1 = fine_pos + (t_min_max.y * facedir_world);

    float strongest_specular = 0;
    uint prev_block = initial_block_id;
    for (int i = 0; i < 5; i++) {
        HitInfo info = {
        ivec3(0),
        vec3(0),
        vec3(0),
        prev_block,
        0,
        };

        if (!traverse_space(g0, g1, info)) {
            return;
        }
        // traverse_space will put valid data into info iff it returns true
        prev_block = info.block_id;
        uint info_flags = cube_info[prev_block >> 12].flags;
        vec3 hit_pos = (vec3(info.hit_block) + info.start_cc) / 16.0;
        vec4 rpos = vec4((hit_pos - fine_pos) * 16.0, 1.0) * vec4(1, -1, 1, 1);
        vec4 transformed = forward_vp_matrix * rpos;
        if (clamp(transformed.z / transformed.w, 0, 1) > prev_depth) {
            return;
        }

        // skip fallback blocks
        if (info_flags != 0) {
            if ((info_flags & 4u) != 4) {
                SampleResult result = sample_simple(info, prev_block >> 12, SPECULAR);
                float alpha_contrib = (1 - f_color.a) * result.diffuse.a;
                f_color.rgb += alpha_contrib * result.diffuse.rgb;
                f_color.a += alpha_contrib;

                if (SPECULAR) {
                    if (length(result.specular.rgb) > 0.01) {
                        vec3 new_dir;
                        vec3 normal = decode_normal(info.face_light & 7u);
                        if (FUZZY_SHADOWS) {
                            vec3 tangent = normalize(cross(facedir_world, normal));
                            vec3 bitangent = cross(normal, tangent);
                            mat3 ntb = mat3(normal, tangent, bitangent);
                            vec3 mul = vec3(
                            0, 0.03 * (random(hit_pos.xz, 43758.5453123) - 0.5), 0.01 * random(hit_pos.xz, 43758.5453123)
                            );

                            new_dir = facedir_world * face_reflectors[info.face_light & 7u] + (ntb * mul);
                        }
                        else {
                            new_dir = facedir_world * face_reflectors[info.face_light & 7u];
                        }
                        float cos_theta = dot(normal, new_dir);
                        float fresnel = min((0.02 + 0.98 * pow(1 - cos_theta, 5)), 1.0);
                        vec3 final_mix = mix(fresnel, 1.0, result.diffuse.a) * result.specular.rgb;
                        if (length(final_mix) >= strongest_specular) {
                            deferred_specular_strength = vec4(final_mix, 1.0);
                            new_dir = normalize(new_dir) * length(hit_pos - fine_pos);
                            deferred_specular_ray_dir = uvec4(floatBitsToUint(new_dir), info.block_id);
                            strongest_specular = length(final_mix);
                        }
                    }
                }

                if (f_color.a > 0.99) {
                    break;
                }
            }
        }
        info.start_cc = mix(info.start_cc, info.end_cc, 0.5);
        g0 = (vec3(info.hit_block) + info.start_cc) / 16.0;
    }

}