Eevee: Add Lamp Specular multiplier.
[blender.git] / source / blender / draw / engines / eevee / shaders / lit_surface_frag.glsl
1
2 #ifndef LIT_SURFACE_UNIFORM
3 #define LIT_SURFACE_UNIFORM
4
5 uniform float refractionDepth;
6
7 #ifndef UTIL_TEX
8 #define UTIL_TEX
9 uniform sampler2DArray utilTex;
10 #define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
11 #endif /* UTIL_TEX */
12
13 in vec3 worldPosition;
14 in vec3 viewPosition;
15
16 #ifdef USE_FLAT_NORMAL
17 flat in vec3 worldNormal;
18 flat in vec3 viewNormal;
19 #else
20 in vec3 worldNormal;
21 in vec3 viewNormal;
22 #endif
23
24 #endif /* LIT_SURFACE_UNIFORM */
25
26 /** AUTO CONFIG
27  * We include the file multiple times each time with a different configuration.
28  * This leads to a lot of deadcode. Better idea would be to only generate the one needed.
29  */
30 #if !defined(SURFACE_DEFAULT)
31         #define SURFACE_DEFAULT
32         #define CLOSURE_NAME eevee_closure_default
33         #define CLOSURE_DIFFUSE
34         #define CLOSURE_GLOSSY
35 #endif /* SURFACE_DEFAULT */
36
37 #if !defined(SURFACE_PRINCIPLED) && !defined(CLOSURE_NAME)
38         #define SURFACE_PRINCIPLED
39         #define CLOSURE_NAME eevee_closure_principled
40         #define CLOSURE_DIFFUSE
41         #define CLOSURE_GLOSSY
42         #define CLOSURE_CLEARCOAT
43         #define CLOSURE_REFRACTION
44         #define CLOSURE_SUBSURFACE
45 #endif /* SURFACE_PRINCIPLED */
46
47 #if !defined(SURFACE_DIFFUSE) && !defined(CLOSURE_NAME)
48         #define SURFACE_DIFFUSE
49         #define CLOSURE_NAME eevee_closure_diffuse
50         #define CLOSURE_DIFFUSE
51 #endif /* SURFACE_DIFFUSE */
52
53 #if !defined(SURFACE_SUBSURFACE) && !defined(CLOSURE_NAME)
54         #define SURFACE_SUBSURFACE
55         #define CLOSURE_NAME eevee_closure_subsurface
56         #define CLOSURE_DIFFUSE
57         #define CLOSURE_SUBSURFACE
58 #endif /* SURFACE_SUBSURFACE */
59
60 #if !defined(SURFACE_GLOSSY) && !defined(CLOSURE_NAME)
61         #define SURFACE_GLOSSY
62         #define CLOSURE_NAME eevee_closure_glossy
63         #define CLOSURE_GLOSSY
64 #endif /* SURFACE_GLOSSY */
65
66 #if !defined(SURFACE_REFRACT) && !defined(CLOSURE_NAME)
67         #define SURFACE_REFRACT
68         #define CLOSURE_NAME eevee_closure_refraction
69         #define CLOSURE_REFRACTION
70 #endif /* SURFACE_REFRACT */
71
72 #if !defined(SURFACE_GLASS) && !defined(CLOSURE_NAME)
73         #define SURFACE_GLASS
74         #define CLOSURE_NAME eevee_closure_glass
75         #define CLOSURE_GLOSSY
76         #define CLOSURE_REFRACTION
77 #endif /* SURFACE_GLASS */
78
79 /* Safety : CLOSURE_CLEARCOAT implies CLOSURE_GLOSSY */
80 #ifdef CLOSURE_CLEARCOAT
81         #ifndef CLOSURE_GLOSSY
82                 #define CLOSURE_GLOSSY
83         #endif
84 #endif /* CLOSURE_CLEARCOAT */
85
86 void CLOSURE_NAME(
87         vec3 N
88 #ifdef CLOSURE_DIFFUSE
89         , vec3 albedo
90 #endif
91 #ifdef CLOSURE_GLOSSY
92         , vec3 f0, int ssr_id
93 #endif
94 #if defined(CLOSURE_GLOSSY) || defined(CLOSURE_REFRACTION)
95         , float roughness
96 #endif
97 #ifdef CLOSURE_CLEARCOAT
98         , vec3 C_N, float C_intensity, float C_roughness
99 #endif
100 #if defined(CLOSURE_GLOSSY) || defined(CLOSURE_DIFFUSE)
101         , float ao
102 #endif
103 #ifdef CLOSURE_SUBSURFACE
104         , float sss_scale
105 #endif
106 #ifdef CLOSURE_REFRACTION
107         , float ior
108 #endif
109 #ifdef CLOSURE_DIFFUSE
110         , out vec3 out_diff
111 #endif
112 #ifdef CLOSURE_SUBSURFACE
113         , out vec3 out_trans
114 #endif
115 #ifdef CLOSURE_GLOSSY
116         , out vec3 out_spec
117 #endif
118 #ifdef CLOSURE_REFRACTION
119         , out vec3 out_refr
120 #endif
121 #ifdef CLOSURE_GLOSSY
122         , out vec3 ssr_spec
123 #endif
124         )
125 {
126 #ifdef CLOSURE_DIFFUSE
127         out_diff = vec3(0.0);
128 #endif
129
130 #ifdef CLOSURE_SUBSURFACE
131         out_trans = vec3(0.0);
132 #endif
133
134 #ifdef CLOSURE_GLOSSY
135         out_spec = vec3(0.0);
136 #endif
137
138 #ifdef CLOSURE_REFRACTION
139         out_refr = vec3(0.0);
140 #endif
141
142         /* Zero length vectors cause issues, see: T51979. */
143         float len = length(N);
144         if (isnan(len)) {
145                 return;
146         }
147         N /= len;
148
149 #ifdef CLOSURE_CLEARCOAT
150         len = length(C_N);
151         if (isnan(len)) {
152                 return;
153         }
154         C_N /= len;
155 #endif
156
157 #if defined(CLOSURE_GLOSSY) || defined(CLOSURE_REFRACTION)
158         roughness = clamp(roughness, 1e-8, 0.9999);
159         float roughnessSquared = roughness * roughness;
160 #endif
161
162 #ifdef CLOSURE_CLEARCOAT
163         C_roughness = clamp(C_roughness, 1e-8, 0.9999);
164         float C_roughnessSquared = C_roughness * C_roughness;
165 #endif
166
167         vec3 V = cameraVec;
168
169         vec4 rand = texelFetch(utilTex, ivec3(ivec2(gl_FragCoord.xy) % LUT_SIZE, 2.0), 0);
170
171         /* ---------------------------------------------------------------- */
172         /* -------------------- SCENE LAMPS LIGHTING ---------------------- */
173         /* ---------------------------------------------------------------- */
174
175 #ifdef HAIR_SHADER
176         vec3 norm_view = cross(V, N);
177         norm_view = normalize(cross(norm_view, N)); /* Normal facing view */
178 #endif
179
180         for (int i = 0; i < MAX_LIGHT && i < laNumLight; ++i) {
181                 LightData ld = lights_data[i];
182
183                 vec4 l_vector; /* Non-Normalized Light Vector with length in last component. */
184                 l_vector.xyz = ld.l_position - worldPosition;
185                 l_vector.w = length(l_vector.xyz);
186
187                 vec3 l_color_vis = ld.l_color * light_visibility(ld, worldPosition, viewPosition, viewNormal, l_vector);
188
189 #ifdef HAIR_SHADER
190                 vec3 norm_lamp, view_vec;
191                 float occlu_trans, occlu;
192                 light_hair_common(ld, N, V, l_vector, norm_view, occlu_trans, occlu, norm_lamp, view_vec);
193
194         #ifdef CLOSURE_DIFFUSE
195                 out_diff += l_color_vis * light_diffuse(ld, -norm_lamp, V, l_vector) * occlu_trans;
196         #endif
197
198         #ifdef CLOSURE_SUBSURFACE
199                 out_trans += ld.l_color * light_translucent(ld, worldPosition, -norm_lamp, l_vector, sss_scale) * occlu_trans;
200         #endif
201
202         #ifdef CLOSURE_GLOSSY
203                 out_spec += l_color_vis * light_specular(ld, N, view_vec, l_vector, roughnessSquared, f0) * occlu * ld.l_spec;
204         #endif
205
206         #ifdef CLOSURE_CLEARCOAT
207                 out_spec += l_color_vis * light_specular(ld, C_N, view_vec, l_vector, C_roughnessSquared, f0) * C_intensity * occlu * ld.l_spec;
208         #endif
209
210 #else /* HAIR_SHADER */
211
212         #ifdef CLOSURE_DIFFUSE
213                 out_diff += l_color_vis * light_diffuse(ld, N, V, l_vector);
214         #endif
215
216         #ifdef CLOSURE_SUBSURFACE
217                 out_trans += ld.l_color * light_translucent(ld, worldPosition, -N, l_vector, sss_scale);
218         #endif
219
220         #ifdef CLOSURE_GLOSSY
221                 out_spec += l_color_vis * light_specular(ld, N, V, l_vector, roughnessSquared, f0) * ld.l_spec;
222         #endif
223
224         #ifdef CLOSURE_CLEARCOAT
225                 out_spec += l_color_vis * light_specular(ld, C_N, V, l_vector, C_roughnessSquared, f0) * C_intensity * ld.l_spec;
226         #endif
227
228 #endif /* HAIR_SHADER */
229         }
230
231 #ifdef HAIR_SHADER
232         N = -norm_view;
233 #endif
234
235
236
237         /* ---------------------------------------------------------------- */
238         /* ---------------- SPECULAR ENVIRONMENT LIGHTING ----------------- */
239         /* ---------------------------------------------------------------- */
240
241         /* Accumulate incomming light from all sources until accumulator is full. Then apply Occlusion and BRDF. */
242 #ifdef CLOSURE_GLOSSY
243         vec4 spec_accum = vec4(0.0);
244 #endif
245
246 #ifdef CLOSURE_CLEARCOAT
247         vec4 C_spec_accum = vec4(0.0);
248 #endif
249
250 #ifdef CLOSURE_REFRACTION
251         vec4 refr_accum = vec4(0.0);
252 #endif
253
254 #ifdef CLOSURE_GLOSSY
255         /* ---------------------------- */
256         /*      Planar Reflections      */
257         /* ---------------------------- */
258
259         for (int i = 0; i < MAX_PLANAR && i < prbNumPlanar && spec_accum.a < 0.999; ++i) {
260                 PlanarData pd = planars_data[i];
261
262                 /* Fade on geometric normal. */
263                 float fade = probe_attenuation_planar(pd, worldPosition, worldNormal, roughness);
264
265                 if (fade > 0.0) {
266                         if (!(ssrToggle && ssr_id == outputSsrId)) {
267                                 vec3 spec = probe_evaluate_planar(float(i), pd, worldPosition, N, V, roughness, fade);
268                                 accumulate_light(spec, fade, spec_accum);
269                         }
270
271         #ifdef CLOSURE_CLEARCOAT
272                         vec3 C_spec = probe_evaluate_planar(float(i), pd, worldPosition, C_N, V, C_roughness, fade);
273                         accumulate_light(C_spec, fade, C_spec_accum);
274         #endif
275
276                 }
277         }
278 #endif
279
280
281 #ifdef CLOSURE_GLOSSY
282         vec3 spec_dir = get_specular_reflection_dominant_dir(N, V, roughnessSquared);
283 #endif
284
285 #ifdef CLOSURE_CLEARCOAT
286         vec3 C_spec_dir = get_specular_reflection_dominant_dir(C_N, V, C_roughnessSquared);
287 #endif
288
289 #ifdef CLOSURE_REFRACTION
290         /* Refract the view vector using the depth heuristic.
291          * Then later Refract a second time the already refracted
292          * ray using the inverse ior. */
293         float final_ior = (refractionDepth > 0.0) ? 1.0 / ior : ior;
294         vec3 refr_V = (refractionDepth > 0.0) ? -refract(-V, N, final_ior) : V;
295         vec3 refr_pos = (refractionDepth > 0.0) ? line_plane_intersect(worldPosition, refr_V, worldPosition - N * refractionDepth, N) : worldPosition;
296         vec3 refr_dir = get_specular_refraction_dominant_dir(N, refr_V, roughness, final_ior);
297 #endif
298
299
300 #ifdef CLOSURE_REFRACTION
301         /* ---------------------------- */
302         /*   Screen Space Refraction    */
303         /* ---------------------------- */
304         #ifdef USE_REFRACTION
305         if (ssrToggle && roughness < ssrMaxRoughness + 0.2) {
306                 /* Find approximated position of the 2nd refraction event. */
307                 vec3 refr_vpos = (refractionDepth > 0.0) ? transform_point(ViewMatrix, refr_pos) : viewPosition;
308                 vec4 trans = screen_space_refraction(refr_vpos, N, refr_V, final_ior, roughnessSquared, rand);
309                 trans.a *= smoothstep(ssrMaxRoughness + 0.2, ssrMaxRoughness, roughness);
310                 accumulate_light(trans.rgb, trans.a, refr_accum);
311         }
312         #endif
313
314 #endif
315
316
317         /* ---------------------------- */
318         /*       Specular probes        */
319         /* ---------------------------- */
320 #if defined(CLOSURE_GLOSSY) || defined(CLOSURE_REFRACTION)
321
322         #ifdef CLOSURE_REFRACTION
323                 #define ACCUM refr_accum
324         #else
325                 #define ACCUM spec_accum
326         #endif
327
328         /* Starts at 1 because 0 is world probe */
329         for (int i = 1; ACCUM.a < 0.999 && i < prbNumRenderCube && i < MAX_PROBE; ++i) {
330                 CubeData cd = probes_data[i];
331
332                 float fade = probe_attenuation_cube(cd, worldPosition);
333
334                 if (fade > 0.0) {
335
336         #ifdef CLOSURE_GLOSSY
337                         if (!(ssrToggle && ssr_id == outputSsrId)) {
338                                 vec3 spec = probe_evaluate_cube(float(i), cd, worldPosition, spec_dir, roughness);
339                                 accumulate_light(spec, fade, spec_accum);
340                         }
341         #endif
342
343         #ifdef CLOSURE_CLEARCOAT
344                         vec3 C_spec = probe_evaluate_cube(float(i), cd, worldPosition, C_spec_dir, C_roughness);
345                         accumulate_light(C_spec, fade, C_spec_accum);
346         #endif
347
348         #ifdef CLOSURE_REFRACTION
349                         vec3 trans = probe_evaluate_cube(float(i), cd, refr_pos, refr_dir, roughnessSquared);
350                         accumulate_light(trans, fade, refr_accum);
351         #endif
352                 }
353         }
354
355         #undef ACCUM
356
357         /* ---------------------------- */
358         /*          World Probe         */
359         /* ---------------------------- */
360         #ifdef CLOSURE_GLOSSY
361         if (spec_accum.a < 0.999) {
362                 if (!(ssrToggle && ssr_id == outputSsrId)) {
363                         vec3 spec = probe_evaluate_world_spec(spec_dir, roughness);
364                         accumulate_light(spec, 1.0, spec_accum);
365                 }
366
367                 #ifdef CLOSURE_CLEARCOAT
368                 vec3 C_spec = probe_evaluate_world_spec(C_spec_dir, C_roughness);
369                 accumulate_light(C_spec, 1.0, C_spec_accum);
370                 #endif
371
372         }
373         #endif
374
375         #ifdef CLOSURE_REFRACTION
376         if (refr_accum.a < 0.999) {
377                 vec3 trans = probe_evaluate_world_spec(refr_dir, roughnessSquared);
378                 accumulate_light(trans, 1.0, refr_accum);
379         }
380         #endif
381 #endif /* Specular probes */ 
382
383
384         /* ---------------------------- */
385         /*       Ambient Occlusion      */
386         /* ---------------------------- */
387 #if defined(CLOSURE_GLOSSY) || defined(CLOSURE_DIFFUSE)
388         vec3 bent_normal;
389         float final_ao = occlusion_compute(N, viewPosition, ao, rand, bent_normal);
390 #endif
391
392
393         /* ---------------------------- */
394         /*        Specular Output       */
395         /* ---------------------------- */
396         float NV = dot(N, V);
397 #ifdef CLOSURE_GLOSSY
398         vec2 uv = lut_coords(NV, roughness);
399         vec2 brdf_lut = texture(utilTex, vec3(uv, 1.0)).rg;
400
401         /* This factor is outputed to be used by SSR in order
402          * to match the intensity of the regular reflections. */
403         ssr_spec = F_ibl(f0, brdf_lut);
404         float spec_occlu = specular_occlusion(NV, final_ao, roughness);
405
406         /* The SSR pass recompute the occlusion to not apply it to the SSR */
407         if (ssrToggle && ssr_id == outputSsrId) {
408                 spec_occlu = 1.0;
409         }
410
411         out_spec += spec_accum.rgb * ssr_spec * spec_occlu * float(specToggle);
412 #endif
413
414 #ifdef CLOSURE_REFRACTION
415         float btdf = get_btdf_lut(utilTex, NV, roughness, ior);
416
417         out_refr += refr_accum.rgb * btdf;
418 #endif
419
420 #ifdef CLOSURE_CLEARCOAT
421         NV = dot(C_N, V);
422         vec2 C_uv = lut_coords(NV, C_roughness);
423         vec2 C_brdf_lut = texture(utilTex, vec3(C_uv, 1.0)).rg;
424         vec3 C_fresnel = F_ibl(vec3(0.04), brdf_lut) * specular_occlusion(NV, final_ao, C_roughness);
425
426         out_spec += C_spec_accum.rgb * C_fresnel * float(specToggle) * C_intensity;
427 #endif
428
429         /* ---------------------------------------------------------------- */
430         /* ---------------- DIFFUSE ENVIRONMENT LIGHTING ------------------ */
431         /* ---------------------------------------------------------------- */
432
433         /* Accumulate light from all sources until accumulator is full. Then apply Occlusion and BRDF. */
434 #ifdef CLOSURE_DIFFUSE
435         vec4 diff_accum = vec4(0.0);
436
437         /* ---------------------------- */
438         /*       Irradiance Grids       */
439         /* ---------------------------- */
440         /* Start at 1 because 0 is world irradiance */
441         for (int i = 1; i < MAX_GRID && i < prbNumRenderGrid && diff_accum.a < 0.999; ++i) {
442                 GridData gd = grids_data[i];
443
444                 vec3 localpos;
445                 float fade = probe_attenuation_grid(gd, worldPosition, localpos);
446
447                 if (fade > 0.0) {
448                         vec3 diff = probe_evaluate_grid(gd, worldPosition, bent_normal, localpos);
449                         accumulate_light(diff, fade, diff_accum);
450                 }
451         }
452
453         /* ---------------------------- */
454         /*        World Diffuse         */
455         /* ---------------------------- */
456         if (diff_accum.a < 0.999 && prbNumRenderGrid > 0) {
457                 vec3 diff = probe_evaluate_world_diff(bent_normal);
458                 accumulate_light(diff, 1.0, diff_accum);
459         }
460
461         out_diff += diff_accum.rgb * gtao_multibounce(final_ao, albedo);
462 #endif
463 }
464
465 /* Cleanup for next configuration */
466 #undef CLOSURE_NAME
467
468 #ifdef CLOSURE_DIFFUSE
469         #undef CLOSURE_DIFFUSE
470 #endif
471
472 #ifdef CLOSURE_GLOSSY
473         #undef CLOSURE_GLOSSY
474 #endif
475
476 #ifdef CLOSURE_CLEARCOAT
477         #undef CLOSURE_CLEARCOAT
478 #endif
479
480 #ifdef CLOSURE_REFRACTION
481         #undef CLOSURE_REFRACTION
482 #endif
483
484 #ifdef CLOSURE_SUBSURFACE
485         #undef CLOSURE_SUBSURFACE
486 #endif