Fix T64158 Eevee: Mixed SSS shader becomes brighter and brighter
[blender.git] / source / blender / draw / engines / eevee / shaders / bsdf_common_lib.glsl
1
2 #define M_PI 3.14159265358979323846     /* pi */
3 #define M_2PI 6.28318530717958647692    /* 2*pi */
4 #define M_PI_2 1.57079632679489661923   /* pi/2 */
5 #define M_1_PI 0.318309886183790671538  /* 1/pi */
6 #define M_1_2PI 0.159154943091895335768 /* 1/(2*pi) */
7 #define M_1_PI2 0.101321183642337771443 /* 1/(pi^2) */
8
9 #define LUT_SIZE 64
10
11 /* Buffers */
12 uniform sampler2D colorBuffer;
13 uniform sampler2D depthBuffer;
14 uniform sampler2D maxzBuffer;
15 uniform sampler2D minzBuffer;
16 uniform sampler2DArray planarDepth;
17
18 #define cameraForward ViewMatrixInverse[2].xyz
19 #define cameraPos ViewMatrixInverse[3].xyz
20 #define cameraVec \
21   ((ProjectionMatrix[3][3] == 0.0) ? normalize(cameraPos - worldPosition) : cameraForward)
22 #define viewCameraVec \
23   ((ProjectionMatrix[3][3] == 0.0) ? normalize(-viewPosition) : vec3(0.0, 0.0, 1.0))
24
25 /* ------- Structures -------- */
26
27 /* ------ Lights ----- */
28 struct LightData {
29   vec4 position_influence;     /* w : InfluenceRadius (inversed and squared) */
30   vec4 color_spec;             /* w : Spec Intensity */
31   vec4 spotdata_radius_shadow; /* x : spot size, y : spot blend, z : radius, w: shadow id */
32   vec4 rightvec_sizex;         /* xyz: Normalized up vector, w: area size X or spot scale X */
33   vec4 upvec_sizey;            /* xyz: Normalized right vector, w: area size Y or spot scale Y */
34   vec4 forwardvec_type;        /* xyz: Normalized forward vector, w: Light Type */
35 };
36
37 /* convenience aliases */
38 #define l_color color_spec.rgb
39 #define l_spec color_spec.a
40 #define l_position position_influence.xyz
41 #define l_influence position_influence.w
42 #define l_sizex rightvec_sizex.w
43 #define l_sizey upvec_sizey.w
44 #define l_right rightvec_sizex.xyz
45 #define l_up upvec_sizey.xyz
46 #define l_forward forwardvec_type.xyz
47 #define l_type forwardvec_type.w
48 #define l_spot_size spotdata_radius_shadow.x
49 #define l_spot_blend spotdata_radius_shadow.y
50 #define l_radius spotdata_radius_shadow.z
51 #define l_shadowid spotdata_radius_shadow.w
52
53 /* ------ Shadows ----- */
54 #ifndef MAX_CASCADE_NUM
55 #  define MAX_CASCADE_NUM 4
56 #endif
57
58 struct ShadowData {
59   vec4 near_far_bias_exp;
60   vec4 shadow_data_start_end;
61   vec4 contact_shadow_data;
62 };
63
64 struct ShadowCubeData {
65   vec4 position;
66 };
67
68 struct ShadowCascadeData {
69   mat4 shadowmat[MAX_CASCADE_NUM];
70   vec4 split_start_distances;
71   vec4 split_end_distances;
72 };
73
74 /* convenience aliases */
75 #define sh_near near_far_bias_exp.x
76 #define sh_far near_far_bias_exp.y
77 #define sh_bias near_far_bias_exp.z
78 #define sh_exp near_far_bias_exp.w
79 #define sh_bleed near_far_bias_exp.w
80 #define sh_tex_start shadow_data_start_end.x
81 #define sh_data_start shadow_data_start_end.y
82 #define sh_multi_nbr shadow_data_start_end.z
83 #define sh_blur shadow_data_start_end.w
84 #define sh_contact_dist contact_shadow_data.x
85 #define sh_contact_offset contact_shadow_data.y
86 #define sh_contact_spread contact_shadow_data.z
87 #define sh_contact_thickness contact_shadow_data.w
88
89 /* ------- Convenience functions --------- */
90
91 vec3 mul(mat3 m, vec3 v)
92 {
93   return m * v;
94 }
95 mat3 mul(mat3 m1, mat3 m2)
96 {
97   return m1 * m2;
98 }
99 vec3 transform_direction(mat4 m, vec3 v)
100 {
101   return mat3(m) * v;
102 }
103 vec3 transform_point(mat4 m, vec3 v)
104 {
105   return (m * vec4(v, 1.0)).xyz;
106 }
107 vec3 project_point(mat4 m, vec3 v)
108 {
109   vec4 tmp = m * vec4(v, 1.0);
110   return tmp.xyz / tmp.w;
111 }
112
113 #define min3(a, b, c) min(a, min(b, c))
114 #define min4(a, b, c, d) min(a, min3(b, c, d))
115 #define min5(a, b, c, d, e) min(a, min4(b, c, d, e))
116 #define min6(a, b, c, d, e, f) min(a, min5(b, c, d, e, f))
117 #define min7(a, b, c, d, e, f, g) min(a, min6(b, c, d, e, f, g))
118 #define min8(a, b, c, d, e, f, g, h) min(a, min7(b, c, d, e, f, g, h))
119 #define min9(a, b, c, d, e, f, g, h, i) min(a, min8(b, c, d, e, f, g, h, i))
120
121 #define max3(a, b, c) max(a, max(b, c))
122 #define max4(a, b, c, d) max(a, max3(b, c, d))
123 #define max5(a, b, c, d, e) max(a, max4(b, c, d, e))
124 #define max6(a, b, c, d, e, f) max(a, max5(b, c, d, e, f))
125 #define max7(a, b, c, d, e, f, g) max(a, max6(b, c, d, e, f, g))
126 #define max8(a, b, c, d, e, f, g, h) max(a, max7(b, c, d, e, f, g, h))
127 #define max9(a, b, c, d, e, f, g, h, i) max(a, max8(b, c, d, e, f, g, h, i))
128
129 #define avg3(a, b, c) (a + b + c) * (1.0 / 3.0)
130 #define avg4(a, b, c, d) (a + b + c + d) * (1.0 / 4.0)
131 #define avg5(a, b, c, d, e) (a + b + c + d + e) * (1.0 / 5.0)
132 #define avg6(a, b, c, d, e, f) (a + b + c + d + e + f) * (1.0 / 6.0)
133 #define avg7(a, b, c, d, e, f, g) (a + b + c + d + e + f + g) * (1.0 / 7.0)
134 #define avg8(a, b, c, d, e, f, g, h) (a + b + c + d + e + f + g + h) * (1.0 / 8.0)
135 #define avg9(a, b, c, d, e, f, g, h, i) (a + b + c + d + e + f + g + h + i) * (1.0 / 9.0)
136
137 float min_v2(vec2 v)
138 {
139   return min(v.x, v.y);
140 }
141 float min_v3(vec3 v)
142 {
143   return min(v.x, min(v.y, v.z));
144 }
145 float max_v2(vec2 v)
146 {
147   return max(v.x, v.y);
148 }
149 float max_v3(vec3 v)
150 {
151   return max(v.x, max(v.y, v.z));
152 }
153
154 float sum(vec2 v)
155 {
156   return dot(vec2(1.0), v);
157 }
158 float sum(vec3 v)
159 {
160   return dot(vec3(1.0), v);
161 }
162 float sum(vec4 v)
163 {
164   return dot(vec4(1.0), v);
165 }
166
167 float saturate(float a)
168 {
169   return clamp(a, 0.0, 1.0);
170 }
171 vec2 saturate(vec2 a)
172 {
173   return clamp(a, 0.0, 1.0);
174 }
175 vec3 saturate(vec3 a)
176 {
177   return clamp(a, 0.0, 1.0);
178 }
179 vec4 saturate(vec4 a)
180 {
181   return clamp(a, 0.0, 1.0);
182 }
183
184 float distance_squared(vec2 a, vec2 b)
185 {
186   a -= b;
187   return dot(a, a);
188 }
189 float distance_squared(vec3 a, vec3 b)
190 {
191   a -= b;
192   return dot(a, a);
193 }
194 float len_squared(vec3 a)
195 {
196   return dot(a, a);
197 }
198
199 float inverse_distance(vec3 V)
200 {
201   return max(1 / length(V), 1e-8);
202 }
203
204 vec2 mip_ratio_interp(float mip)
205 {
206   float low_mip = floor(mip);
207   return mix(mipRatio[int(low_mip)], mipRatio[int(low_mip + 1.0)], mip - low_mip);
208 }
209
210 /* ------- RNG ------- */
211
212 float wang_hash_noise(uint s)
213 {
214   s = (s ^ 61u) ^ (s >> 16u);
215   s *= 9u;
216   s = s ^ (s >> 4u);
217   s *= 0x27d4eb2du;
218   s = s ^ (s >> 15u);
219
220   return fract(float(s) / 4294967296.0);
221 }
222
223 /* ------- Fast Math ------- */
224
225 /* [Drobot2014a] Low Level Optimizations for GCN */
226 float fast_sqrt(float v)
227 {
228   return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1));
229 }
230
231 vec2 fast_sqrt(vec2 v)
232 {
233   return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1));
234 }
235
236 /* [Eberly2014] GPGPU Programming for Games and Science */
237 float fast_acos(float v)
238 {
239   float res = -0.156583 * abs(v) + M_PI_2;
240   res *= fast_sqrt(1.0 - abs(v));
241   return (v >= 0) ? res : M_PI - res;
242 }
243
244 vec2 fast_acos(vec2 v)
245 {
246   vec2 res = -0.156583 * abs(v) + M_PI_2;
247   res *= fast_sqrt(1.0 - abs(v));
248   v.x = (v.x >= 0) ? res.x : M_PI - res.x;
249   v.y = (v.y >= 0) ? res.y : M_PI - res.y;
250   return v;
251 }
252
253 float point_plane_projection_dist(vec3 lineorigin, vec3 planeorigin, vec3 planenormal)
254 {
255   return dot(planenormal, planeorigin - lineorigin);
256 }
257
258 float line_plane_intersect_dist(vec3 lineorigin,
259                                 vec3 linedirection,
260                                 vec3 planeorigin,
261                                 vec3 planenormal)
262 {
263   return dot(planenormal, planeorigin - lineorigin) / dot(planenormal, linedirection);
264 }
265
266 float line_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec4 plane)
267 {
268   vec3 plane_co = plane.xyz * (-plane.w / len_squared(plane.xyz));
269   vec3 h = lineorigin - plane_co;
270   return -dot(plane.xyz, h) / dot(plane.xyz, linedirection);
271 }
272
273 vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin, vec3 planenormal)
274 {
275   float dist = line_plane_intersect_dist(lineorigin, linedirection, planeorigin, planenormal);
276   return lineorigin + linedirection * dist;
277 }
278
279 vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec4 plane)
280 {
281   float dist = line_plane_intersect_dist(lineorigin, linedirection, plane);
282   return lineorigin + linedirection * dist;
283 }
284
285 float line_aligned_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec3 planeorigin)
286 {
287   /* aligned plane normal */
288   vec3 L = planeorigin - lineorigin;
289   float diskdist = length(L);
290   vec3 planenormal = -normalize(L);
291   return -diskdist / dot(planenormal, linedirection);
292 }
293
294 vec3 line_aligned_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin)
295 {
296   float dist = line_aligned_plane_intersect_dist(lineorigin, linedirection, planeorigin);
297   if (dist < 0) {
298     /* if intersection is behind we fake the intersection to be
299      * really far and (hopefully) not inside the radius of interest */
300     dist = 1e16;
301   }
302   return lineorigin + linedirection * dist;
303 }
304
305 float line_unit_sphere_intersect_dist(vec3 lineorigin, vec3 linedirection)
306 {
307   float a = dot(linedirection, linedirection);
308   float b = dot(linedirection, lineorigin);
309   float c = dot(lineorigin, lineorigin) - 1;
310
311   float dist = 1e15;
312   float determinant = b * b - a * c;
313   if (determinant >= 0) {
314     dist = (sqrt(determinant) - b) / a;
315   }
316
317   return dist;
318 }
319
320 float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection)
321 {
322   /* https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
323    */
324   vec3 firstplane = (vec3(1.0) - lineorigin) / linedirection;
325   vec3 secondplane = (vec3(-1.0) - lineorigin) / linedirection;
326   vec3 furthestplane = max(firstplane, secondplane);
327
328   return min_v3(furthestplane);
329 }
330
331 /* Return texture coordinates to sample Surface LUT */
332 vec2 lut_coords(float cosTheta, float roughness)
333 {
334   float theta = acos(cosTheta);
335   vec2 coords = vec2(roughness, theta / M_PI_2);
336
337   /* scale and bias coordinates, for correct filtered lookup */
338   return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE;
339 }
340
341 vec2 lut_coords_ltc(float cosTheta, float roughness)
342 {
343   vec2 coords = vec2(roughness, sqrt(1.0 - cosTheta));
344
345   /* scale and bias coordinates, for correct filtered lookup */
346   return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE;
347 }
348
349 /* -- Tangent Space conversion -- */
350 vec3 tangent_to_world(vec3 vector, vec3 N, vec3 T, vec3 B)
351 {
352   return T * vector.x + B * vector.y + N * vector.z;
353 }
354
355 vec3 world_to_tangent(vec3 vector, vec3 N, vec3 T, vec3 B)
356 {
357   return vec3(dot(T, vector), dot(B, vector), dot(N, vector));
358 }
359
360 void make_orthonormal_basis(vec3 N, out vec3 T, out vec3 B)
361 {
362   vec3 UpVector = abs(N.z) < 0.99999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
363   T = normalize(cross(UpVector, N));
364   B = cross(N, T);
365 }
366
367 /* ---- Opengl Depth conversion ---- */
368
369 float linear_depth(bool is_persp, float z, float zf, float zn)
370 {
371   if (is_persp) {
372     return (zn * zf) / (z * (zn - zf) + zf);
373   }
374   else {
375     return (z * 2.0 - 1.0) * zf;
376   }
377 }
378
379 float buffer_depth(bool is_persp, float z, float zf, float zn)
380 {
381   if (is_persp) {
382     return (zf * (zn - z)) / (z * (zn - zf));
383   }
384   else {
385     return (z / (zf * 2.0)) + 0.5;
386   }
387 }
388
389 float get_view_z_from_depth(float depth)
390 {
391   if (ProjectionMatrix[3][3] == 0.0) {
392     float d = 2.0 * depth - 1.0;
393     return -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]);
394   }
395   else {
396     return viewVecs[0].z + depth * viewVecs[1].z;
397   }
398 }
399
400 float get_depth_from_view_z(float z)
401 {
402   if (ProjectionMatrix[3][3] == 0.0) {
403     float d = (-ProjectionMatrix[3][2] / z) - ProjectionMatrix[2][2];
404     return d * 0.5 + 0.5;
405   }
406   else {
407     return (z - viewVecs[0].z) / viewVecs[1].z;
408   }
409 }
410
411 vec2 get_uvs_from_view(vec3 view)
412 {
413   vec3 ndc = project_point(ProjectionMatrix, view);
414   return ndc.xy * 0.5 + 0.5;
415 }
416
417 vec3 get_view_space_from_depth(vec2 uvcoords, float depth)
418 {
419   if (ProjectionMatrix[3][3] == 0.0) {
420     return vec3(viewVecs[0].xy + uvcoords * viewVecs[1].xy, 1.0) * get_view_z_from_depth(depth);
421   }
422   else {
423     return viewVecs[0].xyz + vec3(uvcoords, depth) * viewVecs[1].xyz;
424   }
425 }
426
427 vec3 get_world_space_from_depth(vec2 uvcoords, float depth)
428 {
429   return (ViewMatrixInverse * vec4(get_view_space_from_depth(uvcoords, depth), 1.0)).xyz;
430 }
431
432 vec3 get_specular_reflection_dominant_dir(vec3 N, vec3 V, float roughness)
433 {
434   vec3 R = -reflect(V, N);
435   float smoothness = 1.0 - roughness;
436   float fac = smoothness * (sqrt(smoothness) + roughness);
437   return normalize(mix(N, R, fac));
438 }
439
440 float specular_occlusion(float NV, float AO, float roughness)
441 {
442   return saturate(pow(NV + AO, roughness) - 1.0 + AO);
443 }
444
445 /* --- Refraction utils --- */
446
447 float ior_from_f0(float f0)
448 {
449   float f = sqrt(f0);
450   return (-f - 1.0) / (f - 1.0);
451 }
452
453 float f0_from_ior(float eta)
454 {
455   float A = (eta - 1.0) / (eta + 1.0);
456   return A * A;
457 }
458
459 vec3 get_specular_refraction_dominant_dir(vec3 N, vec3 V, float roughness, float ior)
460 {
461   /* TODO: This a bad approximation. Better approximation should fit
462    * the refracted vector and roughness into the best prefiltered reflection
463    * lobe. */
464   /* Correct the IOR for ior < 1.0 to not see the abrupt delimitation or the TIR */
465   ior = (ior < 1.0) ? mix(ior, 1.0, roughness) : ior;
466   float eta = 1.0 / ior;
467
468   float NV = dot(N, -V);
469
470   /* Custom Refraction. */
471   float k = 1.0 - eta * eta * (1.0 - NV * NV);
472   k = max(0.0, k); /* Only this changes. */
473   vec3 R = eta * -V - (eta * NV + sqrt(k)) * N;
474
475   return R;
476 }
477
478 float get_btdf_lut(sampler2DArray btdf_lut_tex, float NV, float roughness, float ior)
479 {
480   const vec3 lut_scale_bias_texel_size = vec3((LUT_SIZE - 1.0), 0.5, 1.5) / LUT_SIZE;
481
482   vec3 coords;
483   /* Try to compensate for the low resolution and interpolation error. */
484   coords.x = (ior > 1.0) ? (0.9 + lut_scale_bias_texel_size.z) +
485                                (0.1 - lut_scale_bias_texel_size.z) * f0_from_ior(ior) :
486                            (0.9 + lut_scale_bias_texel_size.z) * ior * ior;
487   coords.y = 1.0 - saturate(NV);
488   coords.xy *= lut_scale_bias_texel_size.x;
489   coords.xy += lut_scale_bias_texel_size.y;
490
491   const float lut_lvl_ofs = 4.0;    /* First texture lvl of roughness. */
492   const float lut_lvl_scale = 16.0; /* How many lvl of roughness in the lut. */
493
494   float mip = roughness * lut_lvl_scale;
495   float mip_floor = floor(mip);
496
497   coords.z = lut_lvl_ofs + mip_floor + 1.0;
498   float btdf_high = textureLod(btdf_lut_tex, coords, 0.0).r;
499
500   coords.z -= 1.0;
501   float btdf_low = textureLod(btdf_lut_tex, coords, 0.0).r;
502
503   float btdf = (ior == 1.0) ? 1.0 : mix(btdf_low, btdf_high, mip - coords.z);
504
505   return btdf;
506 }
507
508 /* ---- Encode / Decode Normal buffer data ---- */
509 /* From http://aras-p.info/texts/CompactNormalStorage.html
510  * Using Method #4: Spheremap Transform */
511 vec2 normal_encode(vec3 n, vec3 view)
512 {
513   float p = sqrt(n.z * 8.0 + 8.0);
514   return n.xy / p + 0.5;
515 }
516
517 vec3 normal_decode(vec2 enc, vec3 view)
518 {
519   vec2 fenc = enc * 4.0 - 2.0;
520   float f = dot(fenc, fenc);
521   float g = sqrt(1.0 - f / 4.0);
522   vec3 n;
523   n.xy = fenc * g;
524   n.z = 1 - f / 2;
525   return n;
526 }
527
528 /* ---- RGBM (shared multiplier) encoding ---- */
529 /* From http://iwasbeingirony.blogspot.fr/2010/06/difference-between-rgbm-and-rgbd.html */
530
531 /* Higher RGBM_MAX_RANGE gives imprecision issues in low intensity. */
532 #define RGBM_MAX_RANGE 512.0
533
534 vec4 rgbm_encode(vec3 rgb)
535 {
536   float maxRGB = max_v3(rgb);
537   float M = maxRGB / RGBM_MAX_RANGE;
538   M = ceil(M * 255.0) / 255.0;
539   return vec4(rgb / (M * RGBM_MAX_RANGE), M);
540 }
541
542 vec3 rgbm_decode(vec4 data)
543 {
544   return data.rgb * (data.a * RGBM_MAX_RANGE);
545 }
546
547 /* ---- RGBE (shared exponent) encoding ---- */
548 vec4 rgbe_encode(vec3 rgb)
549 {
550   float maxRGB = max_v3(rgb);
551   float fexp = ceil(log2(maxRGB));
552   return vec4(rgb / exp2(fexp), (fexp + 128.0) / 255.0);
553 }
554
555 vec3 rgbe_decode(vec4 data)
556 {
557   float fexp = data.a * 255.0 - 128.0;
558   return data.rgb * exp2(fexp);
559 }
560
561 #if 1
562 #  define irradiance_encode rgbe_encode
563 #  define irradiance_decode rgbe_decode
564 #else /* No ecoding (when using floating point format) */
565 #  define irradiance_encode(X) (X).rgbb
566 #  define irradiance_decode(X) (X).rgb
567 #endif
568
569 /* Irradiance Visibility Encoding */
570 #if 1
571 vec4 visibility_encode(vec2 accum, float range)
572 {
573   accum /= range;
574
575   vec4 data;
576   data.x = fract(accum.x);
577   data.y = floor(accum.x) / 255.0;
578   data.z = fract(accum.y);
579   data.w = floor(accum.y) / 255.0;
580
581   return data;
582 }
583
584 vec2 visibility_decode(vec4 data, float range)
585 {
586   return (data.xz + data.yw * 255.0) * range;
587 }
588 #else /* No ecoding (when using floating point format) */
589 vec4 visibility_encode(vec2 accum, float range)
590 {
591   return accum.xyxy;
592 }
593
594 vec2 visibility_decode(vec4 data, float range)
595 {
596   return data.xy;
597 }
598 #endif
599
600 /* Fresnel monochromatic, perfect mirror */
601 float F_eta(float eta, float cos_theta)
602 {
603   /* compute fresnel reflectance without explicitly computing
604    * the refracted direction */
605   float c = abs(cos_theta);
606   float g = eta * eta - 1.0 + c * c;
607   float result;
608
609   if (g > 0.0) {
610     g = sqrt(g);
611     vec2 g_c = vec2(g) + vec2(c, -c);
612     float A = g_c.y / g_c.x;
613     A *= A;
614     g_c *= c;
615     float B = (g_c.y - 1.0) / (g_c.x + 1.0);
616     B *= B;
617     result = 0.5 * A * (1.0 + B);
618   }
619   else {
620     result = 1.0; /* TIR (no refracted component) */
621   }
622
623   return result;
624 }
625
626 /* Fresnel color blend base on fresnel factor */
627 vec3 F_color_blend(float eta, float fresnel, vec3 f0_color)
628 {
629   float f0 = F_eta(eta, 1.0);
630   float fac = saturate((fresnel - f0) / max(1e-8, 1.0 - f0));
631   return mix(f0_color, vec3(1.0), fac);
632 }
633
634 /* Fresnel */
635 vec3 F_schlick(vec3 f0, float cos_theta)
636 {
637   float fac = 1.0 - cos_theta;
638   float fac2 = fac * fac;
639   fac = fac2 * fac2 * fac;
640
641   /* Unreal specular matching : if specular color is below 2% intensity,
642    * (using green channel for intensity) treat as shadowning */
643   return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * fac + (1.0 - fac) * f0;
644 }
645
646 /* Fresnel approximation for LTC area lights (not MRP) */
647 vec3 F_area(vec3 f0, vec2 lut)
648 {
649   /* Unreal specular matching : if specular color is below 2% intensity,
650    * treat as shadowning */
651   return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * lut.y + lut.x * f0;
652 }
653
654 /* Fresnel approximation for IBL */
655 vec3 F_ibl(vec3 f0, vec2 lut)
656 {
657   /* Unreal specular matching : if specular color is below 2% intensity,
658    * treat as shadowning */
659   return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * lut.y + lut.x * f0;
660 }
661
662 /* GGX */
663 float D_ggx_opti(float NH, float a2)
664 {
665   float tmp = (NH * a2 - NH) * NH + 1.0;
666   return M_PI * tmp * tmp; /* Doing RCP and mul a2 at the end */
667 }
668
669 float G1_Smith_GGX(float NX, float a2)
670 {
671   /* Using Brian Karis approach and refactoring by NX/NX
672    * this way the (2*NL)*(2*NV) in G = G1(V) * G1(L) gets canceled by the brdf denominator 4*NL*NV
673    * Rcp is done on the whole G later
674    * Note that this is not convenient for the transmission formula */
675   return NX + sqrt(NX * (NX - NX * a2) + a2);
676   /* return 2 / (1 + sqrt(1 + a2 * (1 - NX*NX) / (NX*NX) ) ); /* Reference function */
677 }
678
679 float bsdf_ggx(vec3 N, vec3 L, vec3 V, float roughness)
680 {
681   float a = roughness;
682   float a2 = a * a;
683
684   vec3 H = normalize(L + V);
685   float NH = max(dot(N, H), 1e-8);
686   float NL = max(dot(N, L), 1e-8);
687   float NV = max(dot(N, V), 1e-8);
688
689   float G = G1_Smith_GGX(NV, a2) * G1_Smith_GGX(NL, a2); /* Doing RCP at the end */
690   float D = D_ggx_opti(NH, a2);
691
692   /* Denominator is canceled by G1_Smith */
693   /* bsdf = D * G / (4.0 * NL * NV); /* Reference function */
694   return NL * a2 / (D * G); /* NL to Fit cycles Equation : line. 345 in bsdf_microfacet.h */
695 }
696
697 void accumulate_light(vec3 light, float fac, inout vec4 accum)
698 {
699   accum += vec4(light, 1.0) * min(fac, (1.0 - accum.a));
700 }
701
702 /* ----------- Cone Aperture Approximation --------- */
703
704 /* Return a fitted cone angle given the input roughness */
705 float cone_cosine(float r)
706 {
707   /* Using phong gloss
708    * roughness = sqrt(2/(gloss+2)) */
709   float gloss = -2 + 2 / (r * r);
710   /* Drobot 2014 in GPUPro5 */
711   // return cos(2.0 * sqrt(2.0 / (gloss + 2)));
712   /* Uludag 2014 in GPUPro5 */
713   // return pow(0.244, 1 / (gloss + 1));
714   /* Jimenez 2016 in Practical Realtime Strategies for Accurate Indirect Occlusion*/
715   return exp2(-3.32193 * r * r);
716 }
717
718 /* --------- Closure ---------- */
719 #ifdef VOLUMETRICS
720
721 struct Closure {
722   vec3 absorption;
723   vec3 scatter;
724   vec3 emission;
725   float anisotropy;
726 };
727
728 #  define CLOSURE_DEFAULT Closure(vec3(0.0), vec3(0.0), vec3(0.0), 0.0)
729
730 Closure closure_mix(Closure cl1, Closure cl2, float fac)
731 {
732   Closure cl;
733   cl.absorption = mix(cl1.absorption, cl2.absorption, fac);
734   cl.scatter = mix(cl1.scatter, cl2.scatter, fac);
735   cl.emission = mix(cl1.emission, cl2.emission, fac);
736   cl.anisotropy = mix(cl1.anisotropy, cl2.anisotropy, fac);
737   return cl;
738 }
739
740 Closure closure_add(Closure cl1, Closure cl2)
741 {
742   Closure cl;
743   cl.absorption = cl1.absorption + cl2.absorption;
744   cl.scatter = cl1.scatter + cl2.scatter;
745   cl.emission = cl1.emission + cl2.emission;
746   cl.anisotropy = (cl1.anisotropy + cl2.anisotropy) / 2.0; /* Average phase (no multi lobe) */
747   return cl;
748 }
749
750 Closure closure_emission(vec3 rgb)
751 {
752   Closure cl = CLOSURE_DEFAULT;
753   cl.emission = rgb;
754   return cl;
755 }
756
757 #else /* VOLUMETRICS */
758
759 struct Closure {
760   vec3 radiance;
761   float opacity;
762 #  ifdef USE_SSS
763   vec4 sss_data;
764 #    ifdef USE_SSS_ALBEDO
765   vec3 sss_albedo;
766 #    endif
767 #  endif
768   vec4 ssr_data;
769   vec2 ssr_normal;
770   int ssr_id;
771 };
772
773 /* This is hacking ssr_id to tag transparent bsdf */
774 #  define TRANSPARENT_CLOSURE_FLAG -2
775 #  define REFRACT_CLOSURE_FLAG -3
776 #  define NO_SSR -999
777
778 #  ifdef USE_SSS
779 #    ifdef USE_SSS_ALBEDO
780 #      define CLOSURE_DEFAULT \
781         Closure(vec3(0.0), 1.0, vec4(0.0), vec3(0.0), vec4(0.0), vec2(0.0), -1)
782 #    else
783 #      define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec4(0.0), vec2(0.0), -1)
784 #    endif
785 #  else
786 #    define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec2(0.0), -1)
787 #  endif
788
789 uniform int outputSsrId;
790
791 Closure closure_mix(Closure cl1, Closure cl2, float fac)
792 {
793   Closure cl;
794
795   if (cl1.ssr_id == TRANSPARENT_CLOSURE_FLAG) {
796     cl1.ssr_normal = cl2.ssr_normal;
797     cl1.ssr_data = cl2.ssr_data;
798     cl1.ssr_id = cl2.ssr_id;
799 #  ifdef USE_SSS
800     cl1.sss_data = cl2.sss_data;
801 #    ifdef USE_SSS_ALBEDO
802     cl1.sss_albedo = cl2.sss_albedo;
803 #    endif
804 #  endif
805   }
806   if (cl2.ssr_id == TRANSPARENT_CLOSURE_FLAG) {
807     cl2.ssr_normal = cl1.ssr_normal;
808     cl2.ssr_data = cl1.ssr_data;
809     cl2.ssr_id = cl1.ssr_id;
810 #  ifdef USE_SSS
811     cl2.sss_data = cl1.sss_data;
812 #    ifdef USE_SSS_ALBEDO
813     cl2.sss_albedo = cl1.sss_albedo;
814 #    endif
815 #  endif
816   }
817
818   /* When mixing SSR don't blend roughness.
819    *
820    * It makes no sense to mix them really, so we take either one of them and
821    * tone down its specularity (ssr_data.xyz) while keeping its roughness (ssr_data.w).
822    */
823   if (cl1.ssr_id == outputSsrId) {
824     cl.ssr_data = mix(cl1.ssr_data.xyzw, vec4(vec3(0.0), cl1.ssr_data.w), fac);
825     cl.ssr_normal = cl1.ssr_normal;
826     cl.ssr_id = cl1.ssr_id;
827   }
828   else {
829     cl.ssr_data = mix(vec4(vec3(0.0), cl2.ssr_data.w), cl2.ssr_data.xyzw, fac);
830     cl.ssr_normal = cl2.ssr_normal;
831     cl.ssr_id = cl2.ssr_id;
832   }
833
834   cl.opacity = mix(cl1.opacity, cl2.opacity, fac);
835   cl.radiance = mix(cl1.radiance * cl1.opacity, cl2.radiance * cl2.opacity, fac);
836   cl.radiance /= max(1e-8, cl.opacity);
837
838 #  ifdef USE_SSS
839   /* Apply Mix on input */
840   cl1.sss_data.rgb *= 1.0 - fac;
841   cl2.sss_data.rgb *= fac;
842
843   /* Select biggest radius. */
844   bool use_cl1 = (cl1.sss_data.a > cl2.sss_data.a);
845   cl.sss_data = (use_cl1) ? cl1.sss_data : cl2.sss_data;
846
847 #    ifdef USE_SSS_ALBEDO
848   /* TODO Find a solution to this. Dither? */
849   cl.sss_albedo = (use_cl1) ? cl1.sss_albedo : cl2.sss_albedo;
850   /* Add radiance that was supposed to be filtered but was rejected. */
851   cl.radiance += (use_cl1) ? cl2.sss_data.rgb * cl2.sss_albedo : cl1.sss_data.rgb * cl1.sss_albedo;
852 #    else
853   /* Add radiance that was supposed to be filtered but was rejected. */
854   cl.radiance += (use_cl1) ? cl2.sss_data.rgb : cl1.sss_data.rgb;
855 #    endif
856 #  endif
857
858   return cl;
859 }
860
861 Closure closure_add(Closure cl1, Closure cl2)
862 {
863   Closure cl = (cl1.ssr_id == outputSsrId) ? cl1 : cl2;
864   cl.radiance = cl1.radiance + cl2.radiance;
865 #  ifdef USE_SSS
866   cl.sss_data = (cl1.sss_data.a > 0.0) ? cl1.sss_data : cl2.sss_data;
867   /* Add radiance that was supposed to be filtered but was rejected. */
868   cl.radiance += (cl1.sss_data.a > 0.0) ? cl2.sss_data.rgb : cl1.sss_data.rgb;
869 #    ifdef USE_SSS_ALBEDO
870   /* TODO Find a solution to this. Dither? */
871   cl.sss_albedo = (cl1.sss_data.a > 0.0) ? cl1.sss_albedo : cl2.sss_albedo;
872 #    endif
873 #  endif
874   cl.opacity = saturate(cl1.opacity + cl2.opacity);
875   return cl;
876 }
877
878 Closure closure_emission(vec3 rgb)
879 {
880   Closure cl = CLOSURE_DEFAULT;
881   cl.radiance = rgb;
882   return cl;
883 }
884
885 /* Breaking this across multiple lines causes issues for some older GLSL compilers. */
886 /* clang-format off */
887 #  if defined(MESH_SHADER) && !defined(USE_ALPHA_HASH) && !defined(USE_ALPHA_CLIP) && !defined(SHADOW_SHADER) && !defined(USE_MULTIPLY)
888 /* clang-format on */
889 layout(location = 0) out vec4 fragColor;
890 layout(location = 1) out vec4 ssrNormals;
891 layout(location = 2) out vec4 ssrData;
892 #    ifdef USE_SSS
893 layout(location = 3) out vec4 sssData;
894 #      ifdef USE_SSS_ALBEDO
895 layout(location = 4) out vec4 sssAlbedo;
896 #      endif /* USE_SSS_ALBEDO */
897 #    endif   /* USE_SSS */
898
899 Closure nodetree_exec(void); /* Prototype */
900
901 #    if defined(USE_ALPHA_BLEND_VOLUMETRICS)
902 /* Prototype because this file is included before volumetric_lib.glsl */
903 vec4 volumetric_resolve(vec4 scene_color, vec2 frag_uvs, float frag_depth);
904 #    endif
905
906 #    define NODETREE_EXEC
907 void main()
908 {
909   Closure cl = nodetree_exec();
910 #    ifndef USE_ALPHA_BLEND
911   /* Prevent alpha hash material writing into alpha channel. */
912   cl.opacity = 1.0;
913 #    endif
914
915 #    if defined(USE_ALPHA_BLEND_VOLUMETRICS)
916   /* XXX fragile, better use real viewport resolution */
917   vec2 uvs = gl_FragCoord.xy / vec2(2 * textureSize(maxzBuffer, 0).xy);
918   fragColor.rgb = volumetric_resolve(vec4(cl.radiance, cl.opacity), uvs, gl_FragCoord.z).rgb;
919   fragColor.a = cl.opacity;
920 #    else
921   fragColor = vec4(cl.radiance, cl.opacity);
922 #    endif
923
924   ssrNormals = cl.ssr_normal.xyyy;
925   ssrData = cl.ssr_data;
926 #    ifdef USE_SSS
927   sssData = cl.sss_data;
928 #      ifdef USE_SSS_ALBEDO
929   sssAlbedo = cl.sss_albedo.rgbb;
930 #      endif
931 #    endif
932
933   /* For Probe capture */
934 #    ifdef USE_SSS
935   float fac = float(!sssToggle);
936
937 #      ifdef USE_REFRACTION
938   /* SSRefraction pass is done after the SSS pass.
939    * In order to not loose the diffuse light totally we
940    * need to merge the SSS radiance to the main radiance. */
941   fac = 1.0;
942 #      endif
943
944 #      ifdef USE_SSS_ALBEDO
945   fragColor.rgb += cl.sss_data.rgb * cl.sss_albedo.rgb * fac;
946 #      else
947   fragColor.rgb += cl.sss_data.rgb * fac;
948 #      endif
949 #    endif
950 }
951
952 #  endif /* MESH_SHADER && !SHADOW_SHADER */
953
954 #endif /* VOLUMETRICS */
955
956 Closure nodetree_exec(void); /* Prototype */
957
958 /* TODO find a better place */
959 #ifdef USE_MULTIPLY
960
961 out vec4 fragColor;
962
963 #  define NODETREE_EXEC
964 void main()
965 {
966   Closure cl = nodetree_exec();
967   fragColor = vec4(mix(vec3(1.0), cl.radiance, cl.opacity), 1.0);
968 }
969 #endif