//#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 float testvalue;
uniform float shininess;

const int maxnumalights=16;
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;
in vec3 originalV;

uniform vec3 camPos;


uniform vec4 glColor;
uniform vec4 flash;

uniform float bias;

uniform int rendercircles;

uniform float iTime;


uniform sampler2D colorMap;
//uniform samplerCube colorMap;
uniform sampler2D specularMap;
uniform sampler2D normalMap;
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;
    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;
}




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);
}

//
// GLSL textureless classic 4D noise "cnoise",
// with an RSL-style periodic variant "pnoise".
// Author:  Stefan Gustavson (stefan.gustavson@liu.se)
// Version: 2011-08-22
//
// Many thanks to Ian McEwan of Ashima Arts for the
// ideas for permutation and gradient selection.
//
// Copyright (c) 2011 Stefan Gustavson. All rights reserved.
// Distributed under the MIT license. See LICENSE file.
// https://github.com/ashima/webgl-noise
//

vec4 mod289(vec4 x)
{
  return x - floor(x * (1.0 / 289.0)) * 289.0;
}

vec4 permute(vec4 x)
{
  return mod289(((x*34.0)+1.0)*x);
}

vec4 taylorInvSqrt(vec4 r)
{
  return 1.79284291400159 - 0.85373472095314 * r;
}

vec4 fade(vec4 t) {
  return t*t*t*(t*(t*6.0-15.0)+10.0);
}

