#version 330 compatibility
#include "includes.glsl"
// Temporal Accumulation //

uniform float near;
uniform float far;
uniform mat4 gbufferProjectionInverse;
uniform mat4 gbufferPreviousProjection;
uniform mat4 gbufferModelViewInverse;
uniform mat4 gbufferPreviousModelView;
mat4 gbufferPreviousModelViewInverse = inverse(gbufferPreviousModelView);
uniform vec3 cameraPosition;
uniform vec3 previousCameraPosition;
vec3 cameraOffset = previousCameraPosition-cameraPosition;

uniform sampler2D depthtex1;
uniform sampler2D colortex0;
uniform sampler2D colortex3; // previous Frames
uniform sampler2D colortex4; // previous Depth
//layout(rgba8) uniform image2D colorimg4;

in vec2 texcoord;

/* DRAWBUFFERS:034 */
layout(location = 0) out vec4 color;
layout(location = 1) out vec4 StoreColor;
layout(location = 2) out float OutDepth;
/*
    const bool colortex3Clear = false;
    const bool colortex4Clear = false;
    const int colortex3Format = RGBA32F;
    const int colortex4Format = R32F;
*/


vec3 ProjectNDivide(mat4 Matrix, vec3 Pos){
    vec4 HgnsPos = Matrix*vec4(Pos,1);
    return HgnsPos.xyz/HgnsPos.w;
}

void main(){
    // Get sample position from the previous frame
    vec3 ScreenPos = vec3(texcoord, texture(depthtex1, texcoord));
    vec3 ViewPos = ProjectNDivide(gbufferProjectionInverse, ScreenPos*2.0-1.0);
    vec4 PrevPlayerPos = gbufferModelViewInverse * vec4(ViewPos, 1.0) - vec4(cameraOffset, 0.0);
    vec3 PrevViewPos = (gbufferPreviousModelView * PrevPlayerPos).xyz;
    vec3 PrevScreenPos = ProjectNDivide(gbufferPreviousProjection, PrevViewPos) * 0.5 + 0.5;
    vec2 ReadCoord = texcoord;
    ReadCoord = PrevScreenPos.xy;

    // Previous Data
    float PrevDepth = (near*far) / (texture(colortex4, ReadCoord).r * (near-far) + far);
    vec3 prevFrameData = texture(colortex3, ReadCoord).rgb;

    // Clamp to prevent floating point errors
    int passNum = min(TemporalAccumulation, int(texture(colortex3, ReadCoord).a*float(TemporalAccumulation) + 0.1) + 1);
    
    // New Data
    float Depth = (near*far) / (ScreenPos.z * (near-far) + far);
    vec4 FrameData = texture(colortex0, texcoord);

    // Reproject to see if previous data should be overwritten
    vec3 PrevWorldPos = (mat3(gbufferPreviousModelViewInverse) * ProjectNDivide(inverse(gbufferPreviousProjection), vec3(ReadCoord, texture(colortex4,ReadCoord).r)*2.0-1.0)) + previousCameraPosition + gbufferPreviousModelViewInverse[3].xyz;
    vec3 WorldPos = mat3(gbufferModelViewInverse) * ViewPos + cameraPosition + gbufferModelViewInverse[3].xyz;
    #ifndef RenderMode
        if (clamp(ReadCoord,0.0,1.0)!=ReadCoord || length(PrevWorldPos-WorldPos) > 0.06 || Depth<.113) passNum = 1;
    #endif

    StoreColor = vec4(mix(prevFrameData, FrameData.rgb, 1.0/float(passNum)), float(passNum)/float(TemporalAccumulation));
    OutDepth = texture(depthtex1, texcoord).x;
    color = vec4(StoreColor.rgb, 1);
}