#include "core.fsh"
#include "pbr.fsh"
#include "commonInput.fsh"

in highp vec3 P_f;

#if defined(PBR_EMI_LIGHT_NUM)
uniform sampler2D texEmi;
uniform vec2 emiUVOff[PBR_EMI_LIGHT_NUM];
flat in int emiIdx_f;
#define _EMISSIVE_ texture(texEmi, uv1_f + emiUVOff[emiIdx_f]).rgb

#elif defined(PBR_EMI_TEX)
#ifndef PBR_EMI_UV1
#define UV_EMI uv_f
#else
#define UV_EMI uv1_f
#endif

uniform sampler2D texEmi;
uniform vec3 emissive;
#define _EMISSIVE_ emissive*texture(texEmi, UV_EMI).rgb

#else
uniform vec3 emissive;
#define _EMISSIVE_ emissive

#endif

#if defined(PBR_MIX_FINAL_COL)
flat in int mixIdx_f;
uniform vec4 CMixs[PBR_MIX_FINAL_COL];
#define _MIX_F_(c) c = mix(c, CMixs[mixIdx_f].rgb, CMixs[mixIdx_f].a);
#else
#define _MIX_F_(c)
#endif

uniform vec4 mix_color;

vec3 LinearToSRGBWrapper(vec3 col)
{
#ifdef PBR_DISABLE_SRGB
    return col;
#else
    return LinearToSRGB(col);
#endif
}

layout(location = 0) out vec4 fragColor;

void main()
{
    PBRInfo info;
    info.albedo = getBaseCol();
    vec2 metaRough = getMetaRough();
    info.metallic  = metaRough.x;
    info.roughness = metaRough.y;
    info.emissive  = _EMISSIVE_;

    info.dirN = getNormal();
    info.dirV = normalize(_WorldEye - P_f);
    vec3 dirR = reflect(-info.dirV, info.dirN);
    
    mat2 rot2D = mat2(CubeRotate2D, vec2(-CubeRotate2D.y, CubeRotate2D.x));
    vec3 rotDirR = dirR;
    vec3 rotDirN = info.dirN;
    rotDirR.xy = rot2D*rotDirR.xy;
    rotDirN.xy = rot2D*rotDirN.xy;
    
    info.iSpec = IBL_Reflect(rotDirR, metaRough.y);
    info.iDiff = IBL_Irradiance(rotDirN);
    _BUILD_AO_
    ADD_AO(info.iSpec);
    ADD_AO(info.iDiff);
    float alpha;
    vec3 color = BRDF_PBS(info, alpha);
    color = LinearToSRGBWrapper(color);
    _MIX_F_(color);
    fragColor = vec4(color * alpha, alpha) * mix_color;
}
