summaryrefslogtreecommitdiff
path: root/gfx/shaders/irradiance_map.frag
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/shaders/irradiance_map.frag')
-rw-r--r--gfx/shaders/irradiance_map.frag60
1 files changed, 60 insertions, 0 deletions
diff --git a/gfx/shaders/irradiance_map.frag b/gfx/shaders/irradiance_map.frag
new file mode 100644
index 0000000..3cfe5b2
--- /dev/null
+++ b/gfx/shaders/irradiance_map.frag
@@ -0,0 +1,60 @@
1precision highp float;
2
3#define PI 3.1415926535897932384626433832795
4#define EPS 0.001
5#define NUM_SAMPLES_AZIMUTH 250
6#define NUM_SAMPLES_ZENITH 50
7#define MAX_AZIMUTH (2*PI)
8#define MAX_ZENITH (PI/2.0)
9#define AZIMUTH_DELTA (MAX_AZIMUTH / float(NUM_SAMPLES_AZIMUTH))
10#define ZENITH_DELTA (MAX_ZENITH / float(NUM_SAMPLES_ZENITH))
11
12uniform samplerCube Sky;
13
14in vec3 Ray;
15
16layout (location = 0) out vec4 Color;
17
18void main()
19{
20 // Tangent space:
21 //
22 // N
23 // |
24 // |
25 // |
26 // |_ _ _ _ _ B
27 // /
28 // /
29 // T
30 vec3 N = normalize(Ray);
31 vec3 B = (abs(N.x) - 1.0 <= EPS) ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
32 vec3 T = cross(B, N);
33 B = cross(N, T);
34
35 int num_samples = 0;
36 vec3 irradiance = vec3(0.0);
37 for (float theta = 0.0; theta < MAX_AZIMUTH; theta += AZIMUTH_DELTA) {
38 for (float phi = 0.0; phi < MAX_ZENITH; phi += ZENITH_DELTA) {
39 // Spherical to Cartesian.
40 vec3 sample_tangent_space = vec3(
41 sin(phi) * cos(theta),
42 sin(phi) * sin(theta),
43 cos(phi));
44 // Tangent space to world space.
45 vec3 sample_world_space =
46 sample_tangent_space.x * B +
47 sample_tangent_space.y * T +
48 sample_tangent_space.z * N;
49
50 irradiance += texture(Sky, sample_world_space).rgb * sin(phi) * cos(phi);
51 num_samples += 1;
52 }
53 }
54 irradiance = PI * irradiance / float(num_samples);
55
56 // For debugging in trace.
57 //irradiance = pow(irradiance, vec3(1.0/2.2));
58
59 Color = vec4(irradiance, 1.0);
60}