//#version 330

#version 430 core

layout(std430, binding = 0) buffer SSBO
{
    vec3 values[100];
};











precision highp float;

out vec4 FragColor; // Declare your own output variable

uniform int demopart;

uniform float testvalue;
uniform float shininess;
uniform float rfiddling; /// 0.3 for tight, 0.8 for mb

const int maxnumalights=8;
uniform float widths[maxnumalights];
uniform float heights[maxnumalights];
uniform vec3 pnormals[maxnumalights];
uniform vec3 right[maxnumalights];





#define MAX_LIGHTS 14
#define TMAX_LIGHTS 20

#define NUMLIGHTS 4
float actualnumlights;
#define NUMLIGHTSINTEXTURE 4

#define TEXTURESIZE 1024.0f
float SHADOW=0.05f;
#define SHADOWORTHO -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];















const int method = 1;





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

in vec4 vpos; 
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 vec4 flash;

uniform float bias;





uniform sampler2D colorMap;
uniform sampler2D normalMap;

uniform sampler2D specularMap;
uniform sampler2D shadowMap;



bool inshadow;






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




vec3 projectOnPlane(in vec3 p, in vec3 pc, in vec3 pn)
{
    float distance = dot(pn, p-pc);
    return p - distance*pn;
}
int sideOfPlane(in vec3 p, in vec3 pc, in vec3 pn){
   if (dot(p-pc,pn)>=0.0) return 1; else return 0;
}
vec3 linePlaneIntersect(in vec3 lp, in vec3 lv, in vec3 pc, in vec3 pn){
   return lp+lv*(dot(pn,pc-lp)/dot(pn,lv));
}

float calculateAttenuation(in int i, in float dist)
{
    
    
    return clamp(1.0 - lightsinvRadius[i] * sqrt(dist), 0.0, 1.0);
}





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;

    vec3 V=v;
    vec3 N_=CalcBumpedNormal();

    actualnumlights=0.0; for (int i=0;i<NUMLIGHTS;i++) if (lightsOn[i]>0.0) actualnumlights+=1.0;
    SHADOW*=NUMLIGHTS-actualnumlights+1.0;
    if (actualnumlights==1.0) SHADOW=0.6;

    base = vec4(0,0,0,1);//texture2D(colorMap, texCoord);

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

    float shadowvalue=SHADOW;
    

    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 = vec4(1.0f,1.0f,1.0f,1.0f)
               * vec4(lightsAmbientr[0],lightsAmbientg[0],lightsAmbientb[0],1.0f);

    vec3 viewDir = normalize(camPos-v);


vec4 aambient=vec4(0,0,0,0);
vec4 adiffuse=vec4(0,0,0,0);
vec4 aspecular=vec4(0,0,0,0);
float diffuseold;


