     norm = vec3(dir.x, dir.y, -dir.z);
   }
 
-  vec3 irradiance = textureLod(environment_map, norm, num_levels - 1.5).rgb;
+  vec3 irradiance = vec3(0.0, 0.0, 0.0);
+  const float m = 0.5;
+  float step = 2 * m;
+  for(float x = -m; x <= m; x += step) {
+      for(float y = -m; y <= m; y += step) {
+        for(float z = -m; z <= m; z += step) {
+            const mat3 rotx = rotate(vec3(1.0, 0.0, 0.0), x);
+            const mat3 roty = rotate(vec3(0.0, 1.0, 0.0), y);
+            const mat3 rotz = rotate(vec3(0.0, 0.0, 1.0), z);
+            irradiance += textureLod(environment_map, rotx * roty * rotz * norm, num_levels - 1.5).rgb;
+          }
+      }
+  }
+  irradiance /= 8.0;
 
   vec3 albedo = texture(environment_albedo_map, dir).rgb;
 

uniform samplerCube environment_map;
uniform samplerCube environment_albedo_map;
uniform int side;

void main() {
  vec2 environment_texture_size = textureSize(environment_map, 0);


  vec3 pass0 = texture(environment_map, dir).rgb;

  //TODO: 0.25 factor is not scientific. Attenuation?
  color = vec4(diffuse_environment * 0.25 + pass0, 1.0);
}
