68 69 layout(std140) uniform common_block 70 { 71 mat4 pastViewProjectionMatrix; 72 vec4 viewVecs[2]; 73 vec2 mipRatio[10]; /* To correct mip level texel mis-alignement */ 74 /* Ambient Occlusion */ 75 vec4 aoParameters[2]; 76 /* Volumetric */ 77 ivec4 volTexSize; 78 vec4 volDepthParameters; /* Parameters to the volume Z equation */ 79 vec4 volInvTexSize; 80 vec4 volJitter; 81 vec4 volCoordScale; /* To convert volume uvs to screen uvs */ 82 float volHistoryAlpha; 83 float volLightClamp; 84 float volShadowSteps; 85 bool volUseLights; 86 /* Screen Space Reflections */ 87 vec4 ssrParameters; 88 float ssrBorderFac; 89 float ssrMaxRoughness; 90 float ssrFireflyFac; 91 float ssrBrdfBias; 92 bool ssrToggle; 93 bool ssrefractToggle; 94 /* SubSurface Scattering */ 95 float sssJitterThreshold; 96 bool sssToggle; 97 /* Specular */ 98 bool specToggle; 99 /* Lights */ 100 int laNumLight; 101 /* Probes */ 102 int prbNumPlanar; 103 int prbNumRenderCube; 104 int prbNumRenderGrid; 105 int prbIrradianceVisSize; 106 float prbIrradianceSmooth; 107 float prbLodCubeMax; 108 float prbLodPlanarMax; 109 /* Misc*/ 110 int hizMipOffset; 111 int rayType; 112 float rayDepth; 113 }; 114 115 /* rayType (keep in sync with ray_type) */ 116 #define EEVEE_RAY_CAMERA 0 117 #define EEVEE_RAY_SHADOW 1 118 #define EEVEE_RAY_DIFFUSE 2 119 #define EEVEE_RAY_GLOSSY 3 120 121 /* aoParameters */ 122 #define aoDistance aoParameters[0].x 123 #define aoSamples aoParameters[0].y /* UNUSED */ 124 #define aoFactor aoParameters[0].z 125 #define aoInvSamples aoParameters[0].w /* UNUSED */ 126 127 #define aoOffset aoParameters[1].x /* UNUSED */ 128 #define aoBounceFac aoParameters[1].y 129 #define aoQuality aoParameters[1].z 130 #define aoSettings aoParameters[1].w 131 132 /* ssrParameters */ 133 #define ssrQuality ssrParameters.x 134 #define ssrThickness ssrParameters.y 135 #define ssrPixelSize ssrParameters.zw 136 137 #define M_PI 3.14159265358979323846 /* pi */ 138 #define M_2PI 6.28318530717958647692 /* 2*pi */ 139 #define M_PI_2 1.57079632679489661923 /* pi/2 */ 140 #define M_1_PI 0.318309886183790671538 /* 1/pi */ 141 #define M_1_2PI 0.159154943091895335768 /* 1/(2*pi) */ 142 #define M_1_PI2 0.101321183642337771443 /* 1/(pi^2) */ 143 144 #define LUT_SIZE 64 145 146 /* Buffers */ 147 uniform sampler2D colorBuffer; 148 uniform sampler2D depthBuffer; 149 uniform sampler2D maxzBuffer; 150 uniform sampler2D minzBuffer; 151 uniform sampler2DArray planarDepth; 152 153 #define cameraForward ViewMatrixInverse[2].xyz 154 #define cameraPos ViewMatrixInverse[3].xyz 155 #define cameraVec \ 156 ((ProjectionMatrix[3][3] == 0.0) ? normalize(cameraPos - worldPosition) : cameraForward) 157 #define viewCameraVec \ 158 ((ProjectionMatrix[3][3] == 0.0) ? normalize(-viewPosition) : vec3(0.0, 0.0, 1.0)) 159 160 /* ------- Structures -------- */ 161 162 /* ------ Lights ----- */ 163 struct LightData { 164 vec4 position_influence; /* w : InfluenceRadius (inversed and squared) */ 165 vec4 color_spec; /* w : Spec Intensity */ 166 vec4 spotdata_radius_shadow; /* x : spot size, y : spot blend, z : radius, w: shadow id */ 167 vec4 rightvec_sizex; /* xyz: Normalized up vector, w: area size X or spot scale X */ 168 vec4 upvec_sizey; /* xyz: Normalized right vector, w: area size Y or spot scale Y */ 169 vec4 forwardvec_type; /* xyz: Normalized forward vector, w: Light Type */ 170 }; 171 172 /* convenience aliases */ 173 #define l_color color_spec.rgb 174 #define l_spec color_spec.a 175 #define l_position position_influence.xyz 176 #define l_influence position_influence.w 177 #define l_sizex rightvec_sizex.w 178 #define l_sizey upvec_sizey.w 179 #define l_right rightvec_sizex.xyz 180 #define l_up upvec_sizey.xyz 181 #define l_forward forwardvec_type.xyz 182 #define l_type forwardvec_type.w 183 #define l_spot_size spotdata_radius_shadow.x 184 #define l_spot_blend spotdata_radius_shadow.y 185 #define l_radius spotdata_radius_shadow.z 186 #define l_shadowid spotdata_radius_shadow.w 187 188 /* ------ Shadows ----- */ 189 #ifndef MAX_CASCADE_NUM 190 # define MAX_CASCADE_NUM 4 191 #endif 192 193 struct ShadowData { 194 vec4 near_far_bias_exp; 195 vec4 shadow_data_start_end; 196 vec4 contact_shadow_data; 197 }; 198 199 struct ShadowCubeData { 200 vec4 position; 201 }; 202 203 struct ShadowCascadeData { 204 mat4 shadowmat[MAX_CASCADE_NUM]; 205 vec4 split_start_distances; 206 vec4 split_end_distances; 207 }; 208 209 /* convenience aliases */ 210 #define sh_near near_far_bias_exp.x 211 #define sh_far near_far_bias_exp.y 212 #define sh_bias near_far_bias_exp.z 213 #define sh_exp near_far_bias_exp.w 214 #define sh_bleed near_far_bias_exp.w 215 #define sh_tex_start shadow_data_start_end.x 216 #define sh_data_start shadow_data_start_end.y 217 #define sh_multi_nbr shadow_data_start_end.z 218 #define sh_blur shadow_data_start_end.w 219 #define sh_contact_dist contact_shadow_data.x 220 #define sh_contact_offset contact_shadow_data.y 221 #define sh_contact_spread contact_shadow_data.z 222 #define sh_contact_thickness contact_shadow_data.w 223 224 /* ------- Convenience functions --------- */ 225 226 vec3 mul(mat3 m, vec3 v) 227 { 228 return m * v; 229 } 230 mat3 mul(mat3 m1, mat3 m2) 231 { 232 return m1 * m2; 233 } 234 vec3 transform_direction(mat4 m, vec3 v) 235 { 236 return mat3(m) * v; 237 } 238 vec3 transform_point(mat4 m, vec3 v) 239 { 240 return (m * vec4(v, 1.0)).xyz; 241 } 242 vec3 project_point(mat4 m, vec3 v) 243 { 244 vec4 tmp = m * vec4(v, 1.0); 245 return tmp.xyz / tmp.w; 246 } 247 248 #define min3(a, b, c) min(a, min(b, c)) 249 #define min4(a, b, c, d) min(a, min3(b, c, d)) 250 #define min5(a, b, c, d, e) min(a, min4(b, c, d, e)) 251 #define min6(a, b, c, d, e, f) min(a, min5(b, c, d, e, f)) 252 #define min7(a, b, c, d, e, f, g) min(a, min6(b, c, d, e, f, g)) 253 #define min8(a, b, c, d, e, f, g, h) min(a, min7(b, c, d, e, f, g, h)) 254 #define min9(a, b, c, d, e, f, g, h, i) min(a, min8(b, c, d, e, f, g, h, i)) 255 256 #define max3(a, b, c) max(a, max(b, c)) 257 #define max4(a, b, c, d) max(a, max3(b, c, d)) 258 #define max5(a, b, c, d, e) max(a, max4(b, c, d, e)) 259 #define max6(a, b, c, d, e, f) max(a, max5(b, c, d, e, f)) 260 #define max7(a, b, c, d, e, f, g) max(a, max6(b, c, d, e, f, g)) 261 #define max8(a, b, c, d, e, f, g, h) max(a, max7(b, c, d, e, f, g, h)) 262 #define max9(a, b, c, d, e, f, g, h, i) max(a, max8(b, c, d, e, f, g, h, i)) 263 264 #define avg3(a, b, c) (a + b + c) * (1.0 / 3.0) 265 #define avg4(a, b, c, d) (a + b + c + d) * (1.0 / 4.0) 266 #define avg5(a, b, c, d, e) (a + b + c + d + e) * (1.0 / 5.0) 267 #define avg6(a, b, c, d, e, f) (a + b + c + d + e + f) * (1.0 / 6.0) 268 #define avg7(a, b, c, d, e, f, g) (a + b + c + d + e + f + g) * (1.0 / 7.0) 269 #define avg8(a, b, c, d, e, f, g, h) (a + b + c + d + e + f + g + h) * (1.0 / 8.0) 270 #define avg9(a, b, c, d, e, f, g, h, i) (a + b + c + d + e + f + g + h + i) * (1.0 / 9.0) 271 272 float min_v2(vec2 v) 273 { 274 return min(v.x, v.y); 275 } 276 float min_v3(vec3 v) 277 { 278 return min(v.x, min(v.y, v.z)); 279 } 280 float max_v2(vec2 v) 281 { 282 return max(v.x, v.y); 283 } 284 float max_v3(vec3 v) 285 { 286 return max(v.x, max(v.y, v.z)); 287 } 288 289 float sum(vec2 v) 290 { 291 return dot(vec2(1.0), v); 292 } 293 float sum(vec3 v) 294 { 295 return dot(vec3(1.0), v); 296 } 297 float sum(vec4 v) 298 { 299 return dot(vec4(1.0), v); 300 } 301 302 float saturate(float a) 303 { 304 return clamp(a, 0.0, 1.0); 305 } 306 vec2 saturate(vec2 a) 307 { 308 return clamp(a, 0.0, 1.0); 309 } 310 vec3 saturate(vec3 a) 311 { 312 return clamp(a, 0.0, 1.0); 313 } 314 vec4 saturate(vec4 a) 315 { 316 return clamp(a, 0.0, 1.0); 317 } 318 319 float distance_squared(vec2 a, vec2 b) 320 { 321 a -= b; 322 return dot(a, a); 323 } 324 float distance_squared(vec3 a, vec3 b) 325 { 326 a -= b; 327 return dot(a, a); 328 } 329 float len_squared(vec3 a) 330 { 331 return dot(a, a); 332 } 333 334 float inverse_distance(vec3 V) 335 { 336 return max(1 / length(V), 1e-8); 337 } 338 339 vec2 mip_ratio_interp(float mip) 340 { 341 float low_mip = floor(mip); 342 return mix(mipRatio[int(low_mip)], mipRatio[int(low_mip + 1.0)], mip - low_mip); 343 } 344 345 /* ------- RNG ------- */ 346 347 float wang_hash_noise(uint s) 348 { 349 s = (s ^ 61u) ^ (s >> 16u); 350 s *= 9u; 351 s = s ^ (s >> 4u); 352 s *= 0x27d4eb2du; 353 s = s ^ (s >> 15u); 354 355 return fract(float(s) / 4294967296.0); 356 } 357 358 /* ------- Fast Math ------- */ 359 360 /* [Drobot2014a] Low Level Optimizations for GCN */ 361 float fast_sqrt(float v) 362 { 363 return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1)); 364 } 365 366 vec2 fast_sqrt(vec2 v) 367 { 368 return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1)); 369 } 370 371 /* [Eberly2014] GPGPU Programming for Games and Science */ 372 float fast_acos(float v) 373 { 374 float res = -0.156583 * abs(v) + M_PI_2; 375 res *= fast_sqrt(1.0 - abs(v)); 376 return (v >= 0) ? res : M_PI - res; 377 } 378 379 vec2 fast_acos(vec2 v) 380 { 381 vec2 res = -0.156583 * abs(v) + M_PI_2; 382 res *= fast_sqrt(1.0 - abs(v)); 383 v.x = (v.x >= 0) ? res.x : M_PI - res.x; 384 v.y = (v.y >= 0) ? res.y : M_PI - res.y; 385 return v; 386 } 387 388 float point_plane_projection_dist(vec3 lineorigin, vec3 planeorigin, vec3 planenormal) 389 { 390 return dot(planenormal, planeorigin - lineorigin); 391 } 392 393 float line_plane_intersect_dist(vec3 lineorigin, 394 vec3 linedirection, 395 vec3 planeorigin, 396 vec3 planenormal) 397 { 398 return dot(planenormal, planeorigin - lineorigin) / dot(planenormal, linedirection); 399 } 400 401 float line_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec4 plane) 402 { 403 vec3 plane_co = plane.xyz * (-plane.w / len_squared(plane.xyz)); 404 vec3 h = lineorigin - plane_co; 405 return -dot(plane.xyz, h) / dot(plane.xyz, linedirection); 406 } 407 408 vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin, vec3 planenormal) 409 { 410 float dist = line_plane_intersect_dist(lineorigin, linedirection, planeorigin, planenormal); 411 return lineorigin + linedirection * dist; 412 } 413 414 vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec4 plane) 415 { 416 float dist = line_plane_intersect_dist(lineorigin, linedirection, plane); 417 return lineorigin + linedirection * dist; 418 } 419 420 float line_aligned_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec3 planeorigin) 421 { 422 /* aligned plane normal */ 423 vec3 L = planeorigin - lineorigin; 424 float diskdist = length(L); 425 vec3 planenormal = -normalize(L); 426 return -diskdist / dot(planenormal, linedirection); 427 } 428 429 vec3 line_aligned_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin) 430 { 431 float dist = line_aligned_plane_intersect_dist(lineorigin, linedirection, planeorigin); 432 if (dist < 0) { 433 /* if intersection is behind we fake the intersection to be 434 * really far and (hopefully) not inside the radius of interest */ 435 dist = 1e16; 436 } 437 return lineorigin + linedirection * dist; 438 } 439 440 float line_unit_sphere_intersect_dist(vec3 lineorigin, vec3 linedirection) 441 { 442 float a = dot(linedirection, linedirection); 443 float b = dot(linedirection, lineorigin); 444 float c = dot(lineorigin, lineorigin) - 1; 445 446 float dist = 1e15; 447 float determinant = b * b - a * c; 448 if (determinant >= 0) { 449 dist = (sqrt(determinant) - b) / a; 450 } 451 452 return dist; 453 } 454 455 float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection) 456 { 457 /* https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ 458 */ 459 vec3 firstplane = (vec3(1.0) - lineorigin) / linedirection; 460 vec3 secondplane = (vec3(-1.0) - lineorigin) / linedirection; 461 vec3 furthestplane = max(firstplane, secondplane); 462 463 return min_v3(furthestplane); 464 } 465 466 /* Return texture coordinates to sample Surface LUT */ 467 vec2 lut_coords(float cosTheta, float roughness) 468 { 469 float theta = acos(cosTheta); 470 vec2 coords = vec2(roughness, theta / M_PI_2); 471 472 /* scale and bias coordinates, for correct filtered lookup */ 473 return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE; 474 } 475 476 vec2 lut_coords_ltc(float cosTheta, float roughness) 477 { 478 vec2 coords = vec2(roughness, sqrt(1.0 - cosTheta)); 479 480 /* scale and bias coordinates, for correct filtered lookup */ 481 return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE; 482 } 483 484 /* -- Tangent Space conversion -- */ 485 vec3 tangent_to_world(vec3 vector, vec3 N, vec3 T, vec3 B) 486 { 487 return T * vector.x + B * vector.y + N * vector.z; 488 } 489 490 vec3 world_to_tangent(vec3 vector, vec3 N, vec3 T, vec3 B) 491 { 492 return vec3(dot(T, vector), dot(B, vector), dot(N, vector)); 493 } 494 495 void make_orthonormal_basis(vec3 N, out vec3 T, out vec3 B) 496 { 497 vec3 UpVector = abs(N.z) < 0.99999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); 498 T = normalize(cross(UpVector, N)); 499 B = cross(N, T); 500 } 501 502 /* ---- Opengl Depth conversion ---- */ 503 504 float linear_depth(bool is_persp, float z, float zf, float zn) 505 { 506 if (is_persp) { 507 return (zn * zf) / (z * (zn - zf) + zf); 508 } 509 else { 510 return (z * 2.0 - 1.0) * zf; 511 } 512 } 513 514 float buffer_depth(bool is_persp, float z, float zf, float zn) 515 { 516 if (is_persp) { 517 return (zf * (zn - z)) / (z * (zn - zf)); 518 } 519 else { 520 return (z / (zf * 2.0)) + 0.5; 521 } 522 } 523 524 float get_view_z_from_depth(float depth) 525 { 526 if (ProjectionMatrix[3][3] == 0.0) { 527 float d = 2.0 * depth - 1.0; 528 return -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]); 529 } 530 else { 531 return viewVecs[0].z + depth * viewVecs[1].z; 532 } 533 } 534 535 float get_depth_from_view_z(float z) 536 { 537 if (ProjectionMatrix[3][3] == 0.0) { 538 float d = (-ProjectionMatrix[3][2] / z) - ProjectionMatrix[2][2]; 539 return d * 0.5 + 0.5; 540 } 541 else { 542 return (z - viewVecs[0].z) / viewVecs[1].z; 543 } 544 } 545 546 vec2 get_uvs_from_view(vec3 view) 547 { 548 vec3 ndc = project_point(ProjectionMatrix, view); 549 return ndc.xy * 0.5 + 0.5; 550 } 551 552 vec3 get_view_space_from_depth(vec2 uvcoords, float depth) 553 { 554 if (ProjectionMatrix[3][3] == 0.0) { 555 return vec3(viewVecs[0].xy + uvcoords * viewVecs[1].xy, 1.0) * get_view_z_from_depth(depth); 556 } 557 else { 558 return viewVecs[0].xyz + vec3(uvcoords, depth) * viewVecs[1].xyz; 559 } 560 } 561 562 vec3 get_world_space_from_depth(vec2 uvcoords, float depth) 563 { 564 return (ViewMatrixInverse * vec4(get_view_space_from_depth(uvcoords, depth), 1.0)).xyz; 565 } 566 567 vec3 get_specular_reflection_dominant_dir(vec3 N, vec3 V, float roughness) 568 { 569 vec3 R = -reflect(V, N); 570 float smoothness = 1.0 - roughness; 571 float fac = smoothness * (sqrt(smoothness) + roughness); 572 return normalize(mix(N, R, fac)); 573 } 574 575 float specular_occlusion(float NV, float AO, float roughness) 576 { 577 return saturate(pow(NV + AO, roughness) - 1.0 + AO); 578 } 579 580 /* --- Refraction utils --- */ 581 582 float ior_from_f0(float f0) 583 { 584 float f = sqrt(f0); 585 return (-f - 1.0) / (f - 1.0); 586 } 587 588 float f0_from_ior(float eta) 589 { 590 float A = (eta - 1.0) / (eta + 1.0); 591 return A * A; 592 } 593 594 vec3 get_specular_refraction_dominant_dir(vec3 N, vec3 V, float roughness, float ior) 595 { 596 /* TODO: This a bad approximation. Better approximation should fit 597 * the refracted vector and roughness into the best prefiltered reflection 598 * lobe. */ 599 /* Correct the IOR for ior < 1.0 to not see the abrupt delimitation or the TIR */ 600 ior = (ior < 1.0) ? mix(ior, 1.0, roughness) : ior; 601 float eta = 1.0 / ior; 602 603 float NV = dot(N, -V); 604 605 /* Custom Refraction. */ 606 float k = 1.0 - eta * eta * (1.0 - NV * NV); 607 k = max(0.0, k); /* Only this changes. */ 608 vec3 R = eta * -V - (eta * NV + sqrt(k)) * N; 609 610 return R; 611 } 612 613 float get_btdf_lut(sampler2DArray btdf_lut_tex, float NV, float roughness, float ior) 614 { 615 const vec3 lut_scale_bias_texel_size = vec3((LUT_SIZE - 1.0), 0.5, 1.5) / LUT_SIZE; 616 617 vec3 coords; 618 /* Try to compensate for the low resolution and interpolation error. */ 619 coords.x = (ior > 1.0) ? (0.9 + lut_scale_bias_texel_size.z) + 620 (0.1 - lut_scale_bias_texel_size.z) * f0_from_ior(ior) : 621 (0.9 + lut_scale_bias_texel_size.z) * ior * ior; 622 coords.y = 1.0 - saturate(NV); 623 coords.xy *= lut_scale_bias_texel_size.x; 624 coords.xy += lut_scale_bias_texel_size.y; 625 626 const float lut_lvl_ofs = 4.0; /* First texture lvl of roughness. */ 627 const float lut_lvl_scale = 16.0; /* How many lvl of roughness in the lut. */ 628 629 float mip = roughness * lut_lvl_scale; 630 float mip_floor = floor(mip); 631 632 coords.z = lut_lvl_ofs + mip_floor + 1.0; 633 float btdf_high = textureLod(btdf_lut_tex, coords, 0.0).r; 634 635 coords.z -= 1.0; 636 float btdf_low = textureLod(btdf_lut_tex, coords, 0.0).r; 637 638 float btdf = (ior == 1.0) ? 1.0 : mix(btdf_low, btdf_high, mip - coords.z); 639 640 return btdf; 641 } 642 643 /* ---- Encode / Decode Normal buffer data ---- */ 644 /* From http://aras-p.info/texts/CompactNormalStorage.html 645 * Using Method #4: Spheremap Transform */ 646 vec2 normal_encode(vec3 n, vec3 view) 647 { 648 float p = sqrt(n.z * 8.0 + 8.0); 649 return n.xy / p + 0.5; 650 } 651 652 vec3 normal_decode(vec2 enc, vec3 view) 653 { 654 vec2 fenc = enc * 4.0 - 2.0; 655 float f = dot(fenc, fenc); 656 float g = sqrt(1.0 - f / 4.0); 657 vec3 n; 658 n.xy = fenc * g; 659 n.z = 1 - f / 2; 660 return n; 661 } 662 663 /* ---- RGBM (shared multiplier) encoding ---- */ 664 /* From http://iwasbeingirony.blogspot.fr/2010/06/difference-between-rgbm-and-rgbd.html */ 665 666 /* Higher RGBM_MAX_RANGE gives imprecision issues in low intensity. */ 667 #define RGBM_MAX_RANGE 512.0 668 669 vec4 rgbm_encode(vec3 rgb) 670 { 671 float maxRGB = max_v3(rgb); 672 float M = maxRGB / RGBM_MAX_RANGE; 673 M = ceil(M * 255.0) / 255.0; 674 return vec4(rgb / (M * RGBM_MAX_RANGE), M); 675 } 676 677 vec3 rgbm_decode(vec4 data) 678 { 679 return data.rgb * (data.a * RGBM_MAX_RANGE); 680 } 681 682 /* ---- RGBE (shared exponent) encoding ---- */ 683 vec4 rgbe_encode(vec3 rgb) 684 { 685 float maxRGB = max_v3(rgb); 686 float fexp = ceil(log2(maxRGB)); 687 return vec4(rgb / exp2(fexp), (fexp + 128.0) / 255.0); 688 } 689 690 vec3 rgbe_decode(vec4 data) 691 { 692 float fexp = data.a * 255.0 - 128.0; 693 return data.rgb * exp2(fexp); 694 } 695 696 #if 1 697 # define irradiance_encode rgbe_encode 698 # define irradiance_decode rgbe_decode 699 #else /* No ecoding (when using floating point format) */ 700 # define irradiance_encode(X) (X).rgbb 701 # define irradiance_decode(X) (X).rgb 702 #endif 703 704 /* Irradiance Visibility Encoding */ 705 #if 1 706 vec4 visibility_encode(vec2 accum, float range) 707 { 708 accum /= range; 709 710 vec4 data; 711 data.x = fract(accum.x); 712 data.y = floor(accum.x) / 255.0; 713 data.z = fract(accum.y); 714 data.w = floor(accum.y) / 255.0; 715 716 return data; 717 } 718 719 vec2 visibility_decode(vec4 data, float range) 720 { 721 return (data.xz + data.yw * 255.0) * range; 722 } 723 #else /* No ecoding (when using floating point format) */ 724 vec4 visibility_encode(vec2 accum, float range) 725 { 726 return accum.xyxy; 727 } 728 729 vec2 visibility_decode(vec4 data, float range) 730 { 731 return data.xy; 732 } 733 #endif 734 735 /* Fresnel monochromatic, perfect mirror */ 736 float F_eta(float eta, float cos_theta) 737 { 738 /* compute fresnel reflectance without explicitly computing 739 * the refracted direction */ 740 float c = abs(cos_theta); 741 float g = eta * eta - 1.0 + c * c; 742 float result; 743 744 if (g > 0.0) { 745 g = sqrt(g); 746 vec2 g_c = vec2(g) + vec2(c, -c); 747 float A = g_c.y / g_c.x; 748 A *= A; 749 g_c *= c; 750 float B = (g_c.y - 1.0) / (g_c.x + 1.0); 751 B *= B; 752 result = 0.5 * A * (1.0 + B); 753 } 754 else { 755 result = 1.0; /* TIR (no refracted component) */ 756 } 757 758 return result; 759 } 760 761 /* Fresnel color blend base on fresnel factor */ 762 vec3 F_color_blend(float eta, float fresnel, vec3 f0_color) 763 { 764 float f0 = F_eta(eta, 1.0); 765 float fac = saturate((fresnel - f0) / max(1e-8, 1.0 - f0)); 766 return mix(f0_color, vec3(1.0), fac); 767 } 768 769 /* Fresnel */ 770 vec3 F_schlick(vec3 f0, float cos_theta) 771 { 772 float fac = 1.0 - cos_theta; 773 float fac2 = fac * fac; 774 fac = fac2 * fac2 * fac; 775 776 /* Unreal specular matching : if specular color is below 2% intensity, 777 * (using green channel for intensity) treat as shadowning */ 778 return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * fac + (1.0 - fac) * f0; 779 } 780 781 /* Fresnel approximation for LTC area lights (not MRP) */ 782 vec3 F_area(vec3 f0, vec3 f90, vec2 lut) 783 { 784 /* Unreal specular matching : if specular color is below 2% intensity, 785 * treat as shadowning */ 786 return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * lut.y * f90 + lut.x * f0; 787 } 788 789 /* Fresnel approximation for IBL */ 790 vec3 F_ibl(vec3 f0, vec3 f90, vec2 lut) 791 { 792 /* Unreal specular matching : if specular color is below 2% intensity, 793 * treat as shadowning */ 794 return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * lut.y * f90 + lut.x * f0; 795 } 796 797 /* GGX */ 798 float D_ggx_opti(float NH, float a2) 799 { 800 float tmp = (NH * a2 - NH) * NH + 1.0; 801 return M_PI * tmp * tmp; /* Doing RCP and mul a2 at the end */ 802 } 803 804 float G1_Smith_GGX(float NX, float a2) 805 { 806 /* Using Brian Karis approach and refactoring by NX/NX 807 * this way the (2*NL)*(2*NV) in G = G1(V) * G1(L) gets canceled by the brdf denominator 4*NL*NV 808 * Rcp is done on the whole G later 809 * Note that this is not convenient for the transmission formula */ 810 return NX + sqrt(NX * (NX - NX * a2) + a2); 811 /* return 2 / (1 + sqrt(1 + a2 * (1 - NX*NX) / (NX*NX) ) ); /* Reference function */ 812 } 813 814 float bsdf_ggx(vec3 N, vec3 L, vec3 V, float roughness) 815 { 816 float a = roughness; 817 float a2 = a * a; 818 819 vec3 H = normalize(L + V); 820 float NH = max(dot(N, H), 1e-8); 821 float NL = max(dot(N, L), 1e-8); 822 float NV = max(dot(N, V), 1e-8); 823 824 float G = G1_Smith_GGX(NV, a2) * G1_Smith_GGX(NL, a2); /* Doing RCP at the end */ 825 float D = D_ggx_opti(NH, a2); 826 827 /* Denominator is canceled by G1_Smith */ 828 /* bsdf = D * G / (4.0 * NL * NV); /* Reference function */ 829 return NL * a2 / (D * G); /* NL to Fit cycles Equation : line. 345 in bsdf_microfacet.h */ 830 } 831 832 void accumulate_light(vec3 light, float fac, inout vec4 accum) 833 { 834 accum += vec4(light, 1.0) * min(fac, (1.0 - accum.a)); 835 } 836 837 /* ----------- Cone Aperture Approximation --------- */ 838 839 /* Return a fitted cone angle given the input roughness */ 840 float cone_cosine(float r) 841 { 842 /* Using phong gloss 843 * roughness = sqrt(2/(gloss+2)) */ 844 float gloss = -2 + 2 / (r * r); 845 /* Drobot 2014 in GPUPro5 */ 846 // return cos(2.0 * sqrt(2.0 / (gloss + 2))); 847 /* Uludag 2014 in GPUPro5 */ 848 // return pow(0.244, 1 / (gloss + 1)); 849 /* Jimenez 2016 in Practical Realtime Strategies for Accurate Indirect Occlusion*/ 850 return exp2(-3.32193 * r * r); 851 } 852 853 /* --------- Closure ---------- */ 854 #ifdef VOLUMETRICS 855 856 struct Closure { 857 vec3 absorption; 858 vec3 scatter; 859 vec3 emission; 860 float anisotropy; 861 }; 862 863 # define CLOSURE_DEFAULT Closure(vec3(0.0), vec3(0.0), vec3(0.0), 0.0) 864 865 Closure closure_mix(Closure cl1, Closure cl2, float fac) 866 { 867 Closure cl; 868 cl.absorption = mix(cl1.absorption, cl2.absorption, fac); 869 cl.scatter = mix(cl1.scatter, cl2.scatter, fac); 870 cl.emission = mix(cl1.emission, cl2.emission, fac); 871 cl.anisotropy = mix(cl1.anisotropy, cl2.anisotropy, fac); 872 return cl; 873 } 874 875 Closure closure_add(Closure cl1, Closure cl2) 876 { 877 Closure cl; 878 cl.absorption = cl1.absorption + cl2.absorption; 879 cl.scatter = cl1.scatter + cl2.scatter; 880 cl.emission = cl1.emission + cl2.emission; 881 cl.anisotropy = (cl1.anisotropy + cl2.anisotropy) / 2.0; /* Average phase (no multi lobe) */ 882 return cl; 883 } 884 885 Closure closure_emission(vec3 rgb) 886 { 887 Closure cl = CLOSURE_DEFAULT; 888 cl.emission = rgb; 889 return cl; 890 } 891 892 #else /* VOLUMETRICS */ 893 894 struct Closure { 895 vec3 radiance; 896 float opacity; 897 # ifdef USE_SSS 898 vec4 sss_data; 899 # ifdef USE_SSS_ALBEDO 900 vec3 sss_albedo; 901 # endif 902 # endif 903 vec4 ssr_data; 904 vec2 ssr_normal; 905 int ssr_id; 906 }; 907 908 /* This is hacking ssr_id to tag transparent bsdf */ 909 # define TRANSPARENT_CLOSURE_FLAG -2 910 # define REFRACT_CLOSURE_FLAG -3 911 # define NO_SSR -999 912 913 # ifdef USE_SSS 914 # ifdef USE_SSS_ALBEDO 915 # define CLOSURE_DEFAULT \ 916 Closure(vec3(0.0), 1.0, vec4(0.0), vec3(0.0), vec4(0.0), vec2(0.0), -1) 917 # else 918 # define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec4(0.0), vec2(0.0), -1) 919 # endif 920 # else 921 # define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec2(0.0), -1) 922 # endif 923 924 uniform int outputSsrId; 925 926 Closure closure_mix(Closure cl1, Closure cl2, float fac) 927 { 928 Closure cl; 929 930 if (cl1.ssr_id == TRANSPARENT_CLOSURE_FLAG) { 931 cl.ssr_normal = cl2.ssr_normal; 932 cl.ssr_data = cl2.ssr_data; 933 cl.ssr_id = cl2.ssr_id; 934 # ifdef USE_SSS 935 cl1.sss_data = cl2.sss_data; 936 # ifdef USE_SSS_ALBEDO 937 cl1.sss_albedo = cl2.sss_albedo; 938 # endif 939 # endif 940 } 941 else if (cl2.ssr_id == TRANSPARENT_CLOSURE_FLAG) { 942 cl.ssr_normal = cl1.ssr_normal; 943 cl.ssr_data = cl1.ssr_data; 944 cl.ssr_id = cl1.ssr_id; 945 # ifdef USE_SSS 946 cl2.sss_data = cl1.sss_data; 947 # ifdef USE_SSS_ALBEDO 948 cl2.sss_albedo = cl1.sss_albedo; 949 # endif 950 # endif 951 } 952 else if (cl1.ssr_id == outputSsrId) { 953 /* When mixing SSR don't blend roughness. 954 * 955 * It makes no sense to mix them really, so we take either one of them and 956 * tone down its specularity (ssr_data.xyz) while keeping its roughness (ssr_data.w). 957 */ 958 cl.ssr_data = mix(cl1.ssr_data.xyzw, vec4(vec3(0.0), cl1.ssr_data.w), fac); 959 cl.ssr_normal = cl1.ssr_normal; 960 cl.ssr_id = cl1.ssr_id; 961 } 962 else { 963 cl.ssr_data = mix(vec4(vec3(0.0), cl2.ssr_data.w), cl2.ssr_data.xyzw, fac); 964 cl.ssr_normal = cl2.ssr_normal; 965 cl.ssr_id = cl2.ssr_id; 966 } 967 968 cl.opacity = mix(cl1.opacity, cl2.opacity, fac); 969 cl.radiance = mix(cl1.radiance * cl1.opacity, cl2.radiance * cl2.opacity, fac); 970 cl.radiance /= max(1e-8, cl.opacity); 971 972 # ifdef USE_SSS 973 /* Apply Mix on input */ 974 cl1.sss_data.rgb *= 1.0 - fac; 975 cl2.sss_data.rgb *= fac; 976 977 /* Select biggest radius. */ 978 bool use_cl1 = (cl1.sss_data.a > cl2.sss_data.a); 979 cl.sss_data = (use_cl1) ? cl1.sss_data : cl2.sss_data; 980 981 # ifdef USE_SSS_ALBEDO 982 /* TODO Find a solution to this. Dither? */ 983 cl.sss_albedo = (use_cl1) ? cl1.sss_albedo : cl2.sss_albedo; 984 /* Add radiance that was supposed to be filtered but was rejected. */ 985 cl.radiance += (use_cl1) ? cl2.sss_data.rgb * cl2.sss_albedo : cl1.sss_data.rgb * cl1.sss_albedo; 986 # else 987 /* Add radiance that was supposed to be filtered but was rejected. */ 988 cl.radiance += (use_cl1) ? cl2.sss_data.rgb : cl1.sss_data.rgb; 989 # endif 990 # endif 991 992 return cl; 993 } 994 995 Closure closure_add(Closure cl1, Closure cl2) 996 { 997 Closure cl = (cl1.ssr_id == outputSsrId) ? cl1 : cl2; 998 cl.radiance = cl1.radiance + cl2.radiance; 999 # ifdef USE_SSS 1000 cl.sss_data = (cl1.sss_data.a > 0.0) ? cl1.sss_data : cl2.sss_data; 1001 /* Add radiance that was supposed to be filtered but was rejected. */ 1002 cl.radiance += (cl1.sss_data.a > 0.0) ? cl2.sss_data.rgb : cl1.sss_data.rgb; 1003 # ifdef USE_SSS_ALBEDO 1004 /* TODO Find a solution to this. Dither? */ 1005 cl.sss_albedo = (cl1.sss_data.a > 0.0) ? cl1.sss_albedo : cl2.sss_albedo; 1006 # endif 1007 # endif 1008 cl.opacity = saturate(cl1.opacity + cl2.opacity); 1009 return cl; 1010 } 1011 1012 Closure closure_emission(vec3 rgb) 1013 { 1014 Closure cl = CLOSURE_DEFAULT; 1015 cl.radiance = rgb; 1016 return cl; 1017 } 1018 1019 /* Breaking this across multiple lines causes issues for some older GLSL compilers. */ 1020 /* clang-format off */ 1021 # if defined(MESH_SHADER) && !defined(USE_ALPHA_HASH) && !defined(USE_ALPHA_CLIP) && !defined(SHADOW_SHADER) && !defined(USE_MULTIPLY ) 1022 /* clang-format on */ 1023 layout(location = 0) out vec4 fragColor; 1024 layout(location = 1) out vec4 ssrNormals; 1025 layout(location = 2) out vec4 ssrData; 1026 # ifdef USE_SSS 1027 layout(location = 3) out vec4 sssData; 1028 # ifdef USE_SSS_ALBEDO 1029 layout(location = 4) out vec4 sssAlbedo; 1030 # endif /* USE_SSS_ALBEDO */ 1031 # endif /* USE_SSS */ 1032 1033 Closure nodetree_exec(void); /* Prototype */ 1034 1035 # if defined(USE_ALPHA_BLEND) 1036 /* Prototype because this file is included before volumetric_lib.glsl */ 1037 void volumetric_resolve(vec2 frag_uvs, 1038 float frag_depth, 1039 out vec3 transmittance, 1040 out vec3 scattering); 1041 # endif 1042 1043 # define NODETREE_EXEC 1044 void main() 1045 { 1046 Closure cl = nodetree_exec(); 1047 # ifndef USE_ALPHA_BLEND 1048 /* Prevent alpha hash material writing into alpha channel. */ 1049 cl.opacity = 1.0; 1050 # endif 1051 1052 # if defined(USE_ALPHA_BLEND) 1053 vec2 uvs = gl_FragCoord.xy * volCoordScale.zw; 1054 vec3 transmittance, scattering; 1055 volumetric_resolve(uvs, gl_FragCoord.z, transmittance, scattering); 1056 fragColor.rgb = cl.radiance * transmittance + scattering; 1057 fragColor.a = cl.opacity; 1058 # else 1059 fragColor = vec4(cl.radiance, cl.opacity); 1060 # endif 1061 1062 ssrNormals = cl.ssr_normal.xyyy; 1063 ssrData = cl.ssr_data; 1064 # ifdef USE_SSS 1065 sssData = cl.sss_data; 1066 # ifdef USE_SSS_ALBEDO 1067 sssAlbedo = cl.sss_albedo.rgbb; 1068 # endif 1069 # endif 1070 1071 /* For Probe capture */ 1072 # ifdef USE_SSS 1073 float fac = float(!sssToggle); 1074 1075 # ifdef USE_REFRACTION 1076 /* SSRefraction pass is done after the SSS pass. 1077 * In order to not loose the diffuse light totally we 1078 * need to merge the SSS radiance to the main radiance. */ 1079 fac = 1.0; 1080 # endif 1081 1082 # ifdef USE_SSS_ALBEDO 1083 fragColor.rgb += cl.sss_data.rgb * cl.sss_albedo.rgb * fac; 1084 # else 1085 fragColor.rgb += cl.sss_data.rgb * fac; 1086 # endif 1087 # endif 1088 } 1089 1090 # endif /* MESH_SHADER && !SHADOW_SHADER */ 1091 1092 #endif /* VOLUMETRICS */ 1093 1094 Closure nodetree_exec(void); /* Prototype */ 1095 1096 /* TODO find a better place */ 1097 #ifdef USE_MULTIPLY 1098 1099 out vec4 fragColor; 1100 1101 # define NODETREE_EXEC 1102 void main() 1103 { 1104 Closure cl = nodetree_exec(); 1105 fragColor = vec4(mix(vec3(1.0), cl.radiance, cl.opacity), 1.0); 1106 } 1107 #endif 1108 1109 vec2 mapping_octahedron(vec3 cubevec, vec2 texel_size) 1110 { 1111 /* projection onto octahedron */ 1112 cubevec /= dot(vec3(1.0), abs(cubevec)); 1113 1114 /* out-folding of the downward faces */ 1115 if (cubevec.z < 0.0) { 1116 vec2 cubevec_sign = step(0.0, cubevec.xy) * 2.0 - 1.0; 1117 cubevec.xy = (1.0 - abs(cubevec.yx)) * cubevec_sign; 1118 } 1119 1120 /* mapping to [0;1]ˆ2 texture space */ 1121 vec2 uvs = cubevec.xy * (0.5) + 0.5; 1122 1123 /* edge filtering fix */ 1124 uvs = (1.0 - 2.0 * texel_size) * uvs + texel_size; 1125 1126 return uvs; 1127 } 1128 1129 vec4 textureLod_octahedron(sampler2DArray tex, vec4 cubevec, float lod, float lod_max) 1130 { 1131 vec2 texelSize = 1.0 / vec2(textureSize(tex, int(lod_max))); 1132 1133 vec2 uvs = mapping_octahedron(cubevec.xyz, texelSize); 1134 1135 return textureLod(tex, vec3(uvs, cubevec.w), lod); 1136 } 1137 1138 vec4 texture_octahedron(sampler2DArray tex, vec4 cubevec) 1139 { 1140 vec2 texelSize = 1.0 / vec2(textureSize(tex, 0)); 1141 1142 vec2 uvs = mapping_octahedron(cubevec.xyz, texelSize); 1143 1144 return texture(tex, vec3(uvs, cubevec.w)); 1145 } 1146 1147 uniform sampler2DArray irradianceGrid; 1148 1149 #define IRRADIANCE_LIB 1150 1151 #ifdef IRRADIANCE_CUBEMAP 1152 struct IrradianceData { 1153 vec3 color; 1154 }; 1155 #elif defined(IRRADIANCE_SH_L2) 1156 struct IrradianceData { 1157 vec3 shcoefs[9]; 1158 }; 1159 #else /* defined(IRRADIANCE_HL2) */ 1160 struct IrradianceData { 1161 vec3 cubesides[3]; 1162 }; 1163 #endif 1164 1165 IrradianceData load_irradiance_cell(int cell, vec3 N) 1166 { 1167 /* Keep in sync with diffuse_filter_probe() */ 1168 1169 #if defined(IRRADIANCE_CUBEMAP) 1170 1171 # define AMBIANT_CUBESIZE 8 1172 ivec2 cell_co = ivec2(AMBIANT_CUBESIZE); 1173 int cell_per_row = textureSize(irradianceGrid, 0).x / cell_co.x; 1174 cell_co.x *= cell % cell_per_row; 1175 cell_co.y *= cell / cell_per_row; 1176 1177 vec2 texelSize = 1.0 / vec2(AMBIANT_CUBESIZE); 1178 1179 vec2 uvs = mapping_octahedron(N, texelSize); 1180 uvs *= vec2(AMBIANT_CUBESIZE) / vec2(textureSize(irradianceGrid, 0)); 1181 uvs += vec2(cell_co) / vec2(textureSize(irradianceGrid, 0)); 1182 1183 IrradianceData ir; 1184 ir.color = texture(irradianceGrid, vec3(uvs, 0.0)).rgb; 1185 1186 #elif defined(IRRADIANCE_SH_L2) 1187 1188 ivec2 cell_co = ivec2(3, 3); 1189 int cell_per_row = textureSize(irradianceGrid, 0).x / cell_co.x; 1190 cell_co.x *= cell % cell_per_row; 1191 cell_co.y *= cell / cell_per_row; 1192 1193 ivec3 ofs = ivec3(0, 1, 2); 1194 1195 IrradianceData ir; 1196 ir.shcoefs[0] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.xx, 0), 0).rgb; 1197 ir.shcoefs[1] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.yx, 0), 0).rgb; 1198 ir.shcoefs[2] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.zx, 0), 0).rgb; 1199 ir.shcoefs[3] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.xy, 0), 0).rgb; 1200 ir.shcoefs[4] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.yy, 0), 0).rgb; 1201 ir.shcoefs[5] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.zy, 0), 0).rgb; 1202 ir.shcoefs[6] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.xz, 0), 0).rgb; 1203 ir.shcoefs[7] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.yz, 0), 0).rgb; 1204 ir.shcoefs[8] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.zz, 0), 0).rgb; 1205 1206 #else /* defined(IRRADIANCE_HL2) */ 1207 1208 ivec2 cell_co = ivec2(3, 2); 1209 int cell_per_row = textureSize(irradianceGrid, 0).x / cell_co.x; 1210 cell_co.x *= cell % cell_per_row; 1211 cell_co.y *= cell / cell_per_row; 1212 1213 ivec3 is_negative = ivec3(step(0.0, -N)); 1214 1215 IrradianceData ir; 1216 ir.cubesides[0] = irradiance_decode( 1217 texelFetch(irradianceGrid, ivec3(cell_co + ivec2(0, is_negative.x), 0), 0)); 1218 ir.cubesides[1] = irradiance_decode( 1219 texelFetch(irradianceGrid, ivec3(cell_co + ivec2(1, is_negative.y), 0), 0)); 1220 ir.cubesides[2] = irradiance_decode( 1221 texelFetch(irradianceGrid, ivec3(cell_co + ivec2(2, is_negative.z), 0), 0)); 1222 1223 #endif 1224 1225 return ir; 1226 } 1227 1228 float load_visibility_cell(int cell, vec3 L, float dist, float bias, float bleed_bias, float range) 1229 { 1230 /* Keep in sync with diffuse_filter_probe() */ 1231 ivec2 cell_co = ivec2(prbIrradianceVisSize); 1232 ivec2 cell_per_row_col = textureSize(irradianceGrid, 0).xy / prbIrradianceVisSize; 1233 cell_co.x *= (cell % cell_per_row_col.x); 1234 cell_co.y *= (cell / cell_per_row_col.x) % cell_per_row_col.y; 1235 float layer = 1.0 + float((cell / cell_per_row_col.x) / cell_per_row_col.y); 1236 1237 vec2 texel_size = 1.0 / vec2(textureSize(irradianceGrid, 0).xy); 1238 vec2 co = vec2(cell_co) * texel_size; 1239 1240 vec2 uv = mapping_octahedron(-L, vec2(1.0 / float(prbIrradianceVisSize))); 1241 uv *= vec2(prbIrradianceVisSize) * texel_size; 1242 1243 vec4 data = texture(irradianceGrid, vec3(co + uv, layer)); 1244 1245 /* Decoding compressed data */ 1246 vec2 moments = visibility_decode(data, range); 1247 1248 /* Doing chebishev test */ 1249 float variance = abs(moments.x * moments.x - moments.y); 1250 variance = max(variance, bias / 10.0); 1251 1252 float d = dist - moments.x; 1253 float p_max = variance / (variance + d * d); 1254 1255 /* Increase contrast in the weight by squaring it */ 1256 p_max *= p_max; 1257 1258 /* Now reduce light-bleeding by removing the [0, x] tail and linearly rescaling (x, 1] */ 1259 p_max = clamp((p_max - bleed_bias) / (1.0 - bleed_bias), 0.0, 1.0); 1260 1261 return (dist <= moments.x) ? 1.0 : p_max; 1262 } 1263 1264 /* http://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/ */ 1265 vec3 spherical_harmonics_L1(vec3 N, vec3 shcoefs[4]) 1266 { 1267 vec3 sh = vec3(0.0); 1268 1269 sh += 0.282095 * shcoefs[0]; 1270 1271 sh += -0.488603 * N.z * shcoefs[1]; 1272 sh += 0.488603 * N.y * shcoefs[2]; 1273 sh += -0.488603 * N.x * shcoefs[3]; 1274 1275 return sh; 1276 } 1277 1278 vec3 spherical_harmonics_L2(vec3 N, vec3 shcoefs[9]) 1279 { 1280 vec3 sh = vec3(0.0); 1281 1282 sh += 0.282095 * shcoefs[0]; 1283 1284 sh += -0.488603 * N.z * shcoefs[1]; 1285 sh += 0.488603 * N.y * shcoefs[2]; 1286 sh += -0.488603 * N.x * shcoefs[3]; 1287 1288 sh += 1.092548 * N.x * N.z * shcoefs[4]; 1289 sh += -1.092548 * N.z * N.y * shcoefs[5]; 1290 sh += 0.315392 * (3.0 * N.y * N.y - 1.0) * shcoefs[6]; 1291 sh += -1.092548 * N.x * N.y * shcoefs[7]; 1292 sh += 0.546274 * (N.x * N.x - N.z * N.z) * shcoefs[8]; 1293 1294 return sh; 1295 } 1296 1297 vec3 hl2_basis(vec3 N, vec3 cubesides[3]) 1298 { 1299 vec3 irradiance = vec3(0.0); 1300 1301 vec3 n_squared = N * N; 1302 1303 irradiance += n_squared.x * cubesides[0]; 1304 irradiance += n_squared.y * cubesides[1]; 1305 irradiance += n_squared.z * cubesides[2]; 1306 1307 return irradiance; 1308 } 1309 1310 vec3 compute_irradiance(vec3 N, IrradianceData ird) 1311 { 1312 #if defined(IRRADIANCE_CUBEMAP) 1313 return ird.color; 1314 #elif defined(IRRADIANCE_SH_L2) 1315 return spherical_harmonics_L2(N, ird.shcoefs); 1316 #else /* defined(IRRADIANCE_HL2) */ 1317 return hl2_basis(N, ird.cubesides); 1318 #endif 1319 } 1320 1321 vec3 irradiance_from_cell_get(int cell, vec3 ir_dir) 1322 { 1323 IrradianceData ir_data = load_irradiance_cell(cell, ir_dir); 1324 return compute_irradiance(ir_dir, ir_data); 1325 } 1326 1327 uniform sampler2DArray shadowCubeTexture; 1328 uniform sampler2DArray shadowCascadeTexture; 1329 1330 #define LAMPS_LIB 1331 1332 layout(std140) uniform shadow_block 1333 { 1334 ShadowData shadows_data[MAX_SHADOW]; 1335 ShadowCubeData shadows_cube_data[MAX_SHADOW_CUBE]; 1336 ShadowCascadeData shadows_cascade_data[MAX_SHADOW_CASCADE]; 1337 }; 1338 1339 layout(std140) uniform light_block 1340 { 1341 LightData lights_data[MAX_LIGHT]; 1342 }; 1343 1344 /* type */ 1345 #define POINT 0.0 1346 #define SUN 1.0 1347 #define SPOT 2.0 1348 #define AREA_RECT 4.0 1349 /* Used to define the area light shape, doesn't directly correspond to a Blender light type. */ 1350 #define AREA_ELLIPSE 100.0 1351 1352 #if defined(SHADOW_VSM) 1353 # define ShadowSample vec2 1354 # define sample_cube(vec, id) texture_octahedron(shadowCubeTexture, vec4(vec, id)).rg 1355 # define sample_cascade(vec, id) texture(shadowCascadeTexture, vec3(vec, id)).rg 1356 #elif defined(SHADOW_ESM) 1357 # define ShadowSample float 1358 # define sample_cube(vec, id) texture_octahedron(shadowCubeTexture, vec4(vec, id)).r 1359 # define sample_cascade(vec, id) texture(shadowCascadeTexture, vec3(vec, id)).r 1360 #else 1361 # define ShadowSample float 1362 # define sample_cube(vec, id) texture_octahedron(shadowCubeTexture, vec4(vec, id)).r 1363 # define sample_cascade(vec, id) texture(shadowCascadeTexture, vec3(vec, id)).r 1364 #endif 1365 1366 #if defined(SHADOW_VSM) 1367 # define get_depth_delta(dist, s) (dist - s.x) 1368 #else 1369 # define get_depth_delta(dist, s) (dist - s) 1370 #endif 1371 1372 /* ----------------------------------------------------------- */ 1373 /* ----------------------- Shadow tests ---------------------- */ 1374 /* ----------------------------------------------------------- */ 1375 1376 #if defined(SHADOW_VSM) 1377 1378 float shadow_test(ShadowSample moments, float dist, ShadowData sd) 1379 { 1380 float p = 0.0; 1381 1382 if (dist <= moments.x) { 1383 p = 1.0; 1384 } 1385 1386 float variance = moments.y - (moments.x * moments.x); 1387 variance = max(variance, sd.sh_bias / 10.0); 1388 1389 float d = moments.x - dist; 1390 float p_max = variance / (variance + d * d); 1391 1392 /* Now reduce light-bleeding by removing the [0, x] tail and linearly rescaling (x, 1] */ 1393 p_max = clamp((p_max - sd.sh_bleed) / (1.0 - sd.sh_bleed), 0.0, 1.0); 1394 1395 return max(p, p_max); 1396 } 1397 1398 #elif defined(SHADOW_ESM) 1399 1400 float shadow_test(ShadowSample z, float dist, ShadowData sd) 1401 { 1402 return saturate(exp(sd.sh_exp * (z - dist + sd.sh_bias))); 1403 } 1404 1405 #else 1406 1407 float shadow_test(ShadowSample z, float dist, ShadowData sd) 1408 { 1409 return step(0, z - dist + sd.sh_bias); 1410 } 1411 1412 #endif 1413 1414 /* ----------------------------------------------------------- */ 1415 /* ----------------------- Shadow types ---------------------- */ 1416 /* ----------------------------------------------------------- */ 1417 1418 float shadow_cubemap(ShadowData sd, ShadowCubeData scd, float texid, vec3 W) 1419 { 1420 vec3 cubevec = W - scd.position.xyz; 1421 float dist = length(cubevec); 1422 1423 cubevec /= dist; 1424 1425 ShadowSample s = sample_cube(cubevec, texid); 1426 return shadow_test(s, dist, sd); 1427 } 1428 1429 float evaluate_cascade(ShadowData sd, mat4 shadowmat, vec3 W, float range, float texid) 1430 { 1431 vec4 shpos = shadowmat * vec4(W, 1.0); 1432 float dist = shpos.z * range; 1433 1434 ShadowSample s = sample_cascade(shpos.xy, texid); 1435 float vis = shadow_test(s, dist, sd); 1436 1437 /* If fragment is out of shadowmap range, do not occlude */ 1438 if (shpos.z < 1.0 && shpos.z > 0.0) { 1439 return vis; 1440 } 1441 else { 1442 return 1.0; 1443 } 1444 } 1445 1446 float shadow_cascade(ShadowData sd, int scd_id, float texid, vec3 W) 1447 { 1448 vec4 view_z = vec4(dot(W - cameraPos, cameraForward)); 1449 vec4 weights = smoothstep(shadows_cascade_data[scd_id].split_end_distances, 1450 shadows_cascade_data[scd_id].split_start_distances.yzwx, 1451 view_z); 1452 1453 weights.yzw -= weights.xyz; 1454 1455 vec4 vis = vec4(1.0); 1456 float range = abs(sd.sh_far - sd.sh_near); /* Same factor as in get_cascade_world_distance(). */ 1457 1458 /* Branching using (weights > 0.0) is reaally slooow on intel so avoid it for now. */ 1459 /* TODO OPTI: Only do 2 samples and blend. */ 1460 vis.x = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[0], W, range, texid + 0); 1461 vis.y = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[1], W, range, texid + 1); 1462 vis.z = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[2], W, range, texid + 2); 1463 vis.w = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[3], W, range, texid + 3); 1464 1465 float weight_sum = dot(vec4(1.0), weights); 1466 if (weight_sum > 0.9999) { 1467 float vis_sum = dot(vec4(1.0), vis * weights); 1468 return vis_sum / weight_sum; 1469 } 1470 else { 1471 float vis_sum = dot(vec4(1.0), vis * step(0.001, weights)); 1472 return mix(1.0, vis_sum, weight_sum); 1473 } 1474 } 1475 1476 /* ----------------------------------------------------------- */ 1477 /* --------------------- Light Functions --------------------- */ 1478 /* ----------------------------------------------------------- */ 1479 1480 /* From Frostbite PBR Course 1481 * Distance based attenuation 1482 * http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf */ 1483 float distance_attenuation(float dist_sqr, float inv_sqr_influence) 1484 { 1485 float factor = dist_sqr * inv_sqr_influence; 1486 float fac = saturate(1.0 - factor * factor); 1487 return fac * fac; 1488 } 1489 1490 float spot_attenuation(LightData ld, vec3 l_vector) 1491 { 1492 float z = dot(ld.l_forward, l_vector.xyz); 1493 vec3 lL = l_vector.xyz / z; 1494 float x = dot(ld.l_right, lL) / ld.l_sizex; 1495 float y = dot(ld.l_up, lL) / ld.l_sizey; 1496 float ellipse = inversesqrt(1.0 + x * x + y * y); 1497 float spotmask = smoothstep(0.0, 1.0, (ellipse - ld.l_spot_size) / ld.l_spot_blend); 1498 return spotmask; 1499 } 1500 1501 float light_visibility(LightData ld, 1502 vec3 W, 1503 #ifndef VOLUMETRICS 1504 vec3 viewPosition, 1505 vec3 vN, 1506 #endif 1507 vec4 l_vector) 1508 { 1509 float vis = 1.0; 1510 1511 if (ld.l_type == SPOT) { 1512 vis *= spot_attenuation(ld, l_vector.xyz); 1513 } 1514 if (ld.l_type >= SPOT) { 1515 vis *= step(0.0, -dot(l_vector.xyz, ld.l_forward)); 1516 } 1517 if (ld.l_type != SUN) { 1518 vis *= distance_attenuation(l_vector.w * l_vector.w, ld.l_influence); 1519 } 1520 1521 #if !defined(VOLUMETRICS) || defined(VOLUME_SHADOW) 1522 /* shadowing */ 1523 if (ld.l_shadowid >= 0.0 && vis > 0.001) { 1524 ShadowData data = shadows_data[int(ld.l_shadowid)]; 1525 1526 if (ld.l_type == SUN) { 1527 vis *= shadow_cascade(data, int(data.sh_data_start), data.sh_tex_start, W); 1528 } 1529 else { 1530 vis *= shadow_cubemap( 1531 data, shadows_cube_data[int(data.sh_data_start)], data.sh_tex_start, W); 1532 } 1533 1534 # ifndef VOLUMETRICS 1535 /* Only compute if not already in shadow. */ 1536 if (data.sh_contact_dist > 0.0) { 1537 vec4 L = (ld.l_type != SUN) ? l_vector : vec4(-ld.l_forward, 1.0); 1538 float trace_distance = (ld.l_type != SUN) ? min(data.sh_contact_dist, l_vector.w) : 1539 data.sh_contact_dist; 1540 1541 vec3 T, B; 1542 make_orthonormal_basis(L.xyz / L.w, T, B); 1543 1544 vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy); 1545 rand.zw *= fast_sqrt(rand.y) * data.sh_contact_spread; 1546 1547 /* We use the full l_vector.xyz so that the spread is minimize 1548 * if the shading point is further away from the light source */ 1549 vec3 ray_dir = L.xyz + T * rand.z + B * rand.w; 1550 ray_dir = transform_direction(ViewMatrix, ray_dir); 1551 ray_dir = normalize(ray_dir); 1552 1553 vec3 ray_ori = viewPosition; 1554 1555 /* Fix translucency shadowed by contact shadows. */ 1556 vN = (gl_FrontFacing) ? vN : -vN; 1557 1558 if (dot(vN, ray_dir) <= 0.0) { 1559 return vis; 1560 } 1561 1562 float bias = 0.5; /* Constant Bias */ 1563 bias += 1.0 - abs(dot(vN, ray_dir)); /* Angle dependent bias */ 1564 bias *= gl_FrontFacing ? data.sh_contact_offset : -data.sh_contact_offset; 1565 1566 vec3 nor_bias = vN * bias; 1567 ray_ori += nor_bias; 1568 1569 ray_dir *= trace_distance; 1570 ray_dir -= nor_bias; 1571 1572 vec3 hit_pos = raycast( 1573 -1, ray_ori, ray_dir, data.sh_contact_thickness, rand.x, 0.1, 0.001, false); 1574 1575 if (hit_pos.z > 0.0) { 1576 hit_pos = get_view_space_from_depth(hit_pos.xy, hit_pos.z); 1577 float hit_dist = distance(viewPosition, hit_pos); 1578 float dist_ratio = hit_dist / trace_distance; 1579 return vis * saturate(dist_ratio * dist_ratio * dist_ratio); 1580 } 1581 } 1582 # endif 1583 } 1584 #endif 1585 1586 return vis; 1587 } 1588 1589 #ifdef USE_LTC 1590 float light_diffuse(LightData ld, vec3 N, vec3 V, vec4 l_vector) 1591 { 1592 if (ld.l_type == AREA_RECT) { 1593 vec3 corners[4]; 1594 corners[0] = normalize((l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * ld.l_sizey); 1595 corners[1] = normalize((l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * -ld.l_sizey); 1596 corners[2] = normalize((l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * -ld.l_sizey); 1597 corners[3] = normalize((l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * ld.l_sizey); 1598 1599 return ltc_evaluate_quad(corners, N); 1600 } 1601 else if (ld.l_type == AREA_ELLIPSE) { 1602 vec3 points[3]; 1603 points[0] = (l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * -ld.l_sizey; 1604 points[1] = (l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * -ld.l_sizey; 1605 points[2] = (l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * ld.l_sizey; 1606 1607 return ltc_evaluate_disk(N, V, mat3(1.0), points); 1608 } 1609 else { 1610 float radius = ld.l_radius; 1611 radius /= (ld.l_type == SUN) ? 1.0 : l_vector.w; 1612 vec3 L = (ld.l_type == SUN) ? -ld.l_forward : (l_vector.xyz / l_vector.w); 1613 1614 return ltc_evaluate_disk_simple(radius, dot(N, L)); 1615 } 1616 } 1617 1618 float light_specular(LightData ld, vec4 ltc_mat, vec3 N, vec3 V, vec4 l_vector) 1619 { 1620 if (ld.l_type == AREA_RECT) { 1621 vec3 corners[4]; 1622 corners[0] = (l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * ld.l_sizey; 1623 corners[1] = (l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * -ld.l_sizey; 1624 corners[2] = (l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * -ld.l_sizey; 1625 corners[3] = (l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * ld.l_sizey; 1626 1627 ltc_transform_quad(N, V, ltc_matrix(ltc_mat), corners); 1628 1629 return ltc_evaluate_quad(corners, vec3(0.0, 0.0, 1.0)); 1630 } 1631 else { 1632 bool is_ellipse = (ld.l_type == AREA_ELLIPSE); 1633 float radius_x = is_ellipse ? ld.l_sizex : ld.l_radius; 1634 float radius_y = is_ellipse ? ld.l_sizey : ld.l_radius; 1635 1636 vec3 L = (ld.l_type == SUN) ? -ld.l_forward : l_vector.xyz; 1637 vec3 Px = ld.l_right; 1638 vec3 Py = ld.l_up; 1639 1640 if (ld.l_type == SPOT || ld.l_type == POINT) { 1641 make_orthonormal_basis(l_vector.xyz / l_vector.w, Px, Py); 1642 } 1643 1644 vec3 points[3]; 1645 points[0] = (L + Px * -radius_x) + Py * -radius_y; 1646 points[1] = (L + Px * radius_x) + Py * -radius_y; 1647 points[2] = (L + Px * radius_x) + Py * radius_y; 1648 1649 return ltc_evaluate_disk(N, V, ltc_matrix(ltc_mat), points); 1650 } 1651 } 1652 #endif 1653 1654 #define MAX_SSS_SAMPLES 65 1655 #define SSS_LUT_SIZE 64.0 1656 #define SSS_LUT_SCALE ((SSS_LUT_SIZE - 1.0) / float(SSS_LUT_SIZE)) 1657 #define SSS_LUT_BIAS (0.5 / float(SSS_LUT_SIZE)) 1658 1659 #ifdef USE_TRANSLUCENCY 1660 layout(std140) uniform sssProfile 1661 { 1662 vec4 kernel[MAX_SSS_SAMPLES]; 1663 vec4 radii_max_radius; 1664 int sss_samples; 1665 }; 1666 1667 uniform sampler1D sssTexProfile; 1668 1669 vec3 sss_profile(float s) 1670 { 1671 s /= radii_max_radius.w; 1672 return texture(sssTexProfile, saturate(s) * SSS_LUT_SCALE + SSS_LUT_BIAS).rgb; 1673 } 1674 #endif 1675 1676 vec3 light_translucent(LightData ld, vec3 W, vec3 N, vec4 l_vector, float scale) 1677 { 1678 #if !defined(USE_TRANSLUCENCY) || defined(VOLUMETRICS) 1679 return vec3(0.0); 1680 #else 1681 vec3 vis = vec3(1.0); 1682 1683 if (ld.l_type == SPOT) { 1684 vis *= spot_attenuation(ld, l_vector.xyz); 1685 } 1686 if (ld.l_type >= SPOT) { 1687 vis *= step(0.0, -dot(l_vector.xyz, ld.l_forward)); 1688 } 1689 if (ld.l_type != SUN) { 1690 vis *= distance_attenuation(l_vector.w * l_vector.w, ld.l_influence); 1691 } 1692 1693 /* Only shadowed light can produce translucency */ 1694 if (ld.l_shadowid >= 0.0 && vis.x > 0.001) { 1695 ShadowData data = shadows_data[int(ld.l_shadowid)]; 1696 float delta; 1697 1698 vec4 L = (ld.l_type != SUN) ? l_vector : vec4(-ld.l_forward, 1.0); 1699 1700 vec3 T, B; 1701 make_orthonormal_basis(L.xyz / L.w, T, B); 1702 1703 vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy); 1704 rand.zw *= fast_sqrt(rand.y) * data.sh_blur; 1705 1706 /* We use the full l_vector.xyz so that the spread is minimize 1707 * if the shading point is further away from the light source */ 1708 W = W + T * rand.z + B * rand.w; 1709 1710 if (ld.l_type == SUN) { 1711 int scd_id = int(data.sh_data_start); 1712 vec4 view_z = vec4(dot(W - cameraPos, cameraForward)); 1713 1714 vec4 weights = step(shadows_cascade_data[scd_id].split_end_distances, view_z); 1715 float id = abs(4.0 - dot(weights, weights)); 1716 1717 if (id > 3.0) { 1718 return vec3(0.0); 1719 } 1720 1721 float range = abs(data.sh_far - 1722 data.sh_near); /* Same factor as in get_cascade_world_distance(). */ 1723 1724 vec4 shpos = shadows_cascade_data[scd_id].shadowmat[int(id)] * vec4(W, 1.0); 1725 float dist = shpos.z * range; 1726 1727 if (shpos.z > 1.0 || shpos.z < 0.0) { 1728 return vec3(0.0); 1729 } 1730 1731 ShadowSample s = sample_cascade(shpos.xy, data.sh_tex_start + id); 1732 delta = get_depth_delta(dist, s); 1733 } 1734 else { 1735 vec3 cubevec = W - shadows_cube_data[int(data.sh_data_start)].position.xyz; 1736 float dist = length(cubevec); 1737 cubevec /= dist; 1738 1739 ShadowSample s = sample_cube(cubevec, data.sh_tex_start); 1740 delta = get_depth_delta(dist, s); 1741 } 1742 1743 /* XXX : Removing Area Power. */ 1744 /* TODO : put this out of the shader. */ 1745 float falloff; 1746 if (ld.l_type == AREA_RECT || ld.l_type == AREA_ELLIPSE) { 1747 vis *= (ld.l_sizex * ld.l_sizey * 4.0 * M_PI) * (1.0 / 80.0); 1748 if (ld.l_type == AREA_ELLIPSE) { 1749 vis *= M_PI * 0.25; 1750 } 1751 vis *= 0.3 * 20.0 * 1752 max(0.0, dot(-ld.l_forward, l_vector.xyz / l_vector.w)); /* XXX ad hoc, empirical */ 1753 vis /= (l_vector.w * l_vector.w); 1754 falloff = dot(N, l_vector.xyz / l_vector.w); 1755 } 1756 else if (ld.l_type == SUN) { 1757 vis /= 1.0f + (ld.l_radius * ld.l_radius * 0.5f); 1758 vis *= ld.l_radius * ld.l_radius * M_PI; /* Removing area light power*/ 1759 vis *= M_2PI * 0.78; /* Matching cycles with point light. */ 1760 vis *= 0.082; /* XXX ad hoc, empirical */ 1761 falloff = dot(N, -ld.l_forward); 1762 } 1763 else { 1764 vis *= (4.0 * ld.l_radius * ld.l_radius) * (1.0 / 10.0); 1765 vis *= 1.5; /* XXX ad hoc, empirical */ 1766 vis /= (l_vector.w * l_vector.w); 1767 falloff = dot(N, l_vector.xyz / l_vector.w); 1768 } 1769 // vis *= M_1_PI; /* Normalize */ 1770 1771 /* Applying profile */ 1772 vis *= sss_profile(abs(delta) / scale); 1773 1774 /* No transmittance at grazing angle (hide artifacts) */ 1775 vis *= saturate(falloff * 2.0); 1776 } 1777 else { 1778 vis = vec3(0.0); 1779 } 1780 1781 return vis; 1782 #endif 1783 } 1784 1785 /* Based on Frosbite Unified Volumetric. 1786 * https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */ 1787 1788 /* Volume slice to view space depth. */ 1789 float volume_z_to_view_z(float z) 1790 { 1791 if (ProjectionMatrix[3][3] == 0.0) { 1792 /* Exponential distribution */ 1793 return (exp2(z / volDepthParameters.z) - volDepthParameters.x) / volDepthParameters.y; 1794 } 1795 else { 1796 /* Linear distribution */ 1797 return mix(volDepthParameters.x, volDepthParameters.y, z); 1798 } 1799 } 1800 1801 float view_z_to_volume_z(float depth) 1802 { 1803 if (ProjectionMatrix[3][3] == 0.0) { 1804 /* Exponential distribution */ 1805 return volDepthParameters.z * log2(depth * volDepthParameters.y + volDepthParameters.x); 1806 } 1807 else { 1808 /* Linear distribution */ 1809 return (depth - volDepthParameters.x) * volDepthParameters.z; 1810 } 1811 } 1812 1813 /* Volume texture normalized coordinates to NDC (special range [0, 1]). */ 1814 vec3 volume_to_ndc(vec3 cos) 1815 { 1816 cos.z = volume_z_to_view_z(cos.z); 1817 cos.z = get_depth_from_view_z(cos.z); 1818 cos.xy /= volCoordScale.xy; 1819 return cos; 1820 } 1821 1822 vec3 ndc_to_volume(vec3 cos) 1823 { 1824 cos.z = get_view_z_from_depth(cos.z); 1825 cos.z = view_z_to_volume_z(cos.z); 1826 cos.xy *= volCoordScale.xy; 1827 return cos; 1828 } 1829 1830 float phase_function_isotropic() 1831 { 1832 return 1.0 / (4.0 * M_PI); 1833 } 1834 1835 float phase_function(vec3 v, vec3 l, float g) 1836 { 1837 /* Henyey-Greenstein */ 1838 float cos_theta = dot(v, l); 1839 g = clamp(g, -1.0 + 1e-3, 1.0 - 1e-3); 1840 float sqr_g = g * g; 1841 return (1 - sqr_g) / max(1e-8, 4.0 * M_PI * pow(1 + sqr_g - 2 * g * cos_theta, 3.0 / 2.0)); 1842 } 1843 1844 #ifdef LAMPS_LIB 1845 vec3 light_volume(LightData ld, vec4 l_vector) 1846 { 1847 float power; 1848 /* TODO : Area lighting ? */ 1849 /* XXX : Removing Area Power. */ 1850 /* TODO : put this out of the shader. */ 1851 /* See eevee_light_setup(). */ 1852 if (ld.l_type == AREA_RECT || ld.l_type == AREA_ELLIPSE) { 1853 power = (ld.l_sizex * ld.l_sizey * 4.0 * M_PI) * (1.0 / 80.0); 1854 if (ld.l_type == AREA_ELLIPSE) { 1855 power *= M_PI * 0.25; 1856 } 1857 power *= 20.0 * 1858 max(0.0, dot(-ld.l_forward, l_vector.xyz / l_vector.w)); /* XXX ad hoc, empirical */ 1859 } 1860 else if (ld.l_type == SUN) { 1861 power = ld.l_radius * ld.l_radius * M_PI; /* Removing area light power*/ 1862 power /= 1.0f + (ld.l_radius * ld.l_radius * 0.5f); 1863 power *= M_PI * 0.5; /* Matching cycles. */ 1864 } 1865 else { 1866 power = (4.0 * ld.l_radius * ld.l_radius) * (1.0 / 10.0); 1867 power *= M_2PI; /* Matching cycles with point light. */ 1868 } 1869 1870 power /= (l_vector.w * l_vector.w); 1871 1872 /* OPTI: find a better way than calculating this on the fly */ 1873 float lum = dot(ld.l_color, vec3(0.3, 0.6, 0.1)); /* luminance approx. */ 1874 vec3 tint = (lum > 0.0) ? ld.l_color / lum : vec3(1.0); /* normalize lum. to isolate hue+sat */ 1875 1876 lum = min(lum * power, volLightClamp); 1877 1878 return tint * lum; 1879 } 1880 1881 # define VOLUMETRIC_SHADOW_MAX_STEP 32.0 1882 1883 vec3 participating_media_extinction(vec3 wpos, sampler3D volume_extinction) 1884 { 1885 /* Waiting for proper volume shadowmaps and out of frustum shadow map. */ 1886 vec3 ndc = project_point(ViewProjectionMatrix, wpos); 1887 vec3 volume_co = ndc_to_volume(ndc * 0.5 + 0.5); 1888 1889 /* Let the texture be clamped to edge. This reduce visual glitches. */ 1890 return texture(volume_extinction, volume_co).rgb; 1891 } 1892 1893 vec3 light_volume_shadow(LightData ld, vec3 ray_wpos, vec4 l_vector, sampler3D volume_extinction) 1894 { 1895 # if defined(VOLUME_SHADOW) 1896 /* Heterogeneous volume shadows */ 1897 float dd = l_vector.w / volShadowSteps; 1898 vec3 L = l_vector.xyz * l_vector.w; 1899 vec3 shadow = vec3(1.0); 1900 for (float s = 0.5; s < VOLUMETRIC_SHADOW_MAX_STEP && s < (volShadowSteps - 0.1); s += 1.0) { 1901 vec3 pos = ray_wpos + L * (s / volShadowSteps); 1902 vec3 s_extinction = participating_media_extinction(pos, volume_extinction); 1903 shadow *= exp(-s_extinction * dd); 1904 } 1905 return shadow; 1906 # else 1907 return vec3(1.0); 1908 # endif /* VOLUME_SHADOW */ 1909 } 1910 #endif 1911 1912 #ifdef IRRADIANCE_LIB 1913 vec3 irradiance_volumetric(vec3 wpos) 1914 { 1915 # ifdef IRRADIANCE_HL2 1916 IrradianceData ir_data = load_irradiance_cell(0, vec3(1.0)); 1917 vec3 irradiance = ir_data.cubesides[0] + ir_data.cubesides[1] + ir_data.cubesides[2]; 1918 ir_data = load_irradiance_cell(0, vec3(-1.0)); 1919 irradiance += ir_data.cubesides[0] + ir_data.cubesides[1] + ir_data.cubesides[2]; 1920 irradiance *= 0.16666666; /* 1/6 */ 1921 return irradiance; 1922 # else 1923 return vec3(0.0); 1924 # endif 1925 } 1926 #endif 1927 1928 uniform sampler3D inScattering; 1929 uniform sampler3D inTransmittance; 1930 1931 void volumetric_resolve(vec2 frag_uvs, 1932 float frag_depth, 1933 out vec3 transmittance, 1934 out vec3 scattering) 1935 { 1936 vec3 volume_cos = ndc_to_volume(vec3(frag_uvs, frag_depth)); 1937 1938 scattering = texture(inScattering, volume_cos).rgb; 1939 transmittance = texture(inTransmittance, volume_cos).rgb; 1940 } 1941 1942 #ifdef MESH_SHADER 1943 /* TODO tight slices */ 1944 layout(triangles) in; 1945 layout(triangle_strip, max_vertices = 3) out; 1946 #else /* World */ 1947 layout(triangles) in; 1948 layout(triangle_strip, max_vertices = 3) out; 1949 #endif 1950 1951 in vec4 vPos[]; 1952 1953 flat out int slice; 1954 1955 #ifdef MESH_SHADER 1956 /* TODO tight slices */ 1957 void main() 1958 { 1959 gl_Layer = slice = int(vPos[0].z); 1960 1961 # ifdef USE_ATTR 1962 pass_attr(0); 1963 # endif 1964 gl_Position = vPos[0].xyww; 1965 EmitVertex(); 1966 1967 # ifdef USE_ATTR 1968 pass_attr(1); 1969 # endif 1970 gl_Position = vPos[1].xyww; 1971 EmitVertex(); 1972 1973 # ifdef USE_ATTR 1974 pass_attr(2); 1975 # endif 1976 gl_Position = vPos[2].xyww; 1977 EmitVertex(); 1978 1979 EndPrimitive(); 1980 } 1981 1982 #else /* World */ 1983 1984 /* This is just a pass-through geometry shader that send the geometry 1985 * to the layer corresponding to it's depth. */ 1986 1987 void main() 1988 { 1989 gl_Layer = slice = int(vPos[0].z); 1990 1991 # ifdef USE_ATTR 1992 pass_attr(0); 1993 # endif 1994 gl_Position = vPos[0].xyww; 1995 EmitVertex(); 1996 1997 # ifdef USE_ATTR 1998 pass_attr(1); 1999 # endif 2000 gl_Position = vPos[1].xyww; 2001 EmitVertex(); 2002 2003 # ifdef USE_ATTR 2004 pass_attr(2); 2005 # endif 2006 gl_Position = vPos[2].xyww; 2007 EmitVertex(); 2008 2009 EndPrimitive(); 2010 } 2011 2012 #endif Number of Geometry Uniforms exceeds HW limits. GPUShader: linking error: ===== shader string 1 ==== 1 #define COMMON_VIEW_LIB 2 3 /* keep in sync with DRWManager.view_data */ 4 layout(std140) uniform viewBlock 5 { 6 /* Same order as DRWViewportMatrixType */ 7 mat4 ViewProjectionMatrix; 8 mat4 ViewProjectionMatrixInverse; 9 mat4 ViewMatrix; 10 mat4 ViewMatrixInverse; 11 mat4 ProjectionMatrix; 12 mat4 ProjectionMatrixInverse; 13 14 vec4 clipPlanes[6]; 15 16 /* TODO move it elsewhere. */ 17 vec4 CameraTexCoFactors; 18 }; 19 20 #ifdef world_clip_planes_calc_clip_distance 21 # undef world_clip_planes_calc_clip_distance 22 # define world_clip_planes_calc_clip_distance(p) \ 23 _world_clip_planes_calc_clip_distance(p, clipPlanes) 24 #endif 25 26 uniform mat4 ModelMatrix; 27 uniform mat4 ModelMatrixInverse; 28 29 /** Transform shortcuts. */ 30 /* Rule of thumb: Try to reuse world positions and normals because converting though viewspace 31 * will always be decomposed in at least 2 matrix operation. */ 32 33 /** 34 * Some clarification: 35 * Usually Normal matrix is transpose(inverse(ViewMatrix * ModelMatrix)) 36 * 37 * But since it is slow to multiply matrices we decompose it. Decomposing 38 * inversion and transposition both invert the product order leaving us with 39 * the same original order: 40 * transpose(ViewMatrixInverse) * transpose(ModelMatrixInverse) 41 * 42 * Knowing that the view matrix is orthogonal, the transpose is also the inverse. 43 * Note: This is only valid because we are only using the mat3 of the ViewMatrixInverse. 44 * ViewMatrix * transpose(ModelMatrixInverse) 45 **/ 46 #define normal_object_to_view(n) (mat3(ViewMatrix) * (transpose(mat3(ModelMatrixInverse)) * n)) 47 #define normal_object_to_world(n) (transpose(mat3(ModelMatrixInverse)) * n) 48 #define normal_world_to_object(n) (transpose(mat3(ModelMatrix)) * n) 49 #define normal_world_to_view(n) (mat3(ViewMatrix) * n) 50 51 #define point_object_to_ndc(p) (ViewProjectionMatrix * vec4((ModelMatrix * vec4(p, 1.0)).xyz, 1.0)) 52 #define point_object_to_view(p) ((ViewMatrix * vec4((ModelMatrix * vec4(p, 1.0)).xyz, 1.0)).xyz) 53 #define point_object_to_world(p) ((ModelMatrix * vec4(p, 1.0)).xyz) 54 #define point_view_to_ndc(p) (ProjectionMatrix * vec4(p, 1.0)) 55 #define point_view_to_object(p) ((ModelMatrixInverse * (ViewMatrixInverse * vec4(p, 1.0))).xyz) 56 #define point_view_to_world(p) ((ViewMatrixInverse * vec4(p, 1.0)).xyz) 57 #define point_world_to_ndc(p) (ViewProjectionMatrix * vec4(p, 1.0)) 58 #define point_world_to_object(p) ((ModelMatrixInverse * vec4(p, 1.0)).xyz) 59 #define point_world_to_view(p) ((ViewMatrix * vec4(p, 1.0)).xyz) 60 61 /* Due to some shader compiler bug, we somewhat need to access gl_VertexID 62 * to make vertex shaders work. even if it's actually dead code. */ 63 #ifdef GPU_INTEL 64 # define GPU_INTEL_VERTEX_SHADER_WORKAROUND gl_Position.x = float(gl_VertexID); 65 #else 66 # define GPU_INTEL_VERTEX_SHADER_WORKAROUND 67 #endif 68 69 layout(std140) uniform common_block 70 { 71 mat4 pastViewProjectionMatrix; 72 vec4 viewVecs[2]; 73 vec2 mipRatio[10]; /* To correct mip level texel mis-alignement */ 74 /* Ambient Occlusion */ 75 vec4 aoParameters[2]; 76 /* Volumetric */ 77 ivec4 volTexSize; 78 vec4 volDepthParameters; /* Parameters to the volume Z equation */ 79 vec4 volInvTexSize; 80 vec4 volJitter; 81 vec4 volCoordScale; /* To convert volume uvs to screen uvs */ 82 float volHistoryAlpha; 83 float volLightClamp; 84 float volShadowSteps; 85 bool volUseLights; 86 /* Screen Space Reflections */ 87 vec4 ssrParameters; 88 float ssrBorderFac; 89 float ssrMaxRoughness; 90 float ssrFireflyFac; 91 float ssrBrdfBias; 92 bool ssrToggle; 93 bool ssrefractToggle; 94 /* SubSurface Scattering */ 95 float sssJitterThreshold; 96 bool sssToggle; 97 /* Specular */ 98 bool specToggle; 99 /* Lights */ 100 int laNumLight; 101 /* Probes */ 102 int prbNumPlanar; 103 int prbNumRenderCube; 104 int prbNumRenderGrid; 105 int prbIrradianceVisSize; 106 float prbIrradianceSmooth; 107 float prbLodCubeMax; 108 float prbLodPlanarMax; 109 /* Misc*/ 110 int hizMipOffset; 111 int rayType; 112 float rayDepth; 113 }; 114 115 /* rayType (keep in sync with ray_type) */ 116 #define EEVEE_RAY_CAMERA 0 117 #define EEVEE_RAY_SHADOW 1 118 #define EEVEE_RAY_DIFFUSE 2 119 #define EEVEE_RAY_GLOSSY 3 120 121 /* aoParameters */ 122 #define aoDistance aoParameters[0].x 123 #define aoSamples aoParameters[0].y /* UNUSED */ 124 #define aoFactor aoParameters[0].z 125 #define aoInvSamples aoParameters[0].w /* UNUSED */ 126 127 #define aoOffset aoParameters[1].x /* UNUSED */ 128 #define aoBounceFac aoParameters[1].y 129 #define aoQuality aoParameters[1].z 130 #define aoSettings aoParameters[1].w 131 132 /* ssrParameters */ 133 #define ssrQuality ssrParameters.x 134 #define ssrThickness ssrParameters.y 135 #define ssrPixelSize ssrParameters.zw 136 137 #define M_PI 3.14159265358979323846 /* pi */ 138 #define M_2PI 6.28318530717958647692 /* 2*pi */ 139 #define M_PI_2 1.57079632679489661923 /* pi/2 */ 140 #define M_1_PI 0.318309886183790671538 /* 1/pi */ 141 #define M_1_2PI 0.159154943091895335768 /* 1/(2*pi) */ 142 #define M_1_PI2 0.101321183642337771443 /* 1/(pi^2) */ 143 144 #define LUT_SIZE 64 145 146 /* Buffers */ 147 uniform sampler2D colorBuffer; 148 uniform sampler2D depthBuffer; 149 uniform sampler2D maxzBuffer; 150 uniform sampler2D minzBuffer; 151 uniform sampler2DArray planarDepth; 152 153 #define cameraForward ViewMatrixInverse[2].xyz 154 #define cameraPos ViewMatrixInverse[3].xyz 155 #define cameraVec \ 156 ((ProjectionMatrix[3][3] == 0.0) ? normalize(cameraPos - worldPosition) : cameraForward) 157 #define viewCameraVec \ 158 ((ProjectionMatrix[3][3] == 0.0) ? normalize(-viewPosition) : vec3(0.0, 0.0, 1.0)) 159 160 /* ------- Structures -------- */ 161 162 /* ------ Lights ----- */ 163 struct LightData { 164 vec4 position_influence; /* w : InfluenceRadius (inversed and squared) */ 165 vec4 color_spec; /* w : Spec Intensity */ 166 vec4 spotdata_radius_shadow; /* x : spot size, y : spot blend, z : radius, w: shadow id */ 167 vec4 rightvec_sizex; /* xyz: Normalized up vector, w: area size X or spot scale X */ 168 vec4 upvec_sizey; /* xyz: Normalized right vector, w: area size Y or spot scale Y */ 169 vec4 forwardvec_type; /* xyz: Normalized forward vector, w: Light Type */ 170 }; 171 172 /* convenience aliases */ 173 #define l_color color_spec.rgb 174 #define l_spec color_spec.a 175 #define l_position position_influence.xyz 176 #define l_influence position_influence.w 177 #define l_sizex rightvec_sizex.w 178 #define l_sizey upvec_sizey.w 179 #define l_right rightvec_sizex.xyz 180 #define l_up upvec_sizey.xyz 181 #define l_forward forwardvec_type.xyz 182 #define l_type forwardvec_type.w 183 #define l_spot_size spotdata_radius_shadow.x 184 #define l_spot_blend spotdata_radius_shadow.y 185 #define l_radius spotdata_radius_shadow.z 186 #define l_shadowid spotdata_radius_shadow.w 187 188 /* ------ Shadows ----- */ 189 #ifndef MAX_CASCADE_NUM 190 # define MAX_CASCADE_NUM 4 191 #endif 192 193 struct ShadowData { 194 vec4 near_far_bias_exp; 195 vec4 shadow_data_start_end; 196 vec4 contact_shadow_data; 197 }; 198 199 struct ShadowCubeData { 200 vec4 position; 201 }; 202 203 struct ShadowCascadeData { 204 mat4 shadowmat[MAX_CASCADE_NUM]; 205 vec4 split_start_distances; 206 vec4 split_end_distances; 207 }; 208 209 /* convenience aliases */ 210 #define sh_near near_far_bias_exp.x 211 #define sh_far near_far_bias_exp.y 212 #define sh_bias near_far_bias_exp.z 213 #define sh_exp near_far_bias_exp.w 214 #define sh_bleed near_far_bias_exp.w 215 #define sh_tex_start shadow_data_start_end.x 216 #define sh_data_start shadow_data_start_end.y 217 #define sh_multi_nbr shadow_data_start_end.z 218 #define sh_blur shadow_data_start_end.w 219 #define sh_contact_dist contact_shadow_data.x 220 #define sh_contact_offset contact_shadow_data.y 221 #define sh_contact_spread contact_shadow_data.z 222 #define sh_contact_thickness contact_shadow_data.w 223 224 /* ------- Convenience functions --------- */ 225 226 vec3 mul(mat3 m, vec3 v) 227 { 228 return m * v; 229 } 230 mat3 mul(mat3 m1, mat3 m2) 231 { 232 return m1 * m2; 233 } 234 vec3 transform_direction(mat4 m, vec3 v) 235 { 236 return mat3(m) * v; 237 } 238 vec3 transform_point(mat4 m, vec3 v) 239 { 240 return (m * vec4(v, 1.0)).xyz; 241 } 242 vec3 project_point(mat4 m, vec3 v) 243 { 244 vec4 tmp = m * vec4(v, 1.0); 245 return tmp.xyz / tmp.w; 246 } 247 248 #define min3(a, b, c) min(a, min(b, c)) 249 #define min4(a, b, c, d) min(a, min3(b, c, d)) 250 #define min5(a, b, c, d, e) min(a, min4(b, c, d, e)) 251 #define min6(a, b, c, d, e, f) min(a, min5(b, c, d, e, f)) 252 #define min7(a, b, c, d, e, f, g) min(a, min6(b, c, d, e, f, g)) 253 #define min8(a, b, c, d, e, f, g, h) min(a, min7(b, c, d, e, f, g, h)) 254 #define min9(a, b, c, d, e, f, g, h, i) min(a, min8(b, c, d, e, f, g, h, i)) 255 256 #define max3(a, b, c) max(a, max(b, c)) 257 #define max4(a, b, c, d) max(a, max3(b, c, d)) 258 #define max5(a, b, c, d, e) max(a, max4(b, c, d, e)) 259 #define max6(a, b, c, d, e, f) max(a, max5(b, c, d, e, f)) 260 #define max7(a, b, c, d, e, f, g) max(a, max6(b, c, d, e, f, g)) 261 #define max8(a, b, c, d, e, f, g, h) max(a, max7(b, c, d, e, f, g, h)) 262 #define max9(a, b, c, d, e, f, g, h, i) max(a, max8(b, c, d, e, f, g, h, i)) 263 264 #define avg3(a, b, c) (a + b + c) * (1.0 / 3.0) 265 #define avg4(a, b, c, d) (a + b + c + d) * (1.0 / 4.0) 266 #define avg5(a, b, c, d, e) (a + b + c + d + e) * (1.0 / 5.0) 267 #define avg6(a, b, c, d, e, f) (a + b + c + d + e + f) * (1.0 / 6.0) 268 #define avg7(a, b, c, d, e, f, g) (a + b + c + d + e + f + g) * (1.0 / 7.0) 269 #define avg8(a, b, c, d, e, f, g, h) (a + b + c + d + e + f + g + h) * (1.0 / 8.0) 270 #define avg9(a, b, c, d, e, f, g, h, i) (a + b + c + d + e + f + g + h + i) * (1.0 / 9.0) 271 272 float min_v2(vec2 v) 273 { 274 return min(v.x, v.y); 275 } 276 float min_v3(vec3 v) 277 { 278 return min(v.x, min(v.y, v.z)); 279 } 280 float max_v2(vec2 v) 281 { 282 return max(v.x, v.y); 283 } 284 float max_v3(vec3 v) 285 { 286 return max(v.x, max(v.y, v.z)); 287 } 288 289 float sum(vec2 v) 290 { 291 return dot(vec2(1.0), v); 292 } 293 float sum(vec3 v) 294 { 295 return dot(vec3(1.0), v); 296 } 297 float sum(vec4 v) 298 { 299 return dot(vec4(1.0), v); 300 } 301 302 float saturate(float a) 303 { 304 return clamp(a, 0.0, 1.0); 305 } 306 vec2 saturate(vec2 a) 307 { 308 return clamp(a, 0.0, 1.0); 309 } 310 vec3 saturate(vec3 a) 311 { 312 return clamp(a, 0.0, 1.0); 313 } 314 vec4 saturate(vec4 a) 315 { 316 return clamp(a, 0.0, 1.0); 317 } 318 319 float distance_squared(vec2 a, vec2 b) 320 { 321 a -= b; 322 return dot(a, a); 323 } 324 float distance_squared(vec3 a, vec3 b) 325 { 326 a -= b; 327 return dot(a, a); 328 } 329 float len_squared(vec3 a) 330 { 331 return dot(a, a); 332 } 333 334 float inverse_distance(vec3 V) 335 { 336 return max(1 / length(V), 1e-8); 337 } 338 339 vec2 mip_ratio_interp(float mip) 340 { 341 float low_mip = floor(mip); 342 return mix(mipRatio[int(low_mip)], mipRatio[int(low_mip + 1.0)], mip - low_mip); 343 } 344 345 /* ------- RNG ------- */ 346 347 float wang_hash_noise(uint s) 348 { 349 s = (s ^ 61u) ^ (s >> 16u); 350 s *= 9u; 351 s = s ^ (s >> 4u); 352 s *= 0x27d4eb2du; 353 s = s ^ (s >> 15u); 354 355 return fract(float(s) / 4294967296.0); 356 } 357 358 /* ------- Fast Math ------- */ 359 360 /* [Drobot2014a] Low Level Optimizations for GCN */ 361 float fast_sqrt(float v) 362 { 363 return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1)); 364 } 365 366 vec2 fast_sqrt(vec2 v) 367 { 368 return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1)); 369 } 370 371 /* [Eberly2014] GPGPU Programming for Games and Science */ 372 float fast_acos(float v) 373 { 374 float res = -0.156583 * abs(v) + M_PI_2; 375 res *= fast_sqrt(1.0 - abs(v)); 376 return (v >= 0) ? res : M_PI - res; 377 } 378 379 vec2 fast_acos(vec2 v) 380 { 381 vec2 res = -0.156583 * abs(v) + M_PI_2; 382 res *= fast_sqrt(1.0 - abs(v)); 383 v.x = (v.x >= 0) ? res.x : M_PI - res.x; 384 v.y = (v.y >= 0) ? res.y : M_PI - res.y; 385 return v; 386 } 387 388 float point_plane_projection_dist(vec3 lineorigin, vec3 planeorigin, vec3 planenormal) 389 { 390 return dot(planenormal, planeorigin - lineorigin); 391 } 392 393 float line_plane_intersect_dist(vec3 lineorigin, 394 vec3 linedirection, 395 vec3 planeorigin, 396 vec3 planenormal) 397 { 398 return dot(planenormal, planeorigin - lineorigin) / dot(planenormal, linedirection); 399 } 400 401 float line_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec4 plane) 402 { 403 vec3 plane_co = plane.xyz * (-plane.w / len_squared(plane.xyz)); 404 vec3 h = lineorigin - plane_co; 405 return -dot(plane.xyz, h) / dot(plane.xyz, linedirection); 406 } 407 408 vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin, vec3 planenormal) 409 { 410 float dist = line_plane_intersect_dist(lineorigin, linedirection, planeorigin, planenormal); 411 return lineorigin + linedirection * dist; 412 } 413 414 vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec4 plane) 415 { 416 float dist = line_plane_intersect_dist(lineorigin, linedirection, plane); 417 return lineorigin + linedirection * dist; 418 } 419 420 float line_aligned_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec3 planeorigin) 421 { 422 /* aligned plane normal */ 423 vec3 L = planeorigin - lineorigin; 424 float diskdist = length(L); 425 vec3 planenormal = -normalize(L); 426 return -diskdist / dot(planenormal, linedirection); 427 } 428 429 vec3 line_aligned_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin) 430 { 431 float dist = line_aligned_plane_intersect_dist(lineorigin, linedirection, planeorigin); 432 if (dist < 0) { 433 /* if intersection is behind we fake the intersection to be 434 * really far and (hopefully) not inside the radius of interest */ 435 dist = 1e16; 436 } 437 return lineorigin + linedirection * dist; 438 } 439 440 float line_unit_sphere_intersect_dist(vec3 lineorigin, vec3 linedirection) 441 { 442 float a = dot(linedirection, linedirection); 443 float b = dot(linedirection, lineorigin); 444 float c = dot(lineorigin, lineorigin) - 1; 445 446 float dist = 1e15; 447 float determinant = b * b - a * c; 448 if (determinant >= 0) { 449 dist = (sqrt(determinant) - b) / a; 450 } 451 452 return dist; 453 } 454 455 float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection) 456 { 457 /* https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ 458 */ 459 vec3 firstplane = (vec3(1.0) - lineorigin) / linedirection; 460 vec3 secondplane = (vec3(-1.0) - lineorigin) / linedirection; 461 vec3 furthestplane = max(firstplane, secondplane); 462 463 return min_v3(furthestplane); 464 } 465 466 /* Return texture coordinates to sample Surface LUT */ 467 vec2 lut_coords(float cosTheta, float roughness) 468 { 469 float theta = acos(cosTheta); 470 vec2 coords = vec2(roughness, theta / M_PI_2); 471 472 /* scale and bias coordinates, for correct filtered lookup */ 473 return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE; 474 } 475 476 vec2 lut_coords_ltc(float cosTheta, float roughness) 477 { 478 vec2 coords = vec2(roughness, sqrt(1.0 - cosTheta)); 479 480 /* scale and bias coordinates, for correct filtered lookup */ 481 return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE; 482 } 483 484 /* -- Tangent Space conversion -- */ 485 vec3 tangent_to_world(vec3 vector, vec3 N, vec3 T, vec3 B) 486 { 487 return T * vector.x + B * vector.y + N * vector.z; 488 } 489 490 vec3 world_to_tangent(vec3 vector, vec3 N, vec3 T, vec3 B) 491 { 492 return vec3(dot(T, vector), dot(B, vector), dot(N, vector)); 493 } 494 495 void make_orthonormal_basis(vec3 N, out vec3 T, out vec3 B) 496 { 497 vec3 UpVector = abs(N.z) < 0.99999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); 498 T = normalize(cross(UpVector, N)); 499 B = cross(N, T); 500 } 501 502 /* ---- Opengl Depth conversion ---- */ 503 504 float linear_depth(bool is_persp, float z, float zf, float zn) 505 { 506 if (is_persp) { 507 return (zn * zf) / (z * (zn - zf) + zf); 508 } 509 else { 510 return (z * 2.0 - 1.0) * zf; 511 } 512 } 513 514 float buffer_depth(bool is_persp, float z, float zf, float zn) 515 { 516 if (is_persp) { 517 return (zf * (zn - z)) / (z * (zn - zf)); 518 } 519 else { 520 return (z / (zf * 2.0)) + 0.5; 521 } 522 } 523 524 float get_view_z_from_depth(float depth) 525 { 526 if (ProjectionMatrix[3][3] == 0.0) { 527 float d = 2.0 * depth - 1.0; 528 return -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]); 529 } 530 else { 531 return viewVecs[0].z + depth * viewVecs[1].z; 532 } 533 } 534 535 float get_depth_from_view_z(float z) 536 { 537 if (ProjectionMatrix[3][3] == 0.0) { 538 float d = (-ProjectionMatrix[3][2] / z) - ProjectionMatrix[2][2]; 539 return d * 0.5 + 0.5; 540 } 541 else { 542 return (z - viewVecs[0].z) / viewVecs[1].z; 543 } 544 } 545 546 vec2 get_uvs_from_view(vec3 view) 547 { 548 vec3 ndc = project_point(ProjectionMatrix, view); 549 return ndc.xy * 0.5 + 0.5; 550 } 551 552 vec3 get_view_space_from_depth(vec2 uvcoords, float depth) 553 { 554 if (ProjectionMatrix[3][3] == 0.0) { 555 return vec3(viewVecs[0].xy + uvcoords * viewVecs[1].xy, 1.0) * get_view_z_from_depth(depth); 556 } 557 else { 558 return viewVecs[0].xyz + vec3(uvcoords, depth) * viewVecs[1].xyz; 559 } 560 } 561 562 vec3 get_world_space_from_depth(vec2 uvcoords, float depth) 563 { 564 return (ViewMatrixInverse * vec4(get_view_space_from_depth(uvcoords, depth), 1.0)).xyz; 565 } 566 567 vec3 get_specular_reflection_dominant_dir(vec3 N, vec3 V, float roughness) 568 { 569 vec3 R = -reflect(V, N); 570 float smoothness = 1.0 - roughness; 571 float fac = smoothness * (sqrt(smoothness) + roughness); 572 return normalize(mix(N, R, fac)); 573 } 574 575 float specular_occlusion(float NV, float AO, float roughness) 576 { 577 return saturate(pow(NV + AO, roughness) - 1.0 + AO); 578 } 579 580 /* --- Refraction utils --- */ 581 582 float ior_from_f0(float f0) 583 { 584 float f = sqrt(f0); 585 return (-f - 1.0) / (f - 1.0); 586 } 587 588 float f0_from_ior(float eta) 589 { 590 float A = (eta - 1.0) / (eta + 1.0); 591 return A * A; 592 } 593 594 vec3 get_specular_refraction_dominant_dir(vec3 N, vec3 V, float roughness, float ior) 595 { 596 /* TODO: This a bad approximation. Better approximation should fit 597 * the refracted vector and roughness into the best prefiltered reflection 598 * lobe. */ 599 /* Correct the IOR for ior < 1.0 to not see the abrupt delimitation or the TIR */ 600 ior = (ior < 1.0) ? mix(ior, 1.0, roughness) : ior; 601 float eta = 1.0 / ior; 602 603 float NV = dot(N, -V); 604 605 /* Custom Refraction. */ 606 float k = 1.0 - eta * eta * (1.0 - NV * NV); 607 k = max(0.0, k); /* Only this changes. */ 608 vec3 R = eta * -V - (eta * NV + sqrt(k)) * N; 609 610 return R; 611 } 612 613 float get_btdf_lut(sampler2DArray btdf_lut_tex, float NV, float roughness, float ior) 614 { 615 const vec3 lut_scale_bias_texel_size = vec3((LUT_SIZE - 1.0), 0.5, 1.5) / LUT_SIZE; 616 617 vec3 coords; 618 /* Try to compensate for the low resolution and interpolation error. */ 619 coords.x = (ior > 1.0) ? (0.9 + lut_scale_bias_texel_size.z) + 620 (0.1 - lut_scale_bias_texel_size.z) * f0_from_ior(ior) : 621 (0.9 + lut_scale_bias_texel_size.z) * ior * ior; 622 coords.y = 1.0 - saturate(NV); 623 coords.xy *= lut_scale_bias_texel_size.x; 624 coords.xy += lut_scale_bias_texel_size.y; 625 626 const float lut_lvl_ofs = 4.0; /* First texture lvl of roughness. */ 627 const float lut_lvl_scale = 16.0; /* How many lvl of roughness in the lut. */ 628 629 float mip = roughness * lut_lvl_scale; 630 float mip_floor = floor(mip); 631 632 coords.z = lut_lvl_ofs + mip_floor + 1.0; 633 float btdf_high = textureLod(btdf_lut_tex, coords, 0.0).r; 634 635 coords.z -= 1.0; 636 float btdf_low = textureLod(btdf_lut_tex, coords, 0.0).r; 637 638 float btdf = (ior == 1.0) ? 1.0 : mix(btdf_low, btdf_high, mip - coords.z); 639 640 return btdf; 641 } 642 643 /* ---- Encode / Decode Normal buffer data ---- */ 644 /* From http://aras-p.info/texts/CompactNormalStorage.html 645 * Using Method #4: Spheremap Transform */ 646 vec2 normal_encode(vec3 n, vec3 view) 647 { 648 float p = sqrt(n.z * 8.0 + 8.0); 649 return n.xy / p + 0.5; 650 } 651 652 vec3 normal_decode(vec2 enc, vec3 view) 653 { 654 vec2 fenc = enc * 4.0 - 2.0; 655 float f = dot(fenc, fenc); 656 float g = sqrt(1.0 - f / 4.0); 657 vec3 n; 658 n.xy = fenc * g; 659 n.z = 1 - f / 2; 660 return n; 661 } 662 663 /* ---- RGBM (shared multiplier) encoding ---- */ 664 /* From http://iwasbeingirony.blogspot.fr/2010/06/difference-between-rgbm-and-rgbd.html */ 665 666 /* Higher RGBM_MAX_RANGE gives imprecision issues in low intensity. */ 667 #define RGBM_MAX_RANGE 512.0 668 669 vec4 rgbm_encode(vec3 rgb) 670 { 671 float maxRGB = max_v3(rgb); 672 float M = maxRGB / RGBM_MAX_RANGE; 673 M = ceil(M * 255.0) / 255.0; 674 return vec4(rgb / (M * RGBM_MAX_RANGE), M); 675 } 676 677 vec3 rgbm_decode(vec4 data) 678 { 679 return data.rgb * (data.a * RGBM_MAX_RANGE); 680 } 681 682 /* ---- RGBE (shared exponent) encoding ---- */ 683 vec4 rgbe_encode(vec3 rgb) 684 { 685 float maxRGB = max_v3(rgb); 686 float fexp = ceil(log2(maxRGB)); 687 return vec4(rgb / exp2(fexp), (fexp + 128.0) / 255.0); 688 } 689 690 vec3 rgbe_decode(vec4 data) 691 { 692 float fexp = data.a * 255.0 - 128.0; 693 return data.rgb * exp2(fexp); 694 } 695 696 #if 1 697 # define irradiance_encode rgbe_encode 698 # define irradiance_decode rgbe_decode 699 #else /* No ecoding (when using floating point format) */ 700 # define irradiance_encode(X) (X).rgbb 701 # define irradiance_decode(X) (X).rgb 702 #endif 703 704 /* Irradiance Visibility Encoding */ 705 #if 1 706 vec4 visibility_encode(vec2 accum, float range) 707 { 708 accum /= range; 709 710 vec4 data; 711 data.x = fract(accum.x); 712 data.y = floor(accum.x) / 255.0; 713 data.z = fract(accum.y); 714 data.w = floor(accum.y) / 255.0; 715 716 return data; 717 } 718 719 vec2 visibility_decode(vec4 data, float range) 720 { 721 return (data.xz + data.yw * 255.0) * range; 722 } 723 #else /* No ecoding (when using floating point format) */ 724 vec4 visibility_encode(vec2 accum, float range) 725 { 726 return accum.xyxy; 727 } 728 729 vec2 visibility_decode(vec4 data, float range) 730 { 731 return data.xy; 732 } 733 #endif 734 735 /* Fresnel monochromatic, perfect mirror */ 736 float F_eta(float eta, float cos_theta) 737 { 738 /* compute fresnel reflectance without explicitly computing 739 * the refracted direction */ 740 float c = abs(cos_theta); 741 float g = eta * eta - 1.0 + c * c; 742 float result; 743 744 if (g > 0.0) { 745 g = sqrt(g); 746 vec2 g_c = vec2(g) + vec2(c, -c); 747 float A = g_c.y / g_c.x; 748 A *= A; 749 g_c *= c; 750 float B = (g_c.y - 1.0) / (g_c.x + 1.0); 751 B *= B; 752 result = 0.5 * A * (1.0 + B); 753 } 754 else { 755 result = 1.0; /* TIR (no refracted component) */ 756 } 757 758 return result; 759 } 760 761 /* Fresnel color blend base on fresnel factor */ 762 vec3 F_color_blend(float eta, float fresnel, vec3 f0_color) 763 { 764 float f0 = F_eta(eta, 1.0); 765 float fac = saturate((fresnel - f0) / max(1e-8, 1.0 - f0)); 766 return mix(f0_color, vec3(1.0), fac); 767 } 768 769 /* Fresnel */ 770 vec3 F_schlick(vec3 f0, float cos_theta) 771 { 772 float fac = 1.0 - cos_theta; 773 float fac2 = fac * fac; 774 fac = fac2 * fac2 * fac; 775 776 /* Unreal specular matching : if specular color is below 2% intensity, 777 * (using green channel for intensity) treat as shadowning */ 778 return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * fac + (1.0 - fac) * f0; 779 } 780 781 /* Fresnel approximation for LTC area lights (not MRP) */ 782 vec3 F_area(vec3 f0, vec3 f90, vec2 lut) 783 { 784 /* Unreal specular matching : if specular color is below 2% intensity, 785 * treat as shadowning */ 786 return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * lut.y * f90 + lut.x * f0; 787 } 788 789 /* Fresnel approximation for IBL */ 790 vec3 F_ibl(vec3 f0, vec3 f90, vec2 lut) 791 { 792 /* Unreal specular matching : if specular color is below 2% intensity, 793 * treat as shadowning */ 794 return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * lut.y * f90 + lut.x * f0; 795 } 796 797 /* GGX */ 798 float D_ggx_opti(float NH, float a2) 799 { 800 float tmp = (NH * a2 - NH) * NH + 1.0; 801 return M_PI * tmp * tmp; /* Doing RCP and mul a2 at the end */ 802 } 803 804 float G1_Smith_GGX(float NX, float a2) 805 { 806 /* Using Brian Karis approach and refactoring by NX/NX 807 * this way the (2*NL)*(2*NV) in G = G1(V) * G1(L) gets canceled by the brdf denominator 4*NL*NV 808 * Rcp is done on the whole G later 809 * Note that this is not convenient for the transmission formula */ 810 return NX + sqrt(NX * (NX - NX * a2) + a2); 811 /* return 2 / (1 + sqrt(1 + a2 * (1 - NX*NX) / (NX*NX) ) ); /* Reference function */ 812 } 813 814 float bsdf_ggx(vec3 N, vec3 L, vec3 V, float roughness) 815 { 816 float a = roughness; 817 float a2 = a * a; 818 819 vec3 H = normalize(L + V); 820 float NH = max(dot(N, H), 1e-8); 821 float NL = max(dot(N, L), 1e-8); 822 float NV = max(dot(N, V), 1e-8); 823 824 float G = G1_Smith_GGX(NV, a2) * G1_Smith_GGX(NL, a2); /* Doing RCP at the end */ 825 float D = D_ggx_opti(NH, a2); 826 827 /* Denominator is canceled by G1_Smith */ 828 /* bsdf = D * G / (4.0 * NL * NV); /* Reference function */ 829 return NL * a2 / (D * G); /* NL to Fit cycles Equation : line. 345 in bsdf_microfacet.h */ 830 } 831 832 void accumulate_light(vec3 light, float fac, inout vec4 accum) 833 { 834 accum += vec4(light, 1.0) * min(fac, (1.0 - accum.a)); 835 } 836 837 /* ----------- Cone Aperture Approximation --------- */ 838 839 /* Return a fitted cone angle given the input roughness */ 840 float cone_cosine(float r) 841 { 842 /* Using phong gloss 843 * roughness = sqrt(2/(gloss+2)) */ 844 float gloss = -2 + 2 / (r * r); 845 /* Drobot 2014 in GPUPro5 */ 846 // return cos(2.0 * sqrt(2.0 / (gloss + 2))); 847 /* Uludag 2014 in GPUPro5 */ 848 // return pow(0.244, 1 / (gloss + 1)); 849 /* Jimenez 2016 in Practical Realtime Strategies for Accurate Indirect Occlusion*/ 850 return exp2(-3.32193 * r * r); 851 } 852 853 /* --------- Closure ---------- */ 854 #ifdef VOLUMETRICS 855 856 struct Closure { 857 vec3 absorption; 858 vec3 scatter; 859 vec3 emission; 860 float anisotropy; 861 }; 862 863 # define CLOSURE_DEFAULT Closure(vec3(0.0), vec3(0.0), vec3(0.0), 0.0) 864 865 Closure closure_mix(Closure cl1, Closure cl2, float fac) 866 { 867 Closure cl; 868 cl.absorption = mix(cl1.absorption, cl2.absorption, fac); 869 cl.scatter = mix(cl1.scatter, cl2.scatter, fac); 870 cl.emission = mix(cl1.emission, cl2.emission, fac); 871 cl.anisotropy = mix(cl1.anisotropy, cl2.anisotropy, fac); 872 return cl; 873 } 874 875 Closure closure_add(Closure cl1, Closure cl2) 876 { 877 Closure cl; 878 cl.absorption = cl1.absorption + cl2.absorption; 879 cl.scatter = cl1.scatter + cl2.scatter; 880 cl.emission = cl1.emission + cl2.emission; 881 cl.anisotropy = (cl1.anisotropy + cl2.anisotropy) / 2.0; /* Average phase (no multi lobe) */ 882 return cl; 883 } 884 885 Closure closure_emission(vec3 rgb) 886 { 887 Closure cl = CLOSURE_DEFAULT; 888 cl.emission = rgb; 889 return cl; 890 } 891 892 #else /* VOLUMETRICS */ 893 894 struct Closure { 895 vec3 radiance; 896 float opacity; 897 # ifdef USE_SSS 898 vec4 sss_data; 899 # ifdef USE_SSS_ALBEDO 900 vec3 sss_albedo; 901 # endif 902 # endif 903 vec4 ssr_data; 904 vec2 ssr_normal; 905 int ssr_id; 906 }; 907 908 /* This is hacking ssr_id to tag transparent bsdf */ 909 # define TRANSPARENT_CLOSURE_FLAG -2 910 # define REFRACT_CLOSURE_FLAG -3 911 # define NO_SSR -999 912 913 # ifdef USE_SSS 914 # ifdef USE_SSS_ALBEDO 915 # define CLOSURE_DEFAULT \ 916 Closure(vec3(0.0), 1.0, vec4(0.0), vec3(0.0), vec4(0.0), vec2(0.0), -1) 917 # else 918 # define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec4(0.0), vec2(0.0), -1) 919 # endif 920 # else 921 # define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec2(0.0), -1) 922 # endif 923 924 uniform int outputSsrId; 925 926 Closure closure_mix(Closure cl1, Closure cl2, float fac) 927 { 928 Closure cl; 929 930 if (cl1.ssr_id == TRANSPARENT_CLOSURE_FLAG) { 931 cl.ssr_normal = cl2.ssr_normal; 932 cl.ssr_data = cl2.ssr_data; 933 cl.ssr_id = cl2.ssr_id; 934 # ifdef USE_SSS 935 cl1.sss_data = cl2.sss_data; 936 # ifdef USE_SSS_ALBEDO 937 cl1.sss_albedo = cl2.sss_albedo; 938 # endif 939 # endif 940 } 941 else if (cl2.ssr_id == TRANSPARENT_CLOSURE_FLAG) { 942 cl.ssr_normal = cl1.ssr_normal; 943 cl.ssr_data = cl1.ssr_data; 944 cl.ssr_id = cl1.ssr_id; 945 # ifdef USE_SSS 946 cl2.sss_data = cl1.sss_data; 947 # ifdef USE_SSS_ALBEDO 948 cl2.sss_albedo = cl1.sss_albedo; 949 # endif 950 # endif 951 } 952 else if (cl1.ssr_id == outputSsrId) { 953 /* When mixing SSR don't blend roughness. 954 * 955 * It makes no sense to mix them really, so we take either one of them and 956 * tone down its specularity (ssr_data.xyz) while keeping its roughness (ssr_data.w). 957 */ 958 cl.ssr_data = mix(cl1.ssr_data.xyzw, vec4(vec3(0.0), cl1.ssr_data.w), fac); 959 cl.ssr_normal = cl1.ssr_normal; 960 cl.ssr_id = cl1.ssr_id; 961 } 962 else { 963 cl.ssr_data = mix(vec4(vec3(0.0), cl2.ssr_data.w), cl2.ssr_data.xyzw, fac); 964 cl.ssr_normal = cl2.ssr_normal; 965 cl.ssr_id = cl2.ssr_id; 966 } 967 968 cl.opacity = mix(cl1.opacity, cl2.opacity, fac); 969 cl.radiance = mix(cl1.radiance * cl1.opacity, cl2.radiance * cl2.opacity, fac); 970 cl.radiance /= max(1e-8, cl.opacity); 971 972 # ifdef USE_SSS 973 /* Apply Mix on input */ 974 cl1.sss_data.rgb *= 1.0 - fac; 975 cl2.sss_data.rgb *= fac; 976 977 /* Select biggest radius. */ 978 bool use_cl1 = (cl1.sss_data.a > cl2.sss_data.a); 979 cl.sss_data = (use_cl1) ? cl1.sss_data : cl2.sss_data; 980 981 # ifdef USE_SSS_ALBEDO 982 /* TODO Find a solution to this. Dither? */ 983 cl.sss_albedo = (use_cl1) ? cl1.sss_albedo : cl2.sss_albedo; 984 /* Add radiance that was supposed to be filtered but was rejected. */ 985 cl.radiance += (use_cl1) ? cl2.sss_data.rgb * cl2.sss_albedo : cl1.sss_data.rgb * cl1.sss_albedo; 986 # else 987 /* Add radiance that was supposed to be filtered but was rejected. */ 988 cl.radiance += (use_cl1) ? cl2.sss_data.rgb : cl1.sss_data.rgb; 989 # endif 990 # endif 991 992 return cl; 993 } 994 995 Closure closure_add(Closure cl1, Closure cl2) 996 { 997 Closure cl = (cl1.ssr_id == outputSsrId) ? cl1 : cl2; 998 cl.radiance = cl1.radiance + cl2.radiance; 999 # ifdef USE_SSS 1000 cl.sss_data = (cl1.sss_data.a > 0.0) ? cl1.sss_data : cl2.sss_data; 1001 /* Add radiance that was supposed to be filtered but was rejected. */ 1002 cl.radiance += (cl1.sss_data.a > 0.0) ? cl2.sss_data.rgb : cl1.sss_data.rgb; 1003 # ifdef USE_SSS_ALBEDO 1004 /* TODO Find a solution to this. Dither? */ 1005 cl.sss_albedo = (cl1.sss_data.a > 0.0) ? cl1.sss_albedo : cl2.sss_albedo; 1006 # endif 1007 # endif 1008 cl.opacity = saturate(cl1.opacity + cl2.opacity); 1009 return cl; 1010 } 1011 1012 Closure closure_emission(vec3 rgb) 1013 { 1014 Closure cl = CLOSURE_DEFAULT; 1015 cl.radiance = rgb; 1016 return cl; 1017 } 1018 1019 /* Breaking this across multiple lines causes issues for some older GLSL compilers. */ 1020 /* clang-format off */ 1021 # if defined(MESH_SHADER) && !defined(USE_ALPHA_HASH) && !defined(USE_ALPHA_CLIP) && !defined(SHADOW_SHADER) && !defined(USE_MULTIPLY ) 1022 /* clang-format on */ 1023 layout(location = 0) out vec4 fragColor; 1024 layout(location = 1) out vec4 ssrNormals; 1025 layout(location = 2) out vec4 ssrData; 1026 # ifdef USE_SSS 1027 layout(location = 3) out vec4 sssData; 1028 # ifdef USE_SSS_ALBEDO 1029 layout(location = 4) out vec4 sssAlbedo; 1030 # endif /* USE_SSS_ALBEDO */ 1031 # endif /* USE_SSS */ 1032 1033 Closure nodetree_exec(void); /* Prototype */ 1034 1035 # if defined(USE_ALPHA_BLEND) 1036 /* Prototype because this file is included before volumetric_lib.glsl */ 1037 void volumetric_resolve(vec2 frag_uvs, 1038 float frag_depth, 1039 out vec3 transmittance, 1040 out vec3 scattering); 1041 # endif 1042 1043 # define NODETREE_EXEC 1044 void main() 1045 { 1046 Closure cl = nodetree_exec(); 1047 # ifndef USE_ALPHA_BLEND 1048 /* Prevent alpha hash material writing into alpha channel. */ 1049 cl.opacity = 1.0; 1050 # endif 1051 1052 # if defined(USE_ALPHA_BLEND) 1053 vec2 uvs = gl_FragCoord.xy * volCoordScale.zw; 1054 vec3 transmittance, scattering; 1055 volumetric_resolve(uvs, gl_FragCoord.z, transmittance, scattering); 1056 fragColor.rgb = cl.radiance * transmittance + scattering; 1057 fragColor.a = cl.opacity; 1058 # else 1059 fragColor = vec4(cl.radiance, cl.opacity); 1060 # endif 1061 1062 ssrNormals = cl.ssr_normal.xyyy; 1063 ssrData = cl.ssr_data; 1064 # ifdef USE_SSS 1065 sssData = cl.sss_data; 1066 # ifdef USE_SSS_ALBEDO 1067 sssAlbedo = cl.sss_albedo.rgbb; 1068 # endif 1069 # endif 1070 1071 /* For Probe capture */ 1072 # ifdef USE_SSS 1073 float fac = float(!sssToggle); 1074 1075 # ifdef USE_REFRACTION 1076 /* SSRefraction pass is done after the SSS pass. 1077 * In order to not loose the diffuse light totally we 1078 * need to merge the SSS radiance to the main radiance. */ 1079 fac = 1.0; 1080 # endif 1081 1082 # ifdef USE_SSS_ALBEDO 1083 fragColor.rgb += cl.sss_data.rgb * cl.sss_albedo.rgb * fac; 1084 # else 1085 fragColor.rgb += cl.sss_data.rgb * fac; 1086 # endif 1087 # endif 1088 } 1089 1090 # endif /* MESH_SHADER && !SHADOW_SHADER */ 1091 1092 #endif /* VOLUMETRICS */ 1093 1094 Closure nodetree_exec(void); /* Prototype */ 1095 1096 /* TODO find a better place */ 1097 #ifdef USE_MULTIPLY 1098 1099 out vec4 fragColor; 1100 1101 # define NODETREE_EXEC 1102 void main() 1103 { 1104 Closure cl = nodetree_exec(); 1105 fragColor = vec4(mix(vec3(1.0), cl.radiance, cl.opacity), 1.0); 1106 } 1107 #endif 1108 1109 vec2 mapping_octahedron(vec3 cubevec, vec2 texel_size) 1110 { 1111 /* projection onto octahedron */ 1112 cubevec /= dot(vec3(1.0), abs(cubevec)); 1113 1114 /* out-folding of the downward faces */ 1115 if (cubevec.z < 0.0) { 1116 vec2 cubevec_sign = step(0.0, cubevec.xy) * 2.0 - 1.0; 1117 cubevec.xy = (1.0 - abs(cubevec.yx)) * cubevec_sign; 1118 } 1119 1120 /* mapping to [0;1]ˆ2 texture space */ 1121 vec2 uvs = cubevec.xy * (0.5) + 0.5; 1122 1123 /* edge filtering fix */ 1124 uvs = (1.0 - 2.0 * texel_size) * uvs + texel_size; 1125 1126 return uvs; 1127 } 1128 1129 vec4 textureLod_octahedron(sampler2DArray tex, vec4 cubevec, float lod, float lod_max) 1130 { 1131 vec2 texelSize = 1.0 / vec2(textureSize(tex, int(lod_max))); 1132 1133 vec2 uvs = mapping_octahedron(cubevec.xyz, texelSize); 1134 1135 return textureLod(tex, vec3(uvs, cubevec.w), lod); 1136 } 1137 1138 vec4 texture_octahedron(sampler2DArray tex, vec4 cubevec) 1139 { 1140 vec2 texelSize = 1.0 / vec2(textureSize(tex, 0)); 1141 1142 vec2 uvs = mapping_octahedron(cubevec.xyz, texelSize); 1143 1144 return texture(tex, vec3(uvs, cubevec.w)); 1145 } 1146 1147 uniform sampler2DArray irradianceGrid; 1148 1149 #define IRRADIANCE_LIB 1150 1151 #ifdef IRRADIANCE_CUBEMAP 1152 struct IrradianceData { 1153 vec3 color; 1154 }; 1155 #elif defined(IRRADIANCE_SH_L2) 1156 struct IrradianceData { 1157 vec3 shcoefs[9]; 1158 }; 1159 #else /* defined(IRRADIANCE_HL2) */ 1160 struct IrradianceData { 1161 vec3 cubesides[3]; 1162 }; 1163 #endif 1164 1165 IrradianceData load_irradiance_cell(int cell, vec3 N) 1166 { 1167 /* Keep in sync with diffuse_filter_probe() */ 1168 1169 #if defined(IRRADIANCE_CUBEMAP) 1170 1171 # define AMBIANT_CUBESIZE 8 1172 ivec2 cell_co = ivec2(AMBIANT_CUBESIZE); 1173 int cell_per_row = textureSize(irradianceGrid, 0).x / cell_co.x; 1174 cell_co.x *= cell % cell_per_row; 1175 cell_co.y *= cell / cell_per_row; 1176 1177 vec2 texelSize = 1.0 / vec2(AMBIANT_CUBESIZE); 1178 1179 vec2 uvs = mapping_octahedron(N, texelSize); 1180 uvs *= vec2(AMBIANT_CUBESIZE) / vec2(textureSize(irradianceGrid, 0)); 1181 uvs += vec2(cell_co) / vec2(textureSize(irradianceGrid, 0)); 1182 1183 IrradianceData ir; 1184 ir.color = texture(irradianceGrid, vec3(uvs, 0.0)).rgb; 1185 1186 #elif defined(IRRADIANCE_SH_L2) 1187 1188 ivec2 cell_co = ivec2(3, 3); 1189 int cell_per_row = textureSize(irradianceGrid, 0).x / cell_co.x; 1190 cell_co.x *= cell % cell_per_row; 1191 cell_co.y *= cell / cell_per_row; 1192 1193 ivec3 ofs = ivec3(0, 1, 2); 1194 1195 IrradianceData ir; 1196 ir.shcoefs[0] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.xx, 0), 0).rgb; 1197 ir.shcoefs[1] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.yx, 0), 0).rgb; 1198 ir.shcoefs[2] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.zx, 0), 0).rgb; 1199 ir.shcoefs[3] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.xy, 0), 0).rgb; 1200 ir.shcoefs[4] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.yy, 0), 0).rgb; 1201 ir.shcoefs[5] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.zy, 0), 0).rgb; 1202 ir.shcoefs[6] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.xz, 0), 0).rgb; 1203 ir.shcoefs[7] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.yz, 0), 0).rgb; 1204 ir.shcoefs[8] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.zz, 0), 0).rgb; 1205 1206 #else /* defined(IRRADIANCE_HL2) */ 1207 1208 ivec2 cell_co = ivec2(3, 2); 1209 int cell_per_row = textureSize(irradianceGrid, 0).x / cell_co.x; 1210 cell_co.x *= cell % cell_per_row; 1211 cell_co.y *= cell / cell_per_row; 1212 1213 ivec3 is_negative = ivec3(step(0.0, -N)); 1214 1215 IrradianceData ir; 1216 ir.cubesides[0] = irradiance_decode( 1217 texelFetch(irradianceGrid, ivec3(cell_co + ivec2(0, is_negative.x), 0), 0)); 1218 ir.cubesides[1] = irradiance_decode( 1219 texelFetch(irradianceGrid, ivec3(cell_co + ivec2(1, is_negative.y), 0), 0)); 1220 ir.cubesides[2] = irradiance_decode( 1221 texelFetch(irradianceGrid, ivec3(cell_co + ivec2(2, is_negative.z), 0), 0)); 1222 1223 #endif 1224 1225 return ir; 1226 } 1227 1228 float load_visibility_cell(int cell, vec3 L, float dist, float bias, float bleed_bias, float range) 1229 { 1230 /* Keep in sync with diffuse_filter_probe() */ 1231 ivec2 cell_co = ivec2(prbIrradianceVisSize); 1232 ivec2 cell_per_row_col = textureSize(irradianceGrid, 0).xy / prbIrradianceVisSize; 1233 cell_co.x *= (cell % cell_per_row_col.x); 1234 cell_co.y *= (cell / cell_per_row_col.x) % cell_per_row_col.y; 1235 float layer = 1.0 + float((cell / cell_per_row_col.x) / cell_per_row_col.y); 1236 1237 vec2 texel_size = 1.0 / vec2(textureSize(irradianceGrid, 0).xy); 1238 vec2 co = vec2(cell_co) * texel_size; 1239 1240 vec2 uv = mapping_octahedron(-L, vec2(1.0 / float(prbIrradianceVisSize))); 1241 uv *= vec2(prbIrradianceVisSize) * texel_size; 1242 1243 vec4 data = texture(irradianceGrid, vec3(co + uv, layer)); 1244 1245 /* Decoding compressed data */ 1246 vec2 moments = visibility_decode(data, range); 1247 1248 /* Doing chebishev test */ 1249 float variance = abs(moments.x * moments.x - moments.y); 1250 variance = max(variance, bias / 10.0); 1251 1252 float d = dist - moments.x; 1253 float p_max = variance / (variance + d * d); 1254 1255 /* Increase contrast in the weight by squaring it */ 1256 p_max *= p_max; 1257 1258 /* Now reduce light-bleeding by removing the [0, x] tail and linearly rescaling (x, 1] */ 1259 p_max = clamp((p_max - bleed_bias) / (1.0 - bleed_bias), 0.0, 1.0); 1260 1261 return (dist <= moments.x) ? 1.0 : p_max; 1262 } 1263 1264 /* http://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/ */ 1265 vec3 spherical_harmonics_L1(vec3 N, vec3 shcoefs[4]) 1266 { 1267 vec3 sh = vec3(0.0); 1268 1269 sh += 0.282095 * shcoefs[0]; 1270 1271 sh += -0.488603 * N.z * shcoefs[1]; 1272 sh += 0.488603 * N.y * shcoefs[2]; 1273 sh += -0.488603 * N.x * shcoefs[3]; 1274 1275 return sh; 1276 } 1277 1278 vec3 spherical_harmonics_L2(vec3 N, vec3 shcoefs[9]) 1279 { 1280 vec3 sh = vec3(0.0); 1281 1282 sh += 0.282095 * shcoefs[0]; 1283 1284 sh += -0.488603 * N.z * shcoefs[1]; 1285 sh += 0.488603 * N.y * shcoefs[2]; 1286 sh += -0.488603 * N.x * shcoefs[3]; 1287 1288 sh += 1.092548 * N.x * N.z * shcoefs[4]; 1289 sh += -1.092548 * N.z * N.y * shcoefs[5]; 1290 sh += 0.315392 * (3.0 * N.y * N.y - 1.0) * shcoefs[6]; 1291 sh += -1.092548 * N.x * N.y * shcoefs[7]; 1292 sh += 0.546274 * (N.x * N.x - N.z * N.z) * shcoefs[8]; 1293 1294 return sh; 1295 } 1296 1297 vec3 hl2_basis(vec3 N, vec3 cubesides[3]) 1298 { 1299 vec3 irradiance = vec3(0.0); 1300 1301 vec3 n_squared = N * N; 1302 1303 irradiance += n_squared.x * cubesides[0]; 1304 irradiance += n_squared.y * cubesides[1]; 1305 irradiance += n_squared.z * cubesides[2]; 1306 1307 return irradiance; 1308 } 1309 1310 vec3 compute_irradiance(vec3 N, IrradianceData ird) 1311 { 1312 #if defined(IRRADIANCE_CUBEMAP) 1313 return ird.color; 1314 #elif defined(IRRADIANCE_SH_L2) 1315 return spherical_harmonics_L2(N, ird.shcoefs); 1316 #else /* defined(IRRADIANCE_HL2) */ 1317 return hl2_basis(N, ird.cubesides); 1318 #endif 1319 } 1320 1321 vec3 irradiance_from_cell_get(int cell, vec3 ir_dir) 1322 { 1323 IrradianceData ir_data = load_irradiance_cell(cell, ir_dir); 1324 return compute_irradiance(ir_dir, ir_data); 1325 } 1326 1327 uniform sampler2DArray shadowCubeTexture; 1328 uniform sampler2DArray shadowCascadeTexture; 1329 1330 #define LAMPS_LIB 1331 1332 layout(std140) uniform shadow_block 1333 { 1334 ShadowData shadows_data[MAX_SHADOW]; 1335 ShadowCubeData shadows_cube_data[MAX_SHADOW_CUBE]; 1336 ShadowCascadeData shadows_cascade_data[MAX_SHADOW_CASCADE]; 1337 }; 1338 1339 layout(std140) uniform light_block 1340 { 1341 LightData lights_data[MAX_LIGHT]; 1342 }; 1343 1344 /* type */ 1345 #define POINT 0.0 1346 #define SUN 1.0 1347 #define SPOT 2.0 1348 #define AREA_RECT 4.0 1349 /* Used to define the area light shape, doesn't directly correspond to a Blender light type. */ 1350 #define AREA_ELLIPSE 100.0 1351 1352 #if defined(SHADOW_VSM) 1353 # define ShadowSample vec2 1354 # define sample_cube(vec, id) texture_octahedron(shadowCubeTexture, vec4(vec, id)).rg 1355 # define sample_cascade(vec, id) texture(shadowCascadeTexture, vec3(vec, id)).rg 1356 #elif defined(SHADOW_ESM) 1357 # define ShadowSample float 1358 # define sample_cube(vec, id) texture_octahedron(shadowCubeTexture, vec4(vec, id)).r 1359 # define sample_cascade(vec, id) texture(shadowCascadeTexture, vec3(vec, id)).r 1360 #else 1361 # define ShadowSample float 1362 # define sample_cube(vec, id) texture_octahedron(shadowCubeTexture, vec4(vec, id)).r 1363 # define sample_cascade(vec, id) texture(shadowCascadeTexture, vec3(vec, id)).r 1364 #endif 1365 1366 #if defined(SHADOW_VSM) 1367 # define get_depth_delta(dist, s) (dist - s.x) 1368 #else 1369 # define get_depth_delta(dist, s) (dist - s) 1370 #endif 1371 1372 /* ----------------------------------------------------------- */ 1373 /* ----------------------- Shadow tests ---------------------- */ 1374 /* ----------------------------------------------------------- */ 1375 1376 #if defined(SHADOW_VSM) 1377 1378 float shadow_test(ShadowSample moments, float dist, ShadowData sd) 1379 { 1380 float p = 0.0; 1381 1382 if (dist <= moments.x) { 1383 p = 1.0; 1384 } 1385 1386 float variance = moments.y - (moments.x * moments.x); 1387 variance = max(variance, sd.sh_bias / 10.0); 1388 1389 float d = moments.x - dist; 1390 float p_max = variance / (variance + d * d); 1391 1392 /* Now reduce light-bleeding by removing the [0, x] tail and linearly rescaling (x, 1] */ 1393 p_max = clamp((p_max - sd.sh_bleed) / (1.0 - sd.sh_bleed), 0.0, 1.0); 1394 1395 return max(p, p_max); 1396 } 1397 1398 #elif defined(SHADOW_ESM) 1399 1400 float shadow_test(ShadowSample z, float dist, ShadowData sd) 1401 { 1402 return saturate(exp(sd.sh_exp * (z - dist + sd.sh_bias))); 1403 } 1404 1405 #else 1406 1407 float shadow_test(ShadowSample z, float dist, ShadowData sd) 1408 { 1409 return step(0, z - dist + sd.sh_bias); 1410 } 1411 1412 #endif 1413 1414 /* ----------------------------------------------------------- */ 1415 /* ----------------------- Shadow types ---------------------- */ 1416 /* ----------------------------------------------------------- */ 1417 1418 float shadow_cubemap(ShadowData sd, ShadowCubeData scd, float texid, vec3 W) 1419 { 1420 vec3 cubevec = W - scd.position.xyz; 1421 float dist = length(cubevec); 1422 1423 cubevec /= dist; 1424 1425 ShadowSample s = sample_cube(cubevec, texid); 1426 return shadow_test(s, dist, sd); 1427 } 1428 1429 float evaluate_cascade(ShadowData sd, mat4 shadowmat, vec3 W, float range, float texid) 1430 { 1431 vec4 shpos = shadowmat * vec4(W, 1.0); 1432 float dist = shpos.z * range; 1433 1434 ShadowSample s = sample_cascade(shpos.xy, texid); 1435 float vis = shadow_test(s, dist, sd); 1436 1437 /* If fragment is out of shadowmap range, do not occlude */ 1438 if (shpos.z < 1.0 && shpos.z > 0.0) { 1439 return vis; 1440 } 1441 else { 1442 return 1.0; 1443 } 1444 } 1445 1446 float shadow_cascade(ShadowData sd, int scd_id, float texid, vec3 W) 1447 { 1448 vec4 view_z = vec4(dot(W - cameraPos, cameraForward)); 1449 vec4 weights = smoothstep(shadows_cascade_data[scd_id].split_end_distances, 1450 shadows_cascade_data[scd_id].split_start_distances.yzwx, 1451 view_z); 1452 1453 weights.yzw -= weights.xyz; 1454 1455 vec4 vis = vec4(1.0); 1456 float range = abs(sd.sh_far - sd.sh_near); /* Same factor as in get_cascade_world_distance(). */ 1457 1458 /* Branching using (weights > 0.0) is reaally slooow on intel so avoid it for now. */ 1459 /* TODO OPTI: Only do 2 samples and blend. */ 1460 vis.x = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[0], W, range, texid + 0); 1461 vis.y = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[1], W, range, texid + 1); 1462 vis.z = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[2], W, range, texid + 2); 1463 vis.w = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[3], W, range, texid + 3); 1464 1465 float weight_sum = dot(vec4(1.0), weights); 1466 if (weight_sum > 0.9999) { 1467 float vis_sum = dot(vec4(1.0), vis * weights); 1468 return vis_sum / weight_sum; 1469 } 1470 else { 1471 float vis_sum = dot(vec4(1.0), vis * step(0.001, weights)); 1472 return mix(1.0, vis_sum, weight_sum); 1473 } 1474 } 1475 1476 /* ----------------------------------------------------------- */ 1477 /* --------------------- Light Functions --------------------- */ 1478 /* ----------------------------------------------------------- */ 1479 1480 /* From Frostbite PBR Course 1481 * Distance based attenuation 1482 * http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf */ 1483 float distance_attenuation(float dist_sqr, float inv_sqr_influence) 1484 { 1485 float factor = dist_sqr * inv_sqr_influence; 1486 float fac = saturate(1.0 - factor * factor); 1487 return fac * fac; 1488 } 1489 1490 float spot_attenuation(LightData ld, vec3 l_vector) 1491 { 1492 float z = dot(ld.l_forward, l_vector.xyz); 1493 vec3 lL = l_vector.xyz / z; 1494 float x = dot(ld.l_right, lL) / ld.l_sizex; 1495 float y = dot(ld.l_up, lL) / ld.l_sizey; 1496 float ellipse = inversesqrt(1.0 + x * x + y * y); 1497 float spotmask = smoothstep(0.0, 1.0, (ellipse - ld.l_spot_size) / ld.l_spot_blend); 1498 return spotmask; 1499 } 1500 1501 float light_visibility(LightData ld, 1502 vec3 W, 1503 #ifndef VOLUMETRICS 1504 vec3 viewPosition, 1505 vec3 vN, 1506 #endif 1507 vec4 l_vector) 1508 { 1509 float vis = 1.0; 1510 1511 if (ld.l_type == SPOT) { 1512 vis *= spot_attenuation(ld, l_vector.xyz); 1513 } 1514 if (ld.l_type >= SPOT) { 1515 vis *= step(0.0, -dot(l_vector.xyz, ld.l_forward)); 1516 } 1517 if (ld.l_type != SUN) { 1518 vis *= distance_attenuation(l_vector.w * l_vector.w, ld.l_influence); 1519 } 1520 1521 #if !defined(VOLUMETRICS) || defined(VOLUME_SHADOW) 1522 /* shadowing */ 1523 if (ld.l_shadowid >= 0.0 && vis > 0.001) { 1524 ShadowData data = shadows_data[int(ld.l_shadowid)]; 1525 1526 if (ld.l_type == SUN) { 1527 vis *= shadow_cascade(data, int(data.sh_data_start), data.sh_tex_start, W); 1528 } 1529 else { 1530 vis *= shadow_cubemap( 1531 data, shadows_cube_data[int(data.sh_data_start)], data.sh_tex_start, W); 1532 } 1533 1534 # ifndef VOLUMETRICS 1535 /* Only compute if not already in shadow. */ 1536 if (data.sh_contact_dist > 0.0) { 1537 vec4 L = (ld.l_type != SUN) ? l_vector : vec4(-ld.l_forward, 1.0); 1538 float trace_distance = (ld.l_type != SUN) ? min(data.sh_contact_dist, l_vector.w) : 1539 data.sh_contact_dist; 1540 1541 vec3 T, B; 1542 make_orthonormal_basis(L.xyz / L.w, T, B); 1543 1544 vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy); 1545 rand.zw *= fast_sqrt(rand.y) * data.sh_contact_spread; 1546 1547 /* We use the full l_vector.xyz so that the spread is minimize 1548 * if the shading point is further away from the light source */ 1549 vec3 ray_dir = L.xyz + T * rand.z + B * rand.w; 1550 ray_dir = transform_direction(ViewMatrix, ray_dir); 1551 ray_dir = normalize(ray_dir); 1552 1553 vec3 ray_ori = viewPosition; 1554 1555 /* Fix translucency shadowed by contact shadows. */ 1556 vN = (gl_FrontFacing) ? vN : -vN; 1557 1558 if (dot(vN, ray_dir) <= 0.0) { 1559 return vis; 1560 } 1561 1562 float bias = 0.5; /* Constant Bias */ 1563 bias += 1.0 - abs(dot(vN, ray_dir)); /* Angle dependent bias */ 1564 bias *= gl_FrontFacing ? data.sh_contact_offset : -data.sh_contact_offset; 1565 1566 vec3 nor_bias = vN * bias; 1567 ray_ori += nor_bias; 1568 1569 ray_dir *= trace_distance; 1570 ray_dir -= nor_bias; 1571 1572 vec3 hit_pos = raycast( 1573 -1, ray_ori, ray_dir, data.sh_contact_thickness, rand.x, 0.1, 0.001, false); 1574 1575 if (hit_pos.z > 0.0) { 1576 hit_pos = get_view_space_from_depth(hit_pos.xy, hit_pos.z); 1577 float hit_dist = distance(viewPosition, hit_pos); 1578 float dist_ratio = hit_dist / trace_distance; 1579 return vis * saturate(dist_ratio * dist_ratio * dist_ratio); 1580 } 1581 } 1582 # endif 1583 } 1584 #endif 1585 1586 return vis; 1587 } 1588 1589 #ifdef USE_LTC 1590 float light_diffuse(LightData ld, vec3 N, vec3 V, vec4 l_vector) 1591 { 1592 if (ld.l_type == AREA_RECT) { 1593 vec3 corners[4]; 1594 corners[0] = normalize((l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * ld.l_sizey); 1595 corners[1] = normalize((l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * -ld.l_sizey); 1596 corners[2] = normalize((l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * -ld.l_sizey); 1597 corners[3] = normalize((l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * ld.l_sizey); 1598 1599 return ltc_evaluate_quad(corners, N); 1600 } 1601 else if (ld.l_type == AREA_ELLIPSE) { 1602 vec3 points[3]; 1603 points[0] = (l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * -ld.l_sizey; 1604 points[1] = (l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * -ld.l_sizey; 1605 points[2] = (l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * ld.l_sizey; 1606 1607 return ltc_evaluate_disk(N, V, mat3(1.0), points); 1608 } 1609 else { 1610 float radius = ld.l_radius; 1611 radius /= (ld.l_type == SUN) ? 1.0 : l_vector.w; 1612 vec3 L = (ld.l_type == SUN) ? -ld.l_forward : (l_vector.xyz / l_vector.w); 1613 1614 return ltc_evaluate_disk_simple(radius, dot(N, L)); 1615 } 1616 } 1617 1618 float light_specular(LightData ld, vec4 ltc_mat, vec3 N, vec3 V, vec4 l_vector) 1619 { 1620 if (ld.l_type == AREA_RECT) { 1621 vec3 corners[4]; 1622 corners[0] = (l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * ld.l_sizey; 1623 corners[1] = (l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * -ld.l_sizey; 1624 corners[2] = (l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * -ld.l_sizey; 1625 corners[3] = (l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * ld.l_sizey; 1626 1627 ltc_transform_quad(N, V, ltc_matrix(ltc_mat), corners); 1628 1629 return ltc_evaluate_quad(corners, vec3(0.0, 0.0, 1.0)); 1630 } 1631 else { 1632 bool is_ellipse = (ld.l_type == AREA_ELLIPSE); 1633 float radius_x = is_ellipse ? ld.l_sizex : ld.l_radius; 1634 float radius_y = is_ellipse ? ld.l_sizey : ld.l_radius; 1635 1636 vec3 L = (ld.l_type == SUN) ? -ld.l_forward : l_vector.xyz; 1637 vec3 Px = ld.l_right; 1638 vec3 Py = ld.l_up; 1639 1640 if (ld.l_type == SPOT || ld.l_type == POINT) { 1641 make_orthonormal_basis(l_vector.xyz / l_vector.w, Px, Py); 1642 } 1643 1644 vec3 points[3]; 1645 points[0] = (L + Px * -radius_x) + Py * -radius_y; 1646 points[1] = (L + Px * radius_x) + Py * -radius_y; 1647 points[2] = (L + Px * radius_x) + Py * radius_y; 1648 1649 return ltc_evaluate_disk(N, V, ltc_matrix(ltc_mat), points); 1650 } 1651 } 1652 #endif 1653 1654 #define MAX_SSS_SAMPLES 65 1655 #define SSS_LUT_SIZE 64.0 1656 #define SSS_LUT_SCALE ((SSS_LUT_SIZE - 1.0) / float(SSS_LUT_SIZE)) 1657 #define SSS_LUT_BIAS (0.5 / float(SSS_LUT_SIZE)) 1658 1659 #ifdef USE_TRANSLUCENCY 1660 layout(std140) uniform sssProfile 1661 { 1662 vec4 kernel[MAX_SSS_SAMPLES]; 1663 vec4 radii_max_radius; 1664 int sss_samples; 1665 }; 1666 1667 uniform sampler1D sssTexProfile; 1668 1669 vec3 sss_profile(float s) 1670 { 1671 s /= radii_max_radius.w; 1672 return texture(sssTexProfile, saturate(s) * SSS_LUT_SCALE + SSS_LUT_BIAS).rgb; 1673 } 1674 #endif 1675 1676 vec3 light_translucent(LightData ld, vec3 W, vec3 N, vec4 l_vector, float scale) 1677 { 1678 #if !defined(USE_TRANSLUCENCY) || defined(VOLUMETRICS) 1679 return vec3(0.0); 1680 #else 1681 vec3 vis = vec3(1.0); 1682 1683 if (ld.l_type == SPOT) { 1684 vis *= spot_attenuation(ld, l_vector.xyz); 1685 } 1686 if (ld.l_type >= SPOT) { 1687 vis *= step(0.0, -dot(l_vector.xyz, ld.l_forward)); 1688 } 1689 if (ld.l_type != SUN) { 1690 vis *= distance_attenuation(l_vector.w * l_vector.w, ld.l_influence); 1691 } 1692 1693 /* Only shadowed light can produce translucency */ 1694 if (ld.l_shadowid >= 0.0 && vis.x > 0.001) { 1695 ShadowData data = shadows_data[int(ld.l_shadowid)]; 1696 float delta; 1697 1698 vec4 L = (ld.l_type != SUN) ? l_vector : vec4(-ld.l_forward, 1.0); 1699 1700 vec3 T, B; 1701 make_orthonormal_basis(L.xyz / L.w, T, B); 1702 1703 vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy); 1704 rand.zw *= fast_sqrt(rand.y) * data.sh_blur; 1705 1706 /* We use the full l_vector.xyz so that the spread is minimize 1707 * if the shading point is further away from the light source */ 1708 W = W + T * rand.z + B * rand.w; 1709 1710 if (ld.l_type == SUN) { 1711 int scd_id = int(data.sh_data_start); 1712 vec4 view_z = vec4(dot(W - cameraPos, cameraForward)); 1713 1714 vec4 weights = step(shadows_cascade_data[scd_id].split_end_distances, view_z); 1715 float id = abs(4.0 - dot(weights, weights)); 1716 1717 if (id > 3.0) { 1718 return vec3(0.0); 1719 } 1720 1721 float range = abs(data.sh_far - 1722 data.sh_near); /* Same factor as in get_cascade_world_distance(). */ 1723 1724 vec4 shpos = shadows_cascade_data[scd_id].shadowmat[int(id)] * vec4(W, 1.0); 1725 float dist = shpos.z * range; 1726 1727 if (shpos.z > 1.0 || shpos.z < 0.0) { 1728 return vec3(0.0); 1729 } 1730 1731 ShadowSample s = sample_cascade(shpos.xy, data.sh_tex_start + id); 1732 delta = get_depth_delta(dist, s); 1733 } 1734 else { 1735 vec3 cubevec = W - shadows_cube_data[int(data.sh_data_start)].position.xyz; 1736 float dist = length(cubevec); 1737 cubevec /= dist; 1738 1739 ShadowSample s = sample_cube(cubevec, data.sh_tex_start); 1740 delta = get_depth_delta(dist, s); 1741 } 1742 1743 /* XXX : Removing Area Power. */ 1744 /* TODO : put this out of the shader. */ 1745 float falloff; 1746 if (ld.l_type == AREA_RECT || ld.l_type == AREA_ELLIPSE) { 1747 vis *= (ld.l_sizex * ld.l_sizey * 4.0 * M_PI) * (1.0 / 80.0); 1748 if (ld.l_type == AREA_ELLIPSE) { 1749 vis *= M_PI * 0.25; 1750 } 1751 vis *= 0.3 * 20.0 * 1752 max(0.0, dot(-ld.l_forward, l_vector.xyz / l_vector.w)); /* XXX ad hoc, empirical */ 1753 vis /= (l_vector.w * l_vector.w); 1754 falloff = dot(N, l_vector.xyz / l_vector.w); 1755 } 1756 else if (ld.l_type == SUN) { 1757 vis /= 1.0f + (ld.l_radius * ld.l_radius * 0.5f); 1758 vis *= ld.l_radius * ld.l_radius * M_PI; /* Removing area light power*/ 1759 vis *= M_2PI * 0.78; /* Matching cycles with point light. */ 1760 vis *= 0.082; /* XXX ad hoc, empirical */ 1761 falloff = dot(N, -ld.l_forward); 1762 } 1763 else { 1764 vis *= (4.0 * ld.l_radius * ld.l_radius) * (1.0 / 10.0); 1765 vis *= 1.5; /* XXX ad hoc, empirical */ 1766 vis /= (l_vector.w * l_vector.w); 1767 falloff = dot(N, l_vector.xyz / l_vector.w); 1768 } 1769 // vis *= M_1_PI; /* Normalize */ 1770 1771 /* Applying profile */ 1772 vis *= sss_profile(abs(delta) / scale); 1773 1774 /* No transmittance at grazing angle (hide artifacts) */ 1775 vis *= saturate(falloff * 2.0); 1776 } 1777 else { 1778 vis = vec3(0.0); 1779 } 1780 1781 return vis; 1782 #endif 1783 } 1784 1785 /* Based on Frosbite Unified Volumetric. 1786 * https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */ 1787 1788 /* Volume slice to view space depth. */ 1789 float volume_z_to_view_z(float z) 1790 { 1791 if (ProjectionMatrix[3][3] == 0.0) { 1792 /* Exponential distribution */ 1793 return (exp2(z / volDepthParameters.z) - volDepthParameters.x) / volDepthParameters.y; 1794 } 1795 else { 1796 /* Linear distribution */ 1797 return mix(volDepthParameters.x, volDepthParameters.y, z); 1798 } 1799 } 1800 1801 float view_z_to_volume_z(float depth) 1802 { 1803 if (ProjectionMatrix[3][3] == 0.0) { 1804 /* Exponential distribution */ 1805 return volDepthParameters.z * log2(depth * volDepthParameters.y + volDepthParameters.x); 1806 } 1807 else { 1808 /* Linear distribution */ 1809 return (depth - volDepthParameters.x) * volDepthParameters.z; 1810 } 1811 } 1812 1813 /* Volume texture normalized coordinates to NDC (special range [0, 1]). */ 1814 vec3 volume_to_ndc(vec3 cos) 1815 { 1816 cos.z = volume_z_to_view_z(cos.z); 1817 cos.z = get_depth_from_view_z(cos.z); 1818 cos.xy /= volCoordScale.xy; 1819 return cos; 1820 } 1821 1822 vec3 ndc_to_volume(vec3 cos) 1823 { 1824 cos.z = get_view_z_from_depth(cos.z); 1825 cos.z = view_z_to_volume_z(cos.z); 1826 cos.xy *= volCoordScale.xy; 1827 return cos; 1828 } 1829 1830 float phase_function_isotropic() 1831 { 1832 return 1.0 / (4.0 * M_PI); 1833 } 1834 1835 float phase_function(vec3 v, vec3 l, float g) 1836 { 1837 /* Henyey-Greenstein */ 1838 float cos_theta = dot(v, l); 1839 g = clamp(g, -1.0 + 1e-3, 1.0 - 1e-3); 1840 float sqr_g = g * g; 1841 return (1 - sqr_g) / max(1e-8, 4.0 * M_PI * pow(1 + sqr_g - 2 * g * cos_theta, 3.0 / 2.0)); 1842 } 1843 1844 #ifdef LAMPS_LIB 1845 vec3 light_volume(LightData ld, vec4 l_vector) 1846 { 1847 float power; 1848 /* TODO : Area lighting ? */ 1849 /* XXX : Removing Area Power. */ 1850 /* TODO : put this out of the shader. */ 1851 /* See eevee_light_setup(). */ 1852 if (ld.l_type == AREA_RECT || ld.l_type == AREA_ELLIPSE) { 1853 power = (ld.l_sizex * ld.l_sizey * 4.0 * M_PI) * (1.0 / 80.0); 1854 if (ld.l_type == AREA_ELLIPSE) { 1855 power *= M_PI * 0.25; 1856 } 1857 power *= 20.0 * 1858 max(0.0, dot(-ld.l_forward, l_vector.xyz / l_vector.w)); /* XXX ad hoc, empirical */ 1859 } 1860 else if (ld.l_type == SUN) { 1861 power = ld.l_radius * ld.l_radius * M_PI; /* Removing area light power*/ 1862 power /= 1.0f + (ld.l_radius * ld.l_radius * 0.5f); 1863 power *= M_PI * 0.5; /* Matching cycles. */ 1864 } 1865 else { 1866 power = (4.0 * ld.l_radius * ld.l_radius) * (1.0 / 10.0); 1867 power *= M_2PI; /* Matching cycles with point light. */ 1868 } 1869 1870 power /= (l_vector.w * l_vector.w); 1871 1872 /* OPTI: find a better way than calculating this on the fly */ 1873 float lum = dot(ld.l_color, vec3(0.3, 0.6, 0.1)); /* luminance approx. */ 1874 vec3 tint = (lum > 0.0) ? ld.l_color / lum : vec3(1.0); /* normalize lum. to isolate hue+sat */ 1875 1876 lum = min(lum * power, volLightClamp); 1877 1878 return tint * lum; 1879 } 1880 1881 # define VOLUMETRIC_SHADOW_MAX_STEP 32.0 1882 1883 vec3 participating_media_extinction(vec3 wpos, sampler3D volume_extinction) 1884 { 1885 /* Waiting for proper volume shadowmaps and out of frustum shadow map. */ 1886 vec3 ndc = project_point(ViewProjectionMatrix, wpos); 1887 vec3 volume_co = ndc_to_volume(ndc * 0.5 + 0.5); 1888 1889 /* Let the texture be clamped to edge. This reduce visual glitches. */ 1890 return texture(volume_extinction, volume_co).rgb; 1891 } 1892 1893 vec3 light_volume_shadow(LightData ld, vec3 ray_wpos, vec4 l_vector, sampler3D volume_extinction) 1894 { 1895 # if defined(VOLUME_SHADOW) 1896 /* Heterogeneous volume shadows */ 1897 float dd = l_vector.w / volShadowSteps; 1898 vec3 L = l_vector.xyz * l_vector.w; 1899 vec3 shadow = vec3(1.0); 1900 for (float s = 0.5; s < VOLUMETRIC_SHADOW_MAX_STEP && s < (volShadowSteps - 0.1); s += 1.0) { 1901 vec3 pos = ray_wpos + L * (s / volShadowSteps); 1902 vec3 s_extinction = participating_media_extinction(pos, volume_extinction); 1903 shadow *= exp(-s_extinction * dd); 1904 } 1905 return shadow; 1906 # else 1907 return vec3(1.0); 1908 # endif /* VOLUME_SHADOW */ 1909 } 1910 #endif 1911 1912 #ifdef IRRADIANCE_LIB 1913 vec3 irradiance_volumetric(vec3 wpos) 1914 { 1915 # ifdef IRRADIANCE_HL2 1916 IrradianceData ir_data = load_irradiance_cell(0, vec3(1.0)); 1917 vec3 irradiance = ir_data.cubesides[0] + ir_data.cubesides[1] + ir_data.cubesides[2]; 1918 ir_data = load_irradiance_cell(0, vec3(-1.0)); 1919 irradiance += ir_data.cubesides[0] + ir_data.cubesides[1] + ir_data.cubesides[2]; 1920 irradiance *= 0.16666666; /* 1/6 */ 1921 return irradiance; 1922 # else 1923 return vec3(0.0); 1924 # endif 1925 } 1926 #endif 1927 1928 uniform sampler3D inScattering; 1929 uniform sampler3D inTransmittance; 1930 1931 void volumetric_resolve(vec2 frag_uvs, 1932 float frag_depth, 1933 out vec3 transmittance, 1934 out vec3 scattering) 1935 { 1936 vec3 volume_cos = ndc_to_volume(vec3(frag_uvs, frag_depth)); 1937 1938 scattering = texture(inScattering, volume_cos).rgb; 1939 transmittance = texture(inTransmittance, volume_cos).rgb; 1940 } 1941 1942 /* Based on Frosbite Unified Volumetric. 1943 * https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */ 1944 1945 /* Step 2 : Evaluate all light scattering for each froxels. 1946 * Also do the temporal reprojection to fight aliasing artifacts. */ 1947 1948 uniform sampler3D volumeScattering; 1949 uniform sampler3D volumeExtinction; 1950 uniform sampler3D volumeEmission; 1951 uniform sampler3D volumePhase; 1952 1953 uniform sampler3D historyScattering; 1954 uniform sampler3D historyTransmittance; 1955 1956 flat in int slice; 1957 1958 layout(location = 0) out vec4 outScattering; 1959 layout(location = 1) out vec4 outTransmittance; 1960 1961 void main() 1962 { 1963 ivec3 volume_cell = ivec3(gl_FragCoord.xy, slice); 1964 1965 /* Emission */ 1966 outScattering = texelFetch(volumeEmission, volume_cell, 0); 1967 outTransmittance = texelFetch(volumeExtinction, volume_cell, 0); 1968 vec3 s_scattering = texelFetch(volumeScattering, volume_cell, 0).rgb; 1969 vec3 volume_ndc = volume_to_ndc((vec3(volume_cell) + volJitter.xyz) * volInvTexSize.xyz); 1970 vec3 worldPosition = get_world_space_from_depth(volume_ndc.xy, volume_ndc.z); 1971 vec3 wdir = cameraVec; 1972 1973 vec2 phase = texelFetch(volumePhase, volume_cell, 0).rg; 1974 float s_anisotropy = phase.x / max(1.0, phase.y); 1975 1976 /* Environment : Average color. */ 1977 outScattering.rgb += irradiance_volumetric(worldPosition) * s_scattering * 1978 phase_function_isotropic(); 1979 1980 #ifdef VOLUME_LIGHTING /* Lights */ 1981 for (int i = 0; i < MAX_LIGHT && i < laNumLight; ++i) { 1982 1983 LightData ld = lights_data[i]; 1984 1985 vec4 l_vector; 1986 l_vector.xyz = (ld.l_type == SUN) ? -ld.l_forward : ld.l_position - worldPosition; 1987 l_vector.w = length(l_vector.xyz); 1988 1989 float Vis = light_visibility(ld, worldPosition, l_vector); 1990 1991 vec3 Li = light_volume(ld, l_vector) * 1992 light_volume_shadow(ld, worldPosition, l_vector, volumeExtinction); 1993 1994 outScattering.rgb += Li * Vis * s_scattering * 1995 phase_function(-wdir, l_vector.xyz / l_vector.w, s_anisotropy); 1996 } 1997 #endif 1998 1999 /* Temporal supersampling */ 2000 /* Note : this uses the cell non-jittered position (texel center). */ 2001 vec3 curr_ndc = volume_to_ndc(vec3(gl_FragCoord.xy, float(slice) + 0.5) * volInvTexSize.xyz); 2002 vec3 wpos = get_world_space_from_depth(curr_ndc.xy, curr_ndc.z); 2003 vec3 prev_ndc = project_point(pastViewProjectionMatrix, wpos); 2004 vec3 prev_volume = ndc_to_volume(prev_ndc * 0.5 + 0.5); 2005 2006 if ((volHistoryAlpha > 0.0) && all(greaterThan(prev_volume, vec3(0.0))) && 2007 all(lessThan(prev_volume, vec3(1.0)))) { 2008 vec4 h_Scattering = texture(historyScattering, prev_volume); 2009 vec4 h_Transmittance = texture(historyTransmittance, prev_volume); 2010 outScattering = mix(outScattering, h_Scattering, volHistoryAlpha); 2011 outTransmittance = mix(outTransmittance, h_Transmittance, volHistoryAlpha); 2012 } 2013 2014 /* Catch NaNs */ 2015 if (any(isnan(outScattering)) || any(isnan(outTransmittance))) { 2016 outScattering = vec4(0.0); 2017 outTransmittance = vec4(1.0); 2018 } 2019 } Number of Geometry Uniforms exceeds HW limits. GPUShader: linking error: ===== shader string 1 ==== 1 #define COMMON_VIEW_LIB 2 3 /* keep in sync with DRWManager.view_data */ 4 layout(std140) uniform viewBlock 5 { 6 /* Same order as DRWViewportMatrixType */ 7 mat4 ViewProjectionMatrix; 8 mat4 ViewProjectionMatrixInverse; 9 mat4 ViewMatrix; 10 mat4 ViewMatrixInverse; 11 mat4 ProjectionMatrix; 12 mat4 ProjectionMatrixInverse; 13 14 vec4 clipPlanes[6]; 15 16 /* TODO move it elsewhere. */ 17 vec4 CameraTexCoFactors; 18 }; 19 20 #ifdef world_clip_planes_calc_clip_distance 21 # undef world_clip_planes_calc_clip_distance 22 # define world_clip_planes_calc_clip_distance(p) \ 23 _world_clip_planes_calc_clip_distance(p, clipPlanes) 24 #endif 25 26 uniform mat4 ModelMatrix; 27 uniform mat4 ModelMatrixInverse; 28 29 /** Transform shortcuts. */ 30 /* Rule of thumb: Try to reuse world positions and normals because converting though viewspace 31 * will always be decomposed in at least 2 matrix operation. */ 32 33 /** 34 * Some clarification: 35 * Usually Normal matrix is transpose(inverse(ViewMatrix * ModelMatrix)) 36 * 37 * But since it is slow to multiply matrices we decompose it. Decomposing 38 * inversion and transposition both invert the product order leaving us with 39 * the same original order: 40 * transpose(ViewMatrixInverse) * transpose(ModelMatrixInverse) 41 * 42 * Knowing that the view matrix is orthogonal, the transpose is also the inverse. 43 * Note: This is only valid because we are only using the mat3 of the ViewMatrixInverse. 44 * ViewMatrix * transpose(ModelMatrixInverse) 45 **/ 46 #define normal_object_to_view(n) (mat3(ViewMatrix) * (transpose(mat3(ModelMatrixInverse)) * n)) 47 #define normal_object_to_world(n) (transpose(mat3(ModelMatrixInverse)) * n) 48 #define normal_world_to_object(n) (transpose(mat3(ModelMatrix)) * n) 49 #define normal_world_to_view(n) (mat3(ViewMatrix) * n) 50 51 #define point_object_to_ndc(p) (ViewProjectionMatrix * vec4((ModelMatrix * vec4(p, 1.0)).xyz, 1.0)) 52 #define point_object_to_view(p) ((ViewMatrix * vec4((ModelMatrix * vec4(p, 1.0)).xyz, 1.0)).xyz) 53 #define point_object_to_world(p) ((ModelMatrix * vec4(p, 1.0)).xyz) 54 #define point_view_to_ndc(p) (ProjectionMatrix * vec4(p, 1.0)) 55 #define point_view_to_object(p) ((ModelMatrixInverse * (ViewMatrixInverse * vec4(p, 1.0))).xyz) 56 #define point_view_to_world(p) ((ViewMatrixInverse * vec4(p, 1.0)).xyz) 57 #define point_world_to_ndc(p) (ViewProjectionMatrix * vec4(p, 1.0)) 58 #define point_world_to_object(p) ((ModelMatrixInverse * vec4(p, 1.0)).xyz) 59 #define point_world_to_view(p) ((ViewMatrix * vec4(p, 1.0)).xyz) 60 61 /* Due to some shader compiler bug, we somewhat need to access gl_VertexID 62 * to make vertex shaders work. even if it's actually dead code. */ 63 #ifdef GPU_INTEL 64 # define GPU_INTEL_VERTEX_SHADER_WORKAROUND gl_Position.x = float(gl_VertexID); 65 #else 66 # define GPU_INTEL_VERTEX_SHADER_WORKAROUND 67 #endif 68 69 layout(std140) uniform common_block 70 { 71 mat4 pastViewProjectionMatrix; 72 vec4 viewVecs[2]; 73 vec2 mipRatio[10]; /* To correct mip level texel mis-alignement */ 74 /* Ambient Occlusion */ 75 vec4 aoParameters[2]; 76 /* Volumetric */ 77 ivec4 volTexSize; 78 vec4 volDepthParameters; /* Parameters to the volume Z equation */ 79 vec4 volInvTexSize; 80 vec4 volJitter; 81 vec4 volCoordScale; /* To convert volume uvs to screen uvs */ 82 float volHistoryAlpha; 83 float volLightClamp; 84 float volShadowSteps; 85 bool volUseLights; 86 /* Screen Space Reflections */ 87 vec4 ssrParameters; 88 float ssrBorderFac; 89 float ssrMaxRoughness; 90 float ssrFireflyFac; 91 float ssrBrdfBias; 92 bool ssrToggle; 93 bool ssrefractToggle; 94 /* SubSurface Scattering */ 95 float sssJitterThreshold; 96 bool sssToggle; 97 /* Specular */ 98 bool specToggle; 99 /* Lights */ 100 int laNumLight; 101 /* Probes */ 102 int prbNumPlanar; 103 int prbNumRenderCube; 104 int prbNumRenderGrid; 105 int prbIrradianceVisSize; 106 float prbIrradianceSmooth; 107 float prbLodCubeMax; 108 float prbLodPlanarMax; 109 /* Misc*/ 110 int hizMipOffset; 111 int rayType; 112 float rayDepth; 113 }; 114 115 /* rayType (keep in sync with ray_type) */ 116 #define EEVEE_RAY_CAMERA 0 117 #define EEVEE_RAY_SHADOW 1 118 #define EEVEE_RAY_DIFFUSE 2 119 #define EEVEE_RAY_GLOSSY 3 120 121 /* aoParameters */ 122 #define aoDistance aoParameters[0].x 123 #define aoSamples aoParameters[0].y /* UNUSED */ 124 #define aoFactor aoParameters[0].z 125 #define aoInvSamples aoParameters[0].w /* UNUSED */ 126 127 #define aoOffset aoParameters[1].x /* UNUSED */ 128 #define aoBounceFac aoParameters[1].y 129 #define aoQuality aoParameters[1].z 130 #define aoSettings aoParameters[1].w 131 132 /* ssrParameters */ 133 #define ssrQuality ssrParameters.x 134 #define ssrThickness ssrParameters.y 135 #define ssrPixelSize ssrParameters.zw 136 137 #define M_PI 3.14159265358979323846 /* pi */ 138 #define M_2PI 6.28318530717958647692 /* 2*pi */ 139 #define M_PI_2 1.57079632679489661923 /* pi/2 */ 140 #define M_1_PI 0.318309886183790671538 /* 1/pi */ 141 #define M_1_2PI 0.159154943091895335768 /* 1/(2*pi) */ 142 #define M_1_PI2 0.101321183642337771443 /* 1/(pi^2) */ 143 144 #define LUT_SIZE 64 145 146 /* Buffers */ 147 uniform sampler2D colorBuffer; 148 uniform sampler2D depthBuffer; 149 uniform sampler2D maxzBuffer; 150 uniform sampler2D minzBuffer; 151 uniform sampler2DArray planarDepth; 152 153 #define cameraForward ViewMatrixInverse[2].xyz 154 #define cameraPos ViewMatrixInverse[3].xyz 155 #define cameraVec \ 156 ((ProjectionMatrix[3][3] == 0.0) ? normalize(cameraPos - worldPosition) : cameraForward) 157 #define viewCameraVec \ 158 ((ProjectionMatrix[3][3] == 0.0) ? normalize(-viewPosition) : vec3(0.0, 0.0, 1.0)) 159 160 /* ------- Structures -------- */ 161 162 /* ------ Lights ----- */ 163 struct LightData { 164 vec4 position_influence; /* w : InfluenceRadius (inversed and squared) */ 165 vec4 color_spec; /* w : Spec Intensity */ 166 vec4 spotdata_radius_shadow; /* x : spot size, y : spot blend, z : radius, w: shadow id */ 167 vec4 rightvec_sizex; /* xyz: Normalized up vector, w: area size X or spot scale X */ 168 vec4 upvec_sizey; /* xyz: Normalized right vector, w: area size Y or spot scale Y */ 169 vec4 forwardvec_type; /* xyz: Normalized forward vector, w: Light Type */ 170 }; 171 172 /* convenience aliases */ 173 #define l_color color_spec.rgb 174 #define l_spec color_spec.a 175 #define l_position position_influence.xyz 176 #define l_influence position_influence.w 177 #define l_sizex rightvec_sizex.w 178 #define l_sizey upvec_sizey.w 179 #define l_right rightvec_sizex.xyz 180 #define l_up upvec_sizey.xyz 181 #define l_forward forwardvec_type.xyz 182 #define l_type forwardvec_type.w 183 #define l_spot_size spotdata_radius_shadow.x 184 #define l_spot_blend spotdata_radius_shadow.y 185 #define l_radius spotdata_radius_shadow.z 186 #define l_shadowid spotdata_radius_shadow.w 187 188 /* ------ Shadows ----- */ 189 #ifndef MAX_CASCADE_NUM 190 # define MAX_CASCADE_NUM 4 191 #endif 192 193 struct ShadowData { 194 vec4 near_far_bias_exp; 195 vec4 shadow_data_start_end; 196 vec4 contact_shadow_data; 197 }; 198 199 struct ShadowCubeData { 200 vec4 position; 201 }; 202 203 struct ShadowCascadeData { 204 mat4 shadowmat[MAX_CASCADE_NUM]; 205 vec4 split_start_distances; 206 vec4 split_end_distances; 207 }; 208 209 /* convenience aliases */ 210 #define sh_near near_far_bias_exp.x 211 #define sh_far near_far_bias_exp.y 212 #define sh_bias near_far_bias_exp.z 213 #define sh_exp near_far_bias_exp.w 214 #define sh_bleed near_far_bias_exp.w 215 #define sh_tex_start shadow_data_start_end.x 216 #define sh_data_start shadow_data_start_end.y 217 #define sh_multi_nbr shadow_data_start_end.z 218 #define sh_blur shadow_data_start_end.w 219 #define sh_contact_dist contact_shadow_data.x 220 #define sh_contact_offset contact_shadow_data.y 221 #define sh_contact_spread contact_shadow_data.z 222 #define sh_contact_thickness contact_shadow_data.w 223 224 /* ------- Convenience functions --------- */ 225 226 vec3 mul(mat3 m, vec3 v) 227 { 228 return m * v; 229 } 230 mat3 mul(mat3 m1, mat3 m2) 231 { 232 return m1 * m2; 233 } 234 vec3 transform_direction(mat4 m, vec3 v) 235 { 236 return mat3(m) * v; 237 } 238 vec3 transform_point(mat4 m, vec3 v) 239 { 240 return (m * vec4(v, 1.0)).xyz; 241 } 242 vec3 project_point(mat4 m, vec3 v) 243 { 244 vec4 tmp = m * vec4(v, 1.0); 245 return tmp.xyz / tmp.w; 246 } 247 248 #define min3(a, b, c) min(a, min(b, c)) 249 #define min4(a, b, c, d) min(a, min3(b, c, d)) 250 #define min5(a, b, c, d, e) min(a, min4(b, c, d, e)) 251 #define min6(a, b, c, d, e, f) min(a, min5(b, c, d, e, f)) 252 #define min7(a, b, c, d, e, f, g) min(a, min6(b, c, d, e, f, g)) 253 #define min8(a, b, c, d, e, f, g, h) min(a, min7(b, c, d, e, f, g, h)) 254 #define min9(a, b, c, d, e, f, g, h, i) min(a, min8(b, c, d, e, f, g, h, i)) 255 256 #define max3(a, b, c) max(a, max(b, c)) 257 #define max4(a, b, c, d) max(a, max3(b, c, d)) 258 #define max5(a, b, c, d, e) max(a, max4(b, c, d, e)) 259 #define max6(a, b, c, d, e, f) max(a, max5(b, c, d, e, f)) 260 #define max7(a, b, c, d, e, f, g) max(a, max6(b, c, d, e, f, g)) 261 #define max8(a, b, c, d, e, f, g, h) max(a, max7(b, c, d, e, f, g, h)) 262 #define max9(a, b, c, d, e, f, g, h, i) max(a, max8(b, c, d, e, f, g, h, i)) 263 264 #define avg3(a, b, c) (a + b + c) * (1.0 / 3.0) 265 #define avg4(a, b, c, d) (a + b + c + d) * (1.0 / 4.0) 266 #define avg5(a, b, c, d, e) (a + b + c + d + e) * (1.0 / 5.0) 267 #define avg6(a, b, c, d, e, f) (a + b + c + d + e + f) * (1.0 / 6.0) 268 #define avg7(a, b, c, d, e, f, g) (a + b + c + d + e + f + g) * (1.0 / 7.0) 269 #define avg8(a, b, c, d, e, f, g, h) (a + b + c + d + e + f + g + h) * (1.0 / 8.0) 270 #define avg9(a, b, c, d, e, f, g, h, i) (a + b + c + d + e + f + g + h + i) * (1.0 / 9.0) 271 272 float min_v2(vec2 v) 273 { 274 return min(v.x, v.y); 275 } 276 float min_v3(vec3 v) 277 { 278 return min(v.x, min(v.y, v.z)); 279 } 280 float max_v2(vec2 v) 281 { 282 return max(v.x, v.y); 283 } 284 float max_v3(vec3 v) 285 { 286 return max(v.x, max(v.y, v.z)); 287 } 288 289 float sum(vec2 v) 290 { 291 return dot(vec2(1.0), v); 292 } 293 float sum(vec3 v) 294 { 295 return dot(vec3(1.0), v); 296 } 297 float sum(vec4 v) 298 { 299 return dot(vec4(1.0), v); 300 } 301 302 float saturate(float a) 303 { 304 return clamp(a, 0.0, 1.0); 305 } 306 vec2 saturate(vec2 a) 307 { 308 return clamp(a, 0.0, 1.0); 309 } 310 vec3 saturate(vec3 a) 311 { 312 return clamp(a, 0.0, 1.0); 313 } 314 vec4 saturate(vec4 a) 315 { 316 return clamp(a, 0.0, 1.0); 317 } 318 319 float distance_squared(vec2 a, vec2 b) 320 { 321 a -= b; 322 return dot(a, a); 323 } 324 float distance_squared(vec3 a, vec3 b) 325 { 326 a -= b; 327 return dot(a, a); 328 } 329 float len_squared(vec3 a) 330 { 331 return dot(a, a); 332 } 333 334 float inverse_distance(vec3 V) 335 { 336 return max(1 / length(V), 1e-8); 337 } 338 339 vec2 mip_ratio_interp(float mip) 340 { 341 float low_mip = floor(mip); 342 return mix(mipRatio[int(low_mip)], mipRatio[int(low_mip + 1.0)], mip - low_mip); 343 } 344 345 /* ------- RNG ------- */ 346 347 float wang_hash_noise(uint s) 348 { 349 s = (s ^ 61u) ^ (s >> 16u); 350 s *= 9u; 351 s = s ^ (s >> 4u); 352 s *= 0x27d4eb2du; 353 s = s ^ (s >> 15u); 354 355 return fract(float(s) / 4294967296.0); 356 } 357 358 /* ------- Fast Math ------- */ 359 360 /* [Drobot2014a] Low Level Optimizations for GCN */ 361 float fast_sqrt(float v) 362 { 363 return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1)); 364 } 365 366 vec2 fast_sqrt(vec2 v) 367 { 368 return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1)); 369 } 370 371 /* [Eberly2014] GPGPU Programming for Games and Science */ 372 float fast_acos(float v) 373 { 374 float res = -0.156583 * abs(v) + M_PI_2; 375 res *= fast_sqrt(1.0 - abs(v)); 376 return (v >= 0) ? res : M_PI - res; 377 } 378 379 vec2 fast_acos(vec2 v) 380 { 381 vec2 res = -0.156583 * abs(v) + M_PI_2; 382 res *= fast_sqrt(1.0 - abs(v)); 383 v.x = (v.x >= 0) ? res.x : M_PI - res.x; 384 v.y = (v.y >= 0) ? res.y : M_PI - res.y; 385 return v; 386 } 387 388 float point_plane_projection_dist(vec3 lineorigin, vec3 planeorigin, vec3 planenormal) 389 { 390 return dot(planenormal, planeorigin - lineorigin); 391 } 392 393 float line_plane_intersect_dist(vec3 lineorigin, 394 vec3 linedirection, 395 vec3 planeorigin, 396 vec3 planenormal) 397 { 398 return dot(planenormal, planeorigin - lineorigin) / dot(planenormal, linedirection); 399 } 400 401 float line_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec4 plane) 402 { 403 vec3 plane_co = plane.xyz * (-plane.w / len_squared(plane.xyz)); 404 vec3 h = lineorigin - plane_co; 405 return -dot(plane.xyz, h) / dot(plane.xyz, linedirection); 406 } 407 408 vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin, vec3 planenormal) 409 { 410 float dist = line_plane_intersect_dist(lineorigin, linedirection, planeorigin, planenormal); 411 return lineorigin + linedirection * dist; 412 } 413 414 vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec4 plane) 415 { 416 float dist = line_plane_intersect_dist(lineorigin, linedirection, plane); 417 return lineorigin + linedirection * dist; 418 } 419 420 float line_aligned_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec3 planeorigin) 421 { 422 /* aligned plane normal */ 423 vec3 L = planeorigin - lineorigin; 424 float diskdist = length(L); 425 vec3 planenormal = -normalize(L); 426 return -diskdist / dot(planenormal, linedirection); 427 } 428 429 vec3 line_aligned_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin) 430 { 431 float dist = line_aligned_plane_intersect_dist(lineorigin, linedirection, planeorigin); 432 if (dist < 0) { 433 /* if intersection is behind we fake the intersection to be 434 * really far and (hopefully) not inside the radius of interest */ 435 dist = 1e16; 436 } 437 return lineorigin + linedirection * dist; 438 } 439 440 float line_unit_sphere_intersect_dist(vec3 lineorigin, vec3 linedirection) 441 { 442 float a = dot(linedirection, linedirection); 443 float b = dot(linedirection, lineorigin); 444 float c = dot(lineorigin, lineorigin) - 1; 445 446 float dist = 1e15; 447 float determinant = b * b - a * c; 448 if (determinant >= 0) { 449 dist = (sqrt(determinant) - b) / a; 450 } 451 452 return dist; 453 } 454 455 float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection) 456 { 457 /* https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ 458 */ 459 vec3 firstplane = (vec3(1.0) - lineorigin) / linedirection; 460 vec3 secondplane = (vec3(-1.0) - lineorigin) / linedirection; 461 vec3 furthestplane = max(firstplane, secondplane); 462 463 return min_v3(furthestplane); 464 } 465 466 /* Return texture coordinates to sample Surface LUT */ 467 vec2 lut_coords(float cosTheta, float roughness) 468 { 469 float theta = acos(cosTheta); 470 vec2 coords = vec2(roughness, theta / M_PI_2); 471 472 /* scale and bias coordinates, for correct filtered lookup */ 473 return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE; 474 } 475 476 vec2 lut_coords_ltc(float cosTheta, float roughness) 477 { 478 vec2 coords = vec2(roughness, sqrt(1.0 - cosTheta)); 479 480 /* scale and bias coordinates, for correct filtered lookup */ 481 return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE; 482 } 483 484 /* -- Tangent Space conversion -- */ 485 vec3 tangent_to_world(vec3 vector, vec3 N, vec3 T, vec3 B) 486 { 487 return T * vector.x + B * vector.y + N * vector.z; 488 } 489 490 vec3 world_to_tangent(vec3 vector, vec3 N, vec3 T, vec3 B) 491 { 492 return vec3(dot(T, vector), dot(B, vector), dot(N, vector)); 493 } 494 495 void make_orthonormal_basis(vec3 N, out vec3 T, out vec3 B) 496 { 497 vec3 UpVector = abs(N.z) < 0.99999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); 498 T = normalize(cross(UpVector, N)); 499 B = cross(N, T); 500 } 501 502 /* ---- Opengl Depth conversion ---- */ 503 504 float linear_depth(bool is_persp, float z, float zf, float zn) 505 { 506 if (is_persp) { 507 return (zn * zf) / (z * (zn - zf) + zf); 508 } 509 else { 510 return (z * 2.0 - 1.0) * zf; 511 } 512 } 513 514 float buffer_depth(bool is_persp, float z, float zf, float zn) 515 { 516 if (is_persp) { 517 return (zf * (zn - z)) / (z * (zn - zf)); 518 } 519 else { 520 return (z / (zf * 2.0)) + 0.5; 521 } 522 } 523 524 float get_view_z_from_depth(float depth) 525 { 526 if (ProjectionMatrix[3][3] == 0.0) { 527 float d = 2.0 * depth - 1.0; 528 return -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]); 529 } 530 else { 531 return viewVecs[0].z + depth * viewVecs[1].z; 532 } 533 } 534 535 float get_depth_from_view_z(float z) 536 { 537 if (ProjectionMatrix[3][3] == 0.0) { 538 float d = (-ProjectionMatrix[3][2] / z) - ProjectionMatrix[2][2]; 539 return d * 0.5 + 0.5; 540 } 541 else { 542 return (z - viewVecs[0].z) / viewVecs[1].z; 543 } 544 } 545 546 vec2 get_uvs_from_view(vec3 view) 547 { 548 vec3 ndc = project_point(ProjectionMatrix, view); 549 return ndc.xy * 0.5 + 0.5; 550 } 551 552 vec3 get_view_space_from_depth(vec2 uvcoords, float depth) 553 { 554 if (ProjectionMatrix[3][3] == 0.0) { 555 return vec3(viewVecs[0].xy + uvcoords * viewVecs[1].xy, 1.0) * get_view_z_from_depth(depth); 556 } 557 else { 558 return viewVecs[0].xyz + vec3(uvcoords, depth) * viewVecs[1].xyz; 559 } 560 } 561 562 vec3 get_world_space_from_depth(vec2 uvcoords, float depth) 563 { 564 return (ViewMatrixInverse * vec4(get_view_space_from_depth(uvcoords, depth), 1.0)).xyz; 565 } 566 567 vec3 get_specular_reflection_dominant_dir(vec3 N, vec3 V, float roughness) 568 { 569 vec3 R = -reflect(V, N); 570 float smoothness = 1.0 - roughness; 571 float fac = smoothness * (sqrt(smoothness) + roughness); 572 return normalize(mix(N, R, fac)); 573 } 574 575 float specular_occlusion(float NV, float AO, float roughness) 576 { 577 return saturate(pow(NV + AO, roughness) - 1.0 + AO); 578 } 579 580 /* --- Refraction utils --- */ 581 582 float ior_from_f0(float f0) 583 { 584 float f = sqrt(f0); 585 return (-f - 1.0) / (f - 1.0); 586 } 587 588 float f0_from_ior(float eta) 589 { 590 float A = (eta - 1.0) / (eta + 1.0); 591 return A * A; 592 } 593 594 vec3 get_specular_refraction_dominant_dir(vec3 N, vec3 V, float roughness, float ior) 595 { 596 /* TODO: This a bad approximation. Better approximation should fit 597 * the refracted vector and roughness into the best prefiltered reflection 598 * lobe. */ 599 /* Correct the IOR for ior < 1.0 to not see the abrupt delimitation or the TIR */ 600 ior = (ior < 1.0) ? mix(ior, 1.0, roughness) : ior; 601 float eta = 1.0 / ior; 602 603 float NV = dot(N, -V); 604 605 /* Custom Refraction. */ 606 float k = 1.0 - eta * eta * (1.0 - NV * NV); 607 k = max(0.0, k); /* Only this changes. */ 608 vec3 R = eta * -V - (eta * NV + sqrt(k)) * N; 609 610 return R; 611 } 612 613 float get_btdf_lut(sampler2DArray btdf_lut_tex, float NV, float roughness, float ior) 614 { 615 const vec3 lut_scale_bias_texel_size = vec3((LUT_SIZE - 1.0), 0.5, 1.5) / LUT_SIZE; 616 617 vec3 coords; 618 /* Try to compensate for the low resolution and interpolation error. */ 619 coords.x = (ior > 1.0) ? (0.9 + lut_scale_bias_texel_size.z) + 620 (0.1 - lut_scale_bias_texel_size.z) * f0_from_ior(ior) : 621 (0.9 + lut_scale_bias_texel_size.z) * ior * ior; 622 coords.y = 1.0 - saturate(NV); 623 coords.xy *= lut_scale_bias_texel_size.x; 624 coords.xy += lut_scale_bias_texel_size.y; 625 626 const float lut_lvl_ofs = 4.0; /* First texture lvl of roughness. */ 627 const float lut_lvl_scale = 16.0; /* How many lvl of roughness in the lut. */ 628 629 float mip = roughness * lut_lvl_scale; 630 float mip_floor = floor(mip); 631 632 coords.z = lut_lvl_ofs + mip_floor + 1.0; 633 float btdf_high = textureLod(btdf_lut_tex, coords, 0.0).r; 634 635 coords.z -= 1.0; 636 float btdf_low = textureLod(btdf_lut_tex, coords, 0.0).r; 637 638 float btdf = (ior == 1.0) ? 1.0 : mix(btdf_low, btdf_high, mip - coords.z); 639 640 return btdf; 641 } 642 643 /* ---- Encode / Decode Normal buffer data ---- */ 644 /* From http://aras-p.info/texts/CompactNormalStorage.html 645 * Using Method #4: Spheremap Transform */ 646 vec2 normal_encode(vec3 n, vec3 view) 647 { 648 float p = sqrt(n.z * 8.0 + 8.0); 649 return n.xy / p + 0.5; 650 } 651 652 vec3 normal_decode(vec2 enc, vec3 view) 653 { 654 vec2 fenc = enc * 4.0 - 2.0; 655 float f = dot(fenc, fenc); 656 float g = sqrt(1.0 - f / 4.0); 657 vec3 n; 658 n.xy = fenc * g; 659 n.z = 1 - f / 2; 660 return n; 661 } 662 663 /* ---- RGBM (shared multiplier) encoding ---- */ 664 /* From http://iwasbeingirony.blogspot.fr/2010/06/difference-between-rgbm-and-rgbd.html */ 665 666 /* Higher RGBM_MAX_RANGE gives imprecision issues in low intensity. */ 667 #define RGBM_MAX_RANGE 512.0 668 669 vec4 rgbm_encode(vec3 rgb) 670 { 671 float maxRGB = max_v3(rgb); 672 float M = maxRGB / RGBM_MAX_RANGE; 673 M = ceil(M * 255.0) / 255.0; 674 return vec4(rgb / (M * RGBM_MAX_RANGE), M); 675 } 676 677 vec3 rgbm_decode(vec4 data) 678 { 679 return data.rgb * (data.a * RGBM_MAX_RANGE); 680 } 681 682 /* ---- RGBE (shared exponent) encoding ---- */ 683 vec4 rgbe_encode(vec3 rgb) 684 { 685 float maxRGB = max_v3(rgb); 686 float fexp = ceil(log2(maxRGB)); 687 return vec4(rgb / exp2(fexp), (fexp + 128.0) / 255.0); 688 } 689 690 vec3 rgbe_decode(vec4 data) 691 { 692 float fexp = data.a * 255.0 - 128.0; 693 return data.rgb * exp2(fexp); 694 } 695 696 #if 1 697 # define irradiance_encode rgbe_encode 698 # define irradiance_decode rgbe_decode 699 #else /* No ecoding (when using floating point format) */ 700 # define irradiance_encode(X) (X).rgbb 701 # define irradiance_decode(X) (X).rgb 702 #endif 703 704 /* Irradiance Visibility Encoding */ 705 #if 1 706 vec4 visibility_encode(vec2 accum, float range) 707 { 708 accum /= range; 709 710 vec4 data; 711 data.x = fract(accum.x); 712 data.y = floor(accum.x) / 255.0; 713 data.z = fract(accum.y); 714 data.w = floor(accum.y) / 255.0; 715 716 return data; 717 } 718 719 vec2 visibility_decode(vec4 data, float range) 720 { 721 return (data.xz + data.yw * 255.0) * range; 722 } 723 #else /* No ecoding (when using floating point format) */ 724 vec4 visibility_encode(vec2 accum, float range) 725 { 726 return accum.xyxy; 727 } 728 729 vec2 visibility_decode(vec4 data, float range) 730 { 731 return data.xy; 732 } 733 #endif 734 735 /* Fresnel monochromatic, perfect mirror */ 736 float F_eta(float eta, float cos_theta) 737 { 738 /* compute fresnel reflectance without explicitly computing 739 * the refracted direction */ 740 float c = abs(cos_theta); 741 float g = eta * eta - 1.0 + c * c; 742 float result; 743 744 if (g > 0.0) { 745 g = sqrt(g); 746 vec2 g_c = vec2(g) + vec2(c, -c); 747 float A = g_c.y / g_c.x; 748 A *= A; 749 g_c *= c; 750 float B = (g_c.y - 1.0) / (g_c.x + 1.0); 751 B *= B; 752 result = 0.5 * A * (1.0 + B); 753 } 754 else { 755 result = 1.0; /* TIR (no refracted component) */ 756 } 757 758 return result; 759 } 760 761 /* Fresnel color blend base on fresnel factor */ 762 vec3 F_color_blend(float eta, float fresnel, vec3 f0_color) 763 { 764 float f0 = F_eta(eta, 1.0); 765 float fac = saturate((fresnel - f0) / max(1e-8, 1.0 - f0)); 766 return mix(f0_color, vec3(1.0), fac); 767 } 768 769 /* Fresnel */ 770 vec3 F_schlick(vec3 f0, float cos_theta) 771 { 772 float fac = 1.0 - cos_theta; 773 float fac2 = fac * fac; 774 fac = fac2 * fac2 * fac; 775 776 /* Unreal specular matching : if specular color is below 2% intensity, 777 * (using green channel for intensity) treat as shadowning */ 778 return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * fac + (1.0 - fac) * f0; 779 } 780 781 /* Fresnel approximation for LTC area lights (not MRP) */ 782 vec3 F_area(vec3 f0, vec3 f90, vec2 lut) 783 { 784 /* Unreal specular matching : if specular color is below 2% intensity, 785 * treat as shadowning */ 786 return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * lut.y * f90 + lut.x * f0; 787 } 788 789 /* Fresnel approximation for IBL */ 790 vec3 F_ibl(vec3 f0, vec3 f90, vec2 lut) 791 { 792 /* Unreal specular matching : if specular color is below 2% intensity, 793 * treat as shadowning */ 794 return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * lut.y * f90 + lut.x * f0; 795 } 796 797 /* GGX */ 798 float D_ggx_opti(float NH, float a2) 799 { 800 float tmp = (NH * a2 - NH) * NH + 1.0; 801 return M_PI * tmp * tmp; /* Doing RCP and mul a2 at the end */ 802 } 803 804 float G1_Smith_GGX(float NX, float a2) 805 { 806 /* Using Brian Karis approach and refactoring by NX/NX 807 * this way the (2*NL)*(2*NV) in G = G1(V) * G1(L) gets canceled by the brdf denominator 4*NL*NV 808 * Rcp is done on the whole G later 809 * Note that this is not convenient for the transmission formula */ 810 return NX + sqrt(NX * (NX - NX * a2) + a2); 811 /* return 2 / (1 + sqrt(1 + a2 * (1 - NX*NX) / (NX*NX) ) ); /* Reference function */ 812 } 813 814 float bsdf_ggx(vec3 N, vec3 L, vec3 V, float roughness) 815 { 816 float a = roughness; 817 float a2 = a * a; 818 819 vec3 H = normalize(L + V); 820 float NH = max(dot(N, H), 1e-8); 821 float NL = max(dot(N, L), 1e-8); 822 float NV = max(dot(N, V), 1e-8); 823 824 float G = G1_Smith_GGX(NV, a2) * G1_Smith_GGX(NL, a2); /* Doing RCP at the end */ 825 float D = D_ggx_opti(NH, a2); 826 827 /* Denominator is canceled by G1_Smith */ 828 /* bsdf = D * G / (4.0 * NL * NV); /* Reference function */ 829 return NL * a2 / (D * G); /* NL to Fit cycles Equation : line. 345 in bsdf_microfacet.h */ 830 } 831 832 void accumulate_light(vec3 light, float fac, inout vec4 accum) 833 { 834 accum += vec4(light, 1.0) * min(fac, (1.0 - accum.a)); 835 } 836 837 /* ----------- Cone Aperture Approximation --------- */ 838 839 /* Return a fitted cone angle given the input roughness */ 840 float cone_cosine(float r) 841 { 842 /* Using phong gloss 843 * roughness = sqrt(2/(gloss+2)) */ 844 float gloss = -2 + 2 / (r * r); 845 /* Drobot 2014 in GPUPro5 */ 846 // return cos(2.0 * sqrt(2.0 / (gloss + 2))); 847 /* Uludag 2014 in GPUPro5 */ 848 // return pow(0.244, 1 / (gloss + 1)); 849 /* Jimenez 2016 in Practical Realtime Strategies for Accurate Indirect Occlusion*/ 850 return exp2(-3.32193 * r * r); 851 } 852 853 /* --------- Closure ---------- */ 854 #ifdef VOLUMETRICS 855 856 struct Closure { 857 vec3 absorption; 858 vec3 scatter; 859 vec3 emission; 860 float anisotropy; 861 }; 862 863 # define CLOSURE_DEFAULT Closure(vec3(0.0), vec3(0.0), vec3(0.0), 0.0) 864 865 Closure closure_mix(Closure cl1, Closure cl2, float fac) 866 { 867 Closure cl; 868 cl.absorption = mix(cl1.absorption, cl2.absorption, fac); 869 cl.scatter = mix(cl1.scatter, cl2.scatter, fac); 870 cl.emission = mix(cl1.emission, cl2.emission, fac); 871 cl.anisotropy = mix(cl1.anisotropy, cl2.anisotropy, fac); 872 return cl; 873 } 874 875 Closure closure_add(Closure cl1, Closure cl2) 876 { 877 Closure cl; 878 cl.absorption = cl1.absorption + cl2.absorption; 879 cl.scatter = cl1.scatter + cl2.scatter; 880 cl.emission = cl1.emission + cl2.emission; 881 cl.anisotropy = (cl1.anisotropy + cl2.anisotropy) / 2.0; /* Average phase (no multi lobe) */ 882 return cl; 883 } 884 885 Closure closure_emission(vec3 rgb) 886 { 887 Closure cl = CLOSURE_DEFAULT; 888 cl.emission = rgb; 889 return cl; 890 } 891 892 #else /* VOLUMETRICS */ 893 894 struct Closure { 895 vec3 radiance; 896 float opacity; 897 # ifdef USE_SSS 898 vec4 sss_data; 899 # ifdef USE_SSS_ALBEDO 900 vec3 sss_albedo; 901 # endif 902 # endif 903 vec4 ssr_data; 904 vec2 ssr_normal; 905 int ssr_id; 906 }; 907 908 /* This is hacking ssr_id to tag transparent bsdf */ 909 # define TRANSPARENT_CLOSURE_FLAG -2 910 # define REFRACT_CLOSURE_FLAG -3 911 # define NO_SSR -999 912 913 # ifdef USE_SSS 914 # ifdef USE_SSS_ALBEDO 915 # define CLOSURE_DEFAULT \ 916 Closure(vec3(0.0), 1.0, vec4(0.0), vec3(0.0), vec4(0.0), vec2(0.0), -1) 917 # else 918 # define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec4(0.0), vec2(0.0), -1) 919 # endif 920 # else 921 # define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec2(0.0), -1) 922 # endif 923 924 uniform int outputSsrId; 925 926 Closure closure_mix(Closure cl1, Closure cl2, float fac) 927 { 928 Closure cl; 929 930 if (cl1.ssr_id == TRANSPARENT_CLOSURE_FLAG) { 931 cl.ssr_normal = cl2.ssr_normal; 932 cl.ssr_data = cl2.ssr_data; 933 cl.ssr_id = cl2.ssr_id; 934 # ifdef USE_SSS 935 cl1.sss_data = cl2.sss_data; 936 # ifdef USE_SSS_ALBEDO 937 cl1.sss_albedo = cl2.sss_albedo; 938 # endif 939 # endif 940 } 941 else if (cl2.ssr_id == TRANSPARENT_CLOSURE_FLAG) { 942 cl.ssr_normal = cl1.ssr_normal; 943 cl.ssr_data = cl1.ssr_data; 944 cl.ssr_id = cl1.ssr_id; 945 # ifdef USE_SSS 946 cl2.sss_data = cl1.sss_data; 947 # ifdef USE_SSS_ALBEDO 948 cl2.sss_albedo = cl1.sss_albedo; 949 # endif 950 # endif 951 } 952 else if (cl1.ssr_id == outputSsrId) { 953 /* When mixing SSR don't blend roughness. 954 * 955 * It makes no sense to mix them really, so we take either one of them and 956 * tone down its specularity (ssr_data.xyz) while keeping its roughness (ssr_data.w). 957 */ 958 cl.ssr_data = mix(cl1.ssr_data.xyzw, vec4(vec3(0.0), cl1.ssr_data.w), fac); 959 cl.ssr_normal = cl1.ssr_normal; 960 cl.ssr_id = cl1.ssr_id; 961 } 962 else { 963 cl.ssr_data = mix(vec4(vec3(0.0), cl2.ssr_data.w), cl2.ssr_data.xyzw, fac); 964 cl.ssr_normal = cl2.ssr_normal; 965 cl.ssr_id = cl2.ssr_id; 966 } 967 968 cl.opacity = mix(cl1.opacity, cl2.opacity, fac); 969 cl.radiance = mix(cl1.radiance * cl1.opacity, cl2.radiance * cl2.opacity, fac); 970 cl.radiance /= max(1e-8, cl.opacity); 971 972 # ifdef USE_SSS 973 /* Apply Mix on input */ 974 cl1.sss_data.rgb *= 1.0 - fac; 975 cl2.sss_data.rgb *= fac; 976 977 /* Select biggest radius. */ 978 bool use_cl1 = (cl1.sss_data.a > cl2.sss_data.a); 979 cl.sss_data = (use_cl1) ? cl1.sss_data : cl2.sss_data; 980 981 # ifdef USE_SSS_ALBEDO 982 /* TODO Find a solution to this. Dither? */ 983 cl.sss_albedo = (use_cl1) ? cl1.sss_albedo : cl2.sss_albedo; 984 /* Add radiance that was supposed to be filtered but was rejected. */ 985 cl.radiance += (use_cl1) ? cl2.sss_data.rgb * cl2.sss_albedo : cl1.sss_data.rgb * cl1.sss_albedo; 986 # else 987 /* Add radiance that was supposed to be filtered but was rejected. */ 988 cl.radiance += (use_cl1) ? cl2.sss_data.rgb : cl1.sss_data.rgb; 989 # endif 990 # endif 991 992 return cl; 993 } 994 995 Closure closure_add(Closure cl1, Closure cl2) 996 { 997 Closure cl = (cl1.ssr_id == outputSsrId) ? cl1 : cl2; 998 cl.radiance = cl1.radiance + cl2.radiance; 999 # ifdef USE_SSS 1000 cl.sss_data = (cl1.sss_data.a > 0.0) ? cl1.sss_data : cl2.sss_data; 1001 /* Add radiance that was supposed to be filtered but was rejected. */ 1002 cl.radiance += (cl1.sss_data.a > 0.0) ? cl2.sss_data.rgb : cl1.sss_data.rgb; 1003 # ifdef USE_SSS_ALBEDO 1004 /* TODO Find a solution to this. Dither? */ 1005 cl.sss_albedo = (cl1.sss_data.a > 0.0) ? cl1.sss_albedo : cl2.sss_albedo; 1006 # endif 1007 # endif 1008 cl.opacity = saturate(cl1.opacity + cl2.opacity); 1009 return cl; 1010 } 1011 1012 Closure closure_emission(vec3 rgb) 1013 { 1014 Closure cl = CLOSURE_DEFAULT; 1015 cl.radiance = rgb; 1016 return cl; 1017 } 1018 1019 /* Breaking this across multiple lines causes issues for some older GLSL compilers. */ 1020 /* clang-format off */ 1021 # if defined(MESH_SHADER) && !defined(USE_ALPHA_HASH) && !defined(USE_ALPHA_CLIP) && !defined(SHADOW_SHADER) && !defined(USE_MULTIPLY ) 1022 /* clang-format on */ 1023 layout(location = 0) out vec4 fragColor; 1024 layout(location = 1) out vec4 ssrNormals; 1025 layout(location = 2) out vec4 ssrData; 1026 # ifdef USE_SSS 1027 layout(location = 3) out vec4 sssData; 1028 # ifdef USE_SSS_ALBEDO 1029 layout(location = 4) out vec4 sssAlbedo; 1030 # endif /* USE_SSS_ALBEDO */ 1031 # endif /* USE_SSS */ 1032 1033 Closure nodetree_exec(void); /* Prototype */ 1034 1035 # if defined(USE_ALPHA_BLEND) 1036 /* Prototype because this file is included before volumetric_lib.glsl */ 1037 void volumetric_resolve(vec2 frag_uvs, 1038 float frag_depth, 1039 out vec3 transmittance, 1040 out vec3 scattering); 1041 # endif 1042 1043 # define NODETREE_EXEC 1044 void main() 1045 { 1046 Closure cl = nodetree_exec(); 1047 # ifndef USE_ALPHA_BLEND 1048 /* Prevent alpha hash material writing into alpha channel. */ 1049 cl.opacity = 1.0; 1050 # endif 1051 1052 # if defined(USE_ALPHA_BLEND) 1053 vec2 uvs = gl_FragCoord.xy * volCoordScale.zw; 1054 vec3 transmittance, scattering; 1055 volumetric_resolve(uvs, gl_FragCoord.z, transmittance, scattering); 1056 fragColor.rgb = cl.radiance * transmittance + scattering; 1057 fragColor.a = cl.opacity; 1058 # else 1059 fragColor = vec4(cl.radiance, cl.opacity); 1060 # endif 1061 1062 ssrNormals = cl.ssr_normal.xyyy; 1063 ssrData = cl.ssr_data; 1064 # ifdef USE_SSS 1065 sssData = cl.sss_data; 1066 # ifdef USE_SSS_ALBEDO 1067 sssAlbedo = cl.sss_albedo.rgbb; 1068 # endif 1069 # endif 1070 1071 /* For Probe capture */ 1072 # ifdef USE_SSS 1073 float fac = float(!sssToggle); 1074 1075 # ifdef USE_REFRACTION 1076 /* SSRefraction pass is done after the SSS pass. 1077 * In order to not loose the diffuse light totally we 1078 * need to merge the SSS radiance to the main radiance. */ 1079 fac = 1.0; 1080 # endif 1081 1082 # ifdef USE_SSS_ALBEDO 1083 fragColor.rgb += cl.sss_data.rgb * cl.sss_albedo.rgb * fac; 1084 # else 1085 fragColor.rgb += cl.sss_data.rgb * fac; 1086 # endif 1087 # endif 1088 } 1089 1090 # endif /* MESH_SHADER && !SHADOW_SHADER */ 1091 1092 #endif /* VOLUMETRICS */ 1093 1094 Closure nodetree_exec(void); /* Prototype */ 1095 1096 /* TODO find a better place */ 1097 #ifdef USE_MULTIPLY 1098 1099 out vec4 fragColor; 1100 1101 # define NODETREE_EXEC 1102 void main() 1103 { 1104 Closure cl = nodetree_exec(); 1105 fragColor = vec4(mix(vec3(1.0), cl.radiance, cl.opacity), 1.0); 1106 } 1107 #endif 1108 1109 vec2 mapping_octahedron(vec3 cubevec, vec2 texel_size) 1110 { 1111 /* projection onto octahedron */ 1112 cubevec /= dot(vec3(1.0), abs(cubevec)); 1113 1114 /* out-folding of the downward faces */ 1115 if (cubevec.z < 0.0) { 1116 vec2 cubevec_sign = step(0.0, cubevec.xy) * 2.0 - 1.0; 1117 cubevec.xy = (1.0 - abs(cubevec.yx)) * cubevec_sign; 1118 } 1119 1120 /* mapping to [0;1]ˆ2 texture space */ 1121 vec2 uvs = cubevec.xy * (0.5) + 0.5; 1122 1123 /* edge filtering fix */ 1124 uvs = (1.0 - 2.0 * texel_size) * uvs + texel_size; 1125 1126 return uvs; 1127 } 1128 1129 vec4 textureLod_octahedron(sampler2DArray tex, vec4 cubevec, float lod, float lod_max) 1130 { 1131 vec2 texelSize = 1.0 / vec2(textureSize(tex, int(lod_max))); 1132 1133 vec2 uvs = mapping_octahedron(cubevec.xyz, texelSize); 1134 1135 return textureLod(tex, vec3(uvs, cubevec.w), lod); 1136 } 1137 1138 vec4 texture_octahedron(sampler2DArray tex, vec4 cubevec) 1139 { 1140 vec2 texelSize = 1.0 / vec2(textureSize(tex, 0)); 1141 1142 vec2 uvs = mapping_octahedron(cubevec.xyz, texelSize); 1143 1144 return texture(tex, vec3(uvs, cubevec.w)); 1145 } 1146 1147 uniform sampler2DArray irradianceGrid; 1148 1149 #define IRRADIANCE_LIB 1150 1151 #ifdef IRRADIANCE_CUBEMAP 1152 struct IrradianceData { 1153 vec3 color; 1154 }; 1155 #elif defined(IRRADIANCE_SH_L2) 1156 struct IrradianceData { 1157 vec3 shcoefs[9]; 1158 }; 1159 #else /* defined(IRRADIANCE_HL2) */ 1160 struct IrradianceData { 1161 vec3 cubesides[3]; 1162 }; 1163 #endif 1164 1165 IrradianceData load_irradiance_cell(int cell, vec3 N) 1166 { 1167 /* Keep in sync with diffuse_filter_probe() */ 1168 1169 #if defined(IRRADIANCE_CUBEMAP) 1170 1171 # define AMBIANT_CUBESIZE 8 1172 ivec2 cell_co = ivec2(AMBIANT_CUBESIZE); 1173 int cell_per_row = textureSize(irradianceGrid, 0).x / cell_co.x; 1174 cell_co.x *= cell % cell_per_row; 1175 cell_co.y *= cell / cell_per_row; 1176 1177 vec2 texelSize = 1.0 / vec2(AMBIANT_CUBESIZE); 1178 1179 vec2 uvs = mapping_octahedron(N, texelSize); 1180 uvs *= vec2(AMBIANT_CUBESIZE) / vec2(textureSize(irradianceGrid, 0)); 1181 uvs += vec2(cell_co) / vec2(textureSize(irradianceGrid, 0)); 1182 1183 IrradianceData ir; 1184 ir.color = texture(irradianceGrid, vec3(uvs, 0.0)).rgb; 1185 1186 #elif defined(IRRADIANCE_SH_L2) 1187 1188 ivec2 cell_co = ivec2(3, 3); 1189 int cell_per_row = textureSize(irradianceGrid, 0).x / cell_co.x; 1190 cell_co.x *= cell % cell_per_row; 1191 cell_co.y *= cell / cell_per_row; 1192 1193 ivec3 ofs = ivec3(0, 1, 2); 1194 1195 IrradianceData ir; 1196 ir.shcoefs[0] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.xx, 0), 0).rgb; 1197 ir.shcoefs[1] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.yx, 0), 0).rgb; 1198 ir.shcoefs[2] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.zx, 0), 0).rgb; 1199 ir.shcoefs[3] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.xy, 0), 0).rgb; 1200 ir.shcoefs[4] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.yy, 0), 0).rgb; 1201 ir.shcoefs[5] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.zy, 0), 0).rgb; 1202 ir.shcoefs[6] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.xz, 0), 0).rgb; 1203 ir.shcoefs[7] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.yz, 0), 0).rgb; 1204 ir.shcoefs[8] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.zz, 0), 0).rgb; 1205 1206 #else /* defined(IRRADIANCE_HL2) */ 1207 1208 ivec2 cell_co = ivec2(3, 2); 1209 int cell_per_row = textureSize(irradianceGrid, 0).x / cell_co.x; 1210 cell_co.x *= cell % cell_per_row; 1211 cell_co.y *= cell / cell_per_row; 1212 1213 ivec3 is_negative = ivec3(step(0.0, -N)); 1214 1215 IrradianceData ir; 1216 ir.cubesides[0] = irradiance_decode( 1217 texelFetch(irradianceGrid, ivec3(cell_co + ivec2(0, is_negative.x), 0), 0)); 1218 ir.cubesides[1] = irradiance_decode( 1219 texelFetch(irradianceGrid, ivec3(cell_co + ivec2(1, is_negative.y), 0), 0)); 1220 ir.cubesides[2] = irradiance_decode( 1221 texelFetch(irradianceGrid, ivec3(cell_co + ivec2(2, is_negative.z), 0), 0)); 1222 1223 #endif 1224 1225 return ir; 1226 } 1227 1228 float load_visibility_cell(int cell, vec3 L, float dist, float bias, float bleed_bias, float range) 1229 { 1230 /* Keep in sync with diffuse_filter_probe() */ 1231 ivec2 cell_co = ivec2(prbIrradianceVisSize); 1232 ivec2 cell_per_row_col = textureSize(irradianceGrid, 0).xy / prbIrradianceVisSize; 1233 cell_co.x *= (cell % cell_per_row_col.x); 1234 cell_co.y *= (cell / cell_per_row_col.x) % cell_per_row_col.y; 1235 float layer = 1.0 + float((cell / cell_per_row_col.x) / cell_per_row_col.y); 1236 1237 vec2 texel_size = 1.0 / vec2(textureSize(irradianceGrid, 0).xy); 1238 vec2 co = vec2(cell_co) * texel_size; 1239 1240 vec2 uv = mapping_octahedron(-L, vec2(1.0 / float(prbIrradianceVisSize))); 1241 uv *= vec2(prbIrradianceVisSize) * texel_size; 1242 1243 vec4 data = texture(irradianceGrid, vec3(co + uv, layer)); 1244 1245 /* Decoding compressed data */ 1246 vec2 moments = visibility_decode(data, range); 1247 1248 /* Doing chebishev test */ 1249 float variance = abs(moments.x * moments.x - moments.y); 1250 variance = max(variance, bias / 10.0); 1251 1252 float d = dist - moments.x; 1253 float p_max = variance / (variance + d * d); 1254 1255 /* Increase contrast in the weight by squaring it */ 1256 p_max *= p_max; 1257 1258 /* Now reduce light-bleeding by removing the [0, x] tail and linearly rescaling (x, 1] */ 1259 p_max = clamp((p_max - bleed_bias) / (1.0 - bleed_bias), 0.0, 1.0); 1260 1261 return (dist <= moments.x) ? 1.0 : p_max; 1262 } 1263 1264 /* http://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/ */ 1265 vec3 spherical_harmonics_L1(vec3 N, vec3 shcoefs[4]) 1266 { 1267 vec3 sh = vec3(0.0); 1268 1269 sh += 0.282095 * shcoefs[0]; 1270 1271 sh += -0.488603 * N.z * shcoefs[1]; 1272 sh += 0.488603 * N.y * shcoefs[2]; 1273 sh += -0.488603 * N.x * shcoefs[3]; 1274 1275 return sh; 1276 } 1277 1278 vec3 spherical_harmonics_L2(vec3 N, vec3 shcoefs[9]) 1279 { 1280 vec3 sh = vec3(0.0); 1281 1282 sh += 0.282095 * shcoefs[0]; 1283 1284 sh += -0.488603 * N.z * shcoefs[1]; 1285 sh += 0.488603 * N.y * shcoefs[2]; 1286 sh += -0.488603 * N.x * shcoefs[3]; 1287 1288 sh += 1.092548 * N.x * N.z * shcoefs[4]; 1289 sh += -1.092548 * N.z * N.y * shcoefs[5]; 1290 sh += 0.315392 * (3.0 * N.y * N.y - 1.0) * shcoefs[6]; 1291 sh += -1.092548 * N.x * N.y * shcoefs[7]; 1292 sh += 0.546274 * (N.x * N.x - N.z * N.z) * shcoefs[8]; 1293 1294 return sh; 1295 } 1296 1297 vec3 hl2_basis(vec3 N, vec3 cubesides[3]) 1298 { 1299 vec3 irradiance = vec3(0.0); 1300 1301 vec3 n_squared = N * N; 1302 1303 irradiance += n_squared.x * cubesides[0]; 1304 irradiance += n_squared.y * cubesides[1]; 1305 irradiance += n_squared.z * cubesides[2]; 1306 1307 return irradiance; 1308 } 1309 1310 vec3 compute_irradiance(vec3 N, IrradianceData ird) 1311 { 1312 #if defined(IRRADIANCE_CUBEMAP) 1313 return ird.color; 1314 #elif defined(IRRADIANCE_SH_L2) 1315 return spherical_harmonics_L2(N, ird.shcoefs); 1316 #else /* defined(IRRADIANCE_HL2) */ 1317 return hl2_basis(N, ird.cubesides); 1318 #endif 1319 } 1320 1321 vec3 irradiance_from_cell_get(int cell, vec3 ir_dir) 1322 { 1323 IrradianceData ir_data = load_irradiance_cell(cell, ir_dir); 1324 return compute_irradiance(ir_dir, ir_data); 1325 } 1326 1327 uniform sampler2DArray shadowCubeTexture; 1328 uniform sampler2DArray shadowCascadeTexture; 1329 1330 #define LAMPS_LIB 1331 1332 layout(std140) uniform shadow_block 1333 { 1334 ShadowData shadows_data[MAX_SHADOW]; 1335 ShadowCubeData shadows_cube_data[MAX_SHADOW_CUBE]; 1336 ShadowCascadeData shadows_cascade_data[MAX_SHADOW_CASCADE]; 1337 }; 1338 1339 layout(std140) uniform light_block 1340 { 1341 LightData lights_data[MAX_LIGHT]; 1342 }; 1343 1344 /* type */ 1345 #define POINT 0.0 1346 #define SUN 1.0 1347 #define SPOT 2.0 1348 #define AREA_RECT 4.0 1349 /* Used to define the area light shape, doesn't directly correspond to a Blender light type. */ 1350 #define AREA_ELLIPSE 100.0 1351 1352 #if defined(SHADOW_VSM) 1353 # define ShadowSample vec2 1354 # define sample_cube(vec, id) texture_octahedron(shadowCubeTexture, vec4(vec, id)).rg 1355 # define sample_cascade(vec, id) texture(shadowCascadeTexture, vec3(vec, id)).rg 1356 #elif defined(SHADOW_ESM) 1357 # define ShadowSample float 1358 # define sample_cube(vec, id) texture_octahedron(shadowCubeTexture, vec4(vec, id)).r 1359 # define sample_cascade(vec, id) texture(shadowCascadeTexture, vec3(vec, id)).r 1360 #else 1361 # define ShadowSample float 1362 # define sample_cube(vec, id) texture_octahedron(shadowCubeTexture, vec4(vec, id)).r 1363 # define sample_cascade(vec, id) texture(shadowCascadeTexture, vec3(vec, id)).r 1364 #endif 1365 1366 #if defined(SHADOW_VSM) 1367 # define get_depth_delta(dist, s) (dist - s.x) 1368 #else 1369 # define get_depth_delta(dist, s) (dist - s) 1370 #endif 1371 1372 /* ----------------------------------------------------------- */ 1373 /* ----------------------- Shadow tests ---------------------- */ 1374 /* ----------------------------------------------------------- */ 1375 1376 #if defined(SHADOW_VSM) 1377 1378 float shadow_test(ShadowSample moments, float dist, ShadowData sd) 1379 { 1380 float p = 0.0; 1381 1382 if (dist <= moments.x) { 1383 p = 1.0; 1384 } 1385 1386 float variance = moments.y - (moments.x * moments.x); 1387 variance = max(variance, sd.sh_bias / 10.0); 1388 1389 float d = moments.x - dist; 1390 float p_max = variance / (variance + d * d); 1391 1392 /* Now reduce light-bleeding by removing the [0, x] tail and linearly rescaling (x, 1] */ 1393 p_max = clamp((p_max - sd.sh_bleed) / (1.0 - sd.sh_bleed), 0.0, 1.0); 1394 1395 return max(p, p_max); 1396 } 1397 1398 #elif defined(SHADOW_ESM) 1399 1400 float shadow_test(ShadowSample z, float dist, ShadowData sd) 1401 { 1402 return saturate(exp(sd.sh_exp * (z - dist + sd.sh_bias))); 1403 } 1404 1405 #else 1406 1407 float shadow_test(ShadowSample z, float dist, ShadowData sd) 1408 { 1409 return step(0, z - dist + sd.sh_bias); 1410 } 1411 1412 #endif 1413 1414 /* ----------------------------------------------------------- */ 1415 /* ----------------------- Shadow types ---------------------- */ 1416 /* ----------------------------------------------------------- */ 1417 1418 float shadow_cubemap(ShadowData sd, ShadowCubeData scd, float texid, vec3 W) 1419 { 1420 vec3 cubevec = W - scd.position.xyz; 1421 float dist = length(cubevec); 1422 1423 cubevec /= dist; 1424 1425 ShadowSample s = sample_cube(cubevec, texid); 1426 return shadow_test(s, dist, sd); 1427 } 1428 1429 float evaluate_cascade(ShadowData sd, mat4 shadowmat, vec3 W, float range, float texid) 1430 { 1431 vec4 shpos = shadowmat * vec4(W, 1.0); 1432 float dist = shpos.z * range; 1433 1434 ShadowSample s = sample_cascade(shpos.xy, texid); 1435 float vis = shadow_test(s, dist, sd); 1436 1437 /* If fragment is out of shadowmap range, do not occlude */ 1438 if (shpos.z < 1.0 && shpos.z > 0.0) { 1439 return vis; 1440 } 1441 else { 1442 return 1.0; 1443 } 1444 } 1445 1446 float shadow_cascade(ShadowData sd, int scd_id, float texid, vec3 W) 1447 { 1448 vec4 view_z = vec4(dot(W - cameraPos, cameraForward)); 1449 vec4 weights = smoothstep(shadows_cascade_data[scd_id].split_end_distances, 1450 shadows_cascade_data[scd_id].split_start_distances.yzwx, 1451 view_z); 1452 1453 weights.yzw -= weights.xyz; 1454 1455 vec4 vis = vec4(1.0); 1456 float range = abs(sd.sh_far - sd.sh_near); /* Same factor as in get_cascade_world_distance(). */ 1457 1458 /* Branching using (weights > 0.0) is reaally slooow on intel so avoid it for now. */ 1459 /* TODO OPTI: Only do 2 samples and blend. */ 1460 vis.x = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[0], W, range, texid + 0); 1461 vis.y = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[1], W, range, texid + 1); 1462 vis.z = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[2], W, range, texid + 2); 1463 vis.w = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[3], W, range, texid + 3); 1464 1465 float weight_sum = dot(vec4(1.0), weights); 1466 if (weight_sum > 0.9999) { 1467 float vis_sum = dot(vec4(1.0), vis * weights); 1468 return vis_sum / weight_sum; 1469 } 1470 else { 1471 float vis_sum = dot(vec4(1.0), vis * step(0.001, weights)); 1472 return mix(1.0, vis_sum, weight_sum); 1473 } 1474 } 1475 1476 /* ----------------------------------------------------------- */ 1477 /* --------------------- Light Functions --------------------- */ 1478 /* ----------------------------------------------------------- */ 1479 1480 /* From Frostbite PBR Course 1481 * Distance based attenuation 1482 * http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf */ 1483 float distance_attenuation(float dist_sqr, float inv_sqr_influence) 1484 { 1485 float factor = dist_sqr * inv_sqr_influence; 1486 float fac = saturate(1.0 - factor * factor); 1487 return fac * fac; 1488 } 1489 1490 float spot_attenuation(LightData ld, vec3 l_vector) 1491 { 1492 float z = dot(ld.l_forward, l_vector.xyz); 1493 vec3 lL = l_vector.xyz / z; 1494 float x = dot(ld.l_right, lL) / ld.l_sizex; 1495 float y = dot(ld.l_up, lL) / ld.l_sizey; 1496 float ellipse = inversesqrt(1.0 + x * x + y * y); 1497 float spotmask = smoothstep(0.0, 1.0, (ellipse - ld.l_spot_size) / ld.l_spot_blend); 1498 return spotmask; 1499 } 1500 1501 float light_visibility(LightData ld, 1502 vec3 W, 1503 #ifndef VOLUMETRICS 1504 vec3 viewPosition, 1505 vec3 vN, 1506 #endif 1507 vec4 l_vector) 1508 { 1509 float vis = 1.0; 1510 1511 if (ld.l_type == SPOT) { 1512 vis *= spot_attenuation(ld, l_vector.xyz); 1513 } 1514 if (ld.l_type >= SPOT) { 1515 vis *= step(0.0, -dot(l_vector.xyz, ld.l_forward)); 1516 } 1517 if (ld.l_type != SUN) { 1518 vis *= distance_attenuation(l_vector.w * l_vector.w, ld.l_influence); 1519 } 1520 1521 #if !defined(VOLUMETRICS) || defined(VOLUME_SHADOW) 1522 /* shadowing */ 1523 if (ld.l_shadowid >= 0.0 && vis > 0.001) { 1524 ShadowData data = shadows_data[int(ld.l_shadowid)]; 1525 1526 if (ld.l_type == SUN) { 1527 vis *= shadow_cascade(data, int(data.sh_data_start), data.sh_tex_start, W); 1528 } 1529 else { 1530 vis *= shadow_cubemap( 1531 data, shadows_cube_data[int(data.sh_data_start)], data.sh_tex_start, W); 1532 } 1533 1534 # ifndef VOLUMETRICS 1535 /* Only compute if not already in shadow. */ 1536 if (data.sh_contact_dist > 0.0) { 1537 vec4 L = (ld.l_type != SUN) ? l_vector : vec4(-ld.l_forward, 1.0); 1538 float trace_distance = (ld.l_type != SUN) ? min(data.sh_contact_dist, l_vector.w) : 1539 data.sh_contact_dist; 1540 1541 vec3 T, B; 1542 make_orthonormal_basis(L.xyz / L.w, T, B); 1543 1544 vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy); 1545 rand.zw *= fast_sqrt(rand.y) * data.sh_contact_spread; 1546 1547 /* We use the full l_vector.xyz so that the spread is minimize 1548 * if the shading point is further away from the light source */ 1549 vec3 ray_dir = L.xyz + T * rand.z + B * rand.w; 1550 ray_dir = transform_direction(ViewMatrix, ray_dir); 1551 ray_dir = normalize(ray_dir); 1552 1553 vec3 ray_ori = viewPosition; 1554 1555 /* Fix translucency shadowed by contact shadows. */ 1556 vN = (gl_FrontFacing) ? vN : -vN; 1557 1558 if (dot(vN, ray_dir) <= 0.0) { 1559 return vis; 1560 } 1561 1562 float bias = 0.5; /* Constant Bias */ 1563 bias += 1.0 - abs(dot(vN, ray_dir)); /* Angle dependent bias */ 1564 bias *= gl_FrontFacing ? data.sh_contact_offset : -data.sh_contact_offset; 1565 1566 vec3 nor_bias = vN * bias; 1567 ray_ori += nor_bias; 1568 1569 ray_dir *= trace_distance; 1570 ray_dir -= nor_bias; 1571 1572 vec3 hit_pos = raycast( 1573 -1, ray_ori, ray_dir, data.sh_contact_thickness, rand.x, 0.1, 0.001, false); 1574 1575 if (hit_pos.z > 0.0) { 1576 hit_pos = get_view_space_from_depth(hit_pos.xy, hit_pos.z); 1577 float hit_dist = distance(viewPosition, hit_pos); 1578 float dist_ratio = hit_dist / trace_distance; 1579 return vis * saturate(dist_ratio * dist_ratio * dist_ratio); 1580 } 1581 } 1582 # endif 1583 } 1584 #endif 1585 1586 return vis; 1587 } 1588 1589 #ifdef USE_LTC 1590 float light_diffuse(LightData ld, vec3 N, vec3 V, vec4 l_vector) 1591 { 1592 if (ld.l_type == AREA_RECT) { 1593 vec3 corners[4]; 1594 corners[0] = normalize((l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * ld.l_sizey); 1595 corners[1] = normalize((l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * -ld.l_sizey); 1596 corners[2] = normalize((l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * -ld.l_sizey); 1597 corners[3] = normalize((l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * ld.l_sizey); 1598 1599 return ltc_evaluate_quad(corners, N); 1600 } 1601 else if (ld.l_type == AREA_ELLIPSE) { 1602 vec3 points[3]; 1603 points[0] = (l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * -ld.l_sizey; 1604 points[1] = (l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * -ld.l_sizey; 1605 points[2] = (l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * ld.l_sizey; 1606 1607 return ltc_evaluate_disk(N, V, mat3(1.0), points); 1608 } 1609 else { 1610 float radius = ld.l_radius; 1611 radius /= (ld.l_type == SUN) ? 1.0 : l_vector.w; 1612 vec3 L = (ld.l_type == SUN) ? -ld.l_forward : (l_vector.xyz / l_vector.w); 1613 1614 return ltc_evaluate_disk_simple(radius, dot(N, L)); 1615 } 1616 } 1617 1618 float light_specular(LightData ld, vec4 ltc_mat, vec3 N, vec3 V, vec4 l_vector) 1619 { 1620 if (ld.l_type == AREA_RECT) { 1621 vec3 corners[4]; 1622 corners[0] = (l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * ld.l_sizey; 1623 corners[1] = (l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * -ld.l_sizey; 1624 corners[2] = (l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * -ld.l_sizey; 1625 corners[3] = (l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * ld.l_sizey; 1626 1627 ltc_transform_quad(N, V, ltc_matrix(ltc_mat), corners); 1628 1629 return ltc_evaluate_quad(corners, vec3(0.0, 0.0, 1.0)); 1630 } 1631 else { 1632 bool is_ellipse = (ld.l_type == AREA_ELLIPSE); 1633 float radius_x = is_ellipse ? ld.l_sizex : ld.l_radius; 1634 float radius_y = is_ellipse ? ld.l_sizey : ld.l_radius; 1635 1636 vec3 L = (ld.l_type == SUN) ? -ld.l_forward : l_vector.xyz; 1637 vec3 Px = ld.l_right; 1638 vec3 Py = ld.l_up; 1639 1640 if (ld.l_type == SPOT || ld.l_type == POINT) { 1641 make_orthonormal_basis(l_vector.xyz / l_vector.w, Px, Py); 1642 } 1643 1644 vec3 points[3]; 1645 points[0] = (L + Px * -radius_x) + Py * -radius_y; 1646 points[1] = (L + Px * radius_x) + Py * -radius_y; 1647 points[2] = (L + Px * radius_x) + Py * radius_y; 1648 1649 return ltc_evaluate_disk(N, V, ltc_matrix(ltc_mat), points); 1650 } 1651 } 1652 #endif 1653 1654 #define MAX_SSS_SAMPLES 65 1655 #define SSS_LUT_SIZE 64.0 1656 #define SSS_LUT_SCALE ((SSS_LUT_SIZE - 1.0) / float(SSS_LUT_SIZE)) 1657 #define SSS_LUT_BIAS (0.5 / float(SSS_LUT_SIZE)) 1658 1659 #ifdef USE_TRANSLUCENCY 1660 layout(std140) uniform sssProfile 1661 { 1662 vec4 kernel[MAX_SSS_SAMPLES]; 1663 vec4 radii_max_radius; 1664 int sss_samples; 1665 }; 1666 1667 uniform sampler1D sssTexProfile; 1668 1669 vec3 sss_profile(float s) 1670 { 1671 s /= radii_max_radius.w; 1672 return texture(sssTexProfile, saturate(s) * SSS_LUT_SCALE + SSS_LUT_BIAS).rgb; 1673 } 1674 #endif 1675 1676 vec3 light_translucent(LightData ld, vec3 W, vec3 N, vec4 l_vector, float scale) 1677 { 1678 #if !defined(USE_TRANSLUCENCY) || defined(VOLUMETRICS) 1679 return vec3(0.0); 1680 #else 1681 vec3 vis = vec3(1.0); 1682 1683 if (ld.l_type == SPOT) { 1684 vis *= spot_attenuation(ld, l_vector.xyz); 1685 } 1686 if (ld.l_type >= SPOT) { 1687 vis *= step(0.0, -dot(l_vector.xyz, ld.l_forward)); 1688 } 1689 if (ld.l_type != SUN) { 1690 vis *= distance_attenuation(l_vector.w * l_vector.w, ld.l_influence); 1691 } 1692 1693 /* Only shadowed light can produce translucency */ 1694 if (ld.l_shadowid >= 0.0 && vis.x > 0.001) { 1695 ShadowData data = shadows_data[int(ld.l_shadowid)]; 1696 float delta; 1697 1698 vec4 L = (ld.l_type != SUN) ? l_vector : vec4(-ld.l_forward, 1.0); 1699 1700 vec3 T, B; 1701 make_orthonormal_basis(L.xyz / L.w, T, B); 1702 1703 vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy); 1704 rand.zw *= fast_sqrt(rand.y) * data.sh_blur; 1705 1706 /* We use the full l_vector.xyz so that the spread is minimize 1707 * if the shading point is further away from the light source */ 1708 W = W + T * rand.z + B * rand.w; 1709 1710 if (ld.l_type == SUN) { 1711 int scd_id = int(data.sh_data_start); 1712 vec4 view_z = vec4(dot(W - cameraPos, cameraForward)); 1713 1714 vec4 weights = step(shadows_cascade_data[scd_id].split_end_distances, view_z); 1715 float id = abs(4.0 - dot(weights, weights)); 1716 1717 if (id > 3.0) { 1718 return vec3(0.0); 1719 } 1720 1721 float range = abs(data.sh_far - 1722 data.sh_near); /* Same factor as in get_cascade_world_distance(). */ 1723 1724 vec4 shpos = shadows_cascade_data[scd_id].shadowmat[int(id)] * vec4(W, 1.0); 1725 float dist = shpos.z * range; 1726 1727 if (shpos.z > 1.0 || shpos.z < 0.0) { 1728 return vec3(0.0); 1729 } 1730 1731 ShadowSample s = sample_cascade(shpos.xy, data.sh_tex_start + id); 1732 delta = get_depth_delta(dist, s); 1733 } 1734 else { 1735 vec3 cubevec = W - shadows_cube_data[int(data.sh_data_start)].position.xyz; 1736 float dist = length(cubevec); 1737 cubevec /= dist; 1738 1739 ShadowSample s = sample_cube(cubevec, data.sh_tex_start); 1740 delta = get_depth_delta(dist, s); 1741 } 1742 1743 /* XXX : Removing Area Power. */ 1744 /* TODO : put this out of the shader. */ 1745 float falloff; 1746 if (ld.l_type == AREA_RECT || ld.l_type == AREA_ELLIPSE) { 1747 vis *= (ld.l_sizex * ld.l_sizey * 4.0 * M_PI) * (1.0 / 80.0); 1748 if (ld.l_type == AREA_ELLIPSE) { 1749 vis *= M_PI * 0.25; 1750 } 1751 vis *= 0.3 * 20.0 * 1752 max(0.0, dot(-ld.l_forward, l_vector.xyz / l_vector.w)); /* XXX ad hoc, empirical */ 1753 vis /= (l_vector.w * l_vector.w); 1754 falloff = dot(N, l_vector.xyz / l_vector.w); 1755 } 1756 else if (ld.l_type == SUN) { 1757 vis /= 1.0f + (ld.l_radius * ld.l_radius * 0.5f); 1758 vis *= ld.l_radius * ld.l_radius * M_PI; /* Removing area light power*/ 1759 vis *= M_2PI * 0.78; /* Matching cycles with point light. */ 1760 vis *= 0.082; /* XXX ad hoc, empirical */ 1761 falloff = dot(N, -ld.l_forward); 1762 } 1763 else { 1764 vis *= (4.0 * ld.l_radius * ld.l_radius) * (1.0 / 10.0); 1765 vis *= 1.5; /* XXX ad hoc, empirical */ 1766 vis /= (l_vector.w * l_vector.w); 1767 falloff = dot(N, l_vector.xyz / l_vector.w); 1768 } 1769 // vis *= M_1_PI; /* Normalize */ 1770 1771 /* Applying profile */ 1772 vis *= sss_profile(abs(delta) / scale); 1773 1774 /* No transmittance at grazing angle (hide artifacts) */ 1775 vis *= saturate(falloff * 2.0); 1776 } 1777 else { 1778 vis = vec3(0.0); 1779 } 1780 1781 return vis; 1782 #endif 1783 } 1784 1785 /* Based on Frosbite Unified Volumetric. 1786 * https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */ 1787 1788 /* Volume slice to view space depth. */ 1789 float volume_z_to_view_z(float z) 1790 { 1791 if (ProjectionMatrix[3][3] == 0.0) { 1792 /* Exponential distribution */ 1793 return (exp2(z / volDepthParameters.z) - volDepthParameters.x) / volDepthParameters.y; 1794 } 1795 else { 1796 /* Linear distribution */ 1797 return mix(volDepthParameters.x, volDepthParameters.y, z); 1798 } 1799 } 1800 1801 float view_z_to_volume_z(float depth) 1802 { 1803 if (ProjectionMatrix[3][3] == 0.0) { 1804 /* Exponential distribution */ 1805 return volDepthParameters.z * log2(depth * volDepthParameters.y + volDepthParameters.x); 1806 } 1807 else { 1808 /* Linear distribution */ 1809 return (depth - volDepthParameters.x) * volDepthParameters.z; 1810 } 1811 } 1812 1813 /* Volume texture normalized coordinates to NDC (special range [0, 1]). */ 1814 vec3 volume_to_ndc(vec3 cos) 1815 { 1816 cos.z = volume_z_to_view_z(cos.z); 1817 cos.z = get_depth_from_view_z(cos.z); 1818 cos.xy /= volCoordScale.xy; 1819 return cos; 1820 } 1821 1822 vec3 ndc_to_volume(vec3 cos) 1823 { 1824 cos.z = get_view_z_from_depth(cos.z); 1825 cos.z = view_z_to_volume_z(cos.z); 1826 cos.xy *= volCoordScale.xy; 1827 return cos; 1828 } 1829 1830 float phase_function_isotropic() 1831 { 1832 return 1.0 / (4.0 * M_PI); 1833 } 1834 1835 float phase_function(vec3 v, vec3 l, float g) 1836 { 1837 /* Henyey-Greenstein */ 1838 float cos_theta = dot(v, l); 1839 g = clamp(g, -1.0 + 1e-3, 1.0 - 1e-3); 1840 float sqr_g = g * g; 1841 return (1 - sqr_g) / max(1e-8, 4.0 * M_PI * pow(1 + sqr_g - 2 * g * cos_theta, 3.0 / 2.0)); 1842 } 1843 1844 #ifdef LAMPS_LIB 1845 vec3 light_volume(LightData ld, vec4 l_vector) 1846 { 1847 float power; 1848 /* TODO : Area lighting ? */ 1849 /* XXX : Removing Area Power. */ 1850 /* TODO : put this out of the shader. */ 1851 /* See eevee_light_setup(). */ 1852 if (ld.l_type == AREA_RECT || ld.l_type == AREA_ELLIPSE) { 1853 power = (ld.l_sizex * ld.l_sizey * 4.0 * M_PI) * (1.0 / 80.0); 1854 if (ld.l_type == AREA_ELLIPSE) { 1855 power *= M_PI * 0.25; 1856 } 1857 power *= 20.0 * 1858 max(0.0, dot(-ld.l_forward, l_vector.xyz / l_vector.w)); /* XXX ad hoc, empirical */ 1859 } 1860 else if (ld.l_type == SUN) { 1861 power = ld.l_radius * ld.l_radius * M_PI; /* Removing area light power*/ 1862 power /= 1.0f + (ld.l_radius * ld.l_radius * 0.5f); 1863 power *= M_PI * 0.5; /* Matching cycles. */ 1864 } 1865 else { 1866 power = (4.0 * ld.l_radius * ld.l_radius) * (1.0 / 10.0); 1867 power *= M_2PI; /* Matching cycles with point light. */ 1868 } 1869 1870 power /= (l_vector.w * l_vector.w); 1871 1872 /* OPTI: find a better way than calculating this on the fly */ 1873 float lum = dot(ld.l_color, vec3(0.3, 0.6, 0.1)); /* luminance approx. */ 1874 vec3 tint = (lum > 0.0) ? ld.l_color / lum : vec3(1.0); /* normalize lum. to isolate hue+sat */ 1875 1876 lum = min(lum * power, volLightClamp); 1877 1878 return tint * lum; 1879 } 1880 1881 # define VOLUMETRIC_SHADOW_MAX_STEP 32.0 1882 1883 vec3 participating_media_extinction(vec3 wpos, sampler3D volume_extinction) 1884 { 1885 /* Waiting for proper volume shadowmaps and out of frustum shadow map. */ 1886 vec3 ndc = project_point(ViewProjectionMatrix, wpos); 1887 vec3 volume_co = ndc_to_volume(ndc * 0.5 + 0.5); 1888 1889 /* Let the texture be clamped to edge. This reduce visual glitches. */ 1890 return texture(volume_extinction, volume_co).rgb; 1891 } 1892 1893 vec3 light_volume_shadow(LightData ld, vec3 ray_wpos, vec4 l_vector, sampler3D volume_extinction) 1894 { 1895 # if defined(VOLUME_SHADOW) 1896 /* Heterogeneous volume shadows */ 1897 float dd = l_vector.w / volShadowSteps; 1898 vec3 L = l_vector.xyz * l_vector.w; 1899 vec3 shadow = vec3(1.0); 1900 for (float s = 0.5; s < VOLUMETRIC_SHADOW_MAX_STEP && s < (volShadowSteps - 0.1); s += 1.0) { 1901 vec3 pos = ray_wpos + L * (s / volShadowSteps); 1902 vec3 s_extinction = participating_media_extinction(pos, volume_extinction); 1903 shadow *= exp(-s_extinction * dd); 1904 } 1905 return shadow; 1906 # else 1907 return vec3(1.0); 1908 # endif /* VOLUME_SHADOW */ 1909 } 1910 #endif 1911 1912 #ifdef IRRADIANCE_LIB 1913 vec3 irradiance_volumetric(vec3 wpos) 1914 { 1915 # ifdef IRRADIANCE_HL2 1916 IrradianceData ir_data = load_irradiance_cell(0, vec3(1.0)); 1917 vec3 irradiance = ir_data.cubesides[0] + ir_data.cubesides[1] + ir_data.cubesides[2]; 1918 ir_data = load_irradiance_cell(0, vec3(-1.0)); 1919 irradiance += ir_data.cubesides[0] + ir_data.cubesides[1] + ir_data.cubesides[2]; 1920 irradiance *= 0.16666666; /* 1/6 */ 1921 return irradiance; 1922 # else 1923 return vec3(0.0); 1924 # endif 1925 } 1926 #endif 1927 1928 uniform sampler3D inScattering; 1929 uniform sampler3D inTransmittance; 1930 1931 void volumetric_resolve(vec2 frag_uvs, 1932 float frag_depth, 1933 out vec3 transmittance, 1934 out vec3 scattering) 1935 { 1936 vec3 volume_cos = ndc_to_volume(vec3(frag_uvs, frag_depth)); 1937 1938 scattering = texture(inScattering, volume_cos).rgb; 1939 transmittance = texture(inTransmittance, volume_cos).rgb; 1940 } 1941 1942 out vec4 vPos; 1943 1944 void main() 1945 { 1946 /* Generate Triangle : less memory fetches from a VBO */ 1947 int v_id = gl_VertexID % 3; /* Vertex Id */ 1948 int t_id = gl_VertexID / 3; /* Triangle Id */ 1949 1950 /* Crappy diagram 1951 * ex 1 1952 * | \ 1953 * | \ 1954 * 1 | \ 1955 * | \ 1956 * | \ 1957 * 0 | \ 1958 * | \ 1959 * | \ 1960 * -1 0 --------------- 2 1961 * -1 0 1 ex 1962 */ 1963 vPos.x = float(v_id / 2) * 4.0 - 1.0; /* int divisor round down */ 1964 vPos.y = float(v_id % 2) * 4.0 - 1.0; 1965 vPos.z = float(t_id); 1966 vPos.w = 1.0; 1967 1968 #ifdef USE_ATTR 1969 pass_attr(vec3(0.0)); 1970 #endif 1971 } Number of Geometry Uniforms exceeds HW limits. GPUShader: linking error: ===== shader string 1 ==== 1 #define COMMON_VIEW_LIB 2 3 /* keep in sync with DRWManager.view_data */ 4 layout(std140) uniform viewBlock 5 { 6 /* Same order as DRWViewportMatrixType */ 7 mat4 ViewProjectionMatrix; 8 mat4 ViewProjectionMatrixInverse; 9 mat4 ViewMatrix; 10 mat4 ViewMatrixInverse; 11 mat4 ProjectionMatrix; 12 mat4 ProjectionMatrixInverse; 13 14 vec4 clipPlanes[6]; 15 16 /* TODO move it elsewhere. */ 17 vec4 CameraTexCoFactors; 18 }; 19 20 #ifdef world_clip_planes_calc_clip_distance 21 # undef world_clip_planes_calc_clip_distance 22 # define world_clip_planes_calc_clip_distance(p) \ 23 _world_clip_planes_calc_clip_distance(p, clipPlanes) 24 #endif 25 26 uniform mat4 ModelMatrix; 27 uniform mat4 ModelMatrixInverse; 28 29 /** Transform shortcuts. */ 30 /* Rule of thumb: Try to reuse world positions and normals because converting though viewspace 31 * will always be decomposed in at least 2 matrix operation. */ 32 33 /** 34 * Some clarification: 35 * Usually Normal matrix is transpose(inverse(ViewMatrix * ModelMatrix)) 36 * 37 * But since it is slow to multiply matrices we decompose it. Decomposing 38 * inversion and transposition both invert the product order leaving us with 39 * the same original order: 40 * transpose(ViewMatrixInverse) * transpose(ModelMatrixInverse) 41 * 42 * Knowing that the view matrix is orthogonal, the transpose is also the inverse. 43 * Note: This is only valid because we are only using the mat3 of the ViewMatrixInverse. 44 * ViewMatrix * transpose(ModelMatrixInverse) 45 **/ 46 #define normal_object_to_view(n) (mat3(ViewMatrix) * (transpose(mat3(ModelMatrixInverse)) * n)) 47 #define normal_object_to_world(n) (transpose(mat3(ModelMatrixInverse)) * n) 48 #define normal_world_to_object(n) (transpose(mat3(ModelMatrix)) * n) 49 #define normal_world_to_view(n) (mat3(ViewMatrix) * n) 50 51 #define point_object_to_ndc(p) (ViewProjectionMatrix * vec4((ModelMatrix * vec4(p, 1.0)).xyz, 1.0)) 52 #define point_object_to_view(p) ((ViewMatrix * vec4((ModelMatrix * vec4(p, 1.0)).xyz, 1.0)).xyz) 53 #define point_object_to_world(p) ((ModelMatrix * vec4(p, 1.0)).xyz) 54 #define point_view_to_ndc(p) (ProjectionMatrix * vec4(p, 1.0)) 55 #define point_view_to_object(p) ((ModelMatrixInverse * (ViewMatrixInverse * vec4(p, 1.0))).xyz) 56 #define point_view_to_world(p) ((ViewMatrixInverse * vec4(p, 1.0)).xyz) 57 #define point_world_to_ndc(p) (ViewProjectionMatrix * vec4(p, 1.0)) 58 #define point_world_to_object(p) ((ModelMatrixInverse * vec4(p, 1.0)).xyz) 59 #define point_world_to_view(p) ((ViewMatrix * vec4(p, 1.0)).xyz) 60 61 /* Due to some shader compiler bug, we somewhat need to access gl_VertexID 62 * to make vertex shaders work. even if it's actually dead code. */ 63 #ifdef GPU_INTEL 64 # define GPU_INTEL_VERTEX_SHADER_WORKAROUND gl_Position.x = float(gl_VertexID); 65 #else 66 # define GPU_INTEL_VERTEX_SHADER_WORKAROUND 67 #endif 68 69 layout(std140) uniform common_block 70 { 71 mat4 pastViewProjectionMatrix; 72 vec4 viewVecs[2]; 73 vec2 mipRatio[10]; /* To correct mip level texel mis-alignement */ 74 /* Ambient Occlusion */ 75 vec4 aoParameters[2]; 76 /* Volumetric */ 77 ivec4 volTexSize; 78 vec4 volDepthParameters; /* Parameters to the volume Z equation */ 79 vec4 volInvTexSize; 80 vec4 volJitter; 81 vec4 volCoordScale; /* To convert volume uvs to screen uvs */ 82 float volHistoryAlpha; 83 float volLightClamp; 84 float volShadowSteps; 85 bool volUseLights; 86 /* Screen Space Reflections */ 87 vec4 ssrParameters; 88 float ssrBorderFac; 89 float ssrMaxRoughness; 90 float ssrFireflyFac; 91 float ssrBrdfBias; 92 bool ssrToggle; 93 bool ssrefractToggle; 94 /* SubSurface Scattering */ 95 float sssJitterThreshold; 96 bool sssToggle; 97 /* Specular */ 98 bool specToggle; 99 /* Lights */ 100 int laNumLight; 101 /* Probes */ 102 int prbNumPlanar; 103 int prbNumRenderCube; 104 int prbNumRenderGrid; 105 int prbIrradianceVisSize; 106 float prbIrradianceSmooth; 107 float prbLodCubeMax; 108 float prbLodPlanarMax; 109 /* Misc*/ 110 int hizMipOffset; 111 int rayType; 112 float rayDepth; 113 }; 114 115 /* rayType (keep in sync with ray_type) */ 116 #define EEVEE_RAY_CAMERA 0 117 #define EEVEE_RAY_SHADOW 1 118 #define EEVEE_RAY_DIFFUSE 2 119 #define EEVEE_RAY_GLOSSY 3 120 121 /* aoParameters */ 122 #define aoDistance aoParameters[0].x 123 #define aoSamples aoParameters[0].y /* UNUSED */ 124 #define aoFactor aoParameters[0].z 125 #define aoInvSamples aoParameters[0].w /* UNUSED */ 126 127 #define aoOffset aoParameters[1].x /* UNUSED */ 128 #define aoBounceFac aoParameters[1].y 129 #define aoQuality aoParameters[1].z 130 #define aoSettings aoParameters[1].w 131 132 /* ssrParameters */ 133 #define ssrQuality ssrParameters.x 134 #define ssrThickness ssrParameters.y 135 #define ssrPixelSize ssrParameters.zw 136 137 #define M_PI 3.14159265358979323846 /* pi */ 138 #define M_2PI 6.28318530717958647692 /* 2*pi */ 139 #define M_PI_2 1.57079632679489661923 /* pi/2 */ 140 #define M_1_PI 0.318309886183790671538 /* 1/pi */ 141 #define M_1_2PI 0.159154943091895335768 /* 1/(2*pi) */ 142 #define M_1_PI2 0.101321183642337771443 /* 1/(pi^2) */ 143 144 #define LUT_SIZE 64 145 146 /* Buffers */ 147 uniform sampler2D colorBuffer; 148 uniform sampler2D depthBuffer; 149 uniform sampler2D maxzBuffer; 150 uniform sampler2D minzBuffer; 151 uniform sampler2DArray planarDepth; 152 153 #define cameraForward ViewMatrixInverse[2].xyz 154 #define cameraPos ViewMatrixInverse[3].xyz 155 #define cameraVec \ 156 ((ProjectionMatrix[3][3] == 0.0) ? normalize(cameraPos - worldPosition) : cameraForward) 157 #define viewCameraVec \ 158 ((ProjectionMatrix[3][3] == 0.0) ? normalize(-viewPosition) : vec3(0.0, 0.0, 1.0)) 159 160 /* ------- Structures -------- */ 161 162 /* ------ Lights ----- */ 163 struct LightData { 164 vec4 position_influence; /* w : InfluenceRadius (inversed and squared) */ 165 vec4 color_spec; /* w : Spec Intensity */ 166 vec4 spotdata_radius_shadow; /* x : spot size, y : spot blend, z : radius, w: shadow id */ 167 vec4 rightvec_sizex; /* xyz: Normalized up vector, w: area size X or spot scale X */ 168 vec4 upvec_sizey; /* xyz: Normalized right vector, w: area size Y or spot scale Y */ 169 vec4 forwardvec_type; /* xyz: Normalized forward vector, w: Light Type */ 170 }; 171 172 /* convenience aliases */ 173 #define l_color color_spec.rgb 174 #define l_spec color_spec.a 175 #define l_position position_influence.xyz 176 #define l_influence position_influence.w 177 #define l_sizex rightvec_sizex.w 178 #define l_sizey upvec_sizey.w 179 #define l_right rightvec_sizex.xyz 180 #define l_up upvec_sizey.xyz 181 #define l_forward forwardvec_type.xyz 182 #define l_type forwardvec_type.w 183 #define l_spot_size spotdata_radius_shadow.x 184 #define l_spot_blend spotdata_radius_shadow.y 185 #define l_radius spotdata_radius_shadow.z 186 #define l_shadowid spotdata_radius_shadow.w 187 188 /* ------ Shadows ----- */ 189 #ifndef MAX_CASCADE_NUM 190 # define MAX_CASCADE_NUM 4 191 #endif 192 193 struct ShadowData { 194 vec4 near_far_bias_exp; 195 vec4 shadow_data_start_end; 196 vec4 contact_shadow_data; 197 }; 198 199 struct ShadowCubeData { 200 vec4 position; 201 }; 202 203 struct ShadowCascadeData { 204 mat4 shadowmat[MAX_CASCADE_NUM]; 205 vec4 split_start_distances; 206 vec4 split_end_distances; 207 }; 208 209 /* convenience aliases */ 210 #define sh_near near_far_bias_exp.x 211 #define sh_far near_far_bias_exp.y 212 #define sh_bias near_far_bias_exp.z 213 #define sh_exp near_far_bias_exp.w 214 #define sh_bleed near_far_bias_exp.w 215 #define sh_tex_start shadow_data_start_end.x 216 #define sh_data_start shadow_data_start_end.y 217 #define sh_multi_nbr shadow_data_start_end.z 218 #define sh_blur shadow_data_start_end.w 219 #define sh_contact_dist contact_shadow_data.x 220 #define sh_contact_offset contact_shadow_data.y 221 #define sh_contact_spread contact_shadow_data.z 222 #define sh_contact_thickness contact_shadow_data.w 223 224 /* ------- Convenience functions --------- */ 225 226 vec3 mul(mat3 m, vec3 v) 227 { 228 return m * v; 229 } 230 mat3 mul(mat3 m1, mat3 m2) 231 { 232 return m1 * m2; 233 } 234 vec3 transform_direction(mat4 m, vec3 v) 235 { 236 return mat3(m) * v; 237 } 238 vec3 transform_point(mat4 m, vec3 v) 239 { 240 return (m * vec4(v, 1.0)).xyz; 241 } 242 vec3 project_point(mat4 m, vec3 v) 243 { 244 vec4 tmp = m * vec4(v, 1.0); 245 return tmp.xyz / tmp.w; 246 } 247 248 #define min3(a, b, c) min(a, min(b, c)) 249 #define min4(a, b, c, d) min(a, min3(b, c, d)) 250 #define min5(a, b, c, d, e) min(a, min4(b, c, d, e)) 251 #define min6(a, b, c, d, e, f) min(a, min5(b, c, d, e, f)) 252 #define min7(a, b, c, d, e, f, g) min(a, min6(b, c, d, e, f, g)) 253 #define min8(a, b, c, d, e, f, g, h) min(a, min7(b, c, d, e, f, g, h)) 254 #define min9(a, b, c, d, e, f, g, h, i) min(a, min8(b, c, d, e, f, g, h, i)) 255 256 #define max3(a, b, c) max(a, max(b, c)) 257 #define max4(a, b, c, d) max(a, max3(b, c, d)) 258 #define max5(a, b, c, d, e) max(a, max4(b, c, d, e)) 259 #define max6(a, b, c, d, e, f) max(a, max5(b, c, d, e, f)) 260 #define max7(a, b, c, d, e, f, g) max(a, max6(b, c, d, e, f, g)) 261 #define max8(a, b, c, d, e, f, g, h) max(a, max7(b, c, d, e, f, g, h)) 262 #define max9(a, b, c, d, e, f, g, h, i) max(a, max8(b, c, d, e, f, g, h, i)) 263 264 #define avg3(a, b, c) (a + b + c) * (1.0 / 3.0) 265 #define avg4(a, b, c, d) (a + b + c + d) * (1.0 / 4.0) 266 #define avg5(a, b, c, d, e) (a + b + c + d + e) * (1.0 / 5.0) 267 #define avg6(a, b, c, d, e, f) (a + b + c + d + e + f) * (1.0 / 6.0) 268 #define avg7(a, b, c, d, e, f, g) (a + b + c + d + e + f + g) * (1.0 / 7.0) 269 #define avg8(a, b, c, d, e, f, g, h) (a + b + c + d + e + f + g + h) * (1.0 / 8.0) 270 #define avg9(a, b, c, d, e, f, g, h, i) (a + b + c + d + e + f + g + h + i) * (1.0 / 9.0) 271 272 float min_v2(vec2 v) 273 { 274 return min(v.x, v.y); 275 } 276 float min_v3(vec3 v) 277 { 278 return min(v.x, min(v.y, v.z)); 279 } 280 float max_v2(vec2 v) 281 { 282 return max(v.x, v.y); 283 } 284 float max_v3(vec3 v) 285 { 286 return max(v.x, max(v.y, v.z)); 287 } 288 289 float sum(vec2 v) 290 { 291 return dot(vec2(1.0), v); 292 } 293 float sum(vec3 v) 294 { 295 return dot(vec3(1.0), v); 296 } 297 float sum(vec4 v) 298 { 299 return dot(vec4(1.0), v); 300 } 301 302 float saturate(float a) 303 { 304 return clamp(a, 0.0, 1.0); 305 } 306 vec2 saturate(vec2 a) 307 { 308 return clamp(a, 0.0, 1.0); 309 } 310 vec3 saturate(vec3 a) 311 { 312 return clamp(a, 0.0, 1.0); 313 } 314 vec4 saturate(vec4 a) 315 { 316 return clamp(a, 0.0, 1.0); 317 } 318 319 float distance_squared(vec2 a, vec2 b) 320 { 321 a -= b; 322 return dot(a, a); 323 } 324 float distance_squared(vec3 a, vec3 b) 325 { 326 a -= b; 327 return dot(a, a); 328 } 329 float len_squared(vec3 a) 330 { 331 return dot(a, a); 332 } 333 334 float inverse_distance(vec3 V) 335 { 336 return max(1 / length(V), 1e-8); 337 } 338 339 vec2 mip_ratio_interp(float mip) 340 { 341 float low_mip = floor(mip); 342 return mix(mipRatio[int(low_mip)], mipRatio[int(low_mip + 1.0)], mip - low_mip); 343 } 344 345 /* ------- RNG ------- */ 346 347 float wang_hash_noise(uint s) 348 { 349 s = (s ^ 61u) ^ (s >> 16u); 350 s *= 9u; 351 s = s ^ (s >> 4u); 352 s *= 0x27d4eb2du; 353 s = s ^ (s >> 15u); 354 355 return fract(float(s) / 4294967296.0); 356 } 357 358 /* ------- Fast Math ------- */ 359 360 /* [Drobot2014a] Low Level Optimizations for GCN */ 361 float fast_sqrt(float v) 362 { 363 return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1)); 364 } 365 366 vec2 fast_sqrt(vec2 v) 367 { 368 return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1)); 369 } 370 371 /* [Eberly2014] GPGPU Programming for Games and Science */ 372 float fast_acos(float v) 373 { 374 float res = -0.156583 * abs(v) + M_PI_2; 375 res *= fast_sqrt(1.0 - abs(v)); 376 return (v >= 0) ? res : M_PI - res; 377 } 378 379 vec2 fast_acos(vec2 v) 380 { 381 vec2 res = -0.156583 * abs(v) + M_PI_2; 382 res *= fast_sqrt(1.0 - abs(v)); 383 v.x = (v.x >= 0) ? res.x : M_PI - res.x; 384 v.y = (v.y >= 0) ? res.y : M_PI - res.y; 385 return v; 386 } 387 388 float point_plane_projection_dist(vec3 lineorigin, vec3 planeorigin, vec3 planenormal) 389 { 390 return dot(planenormal, planeorigin - lineorigin); 391 } 392 393 float line_plane_intersect_dist(vec3 lineorigin, 394 vec3 linedirection, 395 vec3 planeorigin, 396 vec3 planenormal) 397 { 398 return dot(planenormal, planeorigin - lineorigin) / dot(planenormal, linedirection); 399 } 400 401 float line_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec4 plane) 402 { 403 vec3 plane_co = plane.xyz * (-plane.w / len_squared(plane.xyz)); 404 vec3 h = lineorigin - plane_co; 405 return -dot(plane.xyz, h) / dot(plane.xyz, linedirection); 406 } 407 408 vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin, vec3 planenormal) 409 { 410 float dist = line_plane_intersect_dist(lineorigin, linedirection, planeorigin, planenormal); 411 return lineorigin + linedirection * dist; 412 } 413 414 vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec4 plane) 415 { 416 float dist = line_plane_intersect_dist(lineorigin, linedirection, plane); 417 return lineorigin + linedirection * dist; 418 } 419 420 float line_aligned_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec3 planeorigin) 421 { 422 /* aligned plane normal */ 423 vec3 L = planeorigin - lineorigin; 424 float diskdist = length(L); 425 vec3 planenormal = -normalize(L); 426 return -diskdist / dot(planenormal, linedirection); 427 } 428 429 vec3 line_aligned_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin) 430 { 431 float dist = line_aligned_plane_intersect_dist(lineorigin, linedirection, planeorigin); 432 if (dist < 0) { 433 /* if intersection is behind we fake the intersection to be 434 * really far and (hopefully) not inside the radius of interest */ 435 dist = 1e16; 436 } 437 return lineorigin + linedirection * dist; 438 } 439 440 float line_unit_sphere_intersect_dist(vec3 lineorigin, vec3 linedirection) 441 { 442 float a = dot(linedirection, linedirection); 443 float b = dot(linedirection, lineorigin); 444 float c = dot(lineorigin, lineorigin) - 1; 445 446 float dist = 1e15; 447 float determinant = b * b - a * c; 448 if (determinant >= 0) { 449 dist = (sqrt(determinant) - b) / a; 450 } 451 452 return dist; 453 } 454 455 float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection) 456 { 457 /* https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ 458 */ 459 vec3 firstplane = (vec3(1.0) - lineorigin) / linedirection; 460 vec3 secondplane = (vec3(-1.0) - lineorigin) / linedirection; 461 vec3 furthestplane = max(firstplane, secondplane); 462 463 return min_v3(furthestplane); 464 } 465 466 /* Return texture coordinates to sample Surface LUT */ 467 vec2 lut_coords(float cosTheta, float roughness) 468 { 469 float theta = acos(cosTheta); 470 vec2 coords = vec2(roughness, theta / M_PI_2); 471 472 /* scale and bias coordinates, for correct filtered lookup */ 473 return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE; 474 } 475 476 vec2 lut_coords_ltc(float cosTheta, float roughness) 477 { 478 vec2 coords = vec2(roughness, sqrt(1.0 - cosTheta)); 479 480 /* scale and bias coordinates, for correct filtered lookup */ 481 return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE; 482 } 483 484 /* -- Tangent Space conversion -- */ 485 vec3 tangent_to_world(vec3 vector, vec3 N, vec3 T, vec3 B) 486 { 487 return T * vector.x + B * vector.y + N * vector.z; 488 } 489 490 vec3 world_to_tangent(vec3 vector, vec3 N, vec3 T, vec3 B) 491 { 492 return vec3(dot(T, vector), dot(B, vector), dot(N, vector)); 493 } 494 495 void make_orthonormal_basis(vec3 N, out vec3 T, out vec3 B) 496 { 497 vec3 UpVector = abs(N.z) < 0.99999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); 498 T = normalize(cross(UpVector, N)); 499 B = cross(N, T); 500 } 501 502 /* ---- Opengl Depth conversion ---- */ 503 504 float linear_depth(bool is_persp, float z, float zf, float zn) 505 { 506 if (is_persp) { 507 return (zn * zf) / (z * (zn - zf) + zf); 508 } 509 else { 510 return (z * 2.0 - 1.0) * zf; 511 } 512 } 513 514 float buffer_depth(bool is_persp, float z, float zf, float zn) 515 { 516 if (is_persp) { 517 return (zf * (zn - z)) / (z * (zn - zf)); 518 } 519 else { 520 return (z / (zf * 2.0)) + 0.5; 521 } 522 } 523 524 float get_view_z_from_depth(float depth) 525 { 526 if (ProjectionMatrix[3][3] == 0.0) { 527 float d = 2.0 * depth - 1.0; 528 return -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]); 529 } 530 else { 531 return viewVecs[0].z + depth * viewVecs[1].z; 532 } 533 } 534 535 float get_depth_from_view_z(float z) 536 { 537 if (ProjectionMatrix[3][3] == 0.0) { 538 float d = (-ProjectionMatrix[3][2] / z) - ProjectionMatrix[2][2]; 539 return d * 0.5 + 0.5; 540 } 541 else { 542 return (z - viewVecs[0].z) / viewVecs[1].z; 543 } 544 } 545 546 vec2 get_uvs_from_view(vec3 view) 547 { 548 vec3 ndc = project_point(ProjectionMatrix, view); 549 return ndc.xy * 0.5 + 0.5; 550 } 551 552 vec3 get_view_space_from_depth(vec2 uvcoords, float depth) 553 { 554 if (ProjectionMatrix[3][3] == 0.0) { 555 return vec3(viewVecs[0].xy + uvcoords * viewVecs[1].xy, 1.0) * get_view_z_from_depth(depth); 556 } 557 else { 558 return viewVecs[0].xyz + vec3(uvcoords, depth) * viewVecs[1].xyz; 559 } 560 } 561 562 vec3 get_world_space_from_depth(vec2 uvcoords, float depth) 563 { 564 return (ViewMatrixInverse * vec4(get_view_space_from_depth(uvcoords, depth), 1.0)).xyz; 565 } 566 567 vec3 get_specular_reflection_dominant_dir(vec3 N, vec3 V, float roughness) 568 { 569 vec3 R = -reflect(V, N); 570 float smoothness = 1.0 - roughness; 571 float fac = smoothness * (sqrt(smoothness) + roughness); 572 return normalize(mix(N, R, fac)); 573 } 574 575 float specular_occlusion(float NV, float AO, float roughness) 576 { 577 return saturate(pow(NV + AO, roughness) - 1.0 + AO); 578 } 579 580 /* --- Refraction utils --- */ 581 582 float ior_from_f0(float f0) 583 { 584 float f = sqrt(f0); 585 return (-f - 1.0) / (f - 1.0); 586 } 587 588 float f0_from_ior(float eta) 589 { 590 float A = (eta - 1.0) / (eta + 1.0); 591 return A * A; 592 } 593 594 vec3 get_specular_refraction_dominant_dir(vec3 N, vec3 V, float roughness, float ior) 595 { 596 /* TODO: This a bad approximation. Better approximation should fit 597 * the refracted vector and roughness into the best prefiltered reflection 598 * lobe. */ 599 /* Correct the IOR for ior < 1.0 to not see the abrupt delimitation or the TIR */ 600 ior = (ior < 1.0) ? mix(ior, 1.0, roughness) : ior; 601 float eta = 1.0 / ior; 602 603 float NV = dot(N, -V); 604 605 /* Custom Refraction. */ 606 float k = 1.0 - eta * eta * (1.0 - NV * NV); 607 k = max(0.0, k); /* Only this changes. */ 608 vec3 R = eta * -V - (eta * NV + sqrt(k)) * N; 609 610 return R; 611 } 612 613 float get_btdf_lut(sampler2DArray btdf_lut_tex, float NV, float roughness, float ior) 614 { 615 const vec3 lut_scale_bias_texel_size = vec3((LUT_SIZE - 1.0), 0.5, 1.5) / LUT_SIZE; 616 617 vec3 coords; 618 /* Try to compensate for the low resolution and interpolation error. */ 619 coords.x = (ior > 1.0) ? (0.9 + lut_scale_bias_texel_size.z) + 620 (0.1 - lut_scale_bias_texel_size.z) * f0_from_ior(ior) : 621 (0.9 + lut_scale_bias_texel_size.z) * ior * ior; 622 coords.y = 1.0 - saturate(NV); 623 coords.xy *= lut_scale_bias_texel_size.x; 624 coords.xy += lut_scale_bias_texel_size.y; 625 626 const float lut_lvl_ofs = 4.0; /* First texture lvl of roughness. */ 627 const float lut_lvl_scale = 16.0; /* How many lvl of roughness in the lut. */ 628 629 float mip = roughness * lut_lvl_scale; 630 float mip_floor = floor(mip); 631 632 coords.z = lut_lvl_ofs + mip_floor + 1.0; 633 float btdf_high = textureLod(btdf_lut_tex, coords, 0.0).r; 634 635 coords.z -= 1.0; 636 float btdf_low = textureLod(btdf_lut_tex, coords, 0.0).r; 637 638 float btdf = (ior == 1.0) ? 1.0 : mix(btdf_low, btdf_high, mip - coords.z); 639 640 return btdf; 641 } 642 643 /* ---- Encode / Decode Normal buffer data ---- */ 644 /* From http://aras-p.info/texts/CompactNormalStorage.html 645 * Using Method #4: Spheremap Transform */ 646 vec2 normal_encode(vec3 n, vec3 view) 647 { 648 float p = sqrt(n.z * 8.0 + 8.0); 649 return n.xy / p + 0.5; 650 } 651 652 vec3 normal_decode(vec2 enc, vec3 view) 653 { 654 vec2 fenc = enc * 4.0 - 2.0; 655 float f = dot(fenc, fenc); 656 float g = sqrt(1.0 - f / 4.0); 657 vec3 n; 658 n.xy = fenc * g; 659 n.z = 1 - f / 2; 660 return n; 661 } 662 663 /* ---- RGBM (shared multiplier) encoding ---- */ 664 /* From http://iwasbeingirony.blogspot.fr/2010/06/difference-between-rgbm-and-rgbd.html */ 665 666 /* Higher RGBM_MAX_RANGE gives imprecision issues in low intensity. */ 667 #define RGBM_MAX_RANGE 512.0 668 669 vec4 rgbm_encode(vec3 rgb) 670 { 671 float maxRGB = max_v3(rgb); 672 float M = maxRGB / RGBM_MAX_RANGE; 673 M = ceil(M * 255.0) / 255.0; 674 return vec4(rgb / (M * RGBM_MAX_RANGE), M); 675 } 676 677 vec3 rgbm_decode(vec4 data) 678 { 679 return data.rgb * (data.a * RGBM_MAX_RANGE); 680 } 681 682 /* ---- RGBE (shared exponent) encoding ---- */ 683 vec4 rgbe_encode(vec3 rgb) 684 { 685 float maxRGB = max_v3(rgb); 686 float fexp = ceil(log2(maxRGB)); 687 return vec4(rgb / exp2(fexp), (fexp + 128.0) / 255.0); 688 } 689 690 vec3 rgbe_decode(vec4 data) 691 { 692 float fexp = data.a * 255.0 - 128.0; 693 return data.rgb * exp2(fexp); 694 } 695 696 #if 1 697 # define irradiance_encode rgbe_encode 698 # define irradiance_decode rgbe_decode 699 #else /* No ecoding (when using floating point format) */ 700 # define irradiance_encode(X) (X).rgbb 701 # define irradiance_decode(X) (X).rgb 702 #endif 703 704 /* Irradiance Visibility Encoding */ 705 #if 1 706 vec4 visibility_encode(vec2 accum, float range) 707 { 708 accum /= range; 709 710 vec4 data; 711 data.x = fract(accum.x); 712 data.y = floor(accum.x) / 255.0; 713 data.z = fract(accum.y); 714 data.w = floor(accum.y) / 255.0; 715 716 return data; 717 } 718 719 vec2 visibility_decode(vec4 data, float range) 720 { 721 return (data.xz + data.yw * 255.0) * range; 722 } 723 #else /* No ecoding (when using floating point format) */ 724 vec4 visibility_encode(vec2 accum, float range) 725 { 726 return accum.xyxy; 727 } 728 729 vec2 visibility_decode(vec4 data, float range) 730 { 731 return data.xy; 732 } 733 #endif 734 735 /* Fresnel monochromatic, perfect mirror */ 736 float F_eta(float eta, float cos_theta) 737 { 738 /* compute fresnel reflectance without explicitly computing 739 * the refracted direction */ 740 float c = abs(cos_theta); 741 float g = eta * eta - 1.0 + c * c; 742 float result; 743 744 if (g > 0.0) { 745 g = sqrt(g); 746 vec2 g_c = vec2(g) + vec2(c, -c); 747 float A = g_c.y / g_c.x; 748 A *= A; 749 g_c *= c; 750 float B = (g_c.y - 1.0) / (g_c.x + 1.0); 751 B *= B; 752 result = 0.5 * A * (1.0 + B); 753 } 754 else { 755 result = 1.0; /* TIR (no refracted component) */ 756 } 757 758 return result; 759 } 760 761 /* Fresnel color blend base on fresnel factor */ 762 vec3 F_color_blend(float eta, float fresnel, vec3 f0_color) 763 { 764 float f0 = F_eta(eta, 1.0); 765 float fac = saturate((fresnel - f0) / max(1e-8, 1.0 - f0)); 766 return mix(f0_color, vec3(1.0), fac); 767 } 768 769 /* Fresnel */ 770 vec3 F_schlick(vec3 f0, float cos_theta) 771 { 772 float fac = 1.0 - cos_theta; 773 float fac2 = fac * fac; 774 fac = fac2 * fac2 * fac; 775 776 /* Unreal specular matching : if specular color is below 2% intensity, 777 * (using green channel for intensity) treat as shadowning */ 778 return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * fac + (1.0 - fac) * f0; 779 } 780 781 /* Fresnel approximation for LTC area lights (not MRP) */ 782 vec3 F_area(vec3 f0, vec3 f90, vec2 lut) 783 { 784 /* Unreal specular matching : if specular color is below 2% intensity, 785 * treat as shadowning */ 786 return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * lut.y * f90 + lut.x * f0; 787 } 788 789 /* Fresnel approximation for IBL */ 790 vec3 F_ibl(vec3 f0, vec3 f90, vec2 lut) 791 { 792 /* Unreal specular matching : if specular color is below 2% intensity, 793 * treat as shadowning */ 794 return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * lut.y * f90 + lut.x * f0; 795 } 796 797 /* GGX */ 798 float D_ggx_opti(float NH, float a2) 799 { 800 float tmp = (NH * a2 - NH) * NH + 1.0; 801 return M_PI * tmp * tmp; /* Doing RCP and mul a2 at the end */ 802 } 803 804 float G1_Smith_GGX(float NX, float a2) 805 { 806 /* Using Brian Karis approach and refactoring by NX/NX 807 * this way the (2*NL)*(2*NV) in G = G1(V) * G1(L) gets canceled by the brdf denominator 4*NL*NV 808 * Rcp is done on the whole G later 809 * Note that this is not convenient for the transmission formula */ 810 return NX + sqrt(NX * (NX - NX * a2) + a2); 811 /* return 2 / (1 + sqrt(1 + a2 * (1 - NX*NX) / (NX*NX) ) ); /* Reference function */ 812 } 813 814 float bsdf_ggx(vec3 N, vec3 L, vec3 V, float roughness) 815 { 816 float a = roughness; 817 float a2 = a * a; 818 819 vec3 H = normalize(L + V); 820 float NH = max(dot(N, H), 1e-8); 821 float NL = max(dot(N, L), 1e-8); 822 float NV = max(dot(N, V), 1e-8); 823 824 float G = G1_Smith_GGX(NV, a2) * G1_Smith_GGX(NL, a2); /* Doing RCP at the end */ 825 float D = D_ggx_opti(NH, a2); 826 827 /* Denominator is canceled by G1_Smith */ 828 /* bsdf = D * G / (4.0 * NL * NV); /* Reference function */ 829 return NL * a2 / (D * G); /* NL to Fit cycles Equation : line. 345 in bsdf_microfacet.h */ 830 } 831 832 void accumulate_light(vec3 light, float fac, inout vec4 accum) 833 { 834 accum += vec4(light, 1.0) * min(fac, (1.0 - accum.a)); 835 } 836 837 /* ----------- Cone Aperture Approximation --------- */ 838 839 /* Return a fitted cone angle given the input roughness */ 840 float cone_cosine(float r) 841 { 842 /* Using phong gloss 843 * roughness = sqrt(2/(gloss+2)) */ 844 float gloss = -2 + 2 / (r * r); 845 /* Drobot 2014 in GPUPro5 */ 846 // return cos(2.0 * sqrt(2.0 / (gloss + 2))); 847 /* Uludag 2014 in GPUPro5 */ 848 // return pow(0.244, 1 / (gloss + 1)); 849 /* Jimenez 2016 in Practical Realtime Strategies for Accurate Indirect Occlusion*/ 850 return exp2(-3.32193 * r * r); 851 } 852 853 /* --------- Closure ---------- */ 854 #ifdef VOLUMETRICS 855 856 struct Closure { 857 vec3 absorption; 858 vec3 scatter; 859 vec3 emission; 860 float anisotropy; 861 }; 862 863 # define CLOSURE_DEFAULT Closure(vec3(0.0), vec3(0.0), vec3(0.0), 0.0) 864 865 Closure closure_mix(Closure cl1, Closure cl2, float fac) 866 { 867 Closure cl; 868 cl.absorption = mix(cl1.absorption, cl2.absorption, fac); 869 cl.scatter = mix(cl1.scatter, cl2.scatter, fac); 870 cl.emission = mix(cl1.emission, cl2.emission, fac); 871 cl.anisotropy = mix(cl1.anisotropy, cl2.anisotropy, fac); 872 return cl; 873 } 874 875 Closure closure_add(Closure cl1, Closure cl2) 876 { 877 Closure cl; 878 cl.absorption = cl1.absorption + cl2.absorption; 879 cl.scatter = cl1.scatter + cl2.scatter; 880 cl.emission = cl1.emission + cl2.emission; 881 cl.anisotropy = (cl1.anisotropy + cl2.anisotropy) / 2.0; /* Average phase (no multi lobe) */ 882 return cl; 883 } 884 885 Closure closure_emission(vec3 rgb) 886 { 887 Closure cl = CLOSURE_DEFAULT; 888 cl.emission = rgb; 889 return cl; 890 } 891 892 #else /* VOLUMETRICS */ 893 894 struct Closure { 895 vec3 radiance; 896 float opacity; 897 # ifdef USE_SSS 898 vec4 sss_data; 899 # ifdef USE_SSS_ALBEDO 900 vec3 sss_albedo; 901 # endif 902 # endif 903 vec4 ssr_data; 904 vec2 ssr_normal; 905 int ssr_id; 906 }; 907 908 /* This is hacking ssr_id to tag transparent bsdf */ 909 # define TRANSPARENT_CLOSURE_FLAG -2 910 # define REFRACT_CLOSURE_FLAG -3 911 # define NO_SSR -999 912 913 # ifdef USE_SSS 914 # ifdef USE_SSS_ALBEDO 915 # define CLOSURE_DEFAULT \ 916 Closure(vec3(0.0), 1.0, vec4(0.0), vec3(0.0), vec4(0.0), vec2(0.0), -1) 917 # else 918 # define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec4(0.0), vec2(0.0), -1) 919 # endif 920 # else 921 # define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec2(0.0), -1) 922 # endif 923 924 uniform int outputSsrId; 925 926 Closure closure_mix(Closure cl1, Closure cl2, float fac) 927 { 928 Closure cl; 929 930 if (cl1.ssr_id == TRANSPARENT_CLOSURE_FLAG) { 931 cl.ssr_normal = cl2.ssr_normal; 932 cl.ssr_data = cl2.ssr_data; 933 cl.ssr_id = cl2.ssr_id; 934 # ifdef USE_SSS 935 cl1.sss_data = cl2.sss_data; 936 # ifdef USE_SSS_ALBEDO 937 cl1.sss_albedo = cl2.sss_albedo; 938 # endif 939 # endif 940 } 941 else if (cl2.ssr_id == TRANSPARENT_CLOSURE_FLAG) { 942 cl.ssr_normal = cl1.ssr_normal; 943 cl.ssr_data = cl1.ssr_data; 944 cl.ssr_id = cl1.ssr_id; 945 # ifdef USE_SSS 946 cl2.sss_data = cl1.sss_data; 947 # ifdef USE_SSS_ALBEDO 948 cl2.sss_albedo = cl1.sss_albedo; 949 # endif 950 # endif 951 } 952 else if (cl1.ssr_id == outputSsrId) { 953 /* When mixing SSR don't blend roughness. 954 * 955 * It makes no sense to mix them really, so we take either one of them and 956 * tone down its specularity (ssr_data.xyz) while keeping its roughness (ssr_data.w). 957 */ 958 cl.ssr_data = mix(cl1.ssr_data.xyzw, vec4(vec3(0.0), cl1.ssr_data.w), fac); 959 cl.ssr_normal = cl1.ssr_normal; 960 cl.ssr_id = cl1.ssr_id; 961 } 962 else { 963 cl.ssr_data = mix(vec4(vec3(0.0), cl2.ssr_data.w), cl2.ssr_data.xyzw, fac); 964 cl.ssr_normal = cl2.ssr_normal; 965 cl.ssr_id = cl2.ssr_id; 966 } 967 968 cl.opacity = mix(cl1.opacity, cl2.opacity, fac); 969 cl.radiance = mix(cl1.radiance * cl1.opacity, cl2.radiance * cl2.opacity, fac); 970 cl.radiance /= max(1e-8, cl.opacity); 971 972 # ifdef USE_SSS 973 /* Apply Mix on input */ 974 cl1.sss_data.rgb *= 1.0 - fac; 975 cl2.sss_data.rgb *= fac; 976 977 /* Select biggest radius. */ 978 bool use_cl1 = (cl1.sss_data.a > cl2.sss_data.a); 979 cl.sss_data = (use_cl1) ? cl1.sss_data : cl2.sss_data; 980 981 # ifdef USE_SSS_ALBEDO 982 /* TODO Find a solution to this. Dither? */ 983 cl.sss_albedo = (use_cl1) ? cl1.sss_albedo : cl2.sss_albedo; 984 /* Add radiance that was supposed to be filtered but was rejected. */ 985 cl.radiance += (use_cl1) ? cl2.sss_data.rgb * cl2.sss_albedo : cl1.sss_data.rgb * cl1.sss_albedo; 986 # else 987 /* Add radiance that was supposed to be filtered but was rejected. */ 988 cl.radiance += (use_cl1) ? cl2.sss_data.rgb : cl1.sss_data.rgb; 989 # endif 990 # endif 991 992 return cl; 993 } 994 995 Closure closure_add(Closure cl1, Closure cl2) 996 { 997 Closure cl = (cl1.ssr_id == outputSsrId) ? cl1 : cl2; 998 cl.radiance = cl1.radiance + cl2.radiance; 999 # ifdef USE_SSS 1000 cl.sss_data = (cl1.sss_data.a > 0.0) ? cl1.sss_data : cl2.sss_data; 1001 /* Add radiance that was supposed to be filtered but was rejected. */ 1002 cl.radiance += (cl1.sss_data.a > 0.0) ? cl2.sss_data.rgb : cl1.sss_data.rgb; 1003 # ifdef USE_SSS_ALBEDO 1004 /* TODO Find a solution to this. Dither? */ 1005 cl.sss_albedo = (cl1.sss_data.a > 0.0) ? cl1.sss_albedo : cl2.sss_albedo; 1006 # endif 1007 # endif 1008 cl.opacity = saturate(cl1.opacity + cl2.opacity); 1009 return cl; 1010 } 1011 1012 Closure closure_emission(vec3 rgb) 1013 { 1014 Closure cl = CLOSURE_DEFAULT; 1015 cl.radiance = rgb; 1016 return cl; 1017 } 1018 1019 /* Breaking this across multiple lines causes issues for some older GLSL compilers. */ 1020 /* clang-format off */ 1021 # if defined(MESH_SHADER) && !defined(USE_ALPHA_HASH) && !defined(USE_ALPHA_CLIP) && !defined(SHADOW_SHADER) && !defined(USE_MULTIPLY ) 1022 /* clang-format on */ 1023 layout(location = 0) out vec4 fragColor; 1024 layout(location = 1) out vec4 ssrNormals; 1025 layout(location = 2) out vec4 ssrData; 1026 # ifdef USE_SSS 1027 layout(location = 3) out vec4 sssData; 1028 # ifdef USE_SSS_ALBEDO 1029 layout(location = 4) out vec4 sssAlbedo; 1030 # endif /* USE_SSS_ALBEDO */ 1031 # endif /* USE_SSS */ 1032 1033 Closure nodetree_exec(void); /* Prototype */ 1034 1035 # if defined(USE_ALPHA_BLEND) 1036 /* Prototype because this file is included before volumetric_lib.glsl */ 1037 void volumetric_resolve(vec2 frag_uvs, 1038 float frag_depth, 1039 out vec3 transmittance, 1040 out vec3 scattering); 1041 # endif 1042 1043 # define NODETREE_EXEC 1044 void main() 1045 { 1046 Closure cl = nodetree_exec(); 1047 # ifndef USE_ALPHA_BLEND 1048 /* Prevent alpha hash material writing into alpha channel. */ 1049 cl.opacity = 1.0; 1050 # endif 1051 1052 # if defined(USE_ALPHA_BLEND) 1053 vec2 uvs = gl_FragCoord.xy * volCoordScale.zw; 1054 vec3 transmittance, scattering; 1055 volumetric_resolve(uvs, gl_FragCoord.z, transmittance, scattering); 1056 fragColor.rgb = cl.radiance * transmittance + scattering; 1057 fragColor.a = cl.opacity; 1058 # else 1059 fragColor = vec4(cl.radiance, cl.opacity); 1060 # endif 1061 1062 ssrNormals = cl.ssr_normal.xyyy; 1063 ssrData = cl.ssr_data; 1064 # ifdef USE_SSS 1065 sssData = cl.sss_data; 1066 # ifdef USE_SSS_ALBEDO 1067 sssAlbedo = cl.sss_albedo.rgbb; 1068 # endif 1069 # endif 1070 1071 /* For Probe capture */ 1072 # ifdef USE_SSS 1073 float fac = float(!sssToggle); 1074 1075 # ifdef USE_REFRACTION 1076 /* SSRefraction pass is done after the SSS pass. 1077 * In order to not loose the diffuse light totally we 1078 * need to merge the SSS radiance to the main radiance. */ 1079 fac = 1.0; 1080 # endif 1081 1082 # ifdef USE_SSS_ALBEDO 1083 fragColor.rgb += cl.sss_data.rgb * cl.sss_albedo.rgb * fac; 1084 # else 1085 fragColor.rgb += cl.sss_data.rgb * fac; 1086 # endif 1087 # endif 1088 } 1089 1090 # endif /* MESH_SHADER && !SHADOW_SHADER */ 1091 1092 #endif /* VOLUMETRICS */ 1093 1094 Closure nodetree_exec(void); /* Prototype */ 1095 1096 /* TODO find a better place */ 1097 #ifdef USE_MULTIPLY 1098 1099 out vec4 fragColor; 1100 1101 # define NODETREE_EXEC 1102 void main() 1103 { 1104 Closure cl = nodetree_exec(); 1105 fragColor = vec4(mix(vec3(1.0), cl.radiance, cl.opacity), 1.0); 1106 } 1107 #endif 1108 1109 vec2 mapping_octahedron(vec3 cubevec, vec2 texel_size) 1110 { 1111 /* projection onto octahedron */ 1112 cubevec /= dot(vec3(1.0), abs(cubevec)); 1113 1114 /* out-folding of the downward faces */ 1115 if (cubevec.z < 0.0) { 1116 vec2 cubevec_sign = step(0.0, cubevec.xy) * 2.0 - 1.0; 1117 cubevec.xy = (1.0 - abs(cubevec.yx)) * cubevec_sign; 1118 } 1119 1120 /* mapping to [0;1]ˆ2 texture space */ 1121 vec2 uvs = cubevec.xy * (0.5) + 0.5; 1122 1123 /* edge filtering fix */ 1124 uvs = (1.0 - 2.0 * texel_size) * uvs + texel_size; 1125 1126 return uvs; 1127 } 1128 1129 vec4 textureLod_octahedron(sampler2DArray tex, vec4 cubevec, float lod, float lod_max) 1130 { 1131 vec2 texelSize = 1.0 / vec2(textureSize(tex, int(lod_max))); 1132 1133 vec2 uvs = mapping_octahedron(cubevec.xyz, texelSize); 1134 1135 return textureLod(tex, vec3(uvs, cubevec.w), lod); 1136 } 1137 1138 vec4 texture_octahedron(sampler2DArray tex, vec4 cubevec) 1139 { 1140 vec2 texelSize = 1.0 / vec2(textureSize(tex, 0)); 1141 1142 vec2 uvs = mapping_octahedron(cubevec.xyz, texelSize); 1143 1144 return texture(tex, vec3(uvs, cubevec.w)); 1145 } 1146 1147 uniform sampler2DArray irradianceGrid; 1148 1149 #define IRRADIANCE_LIB 1150 1151 #ifdef IRRADIANCE_CUBEMAP 1152 struct IrradianceData { 1153 vec3 color; 1154 }; 1155 #elif defined(IRRADIANCE_SH_L2) 1156 struct IrradianceData { 1157 vec3 shcoefs[9]; 1158 }; 1159 #else /* defined(IRRADIANCE_HL2) */ 1160 struct IrradianceData { 1161 vec3 cubesides[3]; 1162 }; 1163 #endif 1164 1165 IrradianceData load_irradiance_cell(int cell, vec3 N) 1166 { 1167 /* Keep in sync with diffuse_filter_probe() */ 1168 1169 #if defined(IRRADIANCE_CUBEMAP) 1170 1171 # define AMBIANT_CUBESIZE 8 1172 ivec2 cell_co = ivec2(AMBIANT_CUBESIZE); 1173 int cell_per_row = textureSize(irradianceGrid, 0).x / cell_co.x; 1174 cell_co.x *= cell % cell_per_row; 1175 cell_co.y *= cell / cell_per_row; 1176 1177 vec2 texelSize = 1.0 / vec2(AMBIANT_CUBESIZE); 1178 1179 vec2 uvs = mapping_octahedron(N, texelSize); 1180 uvs *= vec2(AMBIANT_CUBESIZE) / vec2(textureSize(irradianceGrid, 0)); 1181 uvs += vec2(cell_co) / vec2(textureSize(irradianceGrid, 0)); 1182 1183 IrradianceData ir; 1184 ir.color = texture(irradianceGrid, vec3(uvs, 0.0)).rgb; 1185 1186 #elif defined(IRRADIANCE_SH_L2) 1187 1188 ivec2 cell_co = ivec2(3, 3); 1189 int cell_per_row = textureSize(irradianceGrid, 0).x / cell_co.x; 1190 cell_co.x *= cell % cell_per_row; 1191 cell_co.y *= cell / cell_per_row; 1192 1193 ivec3 ofs = ivec3(0, 1, 2); 1194 1195 IrradianceData ir; 1196 ir.shcoefs[0] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.xx, 0), 0).rgb; 1197 ir.shcoefs[1] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.yx, 0), 0).rgb; 1198 ir.shcoefs[2] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.zx, 0), 0).rgb; 1199 ir.shcoefs[3] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.xy, 0), 0).rgb; 1200 ir.shcoefs[4] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.yy, 0), 0).rgb; 1201 ir.shcoefs[5] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.zy, 0), 0).rgb; 1202 ir.shcoefs[6] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.xz, 0), 0).rgb; 1203 ir.shcoefs[7] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.yz, 0), 0).rgb; 1204 ir.shcoefs[8] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.zz, 0), 0).rgb; 1205 1206 #else /* defined(IRRADIANCE_HL2) */ 1207 1208 ivec2 cell_co = ivec2(3, 2); 1209 int cell_per_row = textureSize(irradianceGrid, 0).x / cell_co.x; 1210 cell_co.x *= cell % cell_per_row; 1211 cell_co.y *= cell / cell_per_row; 1212 1213 ivec3 is_negative = ivec3(step(0.0, -N)); 1214 1215 IrradianceData ir; 1216 ir.cubesides[0] = irradiance_decode( 1217 texelFetch(irradianceGrid, ivec3(cell_co + ivec2(0, is_negative.x), 0), 0)); 1218 ir.cubesides[1] = irradiance_decode( 1219 texelFetch(irradianceGrid, ivec3(cell_co + ivec2(1, is_negative.y), 0), 0)); 1220 ir.cubesides[2] = irradiance_decode( 1221 texelFetch(irradianceGrid, ivec3(cell_co + ivec2(2, is_negative.z), 0), 0)); 1222 1223 #endif 1224 1225 return ir; 1226 } 1227 1228 float load_visibility_cell(int cell, vec3 L, float dist, float bias, float bleed_bias, float range) 1229 { 1230 /* Keep in sync with diffuse_filter_probe() */ 1231 ivec2 cell_co = ivec2(prbIrradianceVisSize); 1232 ivec2 cell_per_row_col = textureSize(irradianceGrid, 0).xy / prbIrradianceVisSize; 1233 cell_co.x *= (cell % cell_per_row_col.x); 1234 cell_co.y *= (cell / cell_per_row_col.x) % cell_per_row_col.y; 1235 float layer = 1.0 + float((cell / cell_per_row_col.x) / cell_per_row_col.y); 1236 1237 vec2 texel_size = 1.0 / vec2(textureSize(irradianceGrid, 0).xy); 1238 vec2 co = vec2(cell_co) * texel_size; 1239 1240 vec2 uv = mapping_octahedron(-L, vec2(1.0 / float(prbIrradianceVisSize))); 1241 uv *= vec2(prbIrradianceVisSize) * texel_size; 1242 1243 vec4 data = texture(irradianceGrid, vec3(co + uv, layer)); 1244 1245 /* Decoding compressed data */ 1246 vec2 moments = visibility_decode(data, range); 1247 1248 /* Doing chebishev test */ 1249 float variance = abs(moments.x * moments.x - moments.y); 1250 variance = max(variance, bias / 10.0); 1251 1252 float d = dist - moments.x; 1253 float p_max = variance / (variance + d * d); 1254 1255 /* Increase contrast in the weight by squaring it */ 1256 p_max *= p_max; 1257 1258 /* Now reduce light-bleeding by removing the [0, x] tail and linearly rescaling (x, 1] */ 1259 p_max = clamp((p_max - bleed_bias) / (1.0 - bleed_bias), 0.0, 1.0); 1260 1261 return (dist <= moments.x) ? 1.0 : p_max; 1262 } 1263 1264 /* http://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/ */ 1265 vec3 spherical_harmonics_L1(vec3 N, vec3 shcoefs[4]) 1266 { 1267 vec3 sh = vec3(0.0); 1268 1269 sh += 0.282095 * shcoefs[0]; 1270 1271 sh += -0.488603 * N.z * shcoefs[1]; 1272 sh += 0.488603 * N.y * shcoefs[2]; 1273 sh += -0.488603 * N.x * shcoefs[3]; 1274 1275 return sh; 1276 } 1277 1278 vec3 spherical_harmonics_L2(vec3 N, vec3 shcoefs[9]) 1279 { 1280 vec3 sh = vec3(0.0); 1281 1282 sh += 0.282095 * shcoefs[0]; 1283 1284 sh += -0.488603 * N.z * shcoefs[1]; 1285 sh += 0.488603 * N.y * shcoefs[2]; 1286 sh += -0.488603 * N.x * shcoefs[3]; 1287 1288 sh += 1.092548 * N.x * N.z * shcoefs[4]; 1289 sh += -1.092548 * N.z * N.y * shcoefs[5]; 1290 sh += 0.315392 * (3.0 * N.y * N.y - 1.0) * shcoefs[6]; 1291 sh += -1.092548 * N.x * N.y * shcoefs[7]; 1292 sh += 0.546274 * (N.x * N.x - N.z * N.z) * shcoefs[8]; 1293 1294 return sh; 1295 } 1296 1297 vec3 hl2_basis(vec3 N, vec3 cubesides[3]) 1298 { 1299 vec3 irradiance = vec3(0.0); 1300 1301 vec3 n_squared = N * N; 1302 1303 irradiance += n_squared.x * cubesides[0]; 1304 irradiance += n_squared.y * cubesides[1]; 1305 irradiance += n_squared.z * cubesides[2]; 1306 1307 return irradiance; 1308 } 1309 1310 vec3 compute_irradiance(vec3 N, IrradianceData ird) 1311 { 1312 #if defined(IRRADIANCE_CUBEMAP) 1313 return ird.color; 1314 #elif defined(IRRADIANCE_SH_L2) 1315 return spherical_harmonics_L2(N, ird.shcoefs); 1316 #else /* defined(IRRADIANCE_HL2) */ 1317 return hl2_basis(N, ird.cubesides); 1318 #endif 1319 } 1320 1321 vec3 irradiance_from_cell_get(int cell, vec3 ir_dir) 1322 { 1323 IrradianceData ir_data = load_irradiance_cell(cell, ir_dir); 1324 return compute_irradiance(ir_dir, ir_data); 1325 } 1326 1327 uniform sampler2DArray shadowCubeTexture; 1328 uniform sampler2DArray shadowCascadeTexture; 1329 1330 #define LAMPS_LIB 1331 1332 layout(std140) uniform shadow_block 1333 { 1334 ShadowData shadows_data[MAX_SHADOW]; 1335 ShadowCubeData shadows_cube_data[MAX_SHADOW_CUBE]; 1336 ShadowCascadeData shadows_cascade_data[MAX_SHADOW_CASCADE]; 1337 }; 1338 1339 layout(std140) uniform light_block 1340 { 1341 LightData lights_data[MAX_LIGHT]; 1342 }; 1343 1344 /* type */ 1345 #define POINT 0.0 1346 #define SUN 1.0 1347 #define SPOT 2.0 1348 #define AREA_RECT 4.0 1349 /* Used to define the area light shape, doesn't directly correspond to a Blender light type. */ 1350 #define AREA_ELLIPSE 100.0 1351 1352 #if defined(SHADOW_VSM) 1353 # define ShadowSample vec2 1354 # define sample_cube(vec, id) texture_octahedron(shadowCubeTexture, vec4(vec, id)).rg 1355 # define sample_cascade(vec, id) texture(shadowCascadeTexture, vec3(vec, id)).rg 1356 #elif defined(SHADOW_ESM) 1357 # define ShadowSample float 1358 # define sample_cube(vec, id) texture_octahedron(shadowCubeTexture, vec4(vec, id)).r 1359 # define sample_cascade(vec, id) texture(shadowCascadeTexture, vec3(vec, id)).r 1360 #else 1361 # define ShadowSample float 1362 # define sample_cube(vec, id) texture_octahedron(shadowCubeTexture, vec4(vec, id)).r 1363 # define sample_cascade(vec, id) texture(shadowCascadeTexture, vec3(vec, id)).r 1364 #endif 1365 1366 #if defined(SHADOW_VSM) 1367 # define get_depth_delta(dist, s) (dist - s.x) 1368 #else 1369 # define get_depth_delta(dist, s) (dist - s) 1370 #endif 1371 1372 /* ----------------------------------------------------------- */ 1373 /* ----------------------- Shadow tests ---------------------- */ 1374 /* ----------------------------------------------------------- */ 1375 1376 #if defined(SHADOW_VSM) 1377 1378 float shadow_test(ShadowSample moments, float dist, ShadowData sd) 1379 { 1380 float p = 0.0; 1381 1382 if (dist <= moments.x) { 1383 p = 1.0; 1384 } 1385 1386 float variance = moments.y - (moments.x * moments.x); 1387 variance = max(variance, sd.sh_bias / 10.0); 1388 1389 float d = moments.x - dist; 1390 float p_max = variance / (variance + d * d); 1391 1392 /* Now reduce light-bleeding by removing the [0, x] tail and linearly rescaling (x, 1] */ 1393 p_max = clamp((p_max - sd.sh_bleed) / (1.0 - sd.sh_bleed), 0.0, 1.0); 1394 1395 return max(p, p_max); 1396 } 1397 1398 #elif defined(SHADOW_ESM) 1399 1400 float shadow_test(ShadowSample z, float dist, ShadowData sd) 1401 { 1402 return saturate(exp(sd.sh_exp * (z - dist + sd.sh_bias))); 1403 } 1404 1405 #else 1406 1407 float shadow_test(ShadowSample z, float dist, ShadowData sd) 1408 { 1409 return step(0, z - dist + sd.sh_bias); 1410 } 1411 1412 #endif 1413 1414 /* ----------------------------------------------------------- */ 1415 /* ----------------------- Shadow types ---------------------- */ 1416 /* ----------------------------------------------------------- */ 1417 1418 float shadow_cubemap(ShadowData sd, ShadowCubeData scd, float texid, vec3 W) 1419 { 1420 vec3 cubevec = W - scd.position.xyz; 1421 float dist = length(cubevec); 1422 1423 cubevec /= dist; 1424 1425 ShadowSample s = sample_cube(cubevec, texid); 1426 return shadow_test(s, dist, sd); 1427 } 1428 1429 float evaluate_cascade(ShadowData sd, mat4 shadowmat, vec3 W, float range, float texid) 1430 { 1431 vec4 shpos = shadowmat * vec4(W, 1.0); 1432 float dist = shpos.z * range; 1433 1434 ShadowSample s = sample_cascade(shpos.xy, texid); 1435 float vis = shadow_test(s, dist, sd); 1436 1437 /* If fragment is out of shadowmap range, do not occlude */ 1438 if (shpos.z < 1.0 && shpos.z > 0.0) { 1439 return vis; 1440 } 1441 else { 1442 return 1.0; 1443 } 1444 } 1445 1446 float shadow_cascade(ShadowData sd, int scd_id, float texid, vec3 W) 1447 { 1448 vec4 view_z = vec4(dot(W - cameraPos, cameraForward)); 1449 vec4 weights = smoothstep(shadows_cascade_data[scd_id].split_end_distances, 1450 shadows_cascade_data[scd_id].split_start_distances.yzwx, 1451 view_z); 1452 1453 weights.yzw -= weights.xyz; 1454 1455 vec4 vis = vec4(1.0); 1456 float range = abs(sd.sh_far - sd.sh_near); /* Same factor as in get_cascade_world_distance(). */ 1457 1458 /* Branching using (weights > 0.0) is reaally slooow on intel so avoid it for now. */ 1459 /* TODO OPTI: Only do 2 samples and blend. */ 1460 vis.x = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[0], W, range, texid + 0); 1461 vis.y = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[1], W, range, texid + 1); 1462 vis.z = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[2], W, range, texid + 2); 1463 vis.w = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[3], W, range, texid + 3); 1464 1465 float weight_sum = dot(vec4(1.0), weights); 1466 if (weight_sum > 0.9999) { 1467 float vis_sum = dot(vec4(1.0), vis * weights); 1468 return vis_sum / weight_sum; 1469 } 1470 else { 1471 float vis_sum = dot(vec4(1.0), vis * step(0.001, weights)); 1472 return mix(1.0, vis_sum, weight_sum); 1473 } 1474 } 1475 1476 /* ----------------------------------------------------------- */ 1477 /* --------------------- Light Functions --------------------- */ 1478 /* ----------------------------------------------------------- */ 1479 1480 /* From Frostbite PBR Course 1481 * Distance based attenuation 1482 * http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf */ 1483 float distance_attenuation(float dist_sqr, float inv_sqr_influence) 1484 { 1485 float factor = dist_sqr * inv_sqr_influence; 1486 float fac = saturate(1.0 - factor * factor); 1487 return fac * fac; 1488 } 1489 1490 float spot_attenuation(LightData ld, vec3 l_vector) 1491 { 1492 float z = dot(ld.l_forward, l_vector.xyz); 1493 vec3 lL = l_vector.xyz / z; 1494 float x = dot(ld.l_right, lL) / ld.l_sizex; 1495 float y = dot(ld.l_up, lL) / ld.l_sizey; 1496 float ellipse = inversesqrt(1.0 + x * x + y * y); 1497 float spotmask = smoothstep(0.0, 1.0, (ellipse - ld.l_spot_size) / ld.l_spot_blend); 1498 return spotmask; 1499 } 1500 1501 float light_visibility(LightData ld, 1502 vec3 W, 1503 #ifndef VOLUMETRICS 1504 vec3 viewPosition, 1505 vec3 vN, 1506 #endif 1507 vec4 l_vector) 1508 { 1509 float vis = 1.0; 1510 1511 if (ld.l_type == SPOT) { 1512 vis *= spot_attenuation(ld, l_vector.xyz); 1513 } 1514 if (ld.l_type >= SPOT) { 1515 vis *= step(0.0, -dot(l_vector.xyz, ld.l_forward)); 1516 } 1517 if (ld.l_type != SUN) { 1518 vis *= distance_attenuation(l_vector.w * l_vector.w, ld.l_influence); 1519 } 1520 1521 #if !defined(VOLUMETRICS) || defined(VOLUME_SHADOW) 1522 /* shadowing */ 1523 if (ld.l_shadowid >= 0.0 && vis > 0.001) { 1524 ShadowData data = shadows_data[int(ld.l_shadowid)]; 1525 1526 if (ld.l_type == SUN) { 1527 vis *= shadow_cascade(data, int(data.sh_data_start), data.sh_tex_start, W); 1528 } 1529 else { 1530 vis *= shadow_cubemap( 1531 data, shadows_cube_data[int(data.sh_data_start)], data.sh_tex_start, W); 1532 } 1533 1534 # ifndef VOLUMETRICS 1535 /* Only compute if not already in shadow. */ 1536 if (data.sh_contact_dist > 0.0) { 1537 vec4 L = (ld.l_type != SUN) ? l_vector : vec4(-ld.l_forward, 1.0); 1538 float trace_distance = (ld.l_type != SUN) ? min(data.sh_contact_dist, l_vector.w) : 1539 data.sh_contact_dist; 1540 1541 vec3 T, B; 1542 make_orthonormal_basis(L.xyz / L.w, T, B); 1543 1544 vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy); 1545 rand.zw *= fast_sqrt(rand.y) * data.sh_contact_spread; 1546 1547 /* We use the full l_vector.xyz so that the spread is minimize 1548 * if the shading point is further away from the light source */ 1549 vec3 ray_dir = L.xyz + T * rand.z + B * rand.w; 1550 ray_dir = transform_direction(ViewMatrix, ray_dir); 1551 ray_dir = normalize(ray_dir); 1552 1553 vec3 ray_ori = viewPosition; 1554 1555 /* Fix translucency shadowed by contact shadows. */ 1556 vN = (gl_FrontFacing) ? vN : -vN; 1557 1558 if (dot(vN, ray_dir) <= 0.0) { 1559 return vis; 1560 } 1561 1562 float bias = 0.5; /* Constant Bias */ 1563 bias += 1.0 - abs(dot(vN, ray_dir)); /* Angle dependent bias */ 1564 bias *= gl_FrontFacing ? data.sh_contact_offset : -data.sh_contact_offset; 1565 1566 vec3 nor_bias = vN * bias; 1567 ray_ori += nor_bias; 1568 1569 ray_dir *= trace_distance; 1570 ray_dir -= nor_bias; 1571 1572 vec3 hit_pos = raycast( 1573 -1, ray_ori, ray_dir, data.sh_contact_thickness, rand.x, 0.1, 0.001, false); 1574 1575 if (hit_pos.z > 0.0) { 1576 hit_pos = get_view_space_from_depth(hit_pos.xy, hit_pos.z); 1577 float hit_dist = distance(viewPosition, hit_pos); 1578 float dist_ratio = hit_dist / trace_distance; 1579 return vis * saturate(dist_ratio * dist_ratio * dist_ratio); 1580 } 1581 } 1582 # endif 1583 } 1584 #endif 1585 1586 return vis; 1587 } 1588 1589 #ifdef USE_LTC 1590 float light_diffuse(LightData ld, vec3 N, vec3 V, vec4 l_vector) 1591 { 1592 if (ld.l_type == AREA_RECT) { 1593 vec3 corners[4]; 1594 corners[0] = normalize((l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * ld.l_sizey); 1595 corners[1] = normalize((l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * -ld.l_sizey); 1596 corners[2] = normalize((l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * -ld.l_sizey); 1597 corners[3] = normalize((l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * ld.l_sizey); 1598 1599 return ltc_evaluate_quad(corners, N); 1600 } 1601 else if (ld.l_type == AREA_ELLIPSE) { 1602 vec3 points[3]; 1603 points[0] = (l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * -ld.l_sizey; 1604 points[1] = (l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * -ld.l_sizey; 1605 points[2] = (l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * ld.l_sizey; 1606 1607 return ltc_evaluate_disk(N, V, mat3(1.0), points); 1608 } 1609 else { 1610 float radius = ld.l_radius; 1611 radius /= (ld.l_type == SUN) ? 1.0 : l_vector.w; 1612 vec3 L = (ld.l_type == SUN) ? -ld.l_forward : (l_vector.xyz / l_vector.w); 1613 1614 return ltc_evaluate_disk_simple(radius, dot(N, L)); 1615 } 1616 } 1617 1618 float light_specular(LightData ld, vec4 ltc_mat, vec3 N, vec3 V, vec4 l_vector) 1619 { 1620 if (ld.l_type == AREA_RECT) { 1621 vec3 corners[4]; 1622 corners[0] = (l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * ld.l_sizey; 1623 corners[1] = (l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * -ld.l_sizey; 1624 corners[2] = (l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * -ld.l_sizey; 1625 corners[3] = (l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * ld.l_sizey; 1626 1627 ltc_transform_quad(N, V, ltc_matrix(ltc_mat), corners); 1628 1629 return ltc_evaluate_quad(corners, vec3(0.0, 0.0, 1.0)); 1630 } 1631 else { 1632 bool is_ellipse = (ld.l_type == AREA_ELLIPSE); 1633 float radius_x = is_ellipse ? ld.l_sizex : ld.l_radius; 1634 float radius_y = is_ellipse ? ld.l_sizey : ld.l_radius; 1635 1636 vec3 L = (ld.l_type == SUN) ? -ld.l_forward : l_vector.xyz; 1637 vec3 Px = ld.l_right; 1638 vec3 Py = ld.l_up; 1639 1640 if (ld.l_type == SPOT || ld.l_type == POINT) { 1641 make_orthonormal_basis(l_vector.xyz / l_vector.w, Px, Py); 1642 } 1643 1644 vec3 points[3]; 1645 points[0] = (L + Px * -radius_x) + Py * -radius_y; 1646 points[1] = (L + Px * radius_x) + Py * -radius_y; 1647 points[2] = (L + Px * radius_x) + Py * radius_y; 1648 1649 return ltc_evaluate_disk(N, V, ltc_matrix(ltc_mat), points); 1650 } 1651 } 1652 #endif 1653 1654 #define MAX_SSS_SAMPLES 65 1655 #define SSS_LUT_SIZE 64.0 1656 #define SSS_LUT_SCALE ((SSS_LUT_SIZE - 1.0) / float(SSS_LUT_SIZE)) 1657 #define SSS_LUT_BIAS (0.5 / float(SSS_LUT_SIZE)) 1658 1659 #ifdef USE_TRANSLUCENCY 1660 layout(std140) uniform sssProfile 1661 { 1662 vec4 kernel[MAX_SSS_SAMPLES]; 1663 vec4 radii_max_radius; 1664 int sss_samples; 1665 }; 1666 1667 uniform sampler1D sssTexProfile; 1668 1669 vec3 sss_profile(float s) 1670 { 1671 s /= radii_max_radius.w; 1672 return texture(sssTexProfile, saturate(s) * SSS_LUT_SCALE + SSS_LUT_BIAS).rgb; 1673 } 1674 #endif 1675 1676 vec3 light_translucent(LightData ld, vec3 W, vec3 N, vec4 l_vector, float scale) 1677 { 1678 #if !defined(USE_TRANSLUCENCY) || defined(VOLUMETRICS) 1679 return vec3(0.0); 1680 #else 1681 vec3 vis = vec3(1.0); 1682 1683 if (ld.l_type == SPOT) { 1684 vis *= spot_attenuation(ld, l_vector.xyz); 1685 } 1686 if (ld.l_type >= SPOT) { 1687 vis *= step(0.0, -dot(l_vector.xyz, ld.l_forward)); 1688 } 1689 if (ld.l_type != SUN) { 1690 vis *= distance_attenuation(l_vector.w * l_vector.w, ld.l_influence); 1691 } 1692 1693 /* Only shadowed light can produce translucency */ 1694 if (ld.l_shadowid >= 0.0 && vis.x > 0.001) { 1695 ShadowData data = shadows_data[int(ld.l_shadowid)]; 1696 float delta; 1697 1698 vec4 L = (ld.l_type != SUN) ? l_vector : vec4(-ld.l_forward, 1.0); 1699 1700 vec3 T, B; 1701 make_orthonormal_basis(L.xyz / L.w, T, B); 1702 1703 vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy); 1704 rand.zw *= fast_sqrt(rand.y) * data.sh_blur; 1705 1706 /* We use the full l_vector.xyz so that the spread is minimize 1707 * if the shading point is further away from the light source */ 1708 W = W + T * rand.z + B * rand.w; 1709 1710 if (ld.l_type == SUN) { 1711 int scd_id = int(data.sh_data_start); 1712 vec4 view_z = vec4(dot(W - cameraPos, cameraForward)); 1713 1714 vec4 weights = step(shadows_cascade_data[scd_id].split_end_distances, view_z); 1715 float id = abs(4.0 - dot(weights, weights)); 1716 1717 if (id > 3.0) { 1718 return vec3(0.0); 1719 } 1720 1721 float range = abs(data.sh_far - 1722 data.sh_near); /* Same factor as in get_cascade_world_distance(). */ 1723 1724 vec4 shpos = shadows_cascade_data[scd_id].shadowmat[int(id)] * vec4(W, 1.0); 1725 float dist = shpos.z * range; 1726 1727 if (shpos.z > 1.0 || shpos.z < 0.0) { 1728 return vec3(0.0); 1729 } 1730 1731 ShadowSample s = sample_cascade(shpos.xy, data.sh_tex_start + id); 1732 delta = get_depth_delta(dist, s); 1733 } 1734 else { 1735 vec3 cubevec = W - shadows_cube_data[int(data.sh_data_start)].position.xyz; 1736 float dist = length(cubevec); 1737 cubevec /= dist; 1738 1739 ShadowSample s = sample_cube(cubevec, data.sh_tex_start); 1740 delta = get_depth_delta(dist, s); 1741 } 1742 1743 /* XXX : Removing Area Power. */ 1744 /* TODO : put this out of the shader. */ 1745 float falloff; 1746 if (ld.l_type == AREA_RECT || ld.l_type == AREA_ELLIPSE) { 1747 vis *= (ld.l_sizex * ld.l_sizey * 4.0 * M_PI) * (1.0 / 80.0); 1748 if (ld.l_type == AREA_ELLIPSE) { 1749 vis *= M_PI * 0.25; 1750 } 1751 vis *= 0.3 * 20.0 * 1752 max(0.0, dot(-ld.l_forward, l_vector.xyz / l_vector.w)); /* XXX ad hoc, empirical */ 1753 vis /= (l_vector.w * l_vector.w); 1754 falloff = dot(N, l_vector.xyz / l_vector.w); 1755 } 1756 else if (ld.l_type == SUN) { 1757 vis /= 1.0f + (ld.l_radius * ld.l_radius * 0.5f); 1758 vis *= ld.l_radius * ld.l_radius * M_PI; /* Removing area light power*/ 1759 vis *= M_2PI * 0.78; /* Matching cycles with point light. */ 1760 vis *= 0.082; /* XXX ad hoc, empirical */ 1761 falloff = dot(N, -ld.l_forward); 1762 } 1763 else { 1764 vis *= (4.0 * ld.l_radius * ld.l_radius) * (1.0 / 10.0); 1765 vis *= 1.5; /* XXX ad hoc, empirical */ 1766 vis /= (l_vector.w * l_vector.w); 1767 falloff = dot(N, l_vector.xyz / l_vector.w); 1768 } 1769 // vis *= M_1_PI; /* Normalize */ 1770 1771 /* Applying profile */ 1772 vis *= sss_profile(abs(delta) / scale); 1773 1774 /* No transmittance at grazing angle (hide artifacts) */ 1775 vis *= saturate(falloff * 2.0); 1776 } 1777 else { 1778 vis = vec3(0.0); 1779 } 1780 1781 return vis; 1782 #endif 1783 } 1784 1785 /* Based on Frosbite Unified Volumetric. 1786 * https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */ 1787 1788 /* Volume slice to view space depth. */ 1789 float volume_z_to_view_z(float z) 1790 { 1791 if (ProjectionMatrix[3][3] == 0.0) { 1792 /* Exponential distribution */ 1793 return (exp2(z / volDepthParameters.z) - volDepthParameters.x) / volDepthParameters.y; 1794 } 1795 else { 1796 /* Linear distribution */ 1797 return mix(volDepthParameters.x, volDepthParameters.y, z); 1798 } 1799 } 1800 1801 float view_z_to_volume_z(float depth) 1802 { 1803 if (ProjectionMatrix[3][3] == 0.0) { 1804 /* Exponential distribution */ 1805 return volDepthParameters.z * log2(depth * volDepthParameters.y + volDepthParameters.x); 1806 } 1807 else { 1808 /* Linear distribution */ 1809 return (depth - volDepthParameters.x) * volDepthParameters.z; 1810 } 1811 } 1812 1813 /* Volume texture normalized coordinates to NDC (special range [0, 1]). */ 1814 vec3 volume_to_ndc(vec3 cos) 1815 { 1816 cos.z = volume_z_to_view_z(cos.z); 1817 cos.z = get_depth_from_view_z(cos.z); 1818 cos.xy /= volCoordScale.xy; 1819 return cos; 1820 } 1821 1822 vec3 ndc_to_volume(vec3 cos) 1823 { 1824 cos.z = get_view_z_from_depth(cos.z); 1825 cos.z = view_z_to_volume_z(cos.z); 1826 cos.xy *= volCoordScale.xy; 1827 return cos; 1828 } 1829 1830 float phase_function_isotropic() 1831 { 1832 return 1.0 / (4.0 * M_PI); 1833 } 1834 1835 float phase_function(vec3 v, vec3 l, float g) 1836 { 1837 /* Henyey-Greenstein */ 1838 float cos_theta = dot(v, l); 1839 g = clamp(g, -1.0 + 1e-3, 1.0 - 1e-3); 1840 float sqr_g = g * g; 1841 return (1 - sqr_g) / max(1e-8, 4.0 * M_PI * pow(1 + sqr_g - 2 * g * cos_theta, 3.0 / 2.0)); 1842 } 1843 1844 #ifdef LAMPS_LIB 1845 vec3 light_volume(LightData ld, vec4 l_vector) 1846 { 1847 float power; 1848 /* TODO : Area lighting ? */ 1849 /* XXX : Removing Area Power. */ 1850 /* TODO : put this out of the shader. */ 1851 /* See eevee_light_setup(). */ 1852 if (ld.l_type == AREA_RECT || ld.l_type == AREA_ELLIPSE) { 1853 power = (ld.l_sizex * ld.l_sizey * 4.0 * M_PI) * (1.0 / 80.0); 1854 if (ld.l_type == AREA_ELLIPSE) { 1855 power *= M_PI * 0.25; 1856 } 1857 power *= 20.0 * 1858 max(0.0, dot(-ld.l_forward, l_vector.xyz / l_vector.w)); /* XXX ad hoc, empirical */ 1859 } 1860 else if (ld.l_type == SUN) { 1861 power = ld.l_radius * ld.l_radius * M_PI; /* Removing area light power*/ 1862 power /= 1.0f + (ld.l_radius * ld.l_radius * 0.5f); 1863 power *= M_PI * 0.5; /* Matching cycles. */ 1864 } 1865 else { 1866 power = (4.0 * ld.l_radius * ld.l_radius) * (1.0 / 10.0); 1867 power *= M_2PI; /* Matching cycles with point light. */ 1868 } 1869 1870 power /= (l_vector.w * l_vector.w); 1871 1872 /* OPTI: find a better way than calculating this on the fly */ 1873 float lum = dot(ld.l_color, vec3(0.3, 0.6, 0.1)); /* luminance approx. */ 1874 vec3 tint = (lum > 0.0) ? ld.l_color / lum : vec3(1.0); /* normalize lum. to isolate hue+sat */ 1875 1876 lum = min(lum * power, volLightClamp); 1877 1878 return tint * lum; 1879 } 1880 1881 # define VOLUMETRIC_SHADOW_MAX_STEP 32.0 1882 1883 vec3 participating_media_extinction(vec3 wpos, sampler3D volume_extinction) 1884 { 1885 /* Waiting for proper volume shadowmaps and out of frustum shadow map. */ 1886 vec3 ndc = project_point(ViewProjectionMatrix, wpos); 1887 vec3 volume_co = ndc_to_volume(ndc * 0.5 + 0.5); 1888 1889 /* Let the texture be clamped to edge. This reduce visual glitches. */ 1890 return texture(volume_extinction, volume_co).rgb; 1891 } 1892 1893 vec3 light_volume_shadow(LightData ld, vec3 ray_wpos, vec4 l_vector, sampler3D volume_extinction) 1894 { 1895 # if defined(VOLUME_SHADOW) 1896 /* Heterogeneous volume shadows */ 1897 float dd = l_vector.w / volShadowSteps; 1898 vec3 L = l_vector.xyz * l_vector.w; 1899 vec3 shadow = vec3(1.0); 1900 for (float s = 0.5; s < VOLUMETRIC_SHADOW_MAX_STEP && s < (volShadowSteps - 0.1); s += 1.0) { 1901 vec3 pos = ray_wpos + L * (s / volShadowSteps); 1902 vec3 s_extinction = participating_media_extinction(pos, volume_extinction); 1903 shadow *= exp(-s_extinction * dd); 1904 } 1905 return shadow; 1906 # else 1907 return vec3(1.0); 1908 # endif /* VOLUME_SHADOW */ 1909 } 1910 #endif 1911 1912 #ifdef IRRADIANCE_LIB 1913 vec3 irradiance_volumetric(vec3 wpos) 1914 { 1915 # ifdef IRRADIANCE_HL2 1916 IrradianceData ir_data = load_irradiance_cell(0, vec3(1.0)); 1917 vec3 irradiance = ir_data.cubesides[0] + ir_data.cubesides[1] + ir_data.cubesides[2]; 1918 ir_data = load_irradiance_cell(0, vec3(-1.0)); 1919 irradiance += ir_data.cubesides[0] + ir_data.cubesides[1] + ir_data.cubesides[2]; 1920 irradiance *= 0.16666666; /* 1/6 */ 1921 return irradiance; 1922 # else 1923 return vec3(0.0); 1924 # endif 1925 } 1926 #endif 1927 1928 uniform sampler3D inScattering; 1929 uniform sampler3D inTransmittance; 1930 1931 void volumetric_resolve(vec2 frag_uvs, 1932 float frag_depth, 1933 out vec3 transmittance, 1934 out vec3 scattering) 1935 { 1936 vec3 volume_cos = ndc_to_volume(vec3(frag_uvs, frag_depth)); 1937 1938 scattering = texture(inScattering, volume_cos).rgb; 1939 transmittance = texture(inTransmittance, volume_cos).rgb; 1940 } 1941 1942 #ifdef MESH_SHADER 1943 /* TODO tight slices */ 1944 layout(triangles) in; 1945 layout(triangle_strip, max_vertices = 3) out; 1946 #else /* World */ 1947 layout(triangles) in; 1948 layout(triangle_strip, max_vertices = 3) out; 1949 #endif 1950 1951 in vec4 vPos[]; 1952 1953 flat out int slice; 1954 1955 #ifdef MESH_SHADER 1956 /* TODO tight slices */ 1957 void main() 1958 { 1959 gl_Layer = slice = int(vPos[0].z); 1960 1961 # ifdef USE_ATTR 1962 pass_attr(0); 1963 # endif 1964 gl_Position = vPos[0].xyww; 1965 EmitVertex(); 1966 1967 # ifdef USE_ATTR 1968 pass_attr(1); 1969 # endif 1970 gl_Position = vPos[1].xyww; 1971 EmitVertex(); 1972 1973 # ifdef USE_ATTR 1974 pass_attr(2); 1975 # endif 1976 gl_Position = vPos[2].xyww; 1977 EmitVertex(); 1978 1979 EndPrimitive(); 1980 } 1981 1982 #else /* World */ 1983 1984 /* This is just a pass-through geometry shader that send the geometry 1985 * to the layer corresponding to it's depth. */ 1986 1987 void main() 1988 { 1989 gl_Layer = slice = int(vPos[0].z); 1990 1991 # ifdef USE_ATTR 1992 pass_attr(0); 1993 # endif 1994 gl_Position = vPos[0].xyww; 1995 EmitVertex(); 1996 1997 # ifdef USE_ATTR 1998 pass_attr(1); 1999 # endif 2000 gl_Position = vPos[1].xyww; 2001 EmitVertex(); 2002 2003 # ifdef USE_ATTR 2004 pass_attr(2); 2005 # endif 2006 gl_Position = vPos[2].xyww; 2007 EmitVertex(); 2008 2009 EndPrimitive(); 2010 } 2011 2012 #endif Number of Geometry Uniforms exceeds HW limits. GPUShader: linking error: ===== shader string 1 ==== 1 #define COMMON_VIEW_LIB 2 3 /* keep in sync with DRWManager.view_data */ 4 layout(std140) uniform viewBlock 5 { 6 /* Same order as DRWViewportMatrixType */ 7 mat4 ViewProjectionMatrix; 8 mat4 ViewProjectionMatrixInverse; 9 mat4 ViewMatrix; 10 mat4 ViewMatrixInverse; 11 mat4 ProjectionMatrix; 12 mat4 ProjectionMatrixInverse; 13 14 vec4 clipPlanes[6]; 15 16 /* TODO move it elsewhere. */ 17 vec4 CameraTexCoFactors; 18 }; 19 20 #ifdef world_clip_planes_calc_clip_distance 21 # undef world_clip_planes_calc_clip_distance 22 # define world_clip_planes_calc_clip_distance(p) \ 23 _world_clip_planes_calc_clip_distance(p, clipPlanes) 24 #endif 25 26 uniform mat4 ModelMatrix; 27 uniform mat4 ModelMatrixInverse; 28 29 /** Transform shortcuts. */ 30 /* Rule of thumb: Try to reuse world positions and normals because converting though viewspace 31 * will always be decomposed in at least 2 matrix operation. */ 32 33 /** 34 * Some clarification: 35 * Usually Normal matrix is transpose(inverse(ViewMatrix * ModelMatrix)) 36 * 37 * But since it is slow to multiply matrices we decompose it. Decomposing 38 * inversion and transposition both invert the product order leaving us with 39 * the same original order: 40 * transpose(ViewMatrixInverse) * transpose(ModelMatrixInverse) 41 * 42 * Knowing that the view matrix is orthogonal, the transpose is also the inverse. 43 * Note: This is only valid because we are only using the mat3 of the ViewMatrixInverse. 44 * ViewMatrix * transpose(ModelMatrixInverse) 45 **/ 46 #define normal_object_to_view(n) (mat3(ViewMatrix) * (transpose(mat3(ModelMatrixInverse)) * n)) 47 #define normal_object_to_world(n) (transpose(mat3(ModelMatrixInverse)) * n) 48 #define normal_world_to_object(n) (transpose(mat3(ModelMatrix)) * n) 49 #define normal_world_to_view(n) (mat3(ViewMatrix) * n) 50 51 #define point_object_to_ndc(p) (ViewProjectionMatrix * vec4((ModelMatrix * vec4(p, 1.0)).xyz, 1.0)) 52 #define point_object_to_view(p) ((ViewMatrix * vec4((ModelMatrix * vec4(p, 1.0)).xyz, 1.0)).xyz) 53 #define point_object_to_world(p) ((ModelMatrix * vec4(p, 1.0)).xyz) 54 #define point_view_to_ndc(p) (ProjectionMatrix * vec4(p, 1.0)) 55 #define point_view_to_object(p) ((ModelMatrixInverse * (ViewMatrixInverse * vec4(p, 1.0))).xyz) 56 #define point_view_to_world(p) ((ViewMatrixInverse * vec4(p, 1.0)).xyz) 57 #define point_world_to_ndc(p) (ViewProjectionMatrix * vec4(p, 1.0)) 58 #define point_world_to_object(p) ((ModelMatrixInverse * vec4(p, 1.0)).xyz) 59 #define point_world_to_view(p) ((ViewMatrix * vec4(p, 1.0)).xyz) 60 61 /* Due to some shader compiler bug, we somewhat need to access gl_VertexID 62 * to make vertex shaders work. even if it's actually dead code. */ 63 #ifdef GPU_INTEL 64 # define GPU_INTEL_VERTEX_SHADER_WORKAROUND gl_Position.x = float(gl_VertexID); 65 #else 66 # define GPU_INTEL_VERTEX_SHADER_WORKAROUND 67 #endif 68 69 layout(std140) uniform common_block 70 { 71 mat4 pastViewProjectionMatrix; 72 vec4 viewVecs[2]; 73 vec2 mipRatio[10]; /* To correct mip level texel mis-alignement */ 74 /* Ambient Occlusion */ 75 vec4 aoParameters[2]; 76 /* Volumetric */ 77 ivec4 volTexSize; 78 vec4 volDepthParameters; /* Parameters to the volume Z equation */ 79 vec4 volInvTexSize; 80 vec4 volJitter; 81 vec4 volCoordScale; /* To convert volume uvs to screen uvs */ 82 float volHistoryAlpha; 83 float volLightClamp; 84 float volShadowSteps; 85 bool volUseLights; 86 /* Screen Space Reflections */ 87 vec4 ssrParameters; 88 float ssrBorderFac; 89 float ssrMaxRoughness; 90 float ssrFireflyFac; 91 float ssrBrdfBias; 92 bool ssrToggle; 93 bool ssrefractToggle; 94 /* SubSurface Scattering */ 95 float sssJitterThreshold; 96 bool sssToggle; 97 /* Specular */ 98 bool specToggle; 99 /* Lights */ 100 int laNumLight; 101 /* Probes */ 102 int prbNumPlanar; 103 int prbNumRenderCube; 104 int prbNumRenderGrid; 105 int prbIrradianceVisSize; 106 float prbIrradianceSmooth; 107 float prbLodCubeMax; 108 float prbLodPlanarMax; 109 /* Misc*/ 110 int hizMipOffset; 111 int rayType; 112 float rayDepth; 113 }; 114 115 /* rayType (keep in sync with ray_type) */ 116 #define EEVEE_RAY_CAMERA 0 117 #define EEVEE_RAY_SHADOW 1 118 #define EEVEE_RAY_DIFFUSE 2 119 #define EEVEE_RAY_GLOSSY 3 120 121 /* aoParameters */ 122 #define aoDistance aoParameters[0].x 123 #define aoSamples aoParameters[0].y /* UNUSED */ 124 #define aoFactor aoParameters[0].z 125 #define aoInvSamples aoParameters[0].w /* UNUSED */ 126 127 #define aoOffset aoParameters[1].x /* UNUSED */ 128 #define aoBounceFac aoParameters[1].y 129 #define aoQuality aoParameters[1].z 130 #define aoSettings aoParameters[1].w 131 132 /* ssrParameters */ 133 #define ssrQuality ssrParameters.x 134 #define ssrThickness ssrParameters.y 135 #define ssrPixelSize ssrParameters.zw 136 137 #define M_PI 3.14159265358979323846 /* pi */ 138 #define M_2PI 6.28318530717958647692 /* 2*pi */ 139 #define M_PI_2 1.57079632679489661923 /* pi/2 */ 140 #define M_1_PI 0.318309886183790671538 /* 1/pi */ 141 #define M_1_2PI 0.159154943091895335768 /* 1/(2*pi) */ 142 #define M_1_PI2 0.101321183642337771443 /* 1/(pi^2) */ 143 144 #define LUT_SIZE 64 145 146 /* Buffers */ 147 uniform sampler2D colorBuffer; 148 uniform sampler2D depthBuffer; 149 uniform sampler2D maxzBuffer; 150 uniform sampler2D minzBuffer; 151 uniform sampler2DArray planarDepth; 152 153 #define cameraForward ViewMatrixInverse[2].xyz 154 #define cameraPos ViewMatrixInverse[3].xyz 155 #define cameraVec \ 156 ((ProjectionMatrix[3][3] == 0.0) ? normalize(cameraPos - worldPosition) : cameraForward) 157 #define viewCameraVec \ 158 ((ProjectionMatrix[3][3] == 0.0) ? normalize(-viewPosition) : vec3(0.0, 0.0, 1.0)) 159 160 /* ------- Structures -------- */ 161 162 /* ------ Lights ----- */ 163 struct LightData { 164 vec4 position_influence; /* w : InfluenceRadius (inversed and squared) */ 165 vec4 color_spec; /* w : Spec Intensity */ 166 vec4 spotdata_radius_shadow; /* x : spot size, y : spot blend, z : radius, w: shadow id */ 167 vec4 rightvec_sizex; /* xyz: Normalized up vector, w: area size X or spot scale X */ 168 vec4 upvec_sizey; /* xyz: Normalized right vector, w: area size Y or spot scale Y */ 169 vec4 forwardvec_type; /* xyz: Normalized forward vector, w: Light Type */ 170 }; 171 172 /* convenience aliases */ 173 #define l_color color_spec.rgb 174 #define l_spec color_spec.a 175 #define l_position position_influence.xyz 176 #define l_influence position_influence.w 177 #define l_sizex rightvec_sizex.w 178 #define l_sizey upvec_sizey.w 179 #define l_right rightvec_sizex.xyz 180 #define l_up upvec_sizey.xyz 181 #define l_forward forwardvec_type.xyz 182 #define l_type forwardvec_type.w 183 #define l_spot_size spotdata_radius_shadow.x 184 #define l_spot_blend spotdata_radius_shadow.y 185 #define l_radius spotdata_radius_shadow.z 186 #define l_shadowid spotdata_radius_shadow.w 187 188 /* ------ Shadows ----- */ 189 #ifndef MAX_CASCADE_NUM 190 # define MAX_CASCADE_NUM 4 191 #endif 192 193 struct ShadowData { 194 vec4 near_far_bias_exp; 195 vec4 shadow_data_start_end; 196 vec4 contact_shadow_data; 197 }; 198 199 struct ShadowCubeData { 200 vec4 position; 201 }; 202 203 struct ShadowCascadeData { 204 mat4 shadowmat[MAX_CASCADE_NUM]; 205 vec4 split_start_distances; 206 vec4 split_end_distances; 207 }; 208 209 /* convenience aliases */ 210 #define sh_near near_far_bias_exp.x 211 #define sh_far near_far_bias_exp.y 212 #define sh_bias near_far_bias_exp.z 213 #define sh_exp near_far_bias_exp.w 214 #define sh_bleed near_far_bias_exp.w 215 #define sh_tex_start shadow_data_start_end.x 216 #define sh_data_start shadow_data_start_end.y 217 #define sh_multi_nbr shadow_data_start_end.z 218 #define sh_blur shadow_data_start_end.w 219 #define sh_contact_dist contact_shadow_data.x 220 #define sh_contact_offset contact_shadow_data.y 221 #define sh_contact_spread contact_shadow_data.z 222 #define sh_contact_thickness contact_shadow_data.w 223 224 /* ------- Convenience functions --------- */ 225 226 vec3 mul(mat3 m, vec3 v) 227 { 228 return m * v; 229 } 230 mat3 mul(mat3 m1, mat3 m2) 231 { 232 return m1 * m2; 233 } 234 vec3 transform_direction(mat4 m, vec3 v) 235 { 236 return mat3(m) * v; 237 } 238 vec3 transform_point(mat4 m, vec3 v) 239 { 240 return (m * vec4(v, 1.0)).xyz; 241 } 242 vec3 project_point(mat4 m, vec3 v) 243 { 244 vec4 tmp = m * vec4(v, 1.0); 245 return tmp.xyz / tmp.w; 246 } 247 248 #define min3(a, b, c) min(a, min(b, c)) 249 #define min4(a, b, c, d) min(a, min3(b, c, d)) 250 #define min5(a, b, c, d, e) min(a, min4(b, c, d, e)) 251 #define min6(a, b, c, d, e, f) min(a, min5(b, c, d, e, f)) 252 #define min7(a, b, c, d, e, f, g) min(a, min6(b, c, d, e, f, g)) 253 #define min8(a, b, c, d, e, f, g, h) min(a, min7(b, c, d, e, f, g, h)) 254 #define min9(a, b, c, d, e, f, g, h, i) min(a, min8(b, c, d, e, f, g, h, i)) 255 256 #define max3(a, b, c) max(a, max(b, c)) 257 #define max4(a, b, c, d) max(a, max3(b, c, d)) 258 #define max5(a, b, c, d, e) max(a, max4(b, c, d, e)) 259 #define max6(a, b, c, d, e, f) max(a, max5(b, c, d, e, f)) 260 #define max7(a, b, c, d, e, f, g) max(a, max6(b, c, d, e, f, g)) 261 #define max8(a, b, c, d, e, f, g, h) max(a, max7(b, c, d, e, f, g, h)) 262 #define max9(a, b, c, d, e, f, g, h, i) max(a, max8(b, c, d, e, f, g, h, i)) 263 264 #define avg3(a, b, c) (a + b + c) * (1.0 / 3.0) 265 #define avg4(a, b, c, d) (a + b + c + d) * (1.0 / 4.0) 266 #define avg5(a, b, c, d, e) (a + b + c + d + e) * (1.0 / 5.0) 267 #define avg6(a, b, c, d, e, f) (a + b + c + d + e + f) * (1.0 / 6.0) 268 #define avg7(a, b, c, d, e, f, g) (a + b + c + d + e + f + g) * (1.0 / 7.0) 269 #define avg8(a, b, c, d, e, f, g, h) (a + b + c + d + e + f + g + h) * (1.0 / 8.0) 270 #define avg9(a, b, c, d, e, f, g, h, i) (a + b + c + d + e + f + g + h + i) * (1.0 / 9.0) 271 272 float min_v2(vec2 v) 273 { 274 return min(v.x, v.y); 275 } 276 float min_v3(vec3 v) 277 { 278 return min(v.x, min(v.y, v.z)); 279 } 280 float max_v2(vec2 v) 281 { 282 return max(v.x, v.y); 283 } 284 float max_v3(vec3 v) 285 { 286 return max(v.x, max(v.y, v.z)); 287 } 288 289 float sum(vec2 v) 290 { 291 return dot(vec2(1.0), v); 292 } 293 float sum(vec3 v) 294 { 295 return dot(vec3(1.0), v); 296 } 297 float sum(vec4 v) 298 { 299 return dot(vec4(1.0), v); 300 } 301 302 float saturate(float a) 303 { 304 return clamp(a, 0.0, 1.0); 305 } 306 vec2 saturate(vec2 a) 307 { 308 return clamp(a, 0.0, 1.0); 309 } 310 vec3 saturate(vec3 a) 311 { 312 return clamp(a, 0.0, 1.0); 313 } 314 vec4 saturate(vec4 a) 315 { 316 return clamp(a, 0.0, 1.0); 317 } 318 319 float distance_squared(vec2 a, vec2 b) 320 { 321 a -= b; 322 return dot(a, a); 323 } 324 float distance_squared(vec3 a, vec3 b) 325 { 326 a -= b; 327 return dot(a, a); 328 } 329 float len_squared(vec3 a) 330 { 331 return dot(a, a); 332 } 333 334 float inverse_distance(vec3 V) 335 { 336 return max(1 / length(V), 1e-8); 337 } 338 339 vec2 mip_ratio_interp(float mip) 340 { 341 float low_mip = floor(mip); 342 return mix(mipRatio[int(low_mip)], mipRatio[int(low_mip + 1.0)], mip - low_mip); 343 } 344 345 /* ------- RNG ------- */ 346 347 float wang_hash_noise(uint s) 348 { 349 s = (s ^ 61u) ^ (s >> 16u); 350 s *= 9u; 351 s = s ^ (s >> 4u); 352 s *= 0x27d4eb2du; 353 s = s ^ (s >> 15u); 354 355 return fract(float(s) / 4294967296.0); 356 } 357 358 /* ------- Fast Math ------- */ 359 360 /* [Drobot2014a] Low Level Optimizations for GCN */ 361 float fast_sqrt(float v) 362 { 363 return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1)); 364 } 365 366 vec2 fast_sqrt(vec2 v) 367 { 368 return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1)); 369 } 370 371 /* [Eberly2014] GPGPU Programming for Games and Science */ 372 float fast_acos(float v) 373 { 374 float res = -0.156583 * abs(v) + M_PI_2; 375 res *= fast_sqrt(1.0 - abs(v)); 376 return (v >= 0) ? res : M_PI - res; 377 } 378 379 vec2 fast_acos(vec2 v) 380 { 381 vec2 res = -0.156583 * abs(v) + M_PI_2; 382 res *= fast_sqrt(1.0 - abs(v)); 383 v.x = (v.x >= 0) ? res.x : M_PI - res.x; 384 v.y = (v.y >= 0) ? res.y : M_PI - res.y; 385 return v; 386 } 387 388 float point_plane_projection_dist(vec3 lineorigin, vec3 planeorigin, vec3 planenormal) 389 { 390 return dot(planenormal, planeorigin - lineorigin); 391 } 392 393 float line_plane_intersect_dist(vec3 lineorigin, 394 vec3 linedirection, 395 vec3 planeorigin, 396 vec3 planenormal) 397 { 398 return dot(planenormal, planeorigin - lineorigin) / dot(planenormal, linedirection); 399 } 400 401 float line_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec4 plane) 402 { 403 vec3 plane_co = plane.xyz * (-plane.w / len_squared(plane.xyz)); 404 vec3 h = lineorigin - plane_co; 405 return -dot(plane.xyz, h) / dot(plane.xyz, linedirection); 406 } 407 408 vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin, vec3 planenormal) 409 { 410 float dist = line_plane_intersect_dist(lineorigin, linedirection, planeorigin, planenormal); 411 return lineorigin + linedirection * dist; 412 } 413 414 vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec4 plane) 415 { 416 float dist = line_plane_intersect_dist(lineorigin, linedirection, plane); 417 return lineorigin + linedirection * dist; 418 } 419 420 float line_aligned_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec3 planeorigin) 421 { 422 /* aligned plane normal */ 423 vec3 L = planeorigin - lineorigin; 424 float diskdist = length(L); 425 vec3 planenormal = -normalize(L); 426 return -diskdist / dot(planenormal, linedirection); 427 } 428 429 vec3 line_aligned_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin) 430 { 431 float dist = line_aligned_plane_intersect_dist(lineorigin, linedirection, planeorigin); 432 if (dist < 0) { 433 /* if intersection is behind we fake the intersection to be 434 * really far and (hopefully) not inside the radius of interest */ 435 dist = 1e16; 436 } 437 return lineorigin + linedirection * dist; 438 } 439 440 float line_unit_sphere_intersect_dist(vec3 lineorigin, vec3 linedirection) 441 { 442 float a = dot(linedirection, linedirection); 443 float b = dot(linedirection, lineorigin); 444 float c = dot(lineorigin, lineorigin) - 1; 445 446 float dist = 1e15; 447 float determinant = b * b - a * c; 448 if (determinant >= 0) { 449 dist = (sqrt(determinant) - b) / a; 450 } 451 452 return dist; 453 } 454 455 float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection) 456 { 457 /* https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ 458 */ 459 vec3 firstplane = (vec3(1.0) - lineorigin) / linedirection; 460 vec3 secondplane = (vec3(-1.0) - lineorigin) / linedirection; 461 vec3 furthestplane = max(firstplane, secondplane); 462 463 return min_v3(furthestplane); 464 } 465 466 /* Return texture coordinates to sample Surface LUT */ 467 vec2 lut_coords(float cosTheta, float roughness) 468 { 469 float theta = acos(cosTheta); 470 vec2 coords = vec2(roughness, theta / M_PI_2); 471 472 /* scale and bias coordinates, for correct filtered lookup */ 473 return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE; 474 } 475 476 vec2 lut_coords_ltc(float cosTheta, float roughness) 477 { 478 vec2 coords = vec2(roughness, sqrt(1.0 - cosTheta)); 479 480 /* scale and bias coordinates, for correct filtered lookup */ 481 return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE; 482 } 483 484 /* -- Tangent Space conversion -- */ 485 vec3 tangent_to_world(vec3 vector, vec3 N, vec3 T, vec3 B) 486 { 487 return T * vector.x + B * vector.y + N * vector.z; 488 } 489 490 vec3 world_to_tangent(vec3 vector, vec3 N, vec3 T, vec3 B) 491 { 492 return vec3(dot(T, vector), dot(B, vector), dot(N, vector)); 493 } 494 495 void make_orthonormal_basis(vec3 N, out vec3 T, out vec3 B) 496 { 497 vec3 UpVector = abs(N.z) < 0.99999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); 498 T = normalize(cross(UpVector, N)); 499 B = cross(N, T); 500 } 501 502 /* ---- Opengl Depth conversion ---- */ 503 504 float linear_depth(bool is_persp, float z, float zf, float zn) 505 { 506 if (is_persp) { 507 return (zn * zf) / (z * (zn - zf) + zf); 508 } 509 else { 510 return (z * 2.0 - 1.0) * zf; 511 } 512 } 513 514 float buffer_depth(bool is_persp, float z, float zf, float zn) 515 { 516 if (is_persp) { 517 return (zf * (zn - z)) / (z * (zn - zf)); 518 } 519 else { 520 return (z / (zf * 2.0)) + 0.5; 521 } 522 } 523 524 float get_view_z_from_depth(float depth) 525 { 526 if (ProjectionMatrix[3][3] == 0.0) { 527 float d = 2.0 * depth - 1.0; 528 return -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]); 529 } 530 else { 531 return viewVecs[0].z + depth * viewVecs[1].z; 532 } 533 } 534 535 float get_depth_from_view_z(float z) 536 { 537 if (ProjectionMatrix[3][3] == 0.0) { 538 float d = (-ProjectionMatrix[3][2] / z) - ProjectionMatrix[2][2]; 539 return d * 0.5 + 0.5; 540 } 541 else { 542 return (z - viewVecs[0].z) / viewVecs[1].z; 543 } 544 } 545 546 vec2 get_uvs_from_view(vec3 view) 547 { 548 vec3 ndc = project_point(ProjectionMatrix, view); 549 return ndc.xy * 0.5 + 0.5; 550 } 551 552 vec3 get_view_space_from_depth(vec2 uvcoords, float depth) 553 { 554 if (ProjectionMatrix[3][3] == 0.0) { 555 return vec3(viewVecs[0].xy + uvcoords * viewVecs[1].xy, 1.0) * get_view_z_from_depth(depth); 556 } 557 else { 558 return viewVecs[0].xyz + vec3(uvcoords, depth) * viewVecs[1].xyz; 559 } 560 } 561 562 vec3 get_world_space_from_depth(vec2 uvcoords, float depth) 563 { 564 return (ViewMatrixInverse * vec4(get_view_space_from_depth(uvcoords, depth), 1.0)).xyz; 565 } 566 567 vec3 get_specular_reflection_dominant_dir(vec3 N, vec3 V, float roughness) 568 { 569 vec3 R = -reflect(V, N); 570 float smoothness = 1.0 - roughness; 571 float fac = smoothness * (sqrt(smoothness) + roughness); 572 return normalize(mix(N, R, fac)); 573 } 574 575 float specular_occlusion(float NV, float AO, float roughness) 576 { 577 return saturate(pow(NV + AO, roughness) - 1.0 + AO); 578 } 579 580 /* --- Refraction utils --- */ 581 582 float ior_from_f0(float f0) 583 { 584 float f = sqrt(f0); 585 return (-f - 1.0) / (f - 1.0); 586 } 587 588 float f0_from_ior(float eta) 589 { 590 float A = (eta - 1.0) / (eta + 1.0); 591 return A * A; 592 } 593 594 vec3 get_specular_refraction_dominant_dir(vec3 N, vec3 V, float roughness, float ior) 595 { 596 /* TODO: This a bad approximation. Better approximation should fit 597 * the refracted vector and roughness into the best prefiltered reflection 598 * lobe. */ 599 /* Correct the IOR for ior < 1.0 to not see the abrupt delimitation or the TIR */ 600 ior = (ior < 1.0) ? mix(ior, 1.0, roughness) : ior; 601 float eta = 1.0 / ior; 602 603 float NV = dot(N, -V); 604 605 /* Custom Refraction. */ 606 float k = 1.0 - eta * eta * (1.0 - NV * NV); 607 k = max(0.0, k); /* Only this changes. */ 608 vec3 R = eta * -V - (eta * NV + sqrt(k)) * N; 609 610 return R; 611 } 612 613 float get_btdf_lut(sampler2DArray btdf_lut_tex, float NV, float roughness, float ior) 614 { 615 const vec3 lut_scale_bias_texel_size = vec3((LUT_SIZE - 1.0), 0.5, 1.5) / LUT_SIZE; 616 617 vec3 coords; 618 /* Try to compensate for the low resolution and interpolation error. */ 619 coords.x = (ior > 1.0) ? (0.9 + lut_scale_bias_texel_size.z) + 620 (0.1 - lut_scale_bias_texel_size.z) * f0_from_ior(ior) : 621 (0.9 + lut_scale_bias_texel_size.z) * ior * ior; 622 coords.y = 1.0 - saturate(NV); 623 coords.xy *= lut_scale_bias_texel_size.x; 624 coords.xy += lut_scale_bias_texel_size.y; 625 626 const float lut_lvl_ofs = 4.0; /* First texture lvl of roughness. */ 627 const float lut_lvl_scale = 16.0; /* How many lvl of roughness in the lut. */ 628 629 float mip = roughness * lut_lvl_scale; 630 float mip_floor = floor(mip); 631 632 coords.z = lut_lvl_ofs + mip_floor + 1.0; 633 float btdf_high = textureLod(btdf_lut_tex, coords, 0.0).r; 634 635 coords.z -= 1.0; 636 float btdf_low = textureLod(btdf_lut_tex, coords, 0.0).r; 637 638 float btdf = (ior == 1.0) ? 1.0 : mix(btdf_low, btdf_high, mip - coords.z); 639 640 return btdf; 641 } 642 643 /* ---- Encode / Decode Normal buffer data ---- */ 644 /* From http://aras-p.info/texts/CompactNormalStorage.html 645 * Using Method #4: Spheremap Transform */ 646 vec2 normal_encode(vec3 n, vec3 view) 647 { 648 float p = sqrt(n.z * 8.0 + 8.0); 649 return n.xy / p + 0.5; 650 } 651 652 vec3 normal_decode(vec2 enc, vec3 view) 653 { 654 vec2 fenc = enc * 4.0 - 2.0; 655 float f = dot(fenc, fenc); 656 float g = sqrt(1.0 - f / 4.0); 657 vec3 n; 658 n.xy = fenc * g; 659 n.z = 1 - f / 2; 660 return n; 661 } 662 663 /* ---- RGBM (shared multiplier) encoding ---- */ 664 /* From http://iwasbeingirony.blogspot.fr/2010/06/difference-between-rgbm-and-rgbd.html */ 665 666 /* Higher RGBM_MAX_RANGE gives imprecision issues in low intensity. */ 667 #define RGBM_MAX_RANGE 512.0 668 669 vec4 rgbm_encode(vec3 rgb) 670 { 671 float maxRGB = max_v3(rgb); 672 float M = maxRGB / RGBM_MAX_RANGE; 673 M = ceil(M * 255.0) / 255.0; 674 return vec4(rgb / (M * RGBM_MAX_RANGE), M); 675 } 676 677 vec3 rgbm_decode(vec4 data) 678 { 679 return data.rgb * (data.a * RGBM_MAX_RANGE); 680 } 681 682 /* ---- RGBE (shared exponent) encoding ---- */ 683 vec4 rgbe_encode(vec3 rgb) 684 { 685 float maxRGB = max_v3(rgb); 686 float fexp = ceil(log2(maxRGB)); 687 return vec4(rgb / exp2(fexp), (fexp + 128.0) / 255.0); 688 } 689 690 vec3 rgbe_decode(vec4 data) 691 { 692 float fexp = data.a * 255.0 - 128.0; 693 return data.rgb * exp2(fexp); 694 } 695 696 #if 1 697 # define irradiance_encode rgbe_encode 698 # define irradiance_decode rgbe_decode 699 #else /* No ecoding (when using floating point format) */ 700 # define irradiance_encode(X) (X).rgbb 701 # define irradiance_decode(X) (X).rgb 702 #endif 703 704 /* Irradiance Visibility Encoding */ 705 #if 1 706 vec4 visibility_encode(vec2 accum, float range) 707 { 708 accum /= range; 709 710 vec4 data; 711 data.x = fract(accum.x); 712 data.y = floor(accum.x) / 255.0; 713 data.z = fract(accum.y); 714 data.w = floor(accum.y) / 255.0; 715 716 return data; 717 } 718 719 vec2 visibility_decode(vec4 data, float range) 720 { 721 return (data.xz + data.yw * 255.0) * range; 722 } 723 #else /* No ecoding (when using floating point format) */ 724 vec4 visibility_encode(vec2 accum, float range) 725 { 726 return accum.xyxy; 727 } 728 729 vec2 visibility_decode(vec4 data, float range) 730 { 731 return data.xy; 732 } 733 #endif 734 735 /* Fresnel monochromatic, perfect mirror */ 736 float F_eta(float eta, float cos_theta) 737 { 738 /* compute fresnel reflectance without explicitly computing 739 * the refracted direction */ 740 float c = abs(cos_theta); 741 float g = eta * eta - 1.0 + c * c; 742 float result; 743 744 if (g > 0.0) { 745 g = sqrt(g); 746 vec2 g_c = vec2(g) + vec2(c, -c); 747 float A = g_c.y / g_c.x; 748 A *= A; 749 g_c *= c; 750 float B = (g_c.y - 1.0) / (g_c.x + 1.0); 751 B *= B; 752 result = 0.5 * A * (1.0 + B); 753 } 754 else { 755 result = 1.0; /* TIR (no refracted component) */ 756 } 757 758 return result; 759 } 760 761 /* Fresnel color blend base on fresnel factor */ 762 vec3 F_color_blend(float eta, float fresnel, vec3 f0_color) 763 { 764 float f0 = F_eta(eta, 1.0); 765 float fac = saturate((fresnel - f0) / max(1e-8, 1.0 - f0)); 766 return mix(f0_color, vec3(1.0), fac); 767 } 768 769 /* Fresnel */ 770 vec3 F_schlick(vec3 f0, float cos_theta) 771 { 772 float fac = 1.0 - cos_theta; 773 float fac2 = fac * fac; 774 fac = fac2 * fac2 * fac; 775 776 /* Unreal specular matching : if specular color is below 2% intensity, 777 * (using green channel for intensity) treat as shadowning */ 778 return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * fac + (1.0 - fac) * f0; 779 } 780 781 /* Fresnel approximation for LTC area lights (not MRP) */ 782 vec3 F_area(vec3 f0, vec3 f90, vec2 lut) 783 { 784 /* Unreal specular matching : if specular color is below 2% intensity, 785 * treat as shadowning */ 786 return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * lut.y * f90 + lut.x * f0; 787 } 788 789 /* Fresnel approximation for IBL */ 790 vec3 F_ibl(vec3 f0, vec3 f90, vec2 lut) 791 { 792 /* Unreal specular matching : if specular color is below 2% intensity, 793 * treat as shadowning */ 794 return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * lut.y * f90 + lut.x * f0; 795 } 796 797 /* GGX */ 798 float D_ggx_opti(float NH, float a2) 799 { 800 float tmp = (NH * a2 - NH) * NH + 1.0; 801 return M_PI * tmp * tmp; /* Doing RCP and mul a2 at the end */ 802 } 803 804 float G1_Smith_GGX(float NX, float a2) 805 { 806 /* Using Brian Karis approach and refactoring by NX/NX 807 * this way the (2*NL)*(2*NV) in G = G1(V) * G1(L) gets canceled by the brdf denominator 4*NL*NV 808 * Rcp is done on the whole G later 809 * Note that this is not convenient for the transmission formula */ 810 return NX + sqrt(NX * (NX - NX * a2) + a2); 811 /* return 2 / (1 + sqrt(1 + a2 * (1 - NX*NX) / (NX*NX) ) ); /* Reference function */ 812 } 813 814 float bsdf_ggx(vec3 N, vec3 L, vec3 V, float roughness) 815 { 816 float a = roughness; 817 float a2 = a * a; 818 819 vec3 H = normalize(L + V); 820 float NH = max(dot(N, H), 1e-8); 821 float NL = max(dot(N, L), 1e-8); 822 float NV = max(dot(N, V), 1e-8); 823 824 float G = G1_Smith_GGX(NV, a2) * G1_Smith_GGX(NL, a2); /* Doing RCP at the end */ 825 float D = D_ggx_opti(NH, a2); 826 827 /* Denominator is canceled by G1_Smith */ 828 /* bsdf = D * G / (4.0 * NL * NV); /* Reference function */ 829 return NL * a2 / (D * G); /* NL to Fit cycles Equation : line. 345 in bsdf_microfacet.h */ 830 } 831 832 void accumulate_light(vec3 light, float fac, inout vec4 accum) 833 { 834 accum += vec4(light, 1.0) * min(fac, (1.0 - accum.a)); 835 } 836 837 /* ----------- Cone Aperture Approximation --------- */ 838 839 /* Return a fitted cone angle given the input roughness */ 840 float cone_cosine(float r) 841 { 842 /* Using phong gloss 843 * roughness = sqrt(2/(gloss+2)) */ 844 float gloss = -2 + 2 / (r * r); 845 /* Drobot 2014 in GPUPro5 */ 846 // return cos(2.0 * sqrt(2.0 / (gloss + 2))); 847 /* Uludag 2014 in GPUPro5 */ 848 // return pow(0.244, 1 / (gloss + 1)); 849 /* Jimenez 2016 in Practical Realtime Strategies for Accurate Indirect Occlusion*/ 850 return exp2(-3.32193 * r * r); 851 } 852 853 /* --------- Closure ---------- */ 854 #ifdef VOLUMETRICS 855 856 struct Closure { 857 vec3 absorption; 858 vec3 scatter; 859 vec3 emission; 860 float anisotropy; 861 }; 862 863 # define CLOSURE_DEFAULT Closure(vec3(0.0), vec3(0.0), vec3(0.0), 0.0) 864 865 Closure closure_mix(Closure cl1, Closure cl2, float fac) 866 { 867 Closure cl; 868 cl.absorption = mix(cl1.absorption, cl2.absorption, fac); 869 cl.scatter = mix(cl1.scatter, cl2.scatter, fac); 870 cl.emission = mix(cl1.emission, cl2.emission, fac); 871 cl.anisotropy = mix(cl1.anisotropy, cl2.anisotropy, fac); 872 return cl; 873 } 874 875 Closure closure_add(Closure cl1, Closure cl2) 876 { 877 Closure cl; 878 cl.absorption = cl1.absorption + cl2.absorption; 879 cl.scatter = cl1.scatter + cl2.scatter; 880 cl.emission = cl1.emission + cl2.emission; 881 cl.anisotropy = (cl1.anisotropy + cl2.anisotropy) / 2.0; /* Average phase (no multi lobe) */ 882 return cl; 883 } 884 885 Closure closure_emission(vec3 rgb) 886 { 887 Closure cl = CLOSURE_DEFAULT; 888 cl.emission = rgb; 889 return cl; 890 } 891 892 #else /* VOLUMETRICS */ 893 894 struct Closure { 895 vec3 radiance; 896 float opacity; 897 # ifdef USE_SSS 898 vec4 sss_data; 899 # ifdef USE_SSS_ALBEDO 900 vec3 sss_albedo; 901 # endif 902 # endif 903 vec4 ssr_data; 904 vec2 ssr_normal; 905 int ssr_id; 906 }; 907 908 /* This is hacking ssr_id to tag transparent bsdf */ 909 # define TRANSPARENT_CLOSURE_FLAG -2 910 # define REFRACT_CLOSURE_FLAG -3 911 # define NO_SSR -999 912 913 # ifdef USE_SSS 914 # ifdef USE_SSS_ALBEDO 915 # define CLOSURE_DEFAULT \ 916 Closure(vec3(0.0), 1.0, vec4(0.0), vec3(0.0), vec4(0.0), vec2(0.0), -1) 917 # else 918 # define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec4(0.0), vec2(0.0), -1) 919 # endif 920 # else 921 # define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec2(0.0), -1) 922 # endif 923 924 uniform int outputSsrId; 925 926 Closure closure_mix(Closure cl1, Closure cl2, float fac) 927 { 928 Closure cl; 929 930 if (cl1.ssr_id == TRANSPARENT_CLOSURE_FLAG) { 931 cl.ssr_normal = cl2.ssr_normal; 932 cl.ssr_data = cl2.ssr_data; 933 cl.ssr_id = cl2.ssr_id; 934 # ifdef USE_SSS 935 cl1.sss_data = cl2.sss_data; 936 # ifdef USE_SSS_ALBEDO 937 cl1.sss_albedo = cl2.sss_albedo; 938 # endif 939 # endif 940 } 941 else if (cl2.ssr_id == TRANSPARENT_CLOSURE_FLAG) { 942 cl.ssr_normal = cl1.ssr_normal; 943 cl.ssr_data = cl1.ssr_data; 944 cl.ssr_id = cl1.ssr_id; 945 # ifdef USE_SSS 946 cl2.sss_data = cl1.sss_data; 947 # ifdef USE_SSS_ALBEDO 948 cl2.sss_albedo = cl1.sss_albedo; 949 # endif 950 # endif 951 } 952 else if (cl1.ssr_id == outputSsrId) { 953 /* When mixing SSR don't blend roughness. 954 * 955 * It makes no sense to mix them really, so we take either one of them and 956 * tone down its specularity (ssr_data.xyz) while keeping its roughness (ssr_data.w). 957 */ 958 cl.ssr_data = mix(cl1.ssr_data.xyzw, vec4(vec3(0.0), cl1.ssr_data.w), fac); 959 cl.ssr_normal = cl1.ssr_normal; 960 cl.ssr_id = cl1.ssr_id; 961 } 962 else { 963 cl.ssr_data = mix(vec4(vec3(0.0), cl2.ssr_data.w), cl2.ssr_data.xyzw, fac); 964 cl.ssr_normal = cl2.ssr_normal; 965 cl.ssr_id = cl2.ssr_id; 966 } 967 968 cl.opacity = mix(cl1.opacity, cl2.opacity, fac); 969 cl.radiance = mix(cl1.radiance * cl1.opacity, cl2.radiance * cl2.opacity, fac); 970 cl.radiance /= max(1e-8, cl.opacity); 971 972 # ifdef USE_SSS 973 /* Apply Mix on input */ 974 cl1.sss_data.rgb *= 1.0 - fac; 975 cl2.sss_data.rgb *= fac; 976 977 /* Select biggest radius. */ 978 bool use_cl1 = (cl1.sss_data.a > cl2.sss_data.a); 979 cl.sss_data = (use_cl1) ? cl1.sss_data : cl2.sss_data; 980 981 # ifdef USE_SSS_ALBEDO 982 /* TODO Find a solution to this. Dither? */ 983 cl.sss_albedo = (use_cl1) ? cl1.sss_albedo : cl2.sss_albedo; 984 /* Add radiance that was supposed to be filtered but was rejected. */ 985 cl.radiance += (use_cl1) ? cl2.sss_data.rgb * cl2.sss_albedo : cl1.sss_data.rgb * cl1.sss_albedo; 986 # else 987 /* Add radiance that was supposed to be filtered but was rejected. */ 988 cl.radiance += (use_cl1) ? cl2.sss_data.rgb : cl1.sss_data.rgb; 989 # endif 990 # endif 991 992 return cl; 993 } 994 995 Closure closure_add(Closure cl1, Closure cl2) 996 { 997 Closure cl = (cl1.ssr_id == outputSsrId) ? cl1 : cl2; 998 cl.radiance = cl1.radiance + cl2.radiance; 999 # ifdef USE_SSS 1000 cl.sss_data = (cl1.sss_data.a > 0.0) ? cl1.sss_data : cl2.sss_data; 1001 /* Add radiance that was supposed to be filtered but was rejected. */ 1002 cl.radiance += (cl1.sss_data.a > 0.0) ? cl2.sss_data.rgb : cl1.sss_data.rgb; 1003 # ifdef USE_SSS_ALBEDO 1004 /* TODO Find a solution to this. Dither? */ 1005 cl.sss_albedo = (cl1.sss_data.a > 0.0) ? cl1.sss_albedo : cl2.sss_albedo; 1006 # endif 1007 # endif 1008 cl.opacity = saturate(cl1.opacity + cl2.opacity); 1009 return cl; 1010 } 1011 1012 Closure closure_emission(vec3 rgb) 1013 { 1014 Closure cl = CLOSURE_DEFAULT; 1015 cl.radiance = rgb; 1016 return cl; 1017 } 1018 1019 /* Breaking this across multiple lines causes issues for some older GLSL compilers. */ 1020 /* clang-format off */ 1021 # if defined(MESH_SHADER) && !defined(USE_ALPHA_HASH) && !defined(USE_ALPHA_CLIP) && !defined(SHADOW_SHADER) && !defined(USE_MULTIPLY ) 1022 /* clang-format on */ 1023 layout(location = 0) out vec4 fragColor; 1024 layout(location = 1) out vec4 ssrNormals; 1025 layout(location = 2) out vec4 ssrData; 1026 # ifdef USE_SSS 1027 layout(location = 3) out vec4 sssData; 1028 # ifdef USE_SSS_ALBEDO 1029 layout(location = 4) out vec4 sssAlbedo; 1030 # endif /* USE_SSS_ALBEDO */ 1031 # endif /* USE_SSS */ 1032 1033 Closure nodetree_exec(void); /* Prototype */ 1034 1035 # if defined(USE_ALPHA_BLEND) 1036 /* Prototype because this file is included before volumetric_lib.glsl */ 1037 void volumetric_resolve(vec2 frag_uvs, 1038 float frag_depth, 1039 out vec3 transmittance, 1040 out vec3 scattering); 1041 # endif 1042 1043 # define NODETREE_EXEC 1044 void main() 1045 { 1046 Closure cl = nodetree_exec(); 1047 # ifndef USE_ALPHA_BLEND 1048 /* Prevent alpha hash material writing into alpha channel. */ 1049 cl.opacity = 1.0; 1050 # endif 1051 1052 # if defined(USE_ALPHA_BLEND) 1053 vec2 uvs = gl_FragCoord.xy * volCoordScale.zw; 1054 vec3 transmittance, scattering; 1055 volumetric_resolve(uvs, gl_FragCoord.z, transmittance, scattering); 1056 fragColor.rgb = cl.radiance * transmittance + scattering; 1057 fragColor.a = cl.opacity; 1058 # else 1059 fragColor = vec4(cl.radiance, cl.opacity); 1060 # endif 1061 1062 ssrNormals = cl.ssr_normal.xyyy; 1063 ssrData = cl.ssr_data; 1064 # ifdef USE_SSS 1065 sssData = cl.sss_data; 1066 # ifdef USE_SSS_ALBEDO 1067 sssAlbedo = cl.sss_albedo.rgbb; 1068 # endif 1069 # endif 1070 1071 /* For Probe capture */ 1072 # ifdef USE_SSS 1073 float fac = float(!sssToggle); 1074 1075 # ifdef USE_REFRACTION 1076 /* SSRefraction pass is done after the SSS pass. 1077 * In order to not loose the diffuse light totally we 1078 * need to merge the SSS radiance to the main radiance. */ 1079 fac = 1.0; 1080 # endif 1081 1082 # ifdef USE_SSS_ALBEDO 1083 fragColor.rgb += cl.sss_data.rgb * cl.sss_albedo.rgb * fac; 1084 # else 1085 fragColor.rgb += cl.sss_data.rgb * fac; 1086 # endif 1087 # endif 1088 } 1089 1090 # endif /* MESH_SHADER && !SHADOW_SHADER */ 1091 1092 #endif /* VOLUMETRICS */ 1093 1094 Closure nodetree_exec(void); /* Prototype */ 1095 1096 /* TODO find a better place */ 1097 #ifdef USE_MULTIPLY 1098 1099 out vec4 fragColor; 1100 1101 # define NODETREE_EXEC 1102 void main() 1103 { 1104 Closure cl = nodetree_exec(); 1105 fragColor = vec4(mix(vec3(1.0), cl.radiance, cl.opacity), 1.0); 1106 } 1107 #endif 1108 1109 vec2 mapping_octahedron(vec3 cubevec, vec2 texel_size) 1110 { 1111 /* projection onto octahedron */ 1112 cubevec /= dot(vec3(1.0), abs(cubevec)); 1113 1114 /* out-folding of the downward faces */ 1115 if (cubevec.z < 0.0) { 1116 vec2 cubevec_sign = step(0.0, cubevec.xy) * 2.0 - 1.0; 1117 cubevec.xy = (1.0 - abs(cubevec.yx)) * cubevec_sign; 1118 } 1119 1120 /* mapping to [0;1]ˆ2 texture space */ 1121 vec2 uvs = cubevec.xy * (0.5) + 0.5; 1122 1123 /* edge filtering fix */ 1124 uvs = (1.0 - 2.0 * texel_size) * uvs + texel_size; 1125 1126 return uvs; 1127 } 1128 1129 vec4 textureLod_octahedron(sampler2DArray tex, vec4 cubevec, float lod, float lod_max) 1130 { 1131 vec2 texelSize = 1.0 / vec2(textureSize(tex, int(lod_max))); 1132 1133 vec2 uvs = mapping_octahedron(cubevec.xyz, texelSize); 1134 1135 return textureLod(tex, vec3(uvs, cubevec.w), lod); 1136 } 1137 1138 vec4 texture_octahedron(sampler2DArray tex, vec4 cubevec) 1139 { 1140 vec2 texelSize = 1.0 / vec2(textureSize(tex, 0)); 1141 1142 vec2 uvs = mapping_octahedron(cubevec.xyz, texelSize); 1143 1144 return texture(tex, vec3(uvs, cubevec.w)); 1145 } 1146 1147 uniform sampler2DArray irradianceGrid; 1148 1149 #define IRRADIANCE_LIB 1150 1151 #ifdef IRRADIANCE_CUBEMAP 1152 struct IrradianceData { 1153 vec3 color; 1154 }; 1155 #elif defined(IRRADIANCE_SH_L2) 1156 struct IrradianceData { 1157 vec3 shcoefs[9]; 1158 }; 1159 #else /* defined(IRRADIANCE_HL2) */ 1160 struct IrradianceData { 1161 vec3 cubesides[3]; 1162 }; 1163 #endif 1164 1165 IrradianceData load_irradiance_cell(int cell, vec3 N) 1166 { 1167 /* Keep in sync with diffuse_filter_probe() */ 1168 1169 #if defined(IRRADIANCE_CUBEMAP) 1170 1171 # define AMBIANT_CUBESIZE 8 1172 ivec2 cell_co = ivec2(AMBIANT_CUBESIZE); 1173 int cell_per_row = textureSize(irradianceGrid, 0).x / cell_co.x; 1174 cell_co.x *= cell % cell_per_row; 1175 cell_co.y *= cell / cell_per_row; 1176 1177 vec2 texelSize = 1.0 / vec2(AMBIANT_CUBESIZE); 1178 1179 vec2 uvs = mapping_octahedron(N, texelSize); 1180 uvs *= vec2(AMBIANT_CUBESIZE) / vec2(textureSize(irradianceGrid, 0)); 1181 uvs += vec2(cell_co) / vec2(textureSize(irradianceGrid, 0)); 1182 1183 IrradianceData ir; 1184 ir.color = texture(irradianceGrid, vec3(uvs, 0.0)).rgb; 1185 1186 #elif defined(IRRADIANCE_SH_L2) 1187 1188 ivec2 cell_co = ivec2(3, 3); 1189 int cell_per_row = textureSize(irradianceGrid, 0).x / cell_co.x; 1190 cell_co.x *= cell % cell_per_row; 1191 cell_co.y *= cell / cell_per_row; 1192 1193 ivec3 ofs = ivec3(0, 1, 2); 1194 1195 IrradianceData ir; 1196 ir.shcoefs[0] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.xx, 0), 0).rgb; 1197 ir.shcoefs[1] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.yx, 0), 0).rgb; 1198 ir.shcoefs[2] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.zx, 0), 0).rgb; 1199 ir.shcoefs[3] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.xy, 0), 0).rgb; 1200 ir.shcoefs[4] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.yy, 0), 0).rgb; 1201 ir.shcoefs[5] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.zy, 0), 0).rgb; 1202 ir.shcoefs[6] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.xz, 0), 0).rgb; 1203 ir.shcoefs[7] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.yz, 0), 0).rgb; 1204 ir.shcoefs[8] = texelFetch(irradianceGrid, ivec3(cell_co + ofs.zz, 0), 0).rgb; 1205 1206 #else /* defined(IRRADIANCE_HL2) */ 1207 1208 ivec2 cell_co = ivec2(3, 2); 1209 int cell_per_row = textureSize(irradianceGrid, 0).x / cell_co.x; 1210 cell_co.x *= cell % cell_per_row; 1211 cell_co.y *= cell / cell_per_row; 1212 1213 ivec3 is_negative = ivec3(step(0.0, -N)); 1214 1215 IrradianceData ir; 1216 ir.cubesides[0] = irradiance_decode( 1217 texelFetch(irradianceGrid, ivec3(cell_co + ivec2(0, is_negative.x), 0), 0)); 1218 ir.cubesides[1] = irradiance_decode( 1219 texelFetch(irradianceGrid, ivec3(cell_co + ivec2(1, is_negative.y), 0), 0)); 1220 ir.cubesides[2] = irradiance_decode( 1221 texelFetch(irradianceGrid, ivec3(cell_co + ivec2(2, is_negative.z), 0), 0)); 1222 1223 #endif 1224 1225 return ir; 1226 } 1227 1228 float load_visibility_cell(int cell, vec3 L, float dist, float bias, float bleed_bias, float range) 1229 { 1230 /* Keep in sync with diffuse_filter_probe() */ 1231 ivec2 cell_co = ivec2(prbIrradianceVisSize); 1232 ivec2 cell_per_row_col = textureSize(irradianceGrid, 0).xy / prbIrradianceVisSize; 1233 cell_co.x *= (cell % cell_per_row_col.x); 1234 cell_co.y *= (cell / cell_per_row_col.x) % cell_per_row_col.y; 1235 float layer = 1.0 + float((cell / cell_per_row_col.x) / cell_per_row_col.y); 1236 1237 vec2 texel_size = 1.0 / vec2(textureSize(irradianceGrid, 0).xy); 1238 vec2 co = vec2(cell_co) * texel_size; 1239 1240 vec2 uv = mapping_octahedron(-L, vec2(1.0 / float(prbIrradianceVisSize))); 1241 uv *= vec2(prbIrradianceVisSize) * texel_size; 1242 1243 vec4 data = texture(irradianceGrid, vec3(co + uv, layer)); 1244 1245 /* Decoding compressed data */ 1246 vec2 moments = visibility_decode(data, range); 1247 1248 /* Doing chebishev test */ 1249 float variance = abs(moments.x * moments.x - moments.y); 1250 variance = max(variance, bias / 10.0); 1251 1252 float d = dist - moments.x; 1253 float p_max = variance / (variance + d * d); 1254 1255 /* Increase contrast in the weight by squaring it */ 1256 p_max *= p_max; 1257 1258 /* Now reduce light-bleeding by removing the [0, x] tail and linearly rescaling (x, 1] */ 1259 p_max = clamp((p_max - bleed_bias) / (1.0 - bleed_bias), 0.0, 1.0); 1260 1261 return (dist <= moments.x) ? 1.0 : p_max; 1262 } 1263 1264 /* http://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/ */ 1265 vec3 spherical_harmonics_L1(vec3 N, vec3 shcoefs[4]) 1266 { 1267 vec3 sh = vec3(0.0); 1268 1269 sh += 0.282095 * shcoefs[0]; 1270 1271 sh += -0.488603 * N.z * shcoefs[1]; 1272 sh += 0.488603 * N.y * shcoefs[2]; 1273 sh += -0.488603 * N.x * shcoefs[3]; 1274 1275 return sh; 1276 } 1277 1278 vec3 spherical_harmonics_L2(vec3 N, vec3 shcoefs[9]) 1279 { 1280 vec3 sh = vec3(0.0); 1281 1282 sh += 0.282095 * shcoefs[0]; 1283 1284 sh += -0.488603 * N.z * shcoefs[1]; 1285 sh += 0.488603 * N.y * shcoefs[2]; 1286 sh += -0.488603 * N.x * shcoefs[3]; 1287 1288 sh += 1.092548 * N.x * N.z * shcoefs[4]; 1289 sh += -1.092548 * N.z * N.y * shcoefs[5]; 1290 sh += 0.315392 * (3.0 * N.y * N.y - 1.0) * shcoefs[6]; 1291 sh += -1.092548 * N.x * N.y * shcoefs[7]; 1292 sh += 0.546274 * (N.x * N.x - N.z * N.z) * shcoefs[8]; 1293 1294 return sh; 1295 } 1296 1297 vec3 hl2_basis(vec3 N, vec3 cubesides[3]) 1298 { 1299 vec3 irradiance = vec3(0.0); 1300 1301 vec3 n_squared = N * N; 1302 1303 irradiance += n_squared.x * cubesides[0]; 1304 irradiance += n_squared.y * cubesides[1]; 1305 irradiance += n_squared.z * cubesides[2]; 1306 1307 return irradiance; 1308 } 1309 1310 vec3 compute_irradiance(vec3 N, IrradianceData ird) 1311 { 1312 #if defined(IRRADIANCE_CUBEMAP) 1313 return ird.color; 1314 #elif defined(IRRADIANCE_SH_L2) 1315 return spherical_harmonics_L2(N, ird.shcoefs); 1316 #else /* defined(IRRADIANCE_HL2) */ 1317 return hl2_basis(N, ird.cubesides); 1318 #endif 1319 } 1320 1321 vec3 irradiance_from_cell_get(int cell, vec3 ir_dir) 1322 { 1323 IrradianceData ir_data = load_irradiance_cell(cell, ir_dir); 1324 return compute_irradiance(ir_dir, ir_data); 1325 } 1326 1327 uniform sampler2DArray shadowCubeTexture; 1328 uniform sampler2DArray shadowCascadeTexture; 1329 1330 #define LAMPS_LIB 1331 1332 layout(std140) uniform shadow_block 1333 { 1334 ShadowData shadows_data[MAX_SHADOW]; 1335 ShadowCubeData shadows_cube_data[MAX_SHADOW_CUBE]; 1336 ShadowCascadeData shadows_cascade_data[MAX_SHADOW_CASCADE]; 1337 }; 1338 1339 layout(std140) uniform light_block 1340 { 1341 LightData lights_data[MAX_LIGHT]; 1342 }; 1343 1344 /* type */ 1345 #define POINT 0.0 1346 #define SUN 1.0 1347 #define SPOT 2.0 1348 #define AREA_RECT 4.0 1349 /* Used to define the area light shape, doesn't directly correspond to a Blender light type. */ 1350 #define AREA_ELLIPSE 100.0 1351 1352 #if defined(SHADOW_VSM) 1353 # define ShadowSample vec2 1354 # define sample_cube(vec, id) texture_octahedron(shadowCubeTexture, vec4(vec, id)).rg 1355 # define sample_cascade(vec, id) texture(shadowCascadeTexture, vec3(vec, id)).rg 1356 #elif defined(SHADOW_ESM) 1357 # define ShadowSample float 1358 # define sample_cube(vec, id) texture_octahedron(shadowCubeTexture, vec4(vec, id)).r 1359 # define sample_cascade(vec, id) texture(shadowCascadeTexture, vec3(vec, id)).r 1360 #else 1361 # define ShadowSample float 1362 # define sample_cube(vec, id) texture_octahedron(shadowCubeTexture, vec4(vec, id)).r 1363 # define sample_cascade(vec, id) texture(shadowCascadeTexture, vec3(vec, id)).r 1364 #endif 1365 1366 #if defined(SHADOW_VSM) 1367 # define get_depth_delta(dist, s) (dist - s.x) 1368 #else 1369 # define get_depth_delta(dist, s) (dist - s) 1370 #endif 1371 1372 /* ----------------------------------------------------------- */ 1373 /* ----------------------- Shadow tests ---------------------- */ 1374 /* ----------------------------------------------------------- */ 1375 1376 #if defined(SHADOW_VSM) 1377 1378 float shadow_test(ShadowSample moments, float dist, ShadowData sd) 1379 { 1380 float p = 0.0; 1381 1382 if (dist <= moments.x) { 1383 p = 1.0; 1384 } 1385 1386 float variance = moments.y - (moments.x * moments.x); 1387 variance = max(variance, sd.sh_bias / 10.0); 1388 1389 float d = moments.x - dist; 1390 float p_max = variance / (variance + d * d); 1391 1392 /* Now reduce light-bleeding by removing the [0, x] tail and linearly rescaling (x, 1] */ 1393 p_max = clamp((p_max - sd.sh_bleed) / (1.0 - sd.sh_bleed), 0.0, 1.0); 1394 1395 return max(p, p_max); 1396 } 1397 1398 #elif defined(SHADOW_ESM) 1399 1400 float shadow_test(ShadowSample z, float dist, ShadowData sd) 1401 { 1402 return saturate(exp(sd.sh_exp * (z - dist + sd.sh_bias))); 1403 } 1404 1405 #else 1406 1407 float shadow_test(ShadowSample z, float dist, ShadowData sd) 1408 { 1409 return step(0, z - dist + sd.sh_bias); 1410 } 1411 1412 #endif 1413 1414 /* ----------------------------------------------------------- */ 1415 /* ----------------------- Shadow types ---------------------- */ 1416 /* ----------------------------------------------------------- */ 1417 1418 float shadow_cubemap(ShadowData sd, ShadowCubeData scd, float texid, vec3 W) 1419 { 1420 vec3 cubevec = W - scd.position.xyz; 1421 float dist = length(cubevec); 1422 1423 cubevec /= dist; 1424 1425 ShadowSample s = sample_cube(cubevec, texid); 1426 return shadow_test(s, dist, sd); 1427 } 1428 1429 float evaluate_cascade(ShadowData sd, mat4 shadowmat, vec3 W, float range, float texid) 1430 { 1431 vec4 shpos = shadowmat * vec4(W, 1.0); 1432 float dist = shpos.z * range; 1433 1434 ShadowSample s = sample_cascade(shpos.xy, texid); 1435 float vis = shadow_test(s, dist, sd); 1436 1437 /* If fragment is out of shadowmap range, do not occlude */ 1438 if (shpos.z < 1.0 && shpos.z > 0.0) { 1439 return vis; 1440 } 1441 else { 1442 return 1.0; 1443 } 1444 } 1445 1446 float shadow_cascade(ShadowData sd, int scd_id, float texid, vec3 W) 1447 { 1448 vec4 view_z = vec4(dot(W - cameraPos, cameraForward)); 1449 vec4 weights = smoothstep(shadows_cascade_data[scd_id].split_end_distances, 1450 shadows_cascade_data[scd_id].split_start_distances.yzwx, 1451 view_z); 1452 1453 weights.yzw -= weights.xyz; 1454 1455 vec4 vis = vec4(1.0); 1456 float range = abs(sd.sh_far - sd.sh_near); /* Same factor as in get_cascade_world_distance(). */ 1457 1458 /* Branching using (weights > 0.0) is reaally slooow on intel so avoid it for now. */ 1459 /* TODO OPTI: Only do 2 samples and blend. */ 1460 vis.x = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[0], W, range, texid + 0); 1461 vis.y = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[1], W, range, texid + 1); 1462 vis.z = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[2], W, range, texid + 2); 1463 vis.w = evaluate_cascade(sd, shadows_cascade_data[scd_id].shadowmat[3], W, range, texid + 3); 1464 1465 float weight_sum = dot(vec4(1.0), weights); 1466 if (weight_sum > 0.9999) { 1467 float vis_sum = dot(vec4(1.0), vis * weights); 1468 return vis_sum / weight_sum; 1469 } 1470 else { 1471 float vis_sum = dot(vec4(1.0), vis * step(0.001, weights)); 1472 return mix(1.0, vis_sum, weight_sum); 1473 } 1474 } 1475 1476 /* ----------------------------------------------------------- */ 1477 /* --------------------- Light Functions --------------------- */ 1478 /* ----------------------------------------------------------- */ 1479 1480 /* From Frostbite PBR Course 1481 * Distance based attenuation 1482 * http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf */ 1483 float distance_attenuation(float dist_sqr, float inv_sqr_influence) 1484 { 1485 float factor = dist_sqr * inv_sqr_influence; 1486 float fac = saturate(1.0 - factor * factor); 1487 return fac * fac; 1488 } 1489 1490 float spot_attenuation(LightData ld, vec3 l_vector) 1491 { 1492 float z = dot(ld.l_forward, l_vector.xyz); 1493 vec3 lL = l_vector.xyz / z; 1494 float x = dot(ld.l_right, lL) / ld.l_sizex; 1495 float y = dot(ld.l_up, lL) / ld.l_sizey; 1496 float ellipse = inversesqrt(1.0 + x * x + y * y); 1497 float spotmask = smoothstep(0.0, 1.0, (ellipse - ld.l_spot_size) / ld.l_spot_blend); 1498 return spotmask; 1499 } 1500 1501 float light_visibility(LightData ld, 1502 vec3 W, 1503 #ifndef VOLUMETRICS 1504 vec3 viewPosition, 1505 vec3 vN, 1506 #endif 1507 vec4 l_vector) 1508 { 1509 float vis = 1.0; 1510 1511 if (ld.l_type == SPOT) { 1512 vis *= spot_attenuation(ld, l_vector.xyz); 1513 } 1514 if (ld.l_type >= SPOT) { 1515 vis *= step(0.0, -dot(l_vector.xyz, ld.l_forward)); 1516 } 1517 if (ld.l_type != SUN) { 1518 vis *= distance_attenuation(l_vector.w * l_vector.w, ld.l_influence); 1519 } 1520 1521 #if !defined(VOLUMETRICS) || defined(VOLUME_SHADOW) 1522 /* shadowing */ 1523 if (ld.l_shadowid >= 0.0 && vis > 0.001) { 1524 ShadowData data = shadows_data[int(ld.l_shadowid)]; 1525 1526 if (ld.l_type == SUN) { 1527 vis *= shadow_cascade(data, int(data.sh_data_start), data.sh_tex_start, W); 1528 } 1529 else { 1530 vis *= shadow_cubemap( 1531 data, shadows_cube_data[int(data.sh_data_start)], data.sh_tex_start, W); 1532 } 1533 1534 # ifndef VOLUMETRICS 1535 /* Only compute if not already in shadow. */ 1536 if (data.sh_contact_dist > 0.0) { 1537 vec4 L = (ld.l_type != SUN) ? l_vector : vec4(-ld.l_forward, 1.0); 1538 float trace_distance = (ld.l_type != SUN) ? min(data.sh_contact_dist, l_vector.w) : 1539 data.sh_contact_dist; 1540 1541 vec3 T, B; 1542 make_orthonormal_basis(L.xyz / L.w, T, B); 1543 1544 vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy); 1545 rand.zw *= fast_sqrt(rand.y) * data.sh_contact_spread; 1546 1547 /* We use the full l_vector.xyz so that the spread is minimize 1548 * if the shading point is further away from the light source */ 1549 vec3 ray_dir = L.xyz + T * rand.z + B * rand.w; 1550 ray_dir = transform_direction(ViewMatrix, ray_dir); 1551 ray_dir = normalize(ray_dir); 1552 1553 vec3 ray_ori = viewPosition; 1554 1555 /* Fix translucency shadowed by contact shadows. */ 1556 vN = (gl_FrontFacing) ? vN : -vN; 1557 1558 if (dot(vN, ray_dir) <= 0.0) { 1559 return vis; 1560 } 1561 1562 float bias = 0.5; /* Constant Bias */ 1563 bias += 1.0 - abs(dot(vN, ray_dir)); /* Angle dependent bias */ 1564 bias *= gl_FrontFacing ? data.sh_contact_offset : -data.sh_contact_offset; 1565 1566 vec3 nor_bias = vN * bias; 1567 ray_ori += nor_bias; 1568 1569 ray_dir *= trace_distance; 1570 ray_dir -= nor_bias; 1571 1572 vec3 hit_pos = raycast( 1573 -1, ray_ori, ray_dir, data.sh_contact_thickness, rand.x, 0.1, 0.001, false); 1574 1575 if (hit_pos.z > 0.0) { 1576 hit_pos = get_view_space_from_depth(hit_pos.xy, hit_pos.z); 1577 float hit_dist = distance(viewPosition, hit_pos); 1578 float dist_ratio = hit_dist / trace_distance; 1579 return vis * saturate(dist_ratio * dist_ratio * dist_ratio); 1580 } 1581 } 1582 # endif 1583 } 1584 #endif 1585 1586 return vis; 1587 } 1588 1589 #ifdef USE_LTC 1590 float light_diffuse(LightData ld, vec3 N, vec3 V, vec4 l_vector) 1591 { 1592 if (ld.l_type == AREA_RECT) { 1593 vec3 corners[4]; 1594 corners[0] = normalize((l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * ld.l_sizey); 1595 corners[1] = normalize((l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * -ld.l_sizey); 1596 corners[2] = normalize((l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * -ld.l_sizey); 1597 corners[3] = normalize((l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * ld.l_sizey); 1598 1599 return ltc_evaluate_quad(corners, N); 1600 } 1601 else if (ld.l_type == AREA_ELLIPSE) { 1602 vec3 points[3]; 1603 points[0] = (l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * -ld.l_sizey; 1604 points[1] = (l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * -ld.l_sizey; 1605 points[2] = (l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * ld.l_sizey; 1606 1607 return ltc_evaluate_disk(N, V, mat3(1.0), points); 1608 } 1609 else { 1610 float radius = ld.l_radius; 1611 radius /= (ld.l_type == SUN) ? 1.0 : l_vector.w; 1612 vec3 L = (ld.l_type == SUN) ? -ld.l_forward : (l_vector.xyz / l_vector.w); 1613 1614 return ltc_evaluate_disk_simple(radius, dot(N, L)); 1615 } 1616 } 1617 1618 float light_specular(LightData ld, vec4 ltc_mat, vec3 N, vec3 V, vec4 l_vector) 1619 { 1620 if (ld.l_type == AREA_RECT) { 1621 vec3 corners[4]; 1622 corners[0] = (l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * ld.l_sizey; 1623 corners[1] = (l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * -ld.l_sizey; 1624 corners[2] = (l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * -ld.l_sizey; 1625 corners[3] = (l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * ld.l_sizey; 1626 1627 ltc_transform_quad(N, V, ltc_matrix(ltc_mat), corners); 1628 1629 return ltc_evaluate_quad(corners, vec3(0.0, 0.0, 1.0)); 1630 } 1631 else { 1632 bool is_ellipse = (ld.l_type == AREA_ELLIPSE); 1633 float radius_x = is_ellipse ? ld.l_sizex : ld.l_radius; 1634 float radius_y = is_ellipse ? ld.l_sizey : ld.l_radius; 1635 1636 vec3 L = (ld.l_type == SUN) ? -ld.l_forward : l_vector.xyz; 1637 vec3 Px = ld.l_right; 1638 vec3 Py = ld.l_up; 1639 1640 if (ld.l_type == SPOT || ld.l_type == POINT) { 1641 make_orthonormal_basis(l_vector.xyz / l_vector.w, Px, Py); 1642 } 1643 1644 vec3 points[3]; 1645 points[0] = (L + Px * -radius_x) + Py * -radius_y; 1646 points[1] = (L + Px * radius_x) + Py * -radius_y; 1647 points[2] = (L + Px * radius_x) + Py * radius_y; 1648 1649 return ltc_evaluate_disk(N, V, ltc_matrix(ltc_mat), points); 1650 } 1651 } 1652 #endif 1653 1654 #define MAX_SSS_SAMPLES 65 1655 #define SSS_LUT_SIZE 64.0 1656 #define SSS_LUT_SCALE ((SSS_LUT_SIZE - 1.0) / float(SSS_LUT_SIZE)) 1657 #define SSS_LUT_BIAS (0.5 / float(SSS_LUT_SIZE)) 1658 1659 #ifdef USE_TRANSLUCENCY 1660 layout(std140) uniform sssProfile 1661 { 1662 vec4 kernel[MAX_SSS_SAMPLES]; 1663 vec4 radii_max_radius; 1664 int sss_samples; 1665 }; 1666 1667 uniform sampler1D sssTexProfile; 1668 1669 vec3 sss_profile(float s) 1670 { 1671 s /= radii_max_radius.w; 1672 return texture(sssTexProfile, saturate(s) * SSS_LUT_SCALE + SSS_LUT_BIAS).rgb; 1673 } 1674 #endif 1675 1676 vec3 light_translucent(LightData ld, vec3 W, vec3 N, vec4 l_vector, float scale) 1677 { 1678 #if !defined(USE_TRANSLUCENCY) || defined(VOLUMETRICS) 1679 return vec3(0.0); 1680 #else 1681 vec3 vis = vec3(1.0); 1682 1683 if (ld.l_type == SPOT) { 1684 vis *= spot_attenuation(ld, l_vector.xyz); 1685 } 1686 if (ld.l_type >= SPOT) { 1687 vis *= step(0.0, -dot(l_vector.xyz, ld.l_forward)); 1688 } 1689 if (ld.l_type != SUN) { 1690 vis *= distance_attenuation(l_vector.w * l_vector.w, ld.l_influence); 1691 } 1692 1693 /* Only shadowed light can produce translucency */ 1694 if (ld.l_shadowid >= 0.0 && vis.x > 0.001) { 1695 ShadowData data = shadows_data[int(ld.l_shadowid)]; 1696 float delta; 1697 1698 vec4 L = (ld.l_type != SUN) ? l_vector : vec4(-ld.l_forward, 1.0); 1699 1700 vec3 T, B; 1701 make_orthonormal_basis(L.xyz / L.w, T, B); 1702 1703 vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy); 1704 rand.zw *= fast_sqrt(rand.y) * data.sh_blur; 1705 1706 /* We use the full l_vector.xyz so that the spread is minimize 1707 * if the shading point is further away from the light source */ 1708 W = W + T * rand.z + B * rand.w; 1709 1710 if (ld.l_type == SUN) { 1711 int scd_id = int(data.sh_data_start); 1712 vec4 view_z = vec4(dot(W - cameraPos, cameraForward)); 1713 1714 vec4 weights = step(shadows_cascade_data[scd_id].split_end_distances, view_z); 1715 float id = abs(4.0 - dot(weights, weights)); 1716 1717 if (id > 3.0) { 1718 return vec3(0.0); 1719 } 1720 1721 float range = abs(data.sh_far - 1722 data.sh_near); /* Same factor as in get_cascade_world_distance(). */ 1723 1724 vec4 shpos = shadows_cascade_data[scd_id].shadowmat[int(id)] * vec4(W, 1.0); 1725 float dist = shpos.z * range; 1726 1727 if (shpos.z > 1.0 || shpos.z < 0.0) { 1728 return vec3(0.0); 1729 } 1730 1731 ShadowSample s = sample_cascade(shpos.xy, data.sh_tex_start + id); 1732 delta = get_depth_delta(dist, s); 1733 } 1734 else { 1735 vec3 cubevec = W - shadows_cube_data[int(data.sh_data_start)].position.xyz; 1736 float dist = length(cubevec); 1737 cubevec /= dist; 1738 1739 ShadowSample s = sample_cube(cubevec, data.sh_tex_start); 1740 delta = get_depth_delta(dist, s); 1741 } 1742 1743 /* XXX : Removing Area Power. */ 1744 /* TODO : put this out of the shader. */ 1745 float falloff; 1746 if (ld.l_type == AREA_RECT || ld.l_type == AREA_ELLIPSE) { 1747 vis *= (ld.l_sizex * ld.l_sizey * 4.0 * M_PI) * (1.0 / 80.0); 1748 if (ld.l_type == AREA_ELLIPSE) { 1749 vis *= M_PI * 0.25; 1750 } 1751 vis *= 0.3 * 20.0 * 1752 max(0.0, dot(-ld.l_forward, l_vector.xyz / l_vector.w)); /* XXX ad hoc, empirical */ 1753 vis /= (l_vector.w * l_vector.w); 1754 falloff = dot(N, l_vector.xyz / l_vector.w); 1755 } 1756 else if (ld.l_type == SUN) { 1757 vis /= 1.0f + (ld.l_radius * ld.l_radius * 0.5f); 1758 vis *= ld.l_radius * ld.l_radius * M_PI; /* Removing area light power*/ 1759 vis *= M_2PI * 0.78; /* Matching cycles with point light. */ 1760 vis *= 0.082; /* XXX ad hoc, empirical */ 1761 falloff = dot(N, -ld.l_forward); 1762 } 1763 else { 1764 vis *= (4.0 * ld.l_radius * ld.l_radius) * (1.0 / 10.0); 1765 vis *= 1.5; /* XXX ad hoc, empirical */ 1766 vis /= (l_vector.w * l_vector.w); 1767 falloff = dot(N, l_vector.xyz / l_vector.w); 1768 } 1769 // vis *= M_1_PI; /* Normalize */ 1770 1771 /* Applying profile */ 1772 vis *= sss_profile(abs(delta) / scale); 1773 1774 /* No transmittance at grazing angle (hide artifacts) */ 1775 vis *= saturate(falloff * 2.0); 1776 } 1777 else { 1778 vis = vec3(0.0); 1779 } 1780 1781 return vis; 1782 #endif 1783 } 1784 1785 /* Based on Frosbite Unified Volumetric. 1786 * https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */ 1787 1788 /* Volume slice to view space depth. */ 1789 float volume_z_to_view_z(float z) 1790 { 1791 if (ProjectionMatrix[3][3] == 0.0) { 1792 /* Exponential distribution */ 1793 return (exp2(z / volDepthParameters.z) - volDepthParameters.x) / volDepthParameters.y; 1794 } 1795 else { 1796 /* Linear distribution */ 1797 return mix(volDepthParameters.x, volDepthParameters.y, z); 1798 } 1799 } 1800 1801 float view_z_to_volume_z(float depth) 1802 { 1803 if (ProjectionMatrix[3][3] == 0.0) { 1804 /* Exponential distribution */ 1805 return volDepthParameters.z * log2(depth * volDepthParameters.y + volDepthParameters.x); 1806 } 1807 else { 1808 /* Linear distribution */ 1809 return (depth - volDepthParameters.x) * volDepthParameters.z; 1810 } 1811 } 1812 1813 /* Volume texture normalized coordinates to NDC (special range [0, 1]). */ 1814 vec3 volume_to_ndc(vec3 cos) 1815 { 1816 cos.z = volume_z_to_view_z(cos.z); 1817 cos.z = get_depth_from_view_z(cos.z); 1818 cos.xy /= volCoordScale.xy; 1819 return cos; 1820 } 1821 1822 vec3 ndc_to_volume(vec3 cos) 1823 { 1824 cos.z = get_view_z_from_depth(cos.z); 1825 cos.z = view_z_to_volume_z(cos.z); 1826 cos.xy *= volCoordScale.xy; 1827 return cos; 1828 } 1829 1830 float phase_function_isotropic() 1831 { 1832 return 1.0 / (4.0 * M_PI); 1833 } 1834 1835 float phase_function(vec3 v, vec3 l, float g) 1836 { 1837 /* Henyey-Greenstein */ 1838 float cos_theta = dot(v, l); 1839 g = clamp(g, -1.0 + 1e-3, 1.0 - 1e-3); 1840 float sqr_g = g * g; 1841 return (1 - sqr_g) / max(1e-8, 4.0 * M_PI * pow(1 + sqr_g - 2 * g * cos_theta, 3.0 / 2.0)); 1842 } 1843 1844 #ifdef LAMPS_LIB 1845 vec3 light_volume(LightData ld, vec4 l_vector) 1846 { 1847 float power; 1848 /* TODO : Area lighting ? */ 1849 /* XXX : Removing Area Power. */ 1850 /* TODO : put this out of the shader. */ 1851 /* See eevee_light_setup(). */ 1852 if (ld.l_type == AREA_RECT || ld.l_type == AREA_ELLIPSE) { 1853 power = (ld.l_sizex * ld.l_sizey * 4.0 * M_PI) * (1.0 / 80.0); 1854 if (ld.l_type == AREA_ELLIPSE) { 1855 power *= M_PI * 0.25; 1856 } 1857 power *= 20.0 * 1858 max(0.0, dot(-ld.l_forward, l_vector.xyz / l_vector.w)); /* XXX ad hoc, empirical */ 1859 } 1860 else if (ld.l_type == SUN) { 1861 power = ld.l_radius * ld.l_radius * M_PI; /* Removing area light power*/ 1862 power /= 1.0f + (ld.l_radius * ld.l_radius * 0.5f); 1863 power *= M_PI * 0.5; /* Matching cycles. */ 1864 } 1865 else { 1866 power = (4.0 * ld.l_radius * ld.l_radius) * (1.0 / 10.0); 1867 power *= M_2PI; /* Matching cycles with point light. */ 1868 } 1869 1870 power /= (l_vector.w * l_vector.w); 1871 1872 /* OPTI: find a better way than calculating this on the fly */ 1873 float lum = dot(ld.l_color, vec3(0.3, 0.6, 0.1)); /* luminance approx. */ 1874 vec3 tint = (lum > 0.0) ? ld.l_color / lum : vec3(1.0); /* normalize lum. to isolate hue+sat */ 1875 1876 lum = min(lum * power, volLightClamp); 1877 1878 return tint * lum; 1879 } 1880 1881 # define VOLUMETRIC_SHADOW_MAX_STEP 32.0 1882 1883 vec3 participating_media_extinction(vec3 wpos, sampler3D volume_extinction) 1884 { 1885 /* Waiting for proper volume shadowmaps and out of frustum shadow map. */ 1886 vec3 ndc = project_point(ViewProjectionMatrix, wpos); 1887 vec3 volume_co = ndc_to_volume(ndc * 0.5 + 0.5); 1888 1889 /* Let the texture be clamped to edge. This reduce visual glitches. */ 1890 return texture(volume_extinction, volume_co).rgb; 1891 } 1892 1893 vec3 light_volume_shadow(LightData ld, vec3 ray_wpos, vec4 l_vector, sampler3D volume_extinction) 1894 { 1895 # if defined(VOLUME_SHADOW) 1896 /* Heterogeneous volume shadows */ 1897 float dd = l_vector.w / volShadowSteps; 1898 vec3 L = l_vector.xyz * l_vector.w; 1899 vec3 shadow = vec3(1.0); 1900 for (float s = 0.5; s < VOLUMETRIC_SHADOW_MAX_STEP && s < (volShadowSteps - 0.1); s += 1.0) { 1901 vec3 pos = ray_wpos + L * (s / volShadowSteps); 1902 vec3 s_extinction = participating_media_extinction(pos, volume_extinction); 1903 shadow *= exp(-s_extinction * dd); 1904 } 1905 return shadow; 1906 # else 1907 return vec3(1.0); 1908 # endif /* VOLUME_SHADOW */ 1909 } 1910 #endif 1911 1912 #ifdef IRRADIANCE_LIB 1913 vec3 irradiance_volumetric(vec3 wpos) 1914 { 1915 # ifdef IRRADIANCE_HL2 1916 IrradianceData ir_data = load_irradiance_cell(0, vec3(1.0)); 1917 vec3 irradiance = ir_data.cubesides[0] + ir_data.cubesides[1] + ir_data.cubesides[2]; 1918 ir_data = load_irradiance_cell(0, vec3(-1.0)); 1919 irradiance += ir_data.cubesides[0] + ir_data.cubesides[1] + ir_data.cubesides[2]; 1920 irradiance *= 0.16666666; /* 1/6 */ 1921 return irradiance; 1922 # else 1923 return vec3(0.0); 1924 # endif 1925 } 1926 #endif 1927 1928 uniform sampler3D inScattering; 1929 uniform sampler3D inTransmittance; 1930 1931 void volumetric_resolve(vec2 frag_uvs, 1932 float frag_depth, 1933 out vec3 transmittance, 1934 out vec3 scattering) 1935 { 1936 vec3 volume_cos = ndc_to_volume(vec3(frag_uvs, frag_depth)); 1937 1938 scattering = texture(inScattering, volume_cos).rgb; 1939 transmittance = texture(inTransmittance, volume_cos).rgb; 1940 } 1941 1942 /* Based on Frosbite Unified Volumetric. 1943 * https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */ 1944 1945 /* Step 2 : Evaluate all light scattering for each froxels. 1946 * Also do the temporal reprojection to fight aliasing artifacts. */ 1947 1948 uniform sampler3D volumeScattering; 1949 uniform sampler3D volumeExtinction; 1950 uniform sampler3D volumeEmission; 1951 uniform sampler3D volumePhase; 1952 1953 uniform sampler3D historyScattering; 1954 uniform sampler3D historyTransmittance; 1955 1956 flat in int slice; 1957 1958 layout(location = 0) out vec4 outScattering; 1959 layout(location = 1) out vec4 outTransmittance; 1960 1961 void main() 1962 { 1963 ivec3 volume_cell = ivec3(gl_FragCoord.xy, slice); 1964 1965 /* Emission */ 1966 outScattering = texelFetch(volumeEmission, volume_cell, 0); 1967 outTransmittance = texelFetch(volumeExtinction, volume_cell, 0); 1968 vec3 s_scattering = texelFetch(volumeScattering, volume_cell, 0).rgb; 1969 vec3 volume_ndc = volume_to_ndc((vec3(volume_cell) + volJitter.xyz) * volInvTexSize.xyz); 1970 vec3 worldPosition = get_world_space_from_depth(volume_ndc.xy, volume_ndc.z); 1971 vec3 wdir = cameraVec; 1972 1973 vec2 phase = texelFetch(volumePhase, volume_cell, 0).rg; 1974 float s_anisotropy = phase.x / max(1.0, phase.y); 1975 1976 /* Environment : Average color. */ 1977 outScattering.rgb += irradiance_volumetric(worldPosition) * s_scattering * 1978 phase_function_isotropic(); 1979 1980 #ifdef VOLUME_LIGHTING /* Lights */ 1981 for (int i = 0; i < MAX_LIGHT && i < laNumLight; ++i) { 1982 1983 LightData ld = lights_data[i]; 1984 1985 vec4 l_vector; 1986 l_vector.xyz = (ld.l_type == SUN) ? -ld.l_forward : ld.l_position - worldPosition; 1987 l_vector.w = length(l_vector.xyz); 1988 1989 float Vis = light_visibility(ld, worldPosition, l_vector); 1990 1991 vec3 Li = light_volume(ld, l_vector) * 1992 light_volume_shadow(ld, worldPosition, l_vector, volumeExtinction); 1993 1994 outScattering.rgb += Li * Vis * s_scattering * 1995 phase_function(-wdir, l_vector.xyz / l_vector.w, s_anisotropy); 1996 } 1997 #endif 1998 1999 /* Temporal supersampling */ 2000 /* Note : this uses the cell non-jittered position (texel center). */ 2001 vec3 curr_ndc = volume_to_ndc(vec3(gl_FragCoord.xy, float(slice) + 0.5) * volInvTexSize.xyz); 2002 vec3 wpos = get_world_space_from_depth(curr_ndc.xy, curr_ndc.z); 2003 vec3 prev_ndc = project_point(pastViewProjectionMatrix, wpos); 2004 vec3 prev_volume = ndc_to_volume(prev_ndc * 0.5 + 0.5); 2005 2006 if ((volHistoryAlpha > 0.0) && all(greaterThan(prev_volume, vec3(0.0))) && 2007 all(lessThan(prev_volume, vec3(1.0)))) { 2008 vec4 h_Scattering = texture(historyScattering, prev_volume); 2009 vec4 h_Transmittance = texture(historyTransmittance, prev_volume); 2010 outScattering = mix(outScattering, h_Scattering, volHistoryAlpha); 2011 outTransmittance = mix(outTransmittance, h_Transmittance, volHistoryAlpha); 2012 } 2013 2014 /* Catch NaNs */ 2015 if (any(isnan(outScattering)) || any(isnan(outTransmittance))) { 2016 outScattering = vec4(0.0); 2017 outTransmittance = vec4(1.0); 2018 } 2019 } Number of Geometry Uniforms exceeds HW limits. Error : EXCEPTION_ACCESS_VIOLATION Address : 0x0000000140FE1CB0 Module : C:\Program Files\Blender Foundation\Blender\blender.exe C:\Program Files\Blender Foundation\Blender>