3 precision mediump float;
5 const int kMaxLights = 32;
7 const float kAttenuationConst = .05f;
8 const float kAttenuationLinear = .1f;
9 const float kAttenuationQuadratic = .15f;
12 uniform sampler2D uTextureNormal;
13 uniform sampler2D uTexturePosition;
14 uniform sampler2D uTextureColor;
16 uniform mat4 uInvProjection;
17 uniform vec3 uDepth_InvDepth_Near;
19 #define DEPTH uDepth_InvDepth_Near.x
20 #define INV_DEPTH uDepth_InvDepth_Near.y
21 #define NEAR uDepth_InvDepth_Near.z
23 // Light source uniforms
26 vec3 position; // view space
31 uniform Light uLights[kMaxLights];
36 vec4 Unmap(vec4 m) // texture -> projection
38 m.w = m.w * DEPTH + NEAR;
39 m.xyz = (m.xyz - vec3(.5)) * (2.f * m.w);
43 vec3 CalculateLighting(vec3 pos, vec3 normal)
45 vec3 viewDir = normalize(pos);
46 vec3 viewDirRefl = -reflect(viewDir, normal);
48 vec3 light = vec3(0.04f); // fake ambient term
49 for (int i = 0; i < kMaxLights; ++i)
51 vec3 rel = pos - uLights[i].position;
52 float distance = length(rel);
55 float a = uLights[i].radius / (kAttenuationConst + kAttenuationLinear * distance +
56 kAttenuationQuadratic * distance * distance); // attenuation
58 float l = max(0.f, dot(normal, rel)); // lambertian
59 float s = pow(max(0.f, dot(viewDirRefl, rel)), 256.f); // specular
61 light += (uLights[i].color * (l + s)) * a;
69 vec3 normSample = texture(uTextureNormal, vUv).xyz;
70 if (dot(normSample, normSample) == 0.f)
72 discard; // if we didn't write this texel, don't bother lighting it.
75 vec3 normal = normalize(normSample - .5f);
77 vec4 posSample = texture(uTexturePosition, vUv);
78 vec3 pos = (uInvProjection * Unmap(posSample)).xyz;
80 vec3 color = texture(uTextureColor, vUv).rgb;
81 vec3 finalColor = color * CalculateLighting(pos, normal);
83 oColor = vec4(finalColor, 1.f);