uniform sampler2D colortex12;
uniform sampler2D depthtex2;
uniform mat4 gbufferProjectionInverse;
uniform mat4 gbufferModelViewInverse;
uniform vec3 cameraPosition;
uniform mat4 shadowProjection;
uniform vec3 lightDirView;
uniform mat4 shadowModelView;
uniform mat4 shadowModelViewInverse;    
uniform mat4 shadowProjectionInverse;
uniform sampler2D shadowcolor0;
uniform usampler2D shadowcolor1;
uniform float far;

#include "/lib/utility/common_functions.glsl"
#include "/lib/utility/constants.glsl"

#include "/lib/shadows.glsl"
#include "/lib/encoding.glsl"
#include "/lib/voxelization.glsl"
#include "/lib/materials.glsl"
#include "/lib/raytracing.glsl"

vec3 getVoxelAlbedo(vec3 position, vec3 normal, vec4[2] voxel) {
    int id = ExtractVoxelId(voxel);

    // Figure out texture coordinates
    int   tileSize = ExtractVoxelTileSize(voxel);
    ivec2 tileOffs = ExtractVoxelTileIndex(voxel) * tileSize;

    ivec2 tileTexel;
    if (abs(normal.y) > abs(normal.x) && abs(normal.y) > abs(normal.z)) {
        tileTexel = ivec2(fract(position.x) * tileSize, fract(position.z * sign(normal.y)) * tileSize);
    } else {
        tileTexel = ivec2(fract(position.x * sign(normal.z) - position.z * sign(normal.x)) * tileSize, fract(-position.y) * tileSize);
    }

    ivec2 texelIndex = tileOffs + tileTexel;

    // Read textures
    vec4 albedo = texelFetch(depthtex2, texelIndex, 0);

	return albedo.rgb;
}

vec3 debug(vec2 uv) {
    vec4 p   = vec4(uv * 2.0 - 1.0, 0.0, 1.0);
    vec3 dir = (gbufferProjectionInverse * p).xyz / (gbufferProjectionInverse * p).w;
            dir = normalize(mat3(gbufferModelViewInverse) * dir);

    vec3 startVoxelPosition = SceneSpaceToVoxelSpace(gbufferModelViewInverse[3].xyz);

    vec4[2] voxel;
    vec3 hitPos, hitNormal; ivec3 hitIndex;
    vec3 accColor;
    bool hit = RaytraceVoxel(startVoxelPosition, ivec3(floor(startVoxelPosition)), dir, voxel, hitPos, hitIndex, hitNormal, accColor, int(far * sqrt(3)), 0.5);

    if (!hit) return vec3(0.0);

    return getVoxelAlbedo(hitPos, hitNormal, voxel) * accColor;
}