uniform sampler2D t_texture;

varying vec2 vUv;

float lpv_bilinear_lerp(float v00, float v01, float v10, float v11, vec2 fraction) {

    float x0 = mix(v00, v01, fraction.x);
    float x1 = mix(v10, v11, fraction.x);

    return mix(x0, x1, fraction.y);
}

vec3 lpv_bilinear_lerp(vec3 v00, vec3 v01, vec3 v10, vec3 v11, vec2 fraction) {

    vec3 x0 = mix(v00, v01, fraction.x);
    vec3 x1 = mix(v10, v11, fraction.x);

    return mix(x0, x1, fraction.y);
}

ivec2 wrapOctahedralTexelCoordinates(const in ivec2 texel, const in int texture_size) {
    ivec2 wrapped = ((texel % texture_size) + texture_size) % texture_size;

    int fx = (abs(texel.x / texture_size) + int(texel.x < 0));
    int fy = (abs(texel.y / texture_size) + int(texel.y < 0));

    //    return texel;

    if (((fx ^ fy) & 1) != 0) {
        return (texture_size - (wrapped + ivec2(1)));
        //        return ivec2(
        //            texSize.x - (wrapped.x + 1),
        //            (wrapped.y - texSize.y + 1)
        //        );
        return wrapped;
    } else {
        return wrapped;
    }
}


void main() {
    int depth_tile_resolution = 4;
    vec2 depth_tile_resolution_v2 = vec2(depth_tile_resolution);

    vec2 octahedral_uv = vUv;

    vec2 grid = octahedral_uv * depth_tile_resolution_v2 - 0.5;


    vec2 gridFrac = fract(grid);
//    vec2 gridFrac = vec2(0.0);

    ivec2 texel_position = ivec2(floor(grid));

    ivec2 tile_p_00;
    ivec2 tile_p_01;
    ivec2 tile_p_10;
    ivec2 tile_p_11;

        tile_p_00 = texel_position;


    //
    //         tile_p_00 = wrapOctahedralTexelCoordinates(ivec2(floor(grid + vec2(-0.5, -0.5))), depth_tile_resolution);
    //         tile_p_01 = wrapOctahedralTexelCoordinates(ivec2(floor(grid + vec2(0.5, -0.5))), depth_tile_resolution);
    //         tile_p_10 = wrapOctahedralTexelCoordinates(ivec2(floor(grid + vec2(-0.5, 0.5))), depth_tile_resolution);
    //         tile_p_11 = wrapOctahedralTexelCoordinates(ivec2(floor(grid + vec2(0.5, 0.5))), depth_tile_resolution);

    tile_p_00 = wrapOctahedralTexelCoordinates(texel_position , depth_tile_resolution);
    tile_p_01 = wrapOctahedralTexelCoordinates(texel_position + ivec2(1, 0), depth_tile_resolution);
    tile_p_10 = wrapOctahedralTexelCoordinates(texel_position + ivec2(0, 1), depth_tile_resolution);
    tile_p_11 = wrapOctahedralTexelCoordinates(texel_position + ivec2(1, 1), depth_tile_resolution);


    vec3 texel_00 = texelFetch(t_texture, tile_p_00, 0).rgb;
    vec3 texel_01 = texelFetch(t_texture, tile_p_01, 0).rgb;
    vec3 texel_10 = texelFetch(t_texture, tile_p_10, 0).rgb;
    vec3 texel_11 = texelFetch(t_texture, tile_p_11, 0).rgb;

    vec3 texel = lpv_bilinear_lerp(
        texel_00, texel_01,
        texel_10, texel_11,
        gridFrac
    );

    gl_FragColor = vec4(texel, 1.0);
}