1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
/**
* Outputs pre-convolved diffuse irradiance from an input radiance cubemap.
* Input radiance has its mipmaps updated so we can use filtered importance sampling.
* The output is a really small 6 directional basis similar to the ambient cube technique.
* Downside: very very low resolution (6 texels), bleed lighting because of interpolation.
*
* https://cdn.cloudflare.steamstatic.com/apps/valve/2006/SIGGRAPH06_Course_ShadingInValvesSourceEngine.pdf
*/
#pragma BLENDER_REQUIRE(eevee_irradiance_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_sampling_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_bsdf_sampling_lib.glsl)
void main()
{
int x = int(gl_FragCoord.x) % 3;
int y = int(gl_FragCoord.y) % 2;
vec3 N, T, B;
switch (x) {
default:
N = vec3(1.0, 0.0, 0.0);
break;
case 1:
N = vec3(0.0, 1.0, 0.0);
break;
case 2:
N = vec3(0.0, 0.0, 1.0);
break;
}
if (y == 1) {
N = -N;
}
make_orthonormal_basis(N, T, B);
/* Integrating Envmap. */
float weight = 0.0;
vec3 radiance = vec3(0.0);
for (float i = 0; i < filter_buf.sample_count; i++) {
vec3 Xi = sample_cylinder(hammersley_2d(i, filter_buf.sample_count));
float pdf;
vec3 L = sample_uniform_hemisphere(Xi, N, T, B, pdf);
float NL = dot(N, L);
if (NL > 0.0) {
/* Coarse Approximation of the mapping distortion.
* Unit Sphere -> Cubemap Face. */
const float dist = 4.0 * M_PI / 6.0;
/* http://http.developer.nvidia.com/GPUGems3/gpugems3_ch20.html : Equation 13 */
float lod = filter_buf.lod_bias - 0.5 * log2(pdf * dist);
radiance += textureLod(radiance_tx, L, lod).rgb * NL;
weight += NL;
}
}
out_irradiance = irradiance_encode(filter_buf.instensity_fac * radiance / weight);
}
|