#version 120

//#extension GL_ARB_gpu_shader_fp64 : enable
//this is needed if double type is used in versions under 400
//which can't be used here coz of too many deprecated features to edit right now
//(need to be done eventually though)


//#define ATTENUATION

// It was expressed that some drivers required this next line to function properly
precision highp float;
#define MAX_LIGHTS 8

#define NUMLIGHTS 4
#define NUMLIGHTSINTEXTURE 4

#define TEXTURESIZE 1024.0f
#define SHADOW 0.3f














uniform float lightsPosx[MAX_LIGHTS];
uniform float lightsPosy[MAX_LIGHTS];
uniform float lightsPosz[MAX_LIGHTS];

uniform float lightsEnabled[MAX_LIGHTS];
uniform float lightsinvRadius[MAX_LIGHTS];
uniform float lightMapSelect[MAX_LIGHTS];


uniform float lightsAmbientr[MAX_LIGHTS];
uniform float lightsAmbientg[MAX_LIGHTS];
uniform float lightsAmbientb[MAX_LIGHTS];

uniform float lightsDiffuser[MAX_LIGHTS];
uniform float lightsDiffuseg[MAX_LIGHTS];
uniform float lightsDiffuseb[MAX_LIGHTS];

uniform float lightsSpecularr[MAX_LIGHTS];
uniform float lightsSpecularg[MAX_LIGHTS];
uniform float lightsSpecularb[MAX_LIGHTS];













//shadow casting spot lights

//const int method = 0;
uniform int method;
// 0 sharp
// 1 smooth
// 2 smooth with linear interpolation

in vec3 alightVec[MAX_LIGHTS];
in vec3 aeyeVec[MAX_LIGHTS];
in vec2 texCoord;

in vec4 vpos; //vertex pos
uniform int renderingmirror;
uniform vec4 clipeq;

in float ShadowAngle[NUMLIGHTS];
in vec4 ShadowCoord[NUMLIGHTS];
uniform float anglebias;

uniform vec4 LightsPos[NUMLIGHTS];
uniform vec4 Lights[NUMLIGHTS];
uniform float lightsOn[NUMLIGHTS];
in vec4 vN_;

in vec3 v;
in vec3 N;
in vec3 T;
in vec3 B;
uniform vec3 camPos;


uniform vec4 glColor;

uniform float bias;

//uniform float lightsEnabled[MAX_LIGHTS];
//uniform float lightsinvRadius[MAX_LIGHTS];
//uniform float lightMapSelect[MAX_LIGHTS];

uniform sampler2D colorMap;
uniform sampler2D normalMap;
uniform sampler2D lightMap;

//uniform sampler2D specularMap;
uniform sampler2D shadowMap;
//uniform float invRadius;
//out vec4 gl_FragColor;
/*
float texture2DShadowLerp(sampler2D depths, vec2 size, vec2 uv, float compare){
    vec2 texelSize = vec2(1.0)/size;
    vec2 f = fract(uv*size+0.5);
    vec2 centroidUV = floor(uv*size+0.5)/size;

    float lb = texture2DCompare(depths, centroidUV+texelSize*vec2(0.0, 0.0), compare);
    float lt = texture2DCompare(depths, centroidUV+texelSize*vec2(0.0, 1.0), compare);
    float rb = texture2DCompare(depths, centroidUV+texelSize*vec2(1.0, 0.0), compare);
    float rt = texture2DCompare(depths, centroidUV+texelSize*vec2(1.0, 1.0), compare);
    float a = mix(lb, lt, f.y);
    float b = mix(rb, rt, f.y);
    float c = mix(a, b, f.x);
    return c;
}
*/



vec3 CalcBumpedNormal()
{
    vec3 Normal = N;
    vec3 Tangent = T;
    Tangent = normalize(Tangent - dot(Tangent, Normal) * Normal);
    //vec3 Bitangent = cross(Tangent, Normal);
    vec3 Bitangent = B;
    vec3 BumpMapNormal = texture2D(normalMap, texCoord).xyz;
    BumpMapNormal = 2.0 * BumpMapNormal - vec3(1.0, 1.0, 1.0);
    vec3 NewNormal;
    mat3 TBN = mat3(Tangent, Bitangent, Normal);
    NewNormal = TBN * BumpMapNormal;
    NewNormal = normalize(NewNormal);
    return NewNormal;
}




