#version 330 core
layout (location = 0) out vec3 dsbPosition;
layout (location = 1) out vec3 dsbNormal;
layout (location = 2) out vec4 dsbAlbedoSpec;

struct PRS_RES {
	vec3 PosWrld;
	vec2 TexCoord;
	vec3 Normal;
};

in PRS_RES vs_res;

struct Material {
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
    vec3 roughness;

    sampler2D diffTex;
    sampler2D ambtTex;
    sampler2D specTex;
    sampler2D normTex;
    sampler2D dispTex;
};

uniform Material mtrl[2];

void calc_tbn_matrix( out mat3 tbn, vec3 normal, vec3 pixel_pos, vec2 pixel_texcoord ){
    // Calculate derivatives
    vec3 pos_dx  = dFdx(pixel_pos);
    vec3 pos_dy  = dFdy(pixel_pos);
    vec2 texC_dx = dFdx(pixel_texcoord);
    vec2 texC_dy = dFdy(pixel_texcoord);

    // Calculate tangent and bitangent
    vec3 tangent   = normalize(texC_dy.y * pos_dx - texC_dx.y * pos_dy);
    vec3 bitangent = normalize(texC_dx.x * pos_dy - texC_dy.x * pos_dx);

    // Construct TBN matrix
    tbn = mat3( tangent, bitangent, normal ); // normal interpolated vertex normal (after normalization)
}

void main(){
    if( texture( mtrl[0].diffTex, vs_res.TexCoord ).a < 0.05 ){
        discard;
    } else {
        // store the fragment position vector in the first gbuffer texture
        dsbPosition = vs_res.PosWrld;
        // also store the per-fragment normals into the gbuffer
        vec3 normalMapNormal = normalize( texture( mtrl[0].normTex, vs_res.TexCoord ).rgb * 2.0 - 1.0 );
        mat3 tbn;
        calc_tbn_matrix( tbn, vs_res.Normal, vs_res.PosWrld, vs_res.TexCoord );
        dsbNormal = normalize( tbn * normalMapNormal );
        if(!gl_FrontFacing){ dsbNormal = -dsbNormal; }
        // and the diffuse per-fragment color
        dsbAlbedoSpec.rgb = texture( mtrl[0].diffTex, vs_res.TexCoord ).rgb;
        // store specular intensity in gAlbedoSpec's alpha component
        dsbAlbedoSpec.a = texture( mtrl[0].specTex, vs_res.TexCoord ).r;
    }
}