// Classic Perlin noise
float cnoise4D(vec4 P)
{
  vec4 Pi0 = floor(P); // Integer part for indexing
  vec4 Pi1 = Pi0 + 1.0; // Integer part + 1
  Pi0 = mod289(Pi0);
  Pi1 = mod289(Pi1);
  vec4 Pf0 = fract(P); // Fractional part for interpolation
  vec4 Pf1 = Pf0 - 1.0; // Fractional part - 1.0
  vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
  vec4 iy = vec4(Pi0.yy, Pi1.yy);
  vec4 iz0 = vec4(Pi0.zzzz);
  vec4 iz1 = vec4(Pi1.zzzz);
  vec4 iw0 = vec4(Pi0.wwww);
  vec4 iw1 = vec4(Pi1.wwww);

  vec4 ixy = permute(permute(ix) + iy);
  vec4 ixy0 = permute(ixy + iz0);
  vec4 ixy1 = permute(ixy + iz1);
  vec4 ixy00 = permute(ixy0 + iw0);
  vec4 ixy01 = permute(ixy0 + iw1);
  vec4 ixy10 = permute(ixy1 + iw0);
  vec4 ixy11 = permute(ixy1 + iw1);

  vec4 gx00 = ixy00 * (1.0 / 7.0);
  vec4 gy00 = floor(gx00) * (1.0 / 7.0);
  vec4 gz00 = floor(gy00) * (1.0 / 6.0);
  gx00 = fract(gx00) - 0.5;
  gy00 = fract(gy00) - 0.5;
  gz00 = fract(gz00) - 0.5;
  vec4 gw00 = vec4(0.75) - abs(gx00) - abs(gy00) - abs(gz00);
  vec4 sw00 = step(gw00, vec4(0.0));
  gx00 -= sw00 * (step(0.0, gx00) - 0.5);
  gy00 -= sw00 * (step(0.0, gy00) - 0.5);

  vec4 gx01 = ixy01 * (1.0 / 7.0);
  vec4 gy01 = floor(gx01) * (1.0 / 7.0);
  vec4 gz01 = floor(gy01) * (1.0 / 6.0);
  gx01 = fract(gx01) - 0.5;
  gy01 = fract(gy01) - 0.5;
  gz01 = fract(gz01) - 0.5;
  vec4 gw01 = vec4(0.75) - abs(gx01) - abs(gy01) - abs(gz01);
  vec4 sw01 = step(gw01, vec4(0.0));
  gx01 -= sw01 * (step(0.0, gx01) - 0.5);
  gy01 -= sw01 * (step(0.0, gy01) - 0.5);

  vec4 gx10 = ixy10 * (1.0 / 7.0);
  vec4 gy10 = floor(gx10) * (1.0 / 7.0);
  vec4 gz10 = floor(gy10) * (1.0 / 6.0);
  gx10 = fract(gx10) - 0.5;
  gy10 = fract(gy10) - 0.5;
  gz10 = fract(gz10) - 0.5;
  vec4 gw10 = vec4(0.75) - abs(gx10) - abs(gy10) - abs(gz10);
  vec4 sw10 = step(gw10, vec4(0.0));
  gx10 -= sw10 * (step(0.0, gx10) - 0.5);
  gy10 -= sw10 * (step(0.0, gy10) - 0.5);

  vec4 gx11 = ixy11 * (1.0 / 7.0);
  vec4 gy11 = floor(gx11) * (1.0 / 7.0);
  vec4 gz11 = floor(gy11) * (1.0 / 6.0);
  gx11 = fract(gx11) - 0.5;
  gy11 = fract(gy11) - 0.5;
  gz11 = fract(gz11) - 0.5;
  vec4 gw11 = vec4(0.75) - abs(gx11) - abs(gy11) - abs(gz11);
  vec4 sw11 = step(gw11, vec4(0.0));
  gx11 -= sw11 * (step(0.0, gx11) - 0.5);
  gy11 -= sw11 * (step(0.0, gy11) - 0.5);

  vec4 g0000 = vec4(gx00.x,gy00.x,gz00.x,gw00.x);
  vec4 g1000 = vec4(gx00.y,gy00.y,gz00.y,gw00.y);
  vec4 g0100 = vec4(gx00.z,gy00.z,gz00.z,gw00.z);
  vec4 g1100 = vec4(gx00.w,gy00.w,gz00.w,gw00.w);
  vec4 g0010 = vec4(gx10.x,gy10.x,gz10.x,gw10.x);
  vec4 g1010 = vec4(gx10.y,gy10.y,gz10.y,gw10.y);
  vec4 g0110 = vec4(gx10.z,gy10.z,gz10.z,gw10.z);
  vec4 g1110 = vec4(gx10.w,gy10.w,gz10.w,gw10.w);
  vec4 g0001 = vec4(gx01.x,gy01.x,gz01.x,gw01.x);
  vec4 g1001 = vec4(gx01.y,gy01.y,gz01.y,gw01.y);
  vec4 g0101 = vec4(gx01.z,gy01.z,gz01.z,gw01.z);
  vec4 g1101 = vec4(gx01.w,gy01.w,gz01.w,gw01.w);
  vec4 g0011 = vec4(gx11.x,gy11.x,gz11.x,gw11.x);
  vec4 g1011 = vec4(gx11.y,gy11.y,gz11.y,gw11.y);
  vec4 g0111 = vec4(gx11.z,gy11.z,gz11.z,gw11.z);
  vec4 g1111 = vec4(gx11.w,gy11.w,gz11.w,gw11.w);

  vec4 norm00 = taylorInvSqrt(vec4(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100)));
  g0000 *= norm00.x;
  g0100 *= norm00.y;
  g1000 *= norm00.z;
  g1100 *= norm00.w;

  vec4 norm01 = taylorInvSqrt(vec4(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101)));
  g0001 *= norm01.x;
  g0101 *= norm01.y;
  g1001 *= norm01.z;
  g1101 *= norm01.w;

  vec4 norm10 = taylorInvSqrt(vec4(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110)));
  g0010 *= norm10.x;
  g0110 *= norm10.y;
  g1010 *= norm10.z;
  g1110 *= norm10.w;

  vec4 norm11 = taylorInvSqrt(vec4(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111)));
  g0011 *= norm11.x;
  g0111 *= norm11.y;
  g1011 *= norm11.z;
  g1111 *= norm11.w;

  float n0000 = dot(g0000, Pf0);
  float n1000 = dot(g1000, vec4(Pf1.x, Pf0.yzw));
  float n0100 = dot(g0100, vec4(Pf0.x, Pf1.y, Pf0.zw));
  float n1100 = dot(g1100, vec4(Pf1.xy, Pf0.zw));
  float n0010 = dot(g0010, vec4(Pf0.xy, Pf1.z, Pf0.w));
  float n1010 = dot(g1010, vec4(Pf1.x, Pf0.y, Pf1.z, Pf0.w));
  float n0110 = dot(g0110, vec4(Pf0.x, Pf1.yz, Pf0.w));
  float n1110 = dot(g1110, vec4(Pf1.xyz, Pf0.w));
  float n0001 = dot(g0001, vec4(Pf0.xyz, Pf1.w));
  float n1001 = dot(g1001, vec4(Pf1.x, Pf0.yz, Pf1.w));
  float n0101 = dot(g0101, vec4(Pf0.x, Pf1.y, Pf0.z, Pf1.w));
  float n1101 = dot(g1101, vec4(Pf1.xy, Pf0.z, Pf1.w));
  float n0011 = dot(g0011, vec4(Pf0.xy, Pf1.zw));
  float n1011 = dot(g1011, vec4(Pf1.x, Pf0.y, Pf1.zw));
  float n0111 = dot(g0111, vec4(Pf0.x, Pf1.yzw));
  float n1111 = dot(g1111, Pf1);

  vec4 fade_xyzw = fade(Pf0);
  vec4 n_0w = mix(vec4(n0000, n1000, n0100, n1100), vec4(n0001, n1001, n0101, n1101), fade_xyzw.w);
  vec4 n_1w = mix(vec4(n0010, n1010, n0110, n1110), vec4(n0011, n1011, n0111, n1111), fade_xyzw.w);
  vec4 n_zw = mix(n_0w, n_1w, fade_xyzw.z);
  vec2 n_yzw = mix(n_zw.xy, n_zw.zw, fade_xyzw.y);
  float n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x);
  return 2.2 * n_xyzw;
}




