Merge branch 'master' into blender2.8
[blender.git] / source / blender / draw / engines / eevee / shaders / lightprobe_filter_glossy_frag.glsl
1
2 uniform samplerCube probeHdr;
3 uniform float roughnessSquared;
4 uniform float texelSize;
5 uniform float lodFactor;
6 uniform float lodMax;
7 uniform float paddingSize;
8
9 in vec3 worldPosition;
10
11 out vec4 FragColor;
12
13 vec3 octahedral_to_cubemap_proj(vec2 co)
14 {
15         co = co * 2.0 - 1.0;
16
17         vec2 abs_co = abs(co);
18         vec3 v = vec3(co, 1.0 - (abs_co.x + abs_co.y));
19
20         if ( abs_co.x + abs_co.y > 1.0 ) {
21                 v.xy = (abs(co.yx) - 1.0) * -sign(co.xy);
22         }
23
24         return v;
25 }
26
27 void main() {
28         vec2 uvs = gl_FragCoord.xy * texelSize;
29
30         /* Add a N pixel border to ensure filtering is correct
31          * for N mipmap levels. */
32         uvs += uvs * texelSize * paddingSize * 2.0;
33         uvs -= texelSize * paddingSize;
34
35         /* edge mirroring : only mirror if directly adjacent
36          * (not diagonally adjacent) */
37         vec2 m = abs(uvs - 0.5) + 0.5;
38         vec2 f = floor(m);
39         if (f.x - f.y != 0.0) {
40                 uvs = 1.0 - uvs;
41         }
42
43         /* clamp to [0-1] */
44         uvs = fract(uvs);
45
46         /* get cubemap vector */
47         vec3 cubevec = octahedral_to_cubemap_proj(uvs);
48
49         vec3 N, T, B, V;
50
51         vec3 R = normalize(cubevec);
52
53         /* Isotropic assumption */
54         N = V = R;
55
56         make_orthonormal_basis(N, T, B); /* Generate tangent space */
57
58         /* Noise to dither the samples */
59         /* Note : ghosting is better looking than noise. */
60         // setup_noise();
61
62         /* Integrating Envmap */
63         float weight = 0.0;
64         vec3 out_radiance = vec3(0.0);
65         for (float i = 0; i < sampleCount; i++) {
66                 vec3 H = sample_ggx(i, roughnessSquared, N, T, B); /* Microfacet normal */
67                 vec3 L = -reflect(V, H);
68                 float NL = dot(N, L);
69
70                 if (NL > 0.0) {
71                         float NH = max(1e-8, dot(N, H)); /* cosTheta */
72
73                         /* Coarse Approximation of the mapping distortion
74                          * Unit Sphere -> Cubemap Face */
75                         const float dist = 4.0 * M_PI / 6.0;
76                         float pdf = pdf_ggx_reflect(NH, roughnessSquared);
77                         /* http://http.developer.nvidia.com/GPUGems3/gpugems3_ch20.html : Equation 13 */
78                         float lod = clamp(lodFactor - 0.5 * log2(pdf * dist), 0.0, lodMax) ;
79
80                         out_radiance += textureLod(probeHdr, L, lod).rgb * NL;
81                         weight += NL;
82                 }
83         }
84
85         FragColor = vec4(out_radiance / weight, 1.0);
86 }