+#version 330
+
+in vec3 localPos;
+out vec4 fragColor;
+
+uniform samplerCube environmentMap;
+
+const float PI = 3.14159265359;
+
+void main() {
+ // sample dir = hemisphere's orientation
+ vec3 normal = normalize(localPos);
+ vec3 irradiance = vec3(0);
+
+ vec3 up = vec3(0, 1, 0);
+ vec3 right = cross(up, normal);
+ up = cross(normal, right);
+
+ const float sampleDelta = 0.025;
+ float numSamples = 0;
+ for (float phi = 0; phi < 2 * PI; phi += sampleDelta) {
+ for (float theta = 0; theta < 0.5 * PI; theta += sampleDelta) {
+ vec3 tangentSample = vec3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta));
+ // tangent space -> world space
+ vec3 sampleVec = tangentSample.x * right + tangentSample.y * up + tangentSample.z * normal;
+ irradiance += texture(environmentMap, sampleVec).rgb * cos(theta) * sin(theta);
+ numSamples++;
+ }
+ }
+
+ irradiance = (PI * irradiance) / numSamples;
+
+ fragColor = vec4(irradiance, 1);
+}