/// copilot 4d simplex:

// Permutation polynomial: (34x + 1) * x mod 289
vec4 permute_(vec4 x) {
    return mod(((x * 34.0) + 1.0) * x, 289.0);
}

// Taylor‐approximation of inverse square root
vec4 taylorInvSqrt_(vec4 r) {
    return 1.79284291400159 - 0.85373472095314 * r;
}

// Taylor‐approximation of inverse square root (scalar version)
float taylorInvSqrt__(float r) {
    return 1.79284291400159 - 0.85373472095314 * r;
}


// 4D dot product helper
float dot4(vec4 v1, vec4 v2) {
    return dot(v1, v2);
}


float noise4D(vec4 v) {
    // Skewing/Unskewing factors for 4D simplex grid
    const float F4 = 0.309016994374947;  // (sqrt(5)-1)/4
    const float G4 = 0.138196601125011;  // (5-sqrt(5))/20

    // Skew the input space to determine which cell of 4-simplex we’re in
    float s = dot(v, vec4(F4));
    vec4 i = floor(v + s);
    float t = dot(i, vec4(G4));
    vec4 X0 = i - t;             // Unskew back to x,y,z,w space
    vec4 x0 = v - X0;            // The x,y,z,w distances from cell origin

    // Rank sorting x0 components to find simplex corner indices
    /*
    vec3 rank_ = vec3(0.0);
    rank_ += step(x0.yzw, x0.xxx);
    rank_ += step(x0.zww, x0.yyy);
    rank_ += step(x0.www, x0.zzz);
    vec4 rank = vec4(rank_,0.0);
    */
vec4 rank = vec4(
    step(x0.y, x0.x) + step(x0.z, x0.x) + step(x0.w, x0.x),
    step(x0.z, x0.y) + step(x0.w, x0.y) + step(x0.x, x0.y),
    step(x0.w, x0.z) + step(x0.x, x0.z) + step(x0.y, x0.z),
    step(x0.x, x0.w) + step(x0.y, x0.w) + step(x0.z, x0.w)
);


/*
    vec4 i1 = step(vec4(2.0), rank);
    vec4 i2 = step(vec4(1.0), rank) - i1;
    //vec4 i3 = step(vec4(0.0), rank) - step(vec4(-1.0), rank);
    vec4 i3 = step(vec4(0.0), rank) - i1 - i2;
    */
vec4 i1 = step(vec4(3.0), rank);
vec4 i2 = step(vec4(2.0), rank);
vec4 i3 = step(vec4(1.0), rank);

    // Offsets for the remaining corners
    vec4 x1 = x0 - i1 + G4;
    vec4 x2 = x0 - i2 + 2.0 * G4;
    vec4 x3 = x0 - i3 + 3.0 * G4;
    vec4 x4 = x0 - 1.0 + 4.0 * G4;

    // Permutation to generate pseudo-random gradients
    vec4 j0 = permute_(permute_(permute_(permute_(
                 i.w + vec4(0.0, i1.w, i2.w, i3.w))
               + i.z + vec4(0.0, i1.z, i2.z, i3.z))
               + i.y + vec4(0.0, i1.y, i2.y, i3.y))
               + i.x + vec4(0.0, i1.x, i2.x, i3.x));

    vec4 j1 = permute_(j0 + 1.0);
    vec4 j2 = permute_(j0 + 2.0);
    vec4 j3 = permute_(j0 + 3.0);
    vec4 j4 = permute_(j0 + 4.0);

    // Gradients: pseudo-random unit 4D vectors via hashing
    vec4 ip = vec4(0.0, 0.5, 1.0, 1.5);
    vec4 p0 = fract(j0 * (1.0 / 41.0)) * 2.0 - 1.0;
    vec4 p1 = fract(j1 * (1.0 / 41.0)) * 2.0 - 1.0;
    vec4 p2 = fract(j2 * (1.0 / 41.0)) * 2.0 - 1.0;
    vec4 p3 = fract(j3 * (1.0 / 41.0)) * 2.0 - 1.0;
    vec4 p4 = fract(j4 * (1.0 / 41.0)) * 2.0 - 1.0;

    // Normalize gradients with approximate inverse sqrt
    vec4 norm0 = taylorInvSqrt(vec4(dot4(p0,p0), dot4(p1,p1), dot4(p2,p2), dot4(p3,p3)));
    p0 *= norm0.x; p1 *= norm0.y; p2 *= norm0.z; p3 *= norm0.w;
    float norm4 = taylorInvSqrt__(dot(p4,p4));
    p4 *= norm4;

    // Contribution calculations
    float m0 = max(0.65 - dot4(x0,x0), 0.0);
    float m1 = max(0.65 - dot4(x1,x1), 0.0);
    float m2 = max(0.65 - dot4(x2,x2), 0.0);
    float m3 = max(0.65 - dot4(x3,x3), 0.0);
    float m4 = max(0.65 - dot4(x4,x4), 0.0);

    m0 = m0 * m0 * m0 * m0;
    m1 = m1 * m1 * m1 * m1;
    m2 = m2 * m2 * m2 * m2;
    m3 = m3 * m3 * m3 * m3;
    m4 = m4 * m4 * m4 * m4;

    float n0 = m0 * dot4(p0, x0);
    float n1 = m1 * dot4(p1, x1);
    float n2 = m2 * dot4(p2, x2);
    float n3 = m3 * dot4(p3, x3);
    float n4 = m4 * dot4(p4, x4);

    // Sum up and scale the result to cover the range [-1,1]
    float res = 27.0 * (n0 + n1 + n2 + n3 + n4);
    return (1.0+res)/2.0;
}















