Fix shadows of sun type lights on some Intel gpus
[blender.git] / source / blender / draw / engines / eevee / shaders / lamps_lib.glsl
1
2 uniform sampler2DArray shadowCubeTexture;
3 uniform sampler2DArray shadowCascadeTexture;
4
5 #define LAMPS_LIB
6
7 layout(std140) uniform shadow_block {
8         ShadowData        shadows_data[MAX_SHADOW];
9         ShadowCubeData    shadows_cube_data[MAX_SHADOW_CUBE];
10         ShadowCascadeData shadows_cascade_data[MAX_SHADOW_CASCADE];
11 };
12
13 layout(std140) uniform light_block {
14         LightData lights_data[MAX_LIGHT];
15 };
16
17 /* type */
18 #define POINT          0.0
19 #define SUN            1.0
20 #define SPOT           2.0
21 #define HEMI           3.0
22 #define AREA_RECT      4.0
23 /* Used to define the area lamp shape, doesn't directly correspond to a Blender lamp type. */
24 #define AREA_ELLIPSE 100.0
25
26 #if defined(SHADOW_VSM)
27 #define ShadowSample vec2
28 #define sample_cube(vec, id)    texture_octahedron(shadowCubeTexture, vec4(vec, id)).rg
29 #define sample_cascade(vec, id) texture(shadowCascadeTexture, vec3(vec, id)).rg
30 #elif defined(SHADOW_ESM)
31 #define ShadowSample float
32 #define sample_cube(vec, id)    texture_octahedron(shadowCubeTexture, vec4(vec, id)).r
33 #define sample_cascade(vec, id) texture(shadowCascadeTexture, vec3(vec, id)).r
34 #else
35 #define ShadowSample float
36 #define sample_cube(vec, id)    texture_octahedron(shadowCubeTexture, vec4(vec, id)).r
37 #define sample_cascade(vec, id) texture(shadowCascadeTexture, vec3(vec, id)).r
38 #endif
39
40 #if defined(SHADOW_VSM)
41 #define get_depth_delta(s) (dist - s.x)
42 #else
43 #define get_depth_delta(s) (dist - s)
44 #endif
45
46 /* ----------------------------------------------------------- */
47 /* ----------------------- Shadow tests ---------------------- */
48 /* ----------------------------------------------------------- */
49
50 #if defined(SHADOW_VSM)
51
52 float shadow_test(ShadowSample moments, float dist, ShadowData sd)
53 {
54         float p = 0.0;
55
56         if (dist <= moments.x)
57                 p = 1.0;
58
59         float variance = moments.y - (moments.x * moments.x);
60         variance = max(variance, sd.sh_bias / 10.0);
61
62         float d = moments.x - dist;
63         float p_max = variance / (variance + d * d);
64
65         /* Now reduce light-bleeding by removing the [0, x] tail and linearly rescaling (x, 1] */
66         p_max = clamp((p_max - sd.sh_bleed) / (1.0 - sd.sh_bleed), 0.0, 1.0);
67
68         return max(p, p_max);
69 }
70
71 #elif defined(SHADOW_ESM)
72
73 float shadow_test(ShadowSample z, float dist, ShadowData sd)
74 {
75         return saturate(exp(sd.sh_exp * (z - dist + sd.sh_bias)));
76 }
77
78 #else
79
80 float shadow_test(ShadowSample z, float dist, ShadowData sd)
81 {
82         return step(0, z - dist + sd.sh_bias);
83 }
84
85 #endif
86
87 /* ----------------------------------------------------------- */
88 /* ----------------------- Shadow types ---------------------- */
89 /* ----------------------------------------------------------- */
90
91 float shadow_cubemap(ShadowData sd, ShadowCubeData scd, float texid, vec3 W)
92 {
93         vec3 cubevec = W - scd.position.xyz;
94         float dist = length(cubevec);
95
96         /* If fragment is out of shadowmap range, do not occlude */
97         /* XXX : we check radial distance against a cubeface distance.
98          * We loose quite a bit of valid area. */
99         if (dist > sd.sh_far)
100                 return 1.0;
101
102         cubevec /= dist;
103
104         ShadowSample s = sample_cube(cubevec, texid);
105         return shadow_test(s, dist, sd);
106 }
107
108 float evaluate_cascade(ShadowData sd, mat4 shadowmat, vec3 W, float range, float texid)
109 {
110         vec4 shpos = shadowmat * vec4(W, 1.0);
111         float dist = shpos.z * range;
112
113         ShadowSample s = sample_cascade(shpos.xy, texid);
114         float vis = shadow_test(s, dist, sd);
115
116         /* If fragment is out of shadowmap range, do not occlude */
117         if (shpos.z < 1.0 && shpos.z > 0.0) {
118                 return vis;
119         }
120         else {
121                 return 1.0;
122         }
123 }
124
125 float shadow_cascade(ShadowData sd, int scd_id, float texid, vec3 W)
126 {
127         vec4 view_z = vec4(dot(W - cameraPos, cameraForward));
128         vec4 weights = smoothstep(
129                 shadows_cascade_data[scd_id].split_end_distances,
130                 shadows_cascade_data[scd_id].split_start_distances.yzwx,
131                 view_z);
132
133         weights.yzw -= weights.xyz;
134
135         vec4 vis = vec4(1.0);
136         float range = abs(sd.sh_far - sd.sh_near); /* Same factor as in get_cascade_world_distance(). */
137
138         /* Branching using (weights > 0.0) is reaally slooow on intel so avoid it for now. */
139         /* TODO OPTI: Only do 2 samples and blend. */
140         vis.x = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[0], W, range, texid + 0);
141         vis.y = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[1], W, range, texid + 1);
142         vis.z = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[2], W, range, texid + 2);
143         vis.w = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[3], W, range, texid + 3);
144
145         float weight_sum = dot(vec4(1.0), weights);
146         if (weight_sum > 0.9999) {
147                 float vis_sum = dot(vec4(1.0), vis * weights);
148                 return vis_sum / weight_sum;
149         }
150         else {
151                 float vis_sum = dot(vec4(1.0), vis * step(0.001, weights));
152                 return mix(1.0, vis_sum, weight_sum);
153         }
154 }
155
156 /* ----------------------------------------------------------- */
157 /* --------------------- Light Functions --------------------- */
158 /* ----------------------------------------------------------- */
159 #define MAX_MULTI_SHADOW 4
160
161 float light_visibility(LightData ld, vec3 W,
162 #ifndef VOLUMETRICS
163                        vec3 viewPosition,
164                        vec3 viewNormal,
165 #endif
166                        vec4 l_vector)
167 {
168         float vis = 1.0;
169
170         if (ld.l_type == SPOT) {
171                 float z = dot(ld.l_forward, l_vector.xyz);
172                 vec3 lL = l_vector.xyz / z;
173                 float x = dot(ld.l_right, lL) / ld.l_sizex;
174                 float y = dot(ld.l_up, lL) / ld.l_sizey;
175
176                 float ellipse = inversesqrt(1.0 + x * x + y * y);
177
178                 float spotmask = smoothstep(0.0, 1.0, (ellipse - ld.l_spot_size) / ld.l_spot_blend);
179
180                 vis *= spotmask;
181                 vis *= step(0.0, -dot(l_vector.xyz, ld.l_forward));
182         }
183         else if (ld.l_type == AREA_RECT || ld.l_type == AREA_ELLIPSE) {
184                 vis *= step(0.0, -dot(l_vector.xyz, ld.l_forward));
185         }
186
187 #if !defined(VOLUMETRICS) || defined(VOLUME_SHADOW)
188         /* shadowing */
189         if (ld.l_shadowid >= 0.0) {
190                 ShadowData data = shadows_data[int(ld.l_shadowid)];
191
192                 if (ld.l_type == SUN) {
193                         /* TODO : MSM */
194                         // for (int i = 0; i < MAX_MULTI_SHADOW; ++i) {
195                                 vis *= shadow_cascade(
196                                         data, int(data.sh_data_start),
197                                         data.sh_tex_start, W);
198                         // }
199                 }
200                 else {
201                         /* TODO : MSM */
202                         // for (int i = 0; i < MAX_MULTI_SHADOW; ++i) {
203                                 vis *= shadow_cubemap(
204                                         data, shadows_cube_data[int(data.sh_data_start)],
205                                         data.sh_tex_start, W);
206                         // }
207                 }
208
209 #ifndef VOLUMETRICS
210                 /* Only compute if not already in shadow. */
211                 if ((vis > 0.001) && (data.sh_contact_dist > 0.0)) {
212                         vec4 L = (ld.l_type != SUN) ? l_vector : vec4(-ld.l_forward, 1.0);
213                         float trace_distance = (ld.l_type != SUN) ? min(data.sh_contact_dist, l_vector.w) : data.sh_contact_dist;
214
215                         vec3 T, B;
216                         make_orthonormal_basis(L.xyz / L.w, T, B);
217
218                         vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy);
219                         rand.zw *= fast_sqrt(rand.y) * data.sh_contact_spread;
220
221                         /* We use the full l_vector.xyz so that the spread is minimize
222                          * if the shading point is further away from the light source */
223                         vec3 ray_dir = L.xyz + T * rand.z + B * rand.w;
224                         ray_dir = transform_direction(ViewMatrix, ray_dir);
225                         ray_dir = normalize(ray_dir);
226
227                         vec3 ray_ori = viewPosition;
228
229                         float bias = 0.5; /* Constant Bias */
230                         bias += 1.0 - abs(dot(viewNormal, ray_dir)); /* Angle dependent bias */
231                         bias *= gl_FrontFacing ? data.sh_contact_offset : -data.sh_contact_offset;
232
233                         vec3 nor_bias = viewNormal * bias;
234                         ray_ori += nor_bias;
235
236                         ray_dir *= trace_distance;
237                         ray_dir -= nor_bias;
238
239                         vec3 hit_pos = raycast(-1, ray_ori, ray_dir, data.sh_contact_thickness, rand.x,
240                                                0.1, 0.001, false);
241
242                         if (hit_pos.z > 0.0) {
243                                 hit_pos = get_view_space_from_depth(hit_pos.xy, hit_pos.z);
244                                 float hit_dist = distance(viewPosition, hit_pos);
245                                 float dist_ratio = hit_dist / trace_distance;
246                                 return vis * saturate(dist_ratio * dist_ratio * dist_ratio);
247                         }
248                 }
249 #endif
250         }
251 #endif
252
253         return vis;
254 }
255
256 #ifdef USE_LTC
257 float light_diffuse(LightData ld, vec3 N, vec3 V, vec4 l_vector)
258 {
259         if (ld.l_type == AREA_RECT) {
260                 vec3 corners[4];
261                 corners[0] = normalize((l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up *  ld.l_sizey);
262                 corners[1] = normalize((l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * -ld.l_sizey);
263                 corners[2] = normalize((l_vector.xyz + ld.l_right *  ld.l_sizex) + ld.l_up * -ld.l_sizey);
264                 corners[3] = normalize((l_vector.xyz + ld.l_right *  ld.l_sizex) + ld.l_up *  ld.l_sizey);
265
266                 return ltc_evaluate_quad(corners, N);
267         }
268         else if (ld.l_type == AREA_ELLIPSE) {
269                 vec3 points[3];
270                 points[0] = (l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * -ld.l_sizey;
271                 points[1] = (l_vector.xyz + ld.l_right *  ld.l_sizex) + ld.l_up * -ld.l_sizey;
272                 points[2] = (l_vector.xyz + ld.l_right *  ld.l_sizex) + ld.l_up *  ld.l_sizey;
273
274                 return ltc_evaluate_disk(N, V, mat3(1.0), points);
275         }
276         else {
277                 float radius = ld.l_radius;
278                 radius /= (ld.l_type == SUN) ? 1.0 : l_vector.w;
279                 vec3 L = (ld.l_type == SUN) ? -ld.l_forward : (l_vector.xyz / l_vector.w);
280
281                 return ltc_evaluate_disk_simple(radius, dot(N, L));
282         }
283 }
284
285 float light_specular(LightData ld, vec4 ltc_mat, vec3 N, vec3 V, vec4 l_vector)
286 {
287         if (ld.l_type == AREA_RECT) {
288                 vec3 corners[4];
289                 corners[0] = (l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up *  ld.l_sizey;
290                 corners[1] = (l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * -ld.l_sizey;
291                 corners[2] = (l_vector.xyz + ld.l_right *  ld.l_sizex) + ld.l_up * -ld.l_sizey;
292                 corners[3] = (l_vector.xyz + ld.l_right *  ld.l_sizex) + ld.l_up *  ld.l_sizey;
293
294                 ltc_transform_quad(N, V, ltc_matrix(ltc_mat), corners);
295
296                 return ltc_evaluate_quad(corners, vec3(0.0, 0.0, 1.0));
297         }
298         else {
299                 bool is_ellipse = (ld.l_type == AREA_ELLIPSE);
300                 float radius_x = is_ellipse ? ld.l_sizex : ld.l_radius;
301                 float radius_y = is_ellipse ? ld.l_sizey : ld.l_radius;
302
303                 vec3 L = (ld.l_type == SUN) ? -ld.l_forward : l_vector.xyz;
304                 vec3 Px = ld.l_right;
305                 vec3 Py = ld.l_up;
306
307                 if (ld.l_type == SPOT || ld.l_type == POINT) {
308                         make_orthonormal_basis(l_vector.xyz / l_vector.w, Px, Py);
309                 }
310
311                 vec3 points[3];
312                 points[0] = (L + Px * -radius_x) + Py * -radius_y;
313                 points[1] = (L + Px *  radius_x) + Py * -radius_y;
314                 points[2] = (L + Px *  radius_x) + Py *  radius_y;
315
316                 return ltc_evaluate_disk(N, V, ltc_matrix(ltc_mat), points);
317         }
318 }
319 #endif
320
321 #define MAX_SSS_SAMPLES 65
322 #define SSS_LUT_SIZE 64.0
323 #define SSS_LUT_SCALE ((SSS_LUT_SIZE - 1.0) / float(SSS_LUT_SIZE))
324 #define SSS_LUT_BIAS (0.5 / float(SSS_LUT_SIZE))
325
326 #ifdef USE_TRANSLUCENCY
327 layout(std140) uniform sssProfile {
328         vec4 kernel[MAX_SSS_SAMPLES];
329         vec4 radii_max_radius;
330         int sss_samples;
331 };
332
333 uniform sampler1D sssTexProfile;
334
335 vec3 sss_profile(float s) {
336         s /= radii_max_radius.w;
337         return texture(sssTexProfile, saturate(s) * SSS_LUT_SCALE + SSS_LUT_BIAS).rgb;
338 }
339 #endif
340
341 vec3 light_translucent(LightData ld, vec3 W, vec3 N, vec4 l_vector, float scale)
342 {
343 #if !defined(USE_TRANSLUCENCY) || defined(VOLUMETRICS)
344         return vec3(0.0);
345 #else
346         vec3 vis = vec3(1.0);
347
348         /* Only shadowed light can produce translucency */
349         if (ld.l_shadowid >= 0.0) {
350                 ShadowData data = shadows_data[int(ld.l_shadowid)];
351                 float delta;
352
353                 vec4 L = (ld.l_type != SUN) ? l_vector : vec4(-ld.l_forward, 1.0);
354
355                 vec3 T, B;
356                 make_orthonormal_basis(L.xyz / L.w, T, B);
357
358                 vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy);
359                 rand.zw *= fast_sqrt(rand.y) * data.sh_blur;
360
361                 /* We use the full l_vector.xyz so that the spread is minimize
362                  * if the shading point is further away from the light source */
363                 W = W + T * rand.z + B * rand.w;
364
365                 if (ld.l_type == SUN) {
366                         int scd_id = int(data.sh_data_start);
367                         vec4 view_z = vec4(dot(W - cameraPos, cameraForward));
368
369                         vec4 weights = step(shadows_cascade_data[scd_id].split_end_distances, view_z);
370                         float id = abs(4.0 - dot(weights, weights));
371
372                         if (id > 3.0) {
373                                 return vec3(0.0);
374                         }
375
376                         float range = abs(data.sh_far - data.sh_near); /* Same factor as in get_cascade_world_distance(). */
377
378                         vec4 shpos = shadows_cascade_data[scd_id].shadowmat[int(id)] * vec4(W, 1.0);
379                         float dist = shpos.z * range;
380
381                         if (shpos.z > 1.0 || shpos.z < 0.0) {
382                                 return vec3(0.0);
383                         }
384
385                         ShadowSample s = sample_cascade(shpos.xy, data.sh_tex_start + id);
386                         delta = get_depth_delta(s);
387                 }
388                 else {
389                         vec3 cubevec = W - shadows_cube_data[int(data.sh_data_start)].position.xyz;
390                         float dist = length(cubevec);
391
392                         /* If fragment is out of shadowmap range, do not occlude */
393                         /* XXX : we check radial distance against a cubeface distance.
394                          * We loose quite a bit of valid area. */
395                         if (dist < data.sh_far) {
396                                 cubevec /= dist;
397
398                                 ShadowSample s = sample_cube(cubevec, data.sh_tex_start);
399                                 delta = get_depth_delta(s);
400                         }
401                 }
402
403                 /* XXX : Removing Area Power. */
404                 /* TODO : put this out of the shader. */
405                 float falloff;
406                 if (ld.l_type == AREA_RECT || ld.l_type == AREA_ELLIPSE) {
407                         vis *= (ld.l_sizex * ld.l_sizey * 4.0 * M_PI) * (1.0 / 80.0);
408                         if (ld.l_type == AREA_ELLIPSE) {
409                                 vis *= M_PI * 0.25;
410                         }
411                         vis *= 0.3 * 20.0 * max(0.0, dot(-ld.l_forward, l_vector.xyz / l_vector.w)); /* XXX ad hoc, empirical */
412                         vis /= (l_vector.w * l_vector.w);
413                         falloff = dot(N, l_vector.xyz / l_vector.w);
414                 }
415                 else if (ld.l_type == SUN) {
416                         vis *= (4.0f * ld.l_radius * ld.l_radius * M_2PI) * (1.0 / 12.5); /* Removing area light power*/
417                         vis *= M_2PI * 0.78; /* Matching cycles with point light. */
418                         vis *= 0.082; /* XXX ad hoc, empirical */
419                         falloff = dot(N, -ld.l_forward);
420                 }
421                 else {
422                         vis *= (4.0 * ld.l_radius * ld.l_radius) * (1.0 /10.0);
423                         vis *= 1.5; /* XXX ad hoc, empirical */
424                         vis /= (l_vector.w * l_vector.w);
425                         falloff = dot(N, l_vector.xyz / l_vector.w);
426                 }
427                 // vis *= M_1_PI; /* Normalize */
428
429                 /* Applying profile */
430                 vis *= sss_profile(abs(delta) / scale);
431
432                 /* No transmittance at grazing angle (hide artifacts) */
433                 vis *= saturate(falloff * 2.0);
434
435                 if (ld.l_type == SPOT) {
436                         float z = dot(ld.l_forward, l_vector.xyz);
437                         vec3 lL = l_vector.xyz / z;
438                         float x = dot(ld.l_right, lL) / ld.l_sizex;
439                         float y = dot(ld.l_up, lL) / ld.l_sizey;
440
441                         float ellipse = inversesqrt(1.0 + x * x + y * y);
442
443                         float spotmask = smoothstep(0.0, 1.0, (ellipse - ld.l_spot_size) / ld.l_spot_blend);
444
445                         vis *= spotmask;
446                         vis *= step(0.0, -dot(l_vector.xyz, ld.l_forward));
447                 }
448                 else if (ld.l_type == AREA_RECT || ld.l_type == AREA_ELLIPSE) {
449                         vis *= step(0.0, -dot(l_vector.xyz, ld.l_forward));
450                 }
451         }
452         else {
453                 vis = vec3(0.0);
454         }
455
456         return vis;
457 #endif
458 }