for (int i=0;i<2;i++) 
{



    vec3 up = right[i];
    vec3 pnormal = pnormals[i];
    vec3 right = normalize(cross(up,pnormal));

    
    float testvalue1=1.0;
    float testvalue2=1.0;
    float width = widths[i]/2.0/testvalue1;
    float height = heights[i]/2.0/testvalue1;

    
    vec3 lightpos;
    lightpos.x=lightsPosx[i]/testvalue1;
    lightpos.y=lightsPosy[i]+0.1*6.5;
    lightpos.z=lightsPosz[i]/testvalue1;
    if (i==7) lightpos.z=lightsPosz[i-1];
    vec3 projection = projectOnPlane(V,lightpos,pnormal);
    vec3 dir = projection-lightpos;

    
    vec2 diagonal = vec2(dot(dir,right),dot(dir,up));
    vec2 nearest2D = vec2(clamp(diagonal.x,-width,width),clamp(diagonal.y,-height,height));
    vec3 nearestPointInside = lightpos+(right*nearest2D.x+up*nearest2D.y);

    float dist = distance(V,nearestPointInside);

    vec3 L = normalize(nearestPointInside - V);
    float attenuation = calculateAttenuation(i, dist);

    
    
    attenuation*=clamp(0.3+pow(dot(normalize(nearestPointInside-V),N_),0.3),0.0,1.0);
    
    

    
    float nDotL = dot(N_,L);

vec4 colorambient, colordiffuse, colorspecular;
    colorambient.r=0.2;
    colorambient.g=0.2;
    colorambient.b=0.2;
    colorambient.a=1.0;
    colordiffuse.r=lightsDiffuser[i];
    colordiffuse.g=lightsDiffuseg[i];
    colordiffuse.b=lightsDiffuseb[i];
    colordiffuse.a=1.0;
    colorspecular.r=lightsSpecularr[i];
    colorspecular.g=lightsSpecularg[i];
    colorspecular.b=lightsSpecularb[i];
    colorspecular.a=1.0;

    if (nDotL > 0.0 && sideOfPlane(V,lightpos,pnormal) == 1) 
    {
        
        
        vec3 R = reflect(normalize(camPos-V),N_);
        vec3 E = linePlaneIntersect(V,R,lightpos,pnormal);

        float specAngle = dot(R,pnormal);
        if (specAngle > 0.0){
	    vec3 dirSpec = E-lightpos;
	    const float scale=1.0;
    	    vec2 dirSpec2D = vec2(dot(dirSpec,right),dot(dirSpec,up));
            vec2 nearestSpec2D = vec2(clamp( dirSpec2D.x,-width,width  ),clamp(  dirSpec2D.y,-height,height))/scale; 
            
            
    	    
            float specFactor = 1.0-clamp(length(nearestSpec2D-dirSpec2D)*(shininess*3.0*0.015),0.0,1.0);

            float specattenuation=texture2D(specularMap,
                                   vec2(
                                        i/8.0f+1.0/8.0-((nearestSpec2D.x+width)/2.0/width)*scale/8.0f,
                                        -(nearestSpec2D.y+height)/2.0/height*scale
                                        )
                                   ).b;
          aspecular += colorspecular * specattenuation * specFactor * specAngle;
        }

        lightVec=L;
        
        
        distSqr = dot(lightVec, lightVec);
        float boost;
        if (i>=6) boost=4.0*11.0/2.47; else boost=1.0;
        att = clamp(1.0 - lightsinvRadius[i] * sqrt(distSqr), 0.0, 1.0);
        
        lVec = lightVec * inversesqrt(distSqr);
        diffuseold = clamp(dot(lVec, N_), 0.0, 1.0 );

        adiffuse  += colordiffuse * (attenuation * nDotL + diffuseold*0.32 ) * boost;
        
        
    }

    
	aambient=colorambient;
	
}

    
    




    float totalvisibility=1.0f;
    totalvisibility=0.0f;
    vec4 v1;
    vec2 shadowcoordbig;
    vec4 projectorColor=vec4(0.0f,0.0f,0.0f,1.0f);

    vec4 totalprojectorColor=vec4(0.0f,0.0f,0.0f,1.0f);
    
    float depth;
    float ShadowAngle2;
	float totalshadowcount=0.0;
	float visibility = 1.0f;
    float shadowdistance;
    for (int i=0; i<NUMLIGHTS; i++) 
    {
if (lightsOn[i]>0.0)
{	



        float biasx=bias;
        visibility = 0.0f;

        ShadowAngle2=ShadowAngle[i];


        vec4 ShadowCoord2=ShadowCoord[i];





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

        inshadow=false;
        float r=sqrt(x*x+y*y);
        if (r>SPOTR) inshadow=true;
        
        if (false)
        if (ShadowAngle2>0.22){ 
            inshadow=true; shadowvalue=1.0f;
            
        }
        
        {
            
            float ShadowAngle3 = dot(normalize(N),normalize(vec3(vpos.xyz-LightsPos[i].xyz)));
            
        }











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

        if (inshadow)
        {
            
			visibility=1.0; 
            projectorColor=vec4(1.0f,1.0f,1.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;


                        

                        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 ul,dl,ur,dr;
                        if ( depthUL  <  sc2)
                        {
                            ul=shadowvalue;
                        }
                        else
                        {
                            ul=1.0f;
                        }
                        if ( depthDL  <  sc2)
                        {
                            dl=shadowvalue;
                        }
                        else
                        {
                            dl=1.0f;
                        }
                        if ( depthUR  <  sc2)
                        {
                            ur=shadowvalue;
                        }
                        else
                        {
                            ur=1.0f;
                        }
                        if ( depthDR  <  sc2)
                        {
                            dr=shadowvalue;
                        }
                        else
                        {
                            dr=1.0f;
                        }
                        

                        float fx=fract(shadowcoordbig.x*TEXTURESIZE);
                        float fy=fract(shadowcoordbig_y*TEXTURESIZE);
                        
                        float a=mix(dl,ul,fy);
                        float b=mix(dr,ur,fy);
                        visibility4=mix(a,b,fx);
                    }
                    

                    else
                    {
                        
                        if ( depth  <  (ShadowCoord2.z/200.0f-biasx) )
                        {
                            
                            
                            visibility4 = shadowvalue;
                        }
                        else
                        {
                            visibility4 = 1.0f;
                        }
                    }
                    
                    if (visibility4==shadowvalue)
                    {
#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;
            

        }

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

            
            vec4 col=texture2D(specularMap, vec2(4.0/8.0+pCoos.x/8.0,pCoos.y))/1.0;
            projectorColor=col;
        }

        

        totalprojectorColor+=projectorColor;



        

        
        



        
        

        

        
        

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

        }
}
        
        
        if (i==3){
			vec4 ShadowCoord2=ShadowCoord[i];
			float visibility4=0.0;
            const float smoothsize2=12.0;
            visibility=0;
            for (float ys=0.0f; ys<smoothsize2; ys++)
                for (float xs=0.0f; xs<smoothsize2; 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;
                    float sc2=(ShadowCoord2.z);
                    
                    if ( depth < sc2 / 80.85-0.0096){
                        visibility4 = SHADOWORTHO;
                    } else {
                        visibility4=1.0;
                    }
                    visibility+=1.0f-visibility4;
                }
                visibility/=(smoothsize2*smoothsize2);
                visibility=1.0f-visibility;

            

        }

        if (visibility==0.0) visibility=1.0; 

        totalvisibility+=visibility;

        
        
        
        
		totalshadowcount=totalshadowcount+1.0;
    }
	
       
        
    

    for (int i=int(totalshadowcount);i<NUMLIGHTS;i++){totalvisibility+=1.0;}

    totalvisibility/=NUMLIGHTS;
    


    
    totalprojectorColor=totalprojectorColor*totalvisibility;



    
    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;
	v1.a=1.0;

    
    shadowdistance=clamp(length(vpos.xyz-vec3(0,0,0))/(5.0*0.84),0,1); 
    v1+=shadowdistance;
    v1=clamp(v1,0,1);
    















    vec4 totaldiffuse;
    vec4 totalspecular;
    float radius;

    if (true){
        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=CalcBumpedNormal();
        float diffuse;
        vec4 vDiffuse;
        vec4 vSpecular;
        float specular;
        vec3 nrmltexture;

           // 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;

        for (int i=2; i<100; i++)
           {
            const float q = 1.0/2048.0/2.0;
            const float q2 = 1.0/64.0/2.0; // center pixel
            uint x1 = uint(texture2D(normalMap,vec2(float(i*18+0)*(1.0/2048.0)+q,q2)).r*255.0);
            uint x2 = uint(texture2D(normalMap,vec2(float(i*18+1)*(1.0/2048.0)+q,q2)).r*255.0);
            uint x3 = uint(texture2D(normalMap,vec2(float(i*18+2)*(1.0/2048.0)+q,q2)).r*255.0);
            uint x4 = uint(texture2D(normalMap,vec2(float(i*18+3)*(1.0/2048.0)+q,q2)).r*255.0);
            uint y1 = uint(texture2D(normalMap,vec2(float(i*18+4)*(1.0/2048.0)+q,q2)).r*255.0);
            uint y2 = uint(texture2D(normalMap,vec2(float(i*18+5)*(1.0/2048.0)+q,q2)).r*255.0);
            uint y3 = uint(texture2D(normalMap,vec2(float(i*18+6)*(1.0/2048.0)+q,q2)).r*255.0);
            uint y4 = uint(texture2D(normalMap,vec2(float(i*18+7)*(1.0/2048.0)+q,q2)).r*255.0);
            uint z1 = uint(texture2D(normalMap,vec2(float(i*18+8)*(1.0/2048.0)+q,q2)).r*255.0);
            uint z2 = uint(texture2D(normalMap,vec2(float(i*18+9)*(1.0/2048.0)+q,q2)).r*255.0);
            uint z3 = uint(texture2D(normalMap,vec2(float(i*18+10)*(1.0/2048.0)+q,q2)).r*255.0);
            uint z4 = uint(texture2D(normalMap,vec2(float(i*18+11)*(1.0/2048.0)+q,q2)).r*255.0);
            uint intx = (x1 << 24) | (x2 << 16) | (x3 << 8) | x4;
            float x = uintBitsToFloat(intx);
            uint inty = (y1 << 24) | (y2 << 16) | (y3 << 8) | y4;
            float y = uintBitsToFloat(inty);
            uint intz = (z1 << 24) | (z2 << 16) | (z3 << 8) | z4;
            float z = uintBitsToFloat(intz);

            const float qr = 1.0/64.0/2.0+2.0/64.0; // center pixel
            uint r1 = uint(texture2D(normalMap,vec2(float(i*4+0)*(1.0/2048.0)+q,qr)).r*255.0);
            uint r2 = uint(texture2D(normalMap,vec2(float(i*4+1)*(1.0/2048.0)+q,qr)).r*255.0);
            uint r3 = uint(texture2D(normalMap,vec2(float(i*4+2)*(1.0/2048.0)+q,qr)).r*255.0);
            uint r4 = uint(texture2D(normalMap,vec2(float(i*4+3)*(1.0/2048.0)+q,qr)).r*255.0);
            uint intr = (r1 << 24) | (r2 << 16) | (r3 << 8) | r4;
            float r = uintBitsToFloat(intr);
            radius = r;

            float lightsDiffuser=texture2D(normalMap,vec2(float(i*18+12)*(1.0/2048.0),0.0)).r;
            float lightsDiffuseg=texture2D(normalMap,vec2(float(i*18+13)*(1.0/2048.0),0.0)).r;
            float lightsDiffuseb=texture2D(normalMap,vec2(float(i*18+14)*(1.0/2048.0),0.0)).r;
            float lightsSpecularr=texture2D(normalMap,vec2(float(i*18+15)*(1.0/2048.0),0.0)).r;
            float lightsSpecularg=texture2D(normalMap,vec2(float(i*18+16)*(1.0/2048.0),0.0)).r;
            float lightsSpecularb=texture2D(normalMap,vec2(float(i*18+17)*(1.0/2048.0),0.0)).r;
	        //if (lightsEnabled[i]>0.0)
	        {
                //lightVec=alightVec[i];
                ////////////////////////////////// lightVec=values[i];  //<<< this shader storage buffer object thing is not working, so:

                vec3 tmpVec = vec3(x,y,z) - v;
                vec3 alightVec_;
	            lightVec.x = dot(tmpVec, T);
	            lightVec.y = dot(tmpVec, B);
	            lightVec.z = dot(tmpVec, N);

                //lightVec=alightVec[0];
                //eyeVec=aeyeVec[i];

	        distSqr = dot(lightVec, lightVec)/rfiddling; /// 0.3 for tight, 0.8 for mb and torch
	        //att = clamp(1.0 - lightsinvRadius[i] * sqrt(distSqr), 0.0, 1.0);
            float testvalue3=3.3462;
            att = clamp(1.0 - (1.0f / (3.32f*testvalue3) * 0.4f * 10.0f) * sqrt(distSqr), 0.0, 1.0);

	        lVec = lightVec * inversesqrt(distSqr);
	        ///vVec = normalize(eyeVec);

            //nrmltexture= texture2D(normalMap, texCoord).xyz;
            //nrmltexture.z=nrmltexture.z*-1.0f;
	        //bump = normalize(nrmltexture * 2.0f - 1.0);
	        //bump = normalize( texture2D(normalMap, texCoord).xyz * 2.0f - 1.0);
	        //bump = vec3(0.0,0.0,1.0);

	        //diffuse = max( dot(lVec, bump), 0.0 );

            // diffuse
            vec3 lightDirD = normalize(lightVec - v);
            vec3 normal = normalize(bump);
            diffuse = max(dot(lightDirD, normal), 0.0);
















//vec3 bitangent = cross(N, T) * vertexTangentHandedness;
//mat3 TBN = mat3(T, B, N);
//vec3 mappedNormal = normalize(TBN * normalMap);  // `normalMap` should be sampled and remapped from [0,1] to [-1,1]
vec3 lightpos = vec3(x,y,z);
vec3 lightDirdiffuse = normalize(lightpos - v);
float dist = length(lightpos - v);
float attenuation = clamp(1.0 - dist / r, 0.0, 1.0);
diffuse = max(dot(N, lightDirdiffuse), 0.0) * attenuation;
diffuse/=110.0;

















            //if (r==0.0) r=0.000001;
            //r=0.4+r*0.6;
            r=r*1.12;

            float dim=2.0f*1.7f;

	        ///diffuse = clamp( dot(lVec, bump), 0.0, 1.0 );
        //	vDiffuse = gl_LightSource[i].diffuse * gl_FrontMaterial.diffuse * diffuse *
            vec4 diff_=vec4(lightsDiffuser,lightsDiffuseg,lightsDiffuseb,1.0);
	        vDiffuse = diff_ * diffuse;// *
		        //texture2D(lightMap, vec2(diffuse-0.01,lightMapSelect[i]));
	        accvDiffuse = accvDiffuse + vDiffuse/10.0f*att/0.7f   /1.5f /dim * r;

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

	        //specular = pow(clamp(dot(reflect(-lVec, bump), vVec), 0.0, 1.0), gl_FrontMaterial.shininess ) * texture2D(specularMap, texCoord).r;
	        //specular = pow(clamp(dot(reflect(-lVec, bump), vVec), 0.0, 1.0), 1.0f);
            vec3 L = normalize(vec3(x,y,z) - v);
            vec3 lightDir = L;
            vec3 reflectDir=reflect(-lightDir,bump);
            const float shininess=1.5f;
            ///specular = pow(clamp(dot(viewDir,reflectDir)*shininess,0.0f,1.0f),1.2f); 

            specular = pow(max(dot(viewDir, reflectDir), 0.0), 8.0);
        	///specular = pow(clamp(dot(reflect(-lVec, bump), vVec), 0.0, 1.0), 32.0 ) * 1.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(reflect(-lVec, bump), vVec), 0.0, 1.0), 24.0f ) * 1.0f;//texture2D(specularMap, texCoord).r; //here shiness is replaced with 1.0, should introduce material functionality in obj loader //16.0
            //specular = pow(diffuse,48.0f);

	        //vec4 vSpecular = gl_LightSource[0].specular * gl_FrontMaterial.specular * specular;
        //	vSpecular = gl_LightSource[i].specular * gl_FrontMaterial.specular * specular *
            vec4 spec_=vec4(lightsSpecularr,lightsSpecularg,lightsSpecularb,1.0);
	        vSpecular = spec_ * specular;// * texture2D(lightMap, vec2(specular-0.01,lightMapSelect[i]));
	        accvSpecular = accvSpecular + vSpecular/10.0 *att/0.7f   /1.5f/dim * r;
	        }
           }
	        //gl_FragColor = ( vAmbient*base + accvDiffuse*base + accvSpecular) * att;
	        //gl_FragColor = ( vAmbient*base + accvDiffuse*base + accvSpecular);
            
            float daboost=1.0;
            /*
            if (rfiddling>0.7) {
                daboost=10.0/1.8*2.0*4.0; /// if torch or mb part
                if (radius-3.2<0.0001) daboost /= 11.7; // if mbcubes
            }
            else 
                daboost=10.0/1.8*2.0*testvalue; // tight part
            if (radius-3.3<0.0001) daboost = 10.0/1.8*2.0*4.0*0.059; // liquid part
            */

            daboost=10.0/1.8*2.0*4.0; /// general fallback
            if (demopart==0) {daboost=10.0/1.8*2.0;} //tight
            if (demopart==10||demopart==13) {daboost=10.0/1.8*2.0*4.0/6.0;} //mb particles
            if (demopart==11||demopart==14) {daboost=10.0/1.8*2.0*4.0/11.7;} //mb cubes
            if (demopart==2) {daboost=10.0/1.8*2.0*4.0*0.059;} //torch
            if (demopart==3) {daboost=10.0/1.8*2.0*4.0*0.059;} //liquid

//            float daboost = 10.0/1.8*2.0*2.0;
            totaldiffuse=accvDiffuse*daboost;
            totalspecular=accvSpecular*daboost;
    }















    

    


    
	
	aambient=vec4(0.15,0.18,0.31,1.0);
    
    //gl_FragColor = ( aambient*base + adiffuse*base + aspecular)*v1+glColor;
    //gl_FragColor = ( aambient*base + adiffuse*base + totaldiffuse + aspecular + totalspecular)*v1+glColor;
    
    //FragColor = ( aambient*base + adiffuse*base + totaldiffuse + aspecular + totalspecular)*v1+glColor;
    
    //FragColor = ( aambient*base + adiffuse*base + totaldiffuse + aspecular + totalspecular)*v1+glColor;
    //FragColor = (adiffuse + totaldiffuse + aspecular + totalspecular);
    //FragColor = ( aambient*base + adiffuse*base + totaldiffuse + totalspecular)/2.5*texture2D(specularMap,texCoord); /// base = (0,0,0,1)
    
    ///FragColor = (totaldiffuse + totalspecular)/2.5*texture2D(specularMap,texCoord); /// base = (0,0,0,1)
    FragColor = (totalspecular)/2.5*texture2D(specularMap,texCoord); /// base = (0,0,0,1)
    //FragColor.a/=0.0;
    FragColor.a = 1.0;

    //gl_FragColor = vec4(N_.x, N_.y, N_.z, 1.0f);
}