void main (void)
{
    vec3 lightVec;
    vec3 eyeVec;
    vec4 accvDiffuse = vec4(0.0);
    vec4 accvSpecular = vec4(0.0);
    float distSqr;
    vec3 lVec;
    vec3 vVec;
    float att;
    vec4 base;
    vec4 vAmbient;
    vec3 bump;
    float diffuse;
    vec4 vDiffuse;
    vec4 vSpecular;
    float specular;
    vec3 nrmltexture;

    const float SPOTR=0.49f;
    const float SPOTFALLOFF=0.03f;

    float shadowvalue=SHADOW;
    // if (vpos.y<0.0f) discard;
//    if (renderingmirror>0 && dot(gl_ClipPlane[0], vpos) > 0) {
    if (renderingmirror>0 && dot(clipeq, vpos) < 0)
    {
        discard;
    }
    base = texture2D(colorMap, texCoord);
    vAmbient = gl_LightSource[0].ambient * gl_FrontMaterial.ambient;
    base = texture2D(colorMap, texCoord);
    //vAmbient = gl_LightSource[0].ambient * gl_FrontMaterial.ambient;
    vAmbient = vec4(1.0f,1.0f,1.0f,1.0f)
               * vec4(lightsAmbientr[0],lightsAmbientg[0],lightsAmbientb[0],1.0f);

    vec3 viewDir = normalize(camPos-v);

//    for (int i=0; i<MAX_LIGHTS; i++)
    for (int i=0; i<1; i++)
    {
        //if (lightsEnabled[i]>0.0)
        {
            vec3 L = normalize(vec3(lightsPosx[i],lightsPosy[i],lightsPosz[i]) - v);
            vec3 E = normalize(-v); // we are in Eye Coordinates, so EyePos is (0,0,0)
            vec3 R = normalize(-reflect(L,N));
            vec3 lightDir = L;//normalize(lightPos - FragPos);

            lightVec=alightVec[i];
            //eyeVec=aeyeVec[i];
            //lightVec=L; eyeVec=E;

            distSqr = dot(lightVec, lightVec);
            att = clamp(1.0 - lightsinvRadius[i] * sqrt(distSqr), 0.0, 1.0);
            //att = 1.0 - lightsinvRadius[i] * sqrt(distSqr);
            lVec = lightVec * inversesqrt(distSqr);
            //vVec = normalize(eyeVec);

            //bump = normalize( texture2D(normalMap, texCoord).xyz * 2.0f - 1.0);
            //bump = normalize(N);
            bump=CalcBumpedNormal();

            //diffuse = max( dot(lVec, bump), 0.0 );
            /*
            diffuse = clamp( dot(lVec, bump), 0.0, 1.0 );
            //	vDiffuse = gl_LightSource[i].diffuse * gl_FrontMaterial.diffuse * diffuse *
            vDiffuse = vec4(lightsDiffuser[i],lightsDiffuseg[i],lightsDiffuseb[i],1.0f) * diffuse *
                       texture2D(lightMap, vec2(diffuse/1.02f,0.5+lightMapSelect[i]/2.0));
            */
            //diffuse = clamp( dot(lVec, bump), 0.0, 1.0 );
            //diffuse = max(dot(N,L), 0.0);
            diffuse = max(dot(bump,L), 0.0);
            vec4 Idiff = vec4 (lightsDiffuser[i],lightsDiffuseg[i],lightsDiffuseb[i],1.0f)* diffuse*
                        texture2D(lightMap, vec2(diffuse/1.02f,0.5+lightMapSelect[i]/2.0));
            ///Idiff = clamp(Idiff, 0.0, 1.0);

            accvDiffuse = accvDiffuse + Idiff *att;
            //accvDiffuse = accvDiffuse + vDiffuse * att;

            //vDiffuse = gl_LightSource[i].diffuse * diffuse *
            //         texture2D(lightMap, vec2(diffuse-0.01,lightMapSelect[i]));
            //accvDiffuse = accvDiffuse + vDiffuse;

            //specular = pow(clamp(dot(reflect(-lVec, bump), vVec), 0.0, 1.0),
            //gl_FrontMaterial.shininess );


            vec3 reflectDir=reflect(-lightDir,bump);
            const float shininess=1.5f;
            //specular = pow(clamp(dot(reflect(-lVec, bump), vVec), 0.0f, 1.0f), 32.0f );// * texture2D(specularMap, texCoord).r; //here shiness is replaced with 1.0, should introduce material functionality in obj loader //16.0
            specular = pow(clamp(dot(viewDir,reflectDir)*shininess,0.0f,1.0f),1.2f); //32.0f
            //specular = pow(clamp(dot(reflect(-lVec, bump), vVec), 0.0f, 1.0f), 32.0f );// * texture2D(specularMap, texCoord).r; //here shiness is replaced with 1.0, should introduce material functionality in obj loader //16.0
            //specular= clamp( dot(lVec, bump), 0.0, 1.0 ) * texture2D(specularMap, texCoord).r;
            // * pow(max(dot(R,E),0.0),0.3*shininess);

            //vec4 vSpecular = gl_LightSource[0].specular * gl_FrontMaterial.specular * specular;
//	vSpecular = gl_LightSource[i].specular * gl_FrontMaterial.specular * specular *
            vSpecular = vec4(lightsSpecularr[i],lightsSpecularg[i],lightsSpecularb[i],1.0f)* specular *
                        texture2D(lightMap, vec2(specular-0.01,0.5+lightMapSelect[i]/2.0));


            //const float shininess=1.0f;
            //specular=pow(max(dot(normalize(reflect(-L, bump)), E), 0.0f), 32.0f );// * texture2D(specularMap, texCoord).r; //here shiness is replaced with 1.0, should introduce material functionality in obj loader //16.0
            //specular=pow(max(dot(normalize(reflect(-L, bump)), E), 0.0f), 32.0f );// * texture2D(specularMap, texCoord).r; //here shiness is replaced with 1.0, should introduce material functionality in obj loader //16.0
            //specular=max(dot(normalize(L+normalize(E)),bump),0.0f);
            //specular=pow(max(dot(R,E),0.0),0.3*shininess);
            vec4 Ispec = vec4(lightsSpecularr[i],lightsSpecularg[i],lightsSpecularb[i],1.0f) * specular *
                        texture2D(lightMap, vec2(specular/1.02f,0.5+lightMapSelect[i]/2.0));
            // * pow(max(dot(R,E),0.0),0.3*shininess);
            // * pow(max(dot(N,L),0.0),0.3*shininess);
            // * pow(max(dot(R,E),0.0),0.3*shininess);
            ///Ispec = clamp(Ispec, 0.0, 1.0);

            //accvSpecular = accvSpecular + vSpecular * att;
            accvSpecular = accvSpecular + Ispec * att;

            //vSpecular = gl_LightSource[i].specular * specular * texture2D(lightMap, vec2(specular-0.01,lightMapSelect[i]));
            //accvSpecular = accvSpecular + vSpecular;
        }
    }
    //gl_FragColor = ( vAmbient*base + accvDiffuse*base + accvSpecular) * att;
    //gl_FragColor = ( vAmbient*base + accvDiffuse*base + accvSpecular);

//float bias = 0.005;
//float bias = 0.005;
//float biasx=bias;
    float totalvisibility=1.0f;
    float shadowCount=0.0;
    totalvisibility=0.0f;
    vec4 v1;
    vec2 shadowcoordbig;
    vec4 projectorColor=vec4(0.0f,0.0f,0.0f,1.0f);
//vec4 totalprojectorColor=vec4(1.0f,1.0f,1.0f,1.0f);
    vec4 totalprojectorColor=vec4(0.0f,0.0f,0.0f,1.0f);
    /*
    float r1=1.0f;
    float g1=1.0f;
    float b1=1.0f;
    */
    float depth;
    float ShadowAngle2;
    for (int i=0; i<NUMLIGHTS; i++) if (lightsOn[i]>0.0)
    {
        shadowCount+=1.0;
//for (int i=0;i<1;i++){


        float biasx=bias;
        float visibility = 1.0f;
        visibility = 0.0f;
//ShadowAngle2=1.0f-clamp(ShadowAngle[i],0.0f,1.0f);
        ShadowAngle2=ShadowAngle[i];
//if (ShadowAngle<0.25f||ShadowAngle>0.75f) visibility=0.5f+ShadowAngle; else
//if ( texture2D( shadowMap, ShadowCoord.xy ).z  <  ShadowCoord.z-biasx){ //.x should be .z but since we also do coloring in pass1, we can get away with it
        vec4 ShadowCoord2=ShadowCoord[i];
//ShadowCoord2.x-=50.0f;

//if ( texture2D( shadowMap, (ShadowCoord2.xy/ShadowCoord2.w) ).z  <  1.0f-(ShadowCoord2.z/200.0f-0.5f)/ShadowCoord2.w ){


        float x=0.5f-ShadowCoord2.x/ShadowCoord2.w;
        float y=0.5f-ShadowCoord2.y/ShadowCoord2.w;

        bool inshadow=false;
        float r=sqrt(x*x+y*y);
        if (r>SPOTR)
            inshadow=true;// else
        if (ShadowAngle2>0.2f){
            inshadow=true; //else
            shadowvalue=(1.0f-(ShadowAngle2-0.2f));
        }
        if (false){
            float ShadowAngle3 = dot(normalize(Lights[i].xyz),normalize(vec3(vpos.xyz-LightsPos[i].xzy)));
            if (ShadowAngle3<0.0f)
                inshadow=true;
        }


//ShadowAngle2 = dot(normalize(vN_.xyz),normalize(vec3(vpos.xyz-LightsPos[i].xzy)));
//ShadowAngle2 = dot(normalize(vN_.xyz),normalize(vec3(vpos.xyz-LightsPos[i].xzy)));
//if ((ShadowAngle2)>anglebias) inshadow=true;
//if ((ShadowAngle2)>anglebias) inshadow=true;
//>0.0f
//0.2
//0.1
//0.005

        float smoothsize;
        if (method==0)
            smoothsize=1.0f;
        else
            smoothsize=8.0f; //6.0f 10.0f
        float visibility4=0.0f;

        if (inshadow)
        {
            visibility=shadowvalue;
            projectorColor=vec4(0.0f,0.0f,0.0f,1.0f);
        }
        else
        {
            for (float ys=0.0f; ys<smoothsize; ys++)
                for (float xs=0.0f; xs<smoothsize; xs++)
                {

                    shadowcoordbig.x=ShadowCoord2.x/ShadowCoord2.w+xs/TEXTURESIZE;
                    shadowcoordbig.y=(1.0f/NUMLIGHTSINTEXTURE)*i+ShadowCoord2.y/NUMLIGHTSINTEXTURE/ShadowCoord2.w+ys/TEXTURESIZE/NUMLIGHTSINTEXTURE;
                    float shadowcoordbig_y=ShadowCoord2.y/ShadowCoord2.w+ys/TEXTURESIZE;

                    float rdepth=texture2D(shadowMap, shadowcoordbig).r;
                    float gdepth=texture2D(shadowMap, shadowcoordbig).g;
                    float bdepth=texture2D(shadowMap, shadowcoordbig).b;
                    depth=(rdepth*256.0f*256.0f+gdepth*256.0f+bdepth)/65536.0f;

#ifdef ATTENUATION
                    float attenuation=-depth+(ShadowCoord2.z/200.0f-biasx);
#endif

                    if (method==2)
                    {
                        vec3 shadowcoordbigUL;
                        vec3 shadowcoordbigUR;
                        vec3 shadowcoordbigDL;
                        vec3 shadowcoordbigDR;

                        shadowcoordbigUL.x=shadowcoordbigDL.x=shadowcoordbig.x;
                        shadowcoordbigUR.x=shadowcoordbigDR.x=shadowcoordbig.x+1.0f/TEXTURESIZE;

                        shadowcoordbigUL.y=shadowcoordbigUR.y=shadowcoordbig.y+1.0f/TEXTURESIZE/NUMLIGHTSINTEXTURE;
                        shadowcoordbigDL.y=shadowcoordbigDR.y=shadowcoordbig.y;
                        shadowcoordbigUL.z=shadowcoordbigUR.z=shadowcoordbig_y+1.0f/TEXTURESIZE;
                        shadowcoordbigDL.z=shadowcoordbigDR.z=shadowcoordbig_y;


                        /*
                        shadowcoordbigU.x=shadowcoordbigD.x=shadowcoordbig.x;
                        shadowcoordbigU.y=shadowcoordbig.y-1.0f/TEXTURESIZE/NUMLIGHTSINTEXTURE;
                        shadowcoordbigD.y=shadowcoordbig.y+1.0f/TEXTURESIZE/NUMLIGHTSINTEXTURE;
                        shadowcoordbigU.z=shadowcoordbig_y-1.0f/TEXTURESIZE;
                        shadowcoordbigD.z=shadowcoordbig_y+1.0f/TEXTURESIZE;

                        shadowcoordbigL.y=shadowcoordbigR.y=shadowcoordbig.y;
                        shadowcoordbigL.z=shadowcoordbigR.z=shadowcoordbig_y;
                        shadowcoordbigL.x=shadowcoordbig.x-1.0f/TEXTURESIZE;
                        shadowcoordbigR.x=shadowcoordbig.x+1.0f/TEXTURESIZE;
                        */

                        rdepth=texture2D(shadowMap, vec2(shadowcoordbigUL.xy)).r;
                        gdepth=texture2D(shadowMap, vec2(shadowcoordbigUL.xy)).g;
                        bdepth=texture2D(shadowMap, vec2(shadowcoordbigUL.xy)).b;
                        float depthUL=(rdepth*256.0f*256.0f+gdepth*256.0f+bdepth)/65536.0f;
                        rdepth=texture2D(shadowMap, vec2(shadowcoordbigUR.xy)).r;
                        gdepth=texture2D(shadowMap, vec2(shadowcoordbigUR.xy)).g;
                        bdepth=texture2D(shadowMap, vec2(shadowcoordbigUR.xy)).b;
                        float depthUR=(rdepth*256.0f*256.0f+gdepth*256.0f+bdepth)/65536.0f;
                        rdepth=texture2D(shadowMap, vec2(shadowcoordbigDL.xy)).r;
                        gdepth=texture2D(shadowMap, vec2(shadowcoordbigDL.xy)).g;
                        bdepth=texture2D(shadowMap, vec2(shadowcoordbigDL.xy)).b;
                        float depthDL=(rdepth*256.0f*256.0f+gdepth*256.0f+bdepth)/65536.0f;
                        rdepth=texture2D(shadowMap, vec2(shadowcoordbigDR.xy)).r;
                        gdepth=texture2D(shadowMap, vec2(shadowcoordbigDR.xy)).g;
                        bdepth=texture2D(shadowMap, vec2(shadowcoordbigDR.xy)).b;
                        float depthDR=(rdepth*256.0f*256.0f+gdepth*256.0f+bdepth)/65536.0f;

                        visibility4=0.0f;
                        float sc2=(ShadowCoord2.z/200.0f-biasx);
                        //float lcoeff=shadowcoordbigL.x-floor(shadowcoordbigL.x*TEXTURESIZE)/TEXTURESIZE;
                        /*
                        float ulcoeff=abs(shadowcoordbigUR.x-floor(shadowcoordbig.x*TEXTURESIZE)/TEXTURESIZE)*TEXTURESIZE;
                        float urcoeff=abs(shadowcoordbigUL.x-floor(shadowcoordbig.x*TEXTURESIZE)/TEXTURESIZE)*TEXTURESIZE;
                        //float lcoeff=1.0f-rcoeff;
                        float drcoeff=abs(shadowcoordbigDL.z-floor(shadowcoordbig_y*TEXTURESIZE)/TEXTURESIZE)*TEXTURESIZE;
                        float dlcoeff=abs(shadowcoordbigDR.z-floor(shadowcoordbig_y*TEXTURESIZE)/TEXTURESIZE)*TEXTURESIZE;
                        */
                        //float dcoeff=1.0f-ucoeff;
                        float ul,dl,ur,dr;
                        if ( depthUL  <  sc2)
                        {
                            ul=shadowvalue;//SHADOW;
                        }
                        else
                        {
                            ul=1.0f;
                        }
                        if ( depthDL  <  sc2)
                        {
                            dl=shadowvalue;//SHADOW;
                        }
                        else
                        {
                            dl=1.0f;
                        }
                        if ( depthUR  <  sc2)
                        {
                            ur=shadowvalue;//SHADOW;
                        }
                        else
                        {
                            ur=1.0f;
                        }
                        if ( depthDR  <  sc2)
                        {
                            dr=shadowvalue;//SHADOW;
                        }
                        else
                        {
                            dr=1.0f;
                        }
                        //if ( depth  <  sc2) {visibility4+=SHADOW;} else {visibility4+=1.0f;}

                        float fx=fract(shadowcoordbig.x*TEXTURESIZE);
                        float fy=fract(shadowcoordbig_y*TEXTURESIZE);
                        //visibility4/=2.0f;
                        float a=mix(dl,ul,fy);
                        float b=mix(dr,ur,fy);
                        visibility4=mix(a,b,fx);
                    }
//---------------------------------------------------------------
                    else
                    {
                        //if ( depth  <  (ShadowCoord2.z/200.0f) ){
                        if ( depth  <  (ShadowCoord2.z/200.0f-biasx) )
                        {
                            //if ( texture2D( shadowMap, shadowcoordbig ).z  <  (ShadowCoord2.z/200.0f-biasx) ){
                            //if ( texture2D( shadowMap, shadowcoordbig ).z  <  (testz-biasx) ){
                            visibility4 = shadowvalue;//SHADOW;
                        }
                        else
                        {
                            visibility4 = 1.0f;
                        }
                    }
                    //visibility+=visibility4;
                    if (visibility4==shadowvalue)//SHADOW;)
                    {
#ifdef ATTENUATION
                        visibility+=clamp(attenuation*10.0f,0.0f,1.0f);
#else
                        visibility+=1.0f-visibility4;
#endif
                    }
                    else
                        visibility+=0.0f;
                }
            visibility/=(smoothsize*smoothsize);
            visibility=1.0f-visibility;
            /*
            float attenuation=-depth+(ShadowCoord2.z/200.0f-biasx);
            visibility=attenuation;
            visibility=1.0f-(1.0f-visibility)*attenuation; //dim far shadows
            */
        }

        if (!inshadow)
        {
            vec2 pCoos=vec2(ShadowCoord2.xy/ShadowCoord2.w);
            pCoos.y=pCoos.y/2.0f;
            pCoos.y=clamp(pCoos.y,0.01f,0.49f);
            pCoos.x=clamp(pCoos.x,0.01f,0.99f);
            ///projectorColor=texture2D(lightMap, pCoos);

            vec4 col=texture2D(lightMap, pCoos);
            projectorColor=vec4(vec3((col.r+col.g+col.b)/3.0f),1.0f);
        }

        /*
        if (ShadowCoord2.x/ShadowCoord2.w<0.0f) {visibility=0.5; projectorColor=vec4(0.0f,0.0f,0.0f,0.0f);}
        if (ShadowCoord2.x/ShadowCoord2.w>=1.0f) {visibility=0.5; projectorColor=vec4(0.0f,0.0f,0.0f,0.0f);}
        if (ShadowCoord2.y/ShadowCoord2.w<0.0f) {visibility=0.5; projectorColor=vec4(0.0f,0.0f,0.0f,0.0f);}
        if (ShadowCoord2.y/ShadowCoord2.w>=1.0f) {visibility=0.5; projectorColor=vec4(0.0f,0.0f,0.0f,0.0f);}
        */

        totalprojectorColor+=projectorColor;

// 30/180 1/6
//this line was a quick hack to prevent projector wrapping-around, check if it needs correction
        /*
            r1*=ShadowAngle2;
            g1*=ShadowAngle2;
            b1*=ShadowAngle2;//0.5f;
        */
        //v1 = vec4((vec4(r1,g1,b1,1.0f)*visibility).rgb,1.0f);
        //v1= (vec4(1.0f,1.0f,1.ddddddddddddddddddddddddddddddddddddaaaaddddddwwwwwwwssssssssssssssssssssaa0f,1.0f)-((vec4(1.0f,1.0f,1.0f,1.0f)-v1)/1.5f))/1.5f;

//v1 = vec4((vec4(1.0f,1.0f,1.0f,1.0f)*visibility).rgb,1.0f);

        //gl_FragColor = vec4((( vAmbient*base + accvDiffuse*base + accvSpecular) * v1).rgb,1.0f);
        //gl_FragColor = vec4((base * v1).rgb,1.0f)+ accvSpecular;

        //gl_FragColor = vec4((base * v1).rgb,1.0f)+ vec4((accvDiffuse*v1).rgb,1.0f)+vec4(( accvSpecular*v1).rgb,1.0f);

        //if(visibility>0.5f)
        //totalvisibility*=visibility;


        if (!inshadow&&r>=SPOTR-SPOTFALLOFF&&r<=SPOTR) {
            float falloff=(1.0f-float(SHADOW))*(1.0f-(r-(SPOTR-SPOTFALLOFF))/(SPOTFALLOFF))+float(SHADOW);
            //if (float(visibility)>falloff)
                visibility*=float(falloff);
            if (visibility<SHADOW) visibility=SHADOW;
        }

        totalvisibility+=visibility;

        //if (visibility==1.0f)
        //if (visibility==1.0f)
        //totalprojectorColor+=projectorColor;
        /*
            if (false)
            {
                if (ShadowAngle2<-0.5) totalprojectorColor=vec4(1.0f,0.0f,0.0f,1.0f);
                if (ShadowAngle2<0.0&&ShadowAngle2>-0.5f) totalprojectorColor=vec4(0.0f,1.0f,0.0f,1.0f);
                if (ShadowAngle2>0.0) totalprojectorColor=vec4(0.0f,0.0f,1.0f,1.0f);
                if (ShadowAngle2>0.5) totalprojectorColor=vec4(1.0f,1.0f,1.0f,1.0f);
            }
        */
    }
    ///totalvisibility/=NUMLIGHTS;
    totalvisibility/=shadowCount;

    totalprojectorColor=totalprojectorColor*totalvisibility;
//totalvisibility=pow(totalvisibility,2.1f);


    //r1=g1=b1=1.0f;
    totalvisibility=clamp(totalvisibility,0.0f,1.0f);
    v1 = vec4(totalvisibility,totalvisibility,totalvisibility,1.0f);
    v1 = (vec4(1.0f,1.0f,1.0f,1.0f)-((vec4(1.0f,1.0f,1.0f,1.0f)-v1)/1.2f))/1.2f;
    /*
        if (totalvisibility==1.0f)
            gl_FragColor = ( vAmbient*base + accvDiffuse*base + accvSpecular)*v1*glColor+projectorColor;
        else
            gl_FragColor = ( vAmbient*base + accvDiffuse*base + accvSpecular)*v1*glColor;
    */
//debugging:
    /*
    {
            //float ShadowAngle2=ShadowAngle[0];
            //float ShadowAngle2 = dot(normalize(vN_.xyz),normalize(vec3(vpos.xyz-LightsPos[0].xzy)));
            float ShadowAngle2 = dot(normalize(Lights[0].xyz),normalize(vec3(vpos.xyz-LightsPos[0].xyz)));
            if (ShadowAngle2<0.0)
                totalprojectorColor=vec4(0,-ShadowAngle2,0,1);
            else
                totalprojectorColor=vec4(ShadowAngle2,0,0,1);
    }
    */

    gl_FragColor = ( vAmbient*base + accvDiffuse*base + accvSpecular)*v1*glColor+totalprojectorColor;
    //if (v1.r<0.2) v1=vec4(0,0,0,1);
    ///gl_FragColor = ( vAmbient*base + accvDiffuse*base + accvSpecular)*v1*glColor;

    //gl_FragColor = totalprojectorColor;

    //gl_FragColor = vec4(ShadowAngle2,ShadowAngle2,ShadowAngle2,1.0f);
    //gl_FragColor = texture2D( shadowMap, (ShadowCoord2.xy/ShadowCoord2.w) );
    //gl_FragColor = vec4(vec3(ShadowCoord2.z/200.0f),1.0f);
}
