     return color;
 }
 
+// SPHERE functions
+vec3 sphereNormal(vec2 uv) {
+    uv = fract(uv)*2.0-1.0; 
+    vec3 ret;
+    ret.xy = sqrt(uv * uv) * sign(uv);
+    ret.z = sqrt(abs(1.0 - dot(ret.xy,ret.xy)));
+    ret = ret * 0.5 + 0.5;    
+    return mix(vec3(0.0), ret, smoothstep(1.0,0.98,dot(uv,uv)) );
+}
+
+vec2 fishEye(vec2 _uv, float _aperture){
+    float apertureHalf = 0.5 * _aperture;
+    float maxFactor = sin(apertureHalf);
+    vec2 uv = vec2(0.0);
+    vec2 xy = 2.0 * _uv.xy - 1.0;
+    float d = length(xy);
+    if (d < (2.0-maxFactor)){
+        d = length(xy * maxFactor);
+        float z = sqrt(1.0 - d * d);
+        float r = atan(d, z) / PI;
+        float phi = atan(xy.y, xy.x);
+
+        uv.x = r * cos(phi) + 0.5;
+        uv.y = r * sin(phi) + 0.5;
+    } else {
+        uv = _uv.xy;
+    }
+    return uv;
+}
+
+// SCENE Definitions
+//---------------------------------------------------
+
 //  Light accumulator
-Light l; 
+Light l = Light(vec3(0.0),vec3(0.0),vec3(0.0)); 
 
 //  Material
 Material m = Material(Light(vec3(0.8),vec3(0.8),vec3(0.4)),vec3(0.0),20.0);
 
 // Lights
-PointLight a = PointLight(Light(vec3(0.1),vec3(0.0,0.0,1.0),vec3(0.0,1.0,1.0)),vec3(1.0));
-PointLight b = PointLight(Light(vec3(0.25),vec3(0.6,0.2,0.0),vec3(1.0,1.0,0.0)),vec3(1.0));
+PointLight a = PointLight(Light(vec3(0.1),vec3(0.0,0.5,0.8),vec3(0.0,1.0,1.0)),vec3(1.0));
+PointLight b = PointLight(Light(vec3(0.25),vec3(0.8,0.5,0.0),vec3(1.0,1.0,0.0)),vec3(1.0));
+
+// Edges
+float edgeRadius = 0.985;
+vec3 edgeColor = vec3(0.0);
+
 
 void main(){
     vec2 st = gl_FragCoord.xy/u_resolution.xy;
     vec3 color = vec3(0.0);
 
     vec3 normal = normalize(sphereNormal(st)*2.0-1.0);
+
+    if(u_tex0resolution != vec2(0.0)){
+        normal += texture2D(u_tex0, fishEye(st, PI)).rgb*2.0-1.0;
+        normal = normalize(normal);
+    }
     
     a.position = vec3(cos(u_time),0.0,sin(u_time))*4.0 ;
     computeLight(a,m,normal,l);

precision mediump float;
#endif

uniform vec2 u_resolution;
uniform float u_time;

vec3 sphereNormal(vec2 uv) {
    uv = fract(uv)*2.0-1.0; 
    vec3 ret;
    ret.xy = sqrt(uv * uv) * sign(uv);
    ret.z = sqrt(abs(1.0 - dot(ret.xy,ret.xy)));
    ret = ret * 0.5 + 0.5;    
    return mix(vec3(0.0), ret, smoothstep(1.0,0.98,dot(uv,uv)) );
}

struct Light { vec3 ambient, diffuse, specular; };
struct PointLight { Light emission; vec3 position; };
struct Material { Light bounce; vec3 emission; float shininess;};

    color = calculate(m,l);
  
    // turn black the area around the sphere;
    float radius = length( vec2(0.5)-st )*2.0;
    color = mix(color,edgeColor,smoothstep(edgeRadius,1.0,radius));
  
    gl_FragColor = vec4(color, 1.0);
}