precision highp float; #define PI 3.1415926535897932384626433832795 #define EPS 0.001 #define NUM_SAMPLES_AZIMUTH 250 #define NUM_SAMPLES_ZENITH 50 #define MAX_AZIMUTH (2*PI) #define MAX_ZENITH (PI/2.0) #define AZIMUTH_DELTA (MAX_AZIMUTH / float(NUM_SAMPLES_AZIMUTH)) #define ZENITH_DELTA (MAX_ZENITH / float(NUM_SAMPLES_ZENITH)) uniform samplerCube Sky; in vec3 Ray; // DEBUG // in vec2 Texcoord; layout (location = 0) out vec4 Color; void main() { // Tangent space: // // N // | // | // | // |_ _ _ _ _ B // / // / // T vec3 N = normalize(Ray); vec3 B = (abs(N.x) - 1.0 <= EPS) ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); vec3 T = normalize(cross(B, N)); B = normalize(cross(N, T)); int num_samples = 0; vec3 irradiance = vec3(0.0); for (float theta = 0.0; theta < MAX_AZIMUTH; theta += AZIMUTH_DELTA) { for (float phi = 0.0; phi < MAX_ZENITH; phi += ZENITH_DELTA) { // Spherical to Cartesian. vec3 sample_tangent_space = vec3( sin(phi) * cos(theta), sin(phi) * sin(theta), cos(phi)); // Tangent space to world space. vec3 sample_world_space = sample_tangent_space.x * B + sample_tangent_space.y * T + sample_tangent_space.z * N; irradiance += texture(Sky, sample_world_space).rgb * sin(phi) * cos(phi); num_samples += 1; } } irradiance = PI * irradiance / float(num_samples); // For debugging in trace. //irradiance = texture(Sky, Ray).rgb; // irradiance = vec3(Texcoord, 0.0); //irradiance = pow(irradiance, vec3(1.0/2.2)); Color = vec4(irradiance, 1.0); }