//
// Description : Array and textureless GLSL 2D/3D/4D simplex 
//               noise functions.
//      Author : Ian McEwan, Ashima Arts.
//  Maintainer : stegu
//     Lastmod : 20110822 (ijm)
//     License : Copyright (C) 2011 Ashima Arts. All rights reserved.
//               Distributed under the MIT License. See LICENSE file.
//               https://github.com/ashima/webgl-noise
//               https://github.com/stegu/webgl-noise
// 

vec4 mod289x(vec4 x) {
  return x - floor(x * (1.0 / 289.0)) * 289.0; }

float mod289x(float x) {
  return x - floor(x * (1.0 / 289.0)) * 289.0; }

vec4 permutex(vec4 x) {
     return mod289(((x*34.0)+10.0)*x);
}

float permutex(float x) {
     return mod289x(((x*34.0)+10.0)*x);
}

vec4 taylorInvSqrtx(vec4 r)
{
  return 1.79284291400159 - 0.85373472095314 * r;
}

float taylorInvSqrtx(float r)
{
  return 1.79284291400159 - 0.85373472095314 * r;
}

vec4 grad4(float j, vec4 ip)
  {
  const vec4 ones = vec4(1.0, 1.0, 1.0, -1.0);
  vec4 p,s;

  p.xyz = floor( fract (vec3(j) * ip.xyz) * 7.0) * ip.z - 1.0;
  p.w = 1.5 - dot(abs(p.xyz), ones.xyz);
  s = vec4(lessThan(p, vec4(0.0)));
  p.xyz = p.xyz + (s.xyz*2.0 - 1.0) * s.www; 

  return p;
  }
						
// (sqrt(5) - 1)/4 = F4, used once below
#define F4 0.309016994374947451

float snoise(vec4 v)
  {
  const vec4  C = vec4( 0.138196601125011,  // (5 - sqrt(5))/20  G4
                        0.276393202250021,  // 2 * G4
                        0.414589803375032,  // 3 * G4
                       -0.447213595499958); // -1 + 4 * G4

// First corner
  vec4 i  = floor(v + dot(v, vec4(F4)) );
  vec4 x0 = v -   i + dot(i, C.xxxx);

// Other corners

// Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI)
  vec4 i0;
  vec3 isX = step( x0.yzw, x0.xxx );
  vec3 isYZ = step( x0.zww, x0.yyz );
//  i0.x = dot( isX, vec3( 1.0 ) );
  i0.x = isX.x + isX.y + isX.z;
  i0.yzw = 1.0 - isX;
//  i0.y += dot( isYZ.xy, vec2( 1.0 ) );
  i0.y += isYZ.x + isYZ.y;
  i0.zw += 1.0 - isYZ.xy;
  i0.z += isYZ.z;
  i0.w += 1.0 - isYZ.z;

  // i0 now contains the unique values 0,1,2,3 in each channel
  vec4 i3 = clamp( i0, 0.0, 1.0 );
  vec4 i2 = clamp( i0-1.0, 0.0, 1.0 );
  vec4 i1 = clamp( i0-2.0, 0.0, 1.0 );

  //  x0 = x0 - 0.0 + 0.0 * C.xxxx
  //  x1 = x0 - i1  + 1.0 * C.xxxx
  //  x2 = x0 - i2  + 2.0 * C.xxxx
  //  x3 = x0 - i3  + 3.0 * C.xxxx
  //  x4 = x0 - 1.0 + 4.0 * C.xxxx
  vec4 x1 = x0 - i1 + C.xxxx;
  vec4 x2 = x0 - i2 + C.yyyy;
  vec4 x3 = x0 - i3 + C.zzzz;
  vec4 x4 = x0 + C.wwww;

// Permutations
  i = mod289(i); 
  float j0 = permutex( permutex( permutex( permutex(i.w) + i.z) + i.y) + i.x);
  vec4 j1 = permutex( permutex( permutex( permutex (
             i.w + vec4(i1.w, i2.w, i3.w, 1.0 ))
           + i.z + vec4(i1.z, i2.z, i3.z, 1.0 ))
           + i.y + vec4(i1.y, i2.y, i3.y, 1.0 ))
           + i.x + vec4(i1.x, i2.x, i3.x, 1.0 ));

// Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope
// 7*7*6 = 294, which is close to the ring size 17*17 = 289.
  vec4 ip = vec4(1.0/294.0, 1.0/49.0, 1.0/7.0, 0.0) ;

  vec4 p0 = grad4(j0,   ip);
  vec4 p1 = grad4(j1.x, ip);
  vec4 p2 = grad4(j1.y, ip);
  vec4 p3 = grad4(j1.z, ip);
  vec4 p4 = grad4(j1.w, ip);

// Normalise gradients
  vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
  p0 *= norm.x;
  p1 *= norm.y;
  p2 *= norm.z;
  p3 *= norm.w;
  p4 *= taylorInvSqrtx(dot(p4,p4));

// Mix contributions from the five corners
  vec3 m0 = max(0.57 - vec3(dot(x0,x0), dot(x1,x1), dot(x2,x2)), 0.0);
  vec2 m1 = max(0.57 - vec2(dot(x3,x3), dot(x4,x4)            ), 0.0);
  m0 = m0 * m0;
  m1 = m1 * m1;
  return 60.1 * ( dot(m0*m0, vec3( dot( p0, x0 ), dot( p1, x1 ), dot( p2, x2 )))
               + dot(m1*m1, vec2( dot( p3, x3 ), dot( p4, x4 ) ) ) ) ;

  }


















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(1);
    //base = 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;

