         if (uShadowQuality == 3.0) {
             illuminated = PCF(uShadowMap, uShadowMapSize, lightUV, lightDistView - uBias);
         }
+        
+        float depth = readDepth(uShadowMap, lightUV);
+        float z = (lightDistView-uLightNear)/(uLightFar-uLightNear);
+        float z2 = (depth-uLightNear)/(uLightFar-uLightNear);
+
+        if (vPositionWorld.z > 0)
+            debugColor = hsv2rgb(vec3(z2, 1.0, 0.5));
+        else if (z < 0.0) 
+            debugColor = vec3(0.0);
+        else if (z > 1.0) 
+            debugColor = vec3(0.0);
+        else
+            debugColor = hsv2rgb(vec3(z, 1.0, 0.5));
+        /*debugColor = hsv2rgb(vec3(illuminated, 1.0, 0.5));*/
+        /*debugColor = hsv2rgb(vec3(step(lightDist, 8.0), 1.0, 0.5));*/
+        /*debugColor = hsv2rgb(vec3(step(-lightDistView, 10.0), 1.0, 0.5));*/
+        /*debugColor = vec3(lightUV, 0.0); */
     }
     
     //TODO: No kd? so not really energy conserving

    return mix(a, b, lod - upLod);
}

void main() {
    vec3 normalWorld = getNormal();
    vec3 eyeDirWorld = normalize(vEyeDirWorld);


//fron depth buf normalized z to linear (eye space) z
//http://stackoverflow.com/questions/6652253/getting-the-true-z-value-from-the-depth-buffer
float ndcDepthToEyeSpaceProj(float ndcDepth) {
    /*return ((ndcDepth + (uLightFar + uLightNear)/(uLightFar - uLightNear)) * (uLightFar - uLightNear))/2.0;*/
    return 2.0 * uLightNear * uLightFar / (uLightFar + uLightNear - ndcDepth * (uLightFar - uLightNear));
}

//otho
//z = (f - n) * (zn + (f + n)/(f-n))/2
//http://www.ogldev.org/www/tutorial47/tutorial47.html
float ndcDepthToEyeSpace(float ndcDepth) {
    return (uLightFar - uLightNear) * (ndcDepth + (uLightFar + uLightNear) / (uLightFar - uLightNear)) / 2;
}

float readDepth(sampler2D depthMap, vec2 coord) {
    float z_b = texture2D(depthMap, coord).r;
    float z_n = 2.0 * z_b - 1.0;
