#version 300 es
precision highp float;

uniform vec2  iResolution;

uniform vec3  diffuse;    // value=.75,0,0
uniform vec3  specular;   // value=.5,.5,.5
uniform vec3  ambient;    // value=0.1,0,0
uniform float shininess;  // value=16, min=0, max=100, step=0.001

in  vec2 vScreen;
out vec4 fragColor;

const float PI = 3.14159265359;

// https://www.shadertoy.com/view/4d2XWV by Inigo Quilez
float sphereIntersect(vec3 ro, vec3 rd, vec4 sph) {
	vec3 oc = ro - sph.xyz;
	float b = dot( oc, rd );
	float c = dot( oc, oc ) - sph.w*sph.w;
	float h = b*b - c;
	if( h<0.0 ) return -1.0;
	return -b - sqrt( h );
}

void main (){
    vec3 lightPos   = vec3(1.25, 1.0, -2);
    vec3 lightColor = vec3(1);
    vec3 totColor = vec3(0.0);
    
    vec3 ro = vec3(0.0, 0.0, -2.0);

    for (float x = 0.0; x <= 1.0; x += 1.) {
        for (float y = 0.0; y <= 1.0; y += 1.) {
            
            vec3 rd = normalize(vec3(vScreen + vec2(x, y) / iResolution.y, 1.2));
            float d = sphereIntersect(ro, rd, vec4(0,0,0,1));
            
            if (d > 0.) {
                vec3 worldPos = ro + d * rd;
                vec3 N = normalize (worldPos);
                vec3 V = -rd;
                vec3 L = normalize (lightPos - worldPos);
                vec3 H = normalize (V + L);
                
                // Blinn–Phong reflection model
                float spec      = pow(max(dot(H, N), 0.0), shininess);
                float diff      = max(dot(N, L), 0.0);
                float intensity = (1. / dot(lightPos - worldPos, lightPos - worldPos));
                
                vec3  color = pow(ambient, vec3(2.2)) +
                              lightColor * pow(diffuse, vec3(2.2))  * diff * intensity +
                              lightColor * pow(specular, vec3(2.2)) * spec * intensity;
                
                totColor += color;
            }
        }
    }
    
    // HDR tonemapping gamma correct
    fragColor = vec4(pow(totColor/(totColor + 1.0), vec3 (1.0/2.2)), 1.0);
}