float globallight = 0.0;

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



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

    
    float testvalue1=2.5/1.1825;//1.0;
    float testvalue2=4.0*10.0;
    float width = widths[i]/2.0*testvalue2;
    float height = heights[i]/2.0*testvalue2;

    
    vec3 lightpos;
    lightpos.x=lightsPosx[i]*testvalue1;
    lightpos.y=lightsPosy[i];// *testvalue1;
    lightpos.z=lightsPosz[i]*testvalue1;

    vec3 campos=camPos*20.0;
    campos.y=-campos.y;
    lightpos-=campos;//argh

    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;

    globallight+=colorspecular.r;

    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(
                                        -((nearestSpec2D.x+width)/2.0/width)*scale,
                                        -(nearestSpec2D.y+height)/2.0/height*scale
                                        )
                                   ).b;
          aspecular += colorspecular * specattenuation * specFactor * specAngle;
        }

        lightVec=L;
        
        
        distSqr = dot(lightVec, lightVec);
        float boost=0.15;//1.0;
        if (i==0) boost = 4.0;
        if (i==3) boost = 4.0/3.3;
        ///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 * 2.8;
        
    }

    
	aambient=colorambient;
	
}
globallight/=9.0;
    
    



    /*

    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;
    ///if (false)
    //for (int i=0; i<NUMLIGHTS; i++) 

    for (int i=0; i<1; 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);
    */





    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.0;
    float shadowdistance;
    float shadowCount = 0.0;
    for (int i=0; i<1; i++) 
    {
        //vec4 LightsPos_=LightsPos[i]*testvalue;

        shadowCount+=1.0;



        float biasx=bias*1.4;
        float visibility = 1.0f;
        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;

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









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

        if (forcevalue)
        {
            if (inshadow)
            {
                visibility=shadowvalue;
                projectorColor=vec4(0.0f,0.0f,0.0f,1.0f);
            } else {
                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=pCoos.y/2.0f;
            pCoos.y=clamp(pCoos.y,0.01f,0.49f);
            pCoos.x=clamp(pCoos.x,0.01f,0.99f);
            

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

        totalprojectorColor+=projectorColor;



        
        



        
        

        

        
        

        

        
        
        
        
        
        

        
        //if (r>=SPOTR-SPOTFALLOFF) visibility=1.0;
        //if (r>=testvalue) visibility=1.0;
        totalvisibility+=visibility;
        

        
        
        
    }
	
       
        
    

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





















    vec4 totaldiffuse;
    vec4 totalspecular;

    if (false){
        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 test=0; test<2; test++)
        for (float i_=9; i_<99; i_+=0.5)
           {
            int i = int(i_);
            bool frct=true;
            if (i==i_) frct=false;
            float x,y,z,r,lightsSpecularr,lightsSpecularg,lightsSpecularb,lightsDiffuser,lightsDiffuseg,lightsDiffuseb;
            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 xa = uintBitsToFloat(intx);
            uint inty = (y1 << 24) | (y2 << 16) | (y3 << 8) | y4;
            float ya = uintBitsToFloat(inty);
            uint intz = (z1 << 24) | (z2 << 16) | (z3 << 8) | z4;
            float za = 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 ra = uintBitsToFloat(intr);
            
            float lightsDiffusera=texture2D(normalMap,vec2(float(i*18+12)*(1.0/2048.0),0.0)).r;
            float lightsDiffusega=texture2D(normalMap,vec2(float(i*18+13)*(1.0/2048.0),0.0)).r;
            float lightsDiffuseba=texture2D(normalMap,vec2(float(i*18+14)*(1.0/2048.0),0.0)).r;
            float lightsSpecularra=texture2D(normalMap,vec2(float(i*18+15)*(1.0/2048.0),0.0)).r;
            float lightsSpecularga=texture2D(normalMap,vec2(float(i*18+16)*(1.0/2048.0),0.0)).r;
            float lightsSpecularba=texture2D(normalMap,vec2(float(i*18+17)*(1.0/2048.0),0.0)).r;

            {
                i+=1;
                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 xb = uintBitsToFloat(intx);
                uint inty = (y1 << 24) | (y2 << 16) | (y3 << 8) | y4;
                float yb = uintBitsToFloat(inty);
                uint intz = (z1 << 24) | (z2 << 16) | (z3 << 8) | z4;
                float zb = 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 rb = uintBitsToFloat(intr);
            
                float lightsDiffuserb=texture2D(normalMap,vec2(float(i*18+12)*(1.0/2048.0),0.0)).r;
                float lightsDiffusegb=texture2D(normalMap,vec2(float(i*18+13)*(1.0/2048.0),0.0)).r;
                float lightsDiffusebb=texture2D(normalMap,vec2(float(i*18+14)*(1.0/2048.0),0.0)).r;
                float lightsSpecularrb=texture2D(normalMap,vec2(float(i*18+15)*(1.0/2048.0),0.0)).r;
                float lightsSpeculargb=texture2D(normalMap,vec2(float(i*18+16)*(1.0/2048.0),0.0)).r;
                float lightsSpecularbb=texture2D(normalMap,vec2(float(i*18+17)*(1.0/2048.0),0.0)).r;
                i-=1;

                if (lightsSpecularra==lightsSpecularrb&&lightsSpecularga==lightsSpeculargb&&lightsSpecularba==lightsSpecularbb&&frct)
                {
                    x=(xa+xb)/2.0;
                    y=(ya+yb)/2.0;
                    z=(za+zb)/2.0;
                    r=(ra+rb)/2.0;
                    lightsDiffuser=(lightsDiffusera+lightsDiffuserb)/2.0;
                    lightsDiffuseg=(lightsDiffusega+lightsDiffusegb)/2.0;
                    lightsDiffuseb=(lightsDiffuseba+lightsDiffusebb)/2.0;
                    lightsSpecularr=(lightsSpecularra+lightsSpecularrb)/2.0;
                    lightsSpecularg=(lightsSpecularga+lightsSpeculargb)/2.0;
                    lightsSpecularb=(lightsSpecularba+lightsSpecularbb)/2.0;
                } else {
                    x=xa;
                    y=ya;
                    z=za;
                    r=ra;
                    lightsDiffuser=lightsDiffusera;
                    lightsDiffuseg=lightsDiffusega;
                    lightsDiffuseb=lightsDiffuseba;
                    lightsSpecularr=lightsSpecularra;
                    lightsSpecularg=lightsSpecularga;
                    lightsSpecularb=lightsSpecularba;
                }
            }
	        //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);
	        //att = clamp(1.0 - lightsinvRadius[i] * sqrt(distSqr), 0.0, 1.0);
            att = clamp(1.0 - (1.0f / (3.32*1.0) * 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);

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

            float dim=2.0f*1.7f*1.4f;

	        ///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.0f *att/0.7f   /1.5f/dim * r;
	        }
           }
	        //gl_FragColor = ( vAmbient*base + accvDiffuse*base + accvSpecular) * att;
	        //gl_FragColor = ( vAmbient*base + accvDiffuse*base + accvSpecular);
            float daboost=10.0f/1.8f;
            totaldiffuse=accvDiffuse*daboost;
            totalspecular=accvSpecular*daboost;
    }








        






    

    


    vec3 I = normalize(v - camPos);
    vec3 R = refract(I, normalize(N_),1.0/0.98);
    vec4 fx = vec4(0.5,0.5,0.5,1);//vec4(texture(colorMap, R).rgb, 1.0);

    v1=clamp(v1,0,1);
	
	aambient=vec4(0.15,0.18,0.31,1.0);
    
    //FragColor = ( aambient*base + adiffuse*base + totaldiffuse ) * v1 + aspecular;

    float iTime2=iTime;
    vec4 scroll = vec4(0,0,iTime2*4.0/0.79,0);
    vec3 originalV_=originalV/2.7*0.45;
    float noiseb=2.0*0.44;
    float noisea1 = (snoise(scroll/2.0+vec4(originalV_/1.33/1.0,iTime2*1.15)+vec4(23345)))/noiseb;
    float noisea2 = (snoise(scroll/2.0+vec4(originalV_/1.33/1.56,iTime2*1.25)+vec4(233451)))/noiseb;
    float noisea3 = (snoise(scroll/2.0+vec4(originalV_/1.33/1.33,iTime2*1.35)+vec4(4523)))/noiseb;
    base = vec4(snoise(scroll+vec4(originalV_,0.0)+vec4(noisea1,noisea2,noisea3,iTime2*1.25)+vec4(345)))/1.2;

    float iTime_=iTime2;// /testvalue;

    vec4 base4 = base-clamp(vec4(snoise(scroll/2.0+vec4(originalV_/0.5,iTime_*1.4)+vec4(12345))),0.0,1.0)*0.1*13.0;
    base4 += clamp(vec4(snoise(scroll/2.0+vec4(originalV_/0.55,iTime_*0.9)+vec4(1234))),0.0,1.0)*0.1*13.0/2.0;
    base=mix(base,base4,0.45);

    base += clamp(vec4(snoise(vec4(originalV_/3.5,iTime_*1.4)+vec4(1234))),0.0,0.2);
    base += clamp(vec4(snoise(vec4(originalV_/8.5,iTime_*1.7)+vec4(2345))),0.0,0.3);
    base = vec4(1.0)-base;
    base *= vec4(0.1,0.45,1.2,1.0);// *1.5/testvalue;
    base -= 0.2;
    base = clamp(base,0,1);
    //base/=1.1;
    //base*=(0.5+v1.x/2.0);
    //base+=aspecular/1.5;

    /*
    float dim = 0.7*1.5;
    float zoom=0.01;
    vec4 base2 = base;
    if (abs(originalV.x)<15.4) /// front mapper limits
        //base2 *= texture2D(colorMap, vec2(originalV.x,originalV.z)*zoom)*1.2;
        base2 *= texture2D(colorMap, vec2(texCoord))*1.2;
    if (abs(originalV.y)<6.22) /// side mapper limits
        base2 *= texture2D(colorMap, vec2(originalV.y,originalV.z)*zoom)*1.2;
    base=mix(base,base2,0.825);
    */

    base.a = 1.0;
    //vec4 FragColor_ = base * (0.5+v1/2.0) + aspecular/1.5;
    
    fx=mix(base+fx*(1.0f-base.b)/2.65,fx,0.36);
    fx*=0.88;
    fx*=clamp(globallight,0.5*1.3,1.0);
    fx.b*=1.75;
    fx.a=1.0;
    //fx+=vec4(0,0,sin(iTime*6.28),1);

    //fx = mix(FragColor_,fx,1.0-FragColor_.b);
    FragColor = fx;
    FragColor *= 0.5+v1/2.0;
    //FragColor += (aspecular+adiffuse);

    //FragColor = aspecular/1.5+adiffuse/9.0;
    FragColor.a = 1.0;
    FragColor.r-=0.05;

	vec3 cameyevector = (v-camPos);
    eyeVec = vec3(dot(-normalize(N_), normalize(cameyevector)));
	vVec=eyeVec;
	//float alpha = texture2D(lightMap, vec2(0.0,pow(float(clamp(vVec, 0.1, 0.98)),1.0)));
	float outline = (1.0-float(clamp(vVec,0.0,0.98)))*0.66*0.8;
    FragColor += outline;
    FragColor.a=1.0;
    float factor = 0.14;
    FragColor.rgb = clamp((FragColor.rgb - 0.5) * (1.0 + factor) + 0.5, 0.0, 1.0);

    float gradient = clamp((FragColor.r+FragColor.g+FragColor.b)/3.0,2.0/512.0,1.0-2.0/512.0);
    float f = 1.3; //testvalue;
    float s = 0.12;
    gradient=clamp((gradient-0.5)*f+0.5,2.0/512.0,1.0-2.0/512.0);
    vec4 ramp=texture2D(colorMap,vec2(gradient,0.5));
    float bw=(ramp.x+ramp.y+ramp.z)/3.0;
    FragColor=mix(ramp,vec4(bw,bw,bw,1),s);
    //FragColor = vec4(N,1.0)+(testvalue-1.0);

}
