Godot Engine v4.1.dev1.official.db1302637 - https://godotengine.org TextServer: Added interface "Dummy" TextServer: Added interface "ICU / HarfBuzz / Graphite (Built-in)" Text-to-Speech: SAPI initialized. Using "winink" pen tablet driver... OpenGL debugging not supported! 1: #version 330 2: #define USE_GLES_OVER_GL 3: #define USE_RADIANCE_MAP 4: 5: #define MAX_GLOBAL_SHADER_UNIFORMS 256 6: 7: #define MAX_LIGHT_DATA_STRUCTS 32 8: 9: #define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS 8 10: 11: #define MAX_FORWARD_LIGHTS uint(8) 12: #define BASE_PASS 13: 14: #ifdef USE_MULTIVIEW 15: #if defined(GL_OVR_multiview2) 16: #extension GL_OVR_multiview2 : require 17: #elif defined(GL_OVR_multiview) 18: #extension GL_OVR_multiview : require 19: #endif 20: #define ViewIndex gl_ViewID_OVR 21: #define MAX_VIEWS 2 22: #else 23: #define ViewIndex uint(0) 24: #define MAX_VIEWS 1 25: #endif 26: precision highp float; 27: precision highp int; 28: 29: // Default to SPECULAR_SCHLICK_GGX. 30: #if !defined(SPECULAR_DISABLED) && !defined(SPECULAR_SCHLICK_GGX) && !defined(SPECULAR_TOON) 31: #define SPECULAR_SCHLICK_GGX 32: #endif 33: 34: #if !defined(MODE_RENDER_DEPTH) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) ||defined(LIGHT_CLEARCOAT_USED) 35: #ifndef NORMAL_USED 36: #define NORMAL_USED 37: #endif 38: #endif 39: 40: #ifndef MODE_RENDER_DEPTH 41: #ifdef USE_BCS 42: uniform vec3 bcs; 43: #endif 44: 45: #ifdef USE_COLOR_CORRECTION 46: #ifdef USE_1D_LUT 47: uniform sampler2D source_color_correction; //texunit:-1 48: #else 49: uniform sampler3D source_color_correction; //texunit:-1 50: #endif 51: #endif 52: 53: layout(std140) uniform TonemapData { //ubo:0 54: float exposure; 55: float white; 56: int tonemapper; 57: int pad; 58: }; 59: 60: vec3 apply_bcs(vec3 color, vec3 bcs) { 61: color = mix(vec3(0.0), color, bcs.x); 62: color = mix(vec3(0.5), color, bcs.y); 63: color = mix(vec3(dot(vec3(1.0), color) * 0.33333), color, bcs.z); 64: 65: return color; 66: } 67: #ifdef USE_COLOR_CORRECTION 68: #ifdef USE_1D_LUT 69: vec3 apply_color_correction(vec3 color) { 70: color.r = texture(source_color_correction, vec2(color.r, 0.0f)).r; 71: color.g = texture(source_color_correction, vec2(color.g, 0.0f)).g; 72: color.b = texture(source_color_correction, vec2(color.b, 0.0f)).b; 73: return color; 74: } 75: #else 76: vec3 apply_color_correction(vec3 color) { 77: return textureLod(source_color_correction, color, 0.0).rgb; 78: } 79: #endif 80: #endif 81: 82: vec3 tonemap_filmic(vec3 color, float p_white) { 83: // exposure bias: input scale (color *= bias, white *= bias) to make the brightness consistent with other tonemappers 84: // also useful to scale the input to the range that the tonemapper is designed for (some require very high input values) 85: // has no effect on the curve's general shape or visual properties 86: const float exposure_bias = 2.0f; 87: const float A = 0.22f * exposure_bias * exposure_bias; // bias baked into constants for performance 88: const float B = 0.30f * exposure_bias; 89: const float C = 0.10f; 90: const float D = 0.20f; 91: const float E = 0.01f; 92: const float F = 0.30f; 93: 94: vec3 color_tonemapped = ((color * (A * color + C * B) + D * E) / (color * (A * color + B) + D * F)) - E / F; 95: float p_white_tonemapped = ((p_white * (A * p_white + C * B) + D * E) / (p_white * (A * p_white + B) + D * F)) - E / F; 96: 97: return color_tonemapped / p_white_tonemapped; 98: } 99: 100: // Adapted from https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl 101: // (MIT License). 102: vec3 tonemap_aces(vec3 color, float p_white) { 103: const float exposure_bias = 1.8f; 104: const float A = 0.0245786f; 105: const float B = 0.000090537f; 106: const float C = 0.983729f; 107: const float D = 0.432951f; 108: const float E = 0.238081f; 109: 110: // Exposure bias baked into transform to save shader instructions. Equivalent to `color *= exposure_bias` 111: const mat3 rgb_to_rrt = mat3( 112: vec3(0.59719f * exposure_bias, 0.35458f * exposure_bias, 0.04823f * exposure_bias), 113: vec3(0.07600f * exposure_bias, 0.90834f * exposure_bias, 0.01566f * exposure_bias), 114: vec3(0.02840f * exposure_bias, 0.13383f * exposure_bias, 0.83777f * exposure_bias)); 115: 116: const mat3 odt_to_rgb = mat3( 117: vec3(1.60475f, -0.53108f, -0.07367f), 118: vec3(-0.10208f, 1.10813f, -0.00605f), 119: vec3(-0.00327f, -0.07276f, 1.07602f)); 120: 121: color *= rgb_to_rrt; 122: vec3 color_tonemapped = (color * (color + A) - B) / (color * (C * color + D) + E); 123: color_tonemapped *= odt_to_rgb; 124: 125: p_white *= exposure_bias; 126: float p_white_tonemapped = (p_white * (p_white + A) - B) / (p_white * (C * p_white + D) + E); 127: 128: return color_tonemapped / p_white_tonemapped; 129: } 130: 131: vec3 tonemap_reinhard(vec3 color, float p_white) { 132: return (p_white * color + color) / (color * p_white + p_white); 133: } 134: 135: // This expects 0-1 range input. 136: vec3 linear_to_srgb(vec3 color) { 137: //color = clamp(color, vec3(0.0), vec3(1.0)); 138: //const vec3 a = vec3(0.055f); 139: //return mix((vec3(1.0f) + a) * pow(color.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * color.rgb, lessThan(color.rgb, vec3(0.0031308f))); 140: // Approximation from http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html 141: return max(vec3(1.055) * pow(color, vec3(0.416666667)) - vec3(0.055), vec3(0.0)); 142: } 143: 144: // This expects 0-1 range input, outside that range it behaves poorly. 145: vec3 srgb_to_linear(vec3 color) { 146: // Approximation from http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html 147: return color * (color * (color * 0.305306011 + 0.682171111) + 0.012522878); 148: } 149: 150: #define TONEMAPPER_LINEAR 0 151: #define TONEMAPPER_REINHARD 1 152: #define TONEMAPPER_FILMIC 2 153: #define TONEMAPPER_ACES 3 154: 155: vec3 apply_tonemapping(vec3 color, float p_white) { // inputs are LINEAR, always outputs clamped [0;1] color 156: // Ensure color values passed to tonemappers are positive. 157: // They can be negative in the case of negative lights, which leads to undesired behavior. 158: if (tonemapper == TONEMAPPER_LINEAR) { 159: return color; 160: } else if (tonemapper == TONEMAPPER_REINHARD) { 161: return tonemap_reinhard(max(vec3(0.0f), color), p_white); 162: } else if (tonemapper == TONEMAPPER_FILMIC) { 163: return tonemap_filmic(max(vec3(0.0f), color), p_white); 164: } else { // TONEMAPPER_ACES 165: return tonemap_aces(max(vec3(0.0f), color), p_white); 166: } 167: } 168: #endif 169: 170: #ifdef USE_GLES_OVER_GL 171: // Floating point pack/unpack functions are part of the GLSL ES 300 specification used by web and mobile. 172: uint float2half(uint f) { 173: uint e = f & uint(0x7f800000); 174: if (e <= uint(0x38000000)) { 175: return uint(0); 176: } else { 177: return ((f >> uint(16)) & uint(0x8000)) | 178: (((e - uint(0x38000000)) >> uint(13)) & uint(0x7c00)) | 179: ((f >> uint(13)) & uint(0x03ff)); 180: } 181: } 182: 183: uint half2float(uint h) { 184: uint h_e = h & uint(0x7c00); 185: return ((h & uint(0x8000)) << uint(16)) | uint((h_e >> uint(10)) != uint(0)) * (((h_e + uint(0x1c000)) << uint(13)) | ((h & uint(0x03ff)) << uint(13))); 186: } 187: 188: uint packHalf2x16(vec2 v) { 189: return float2half(floatBitsToUint(v.x)) | float2half(floatBitsToUint(v.y)) << uint(16); 190: } 191: 192: vec2 unpackHalf2x16(uint v) { 193: return vec2(uintBitsToFloat(half2float(v & uint(0xffff))), 194: uintBitsToFloat(half2float(v >> uint(16)))); 195: } 196: 197: uint packUnorm2x16(vec2 v) { 198: uvec2 uv = uvec2(round(clamp(v, vec2(0.0), vec2(1.0)) * 65535.0)); 199: return uv.x | uv.y << uint(16); 200: } 201: 202: vec2 unpackUnorm2x16(uint p) { 203: return vec2(float(p & uint(0xffff)), float(p >> uint(16))) * 0.000015259021; // 1.0 / 65535.0 optimization 204: } 205: 206: uint packSnorm2x16(vec2 v) { 207: uvec2 uv = uvec2(round(clamp(v, vec2(-1.0), vec2(1.0)) * 32767.0) + 32767.0); 208: return uv.x | uv.y << uint(16); 209: } 210: 211: vec2 unpackSnorm2x16(uint p) { 212: vec2 v = vec2(float(p & uint(0xffff)), float(p >> uint(16))); 213: return clamp((v - 32767.0) * vec2(0.00003051851), vec2(-1.0), vec2(1.0)); 214: } 215: 216: #endif 217: 218: // Compatibility renames. These are exposed with the "godot_" prefix 219: // to work around an Adreno bug which was exposing these ES310 functions 220: // in ES300 shaders. Internally, we must use the "godot_" prefix, but user shaders 221: // will be mapped automatically. 222: uint godot_packUnorm4x8(vec4 v) { 223: uvec4 uv = uvec4(round(clamp(v, vec4(0.0), vec4(1.0)) * 255.0)); 224: return uv.x | (uv.y << uint(8)) | (uv.z << uint(16)) | (uv.w << uint(24)); 225: } 226: 227: vec4 godot_unpackUnorm4x8(uint p) { 228: return vec4(float(p & uint(0xff)), float((p >> uint(8)) & uint(0xff)), float((p >> uint(16)) & uint(0xff)), float(p >> uint(24))) * 0.00392156862; // 1.0 / 255.0 229: } 230: 231: uint godot_packSnorm4x8(vec4 v) { 232: uvec4 uv = uvec4(round(clamp(v, vec4(-1.0), vec4(1.0)) * 127.0) + 127.0); 233: return uv.x | uv.y << uint(8) | uv.z << uint(16) | uv.w << uint(24); 234: } 235: 236: vec4 godot_unpackSnorm4x8(uint p) { 237: vec4 v = vec4(float(p & uint(0xff)), float((p >> uint(8)) & uint(0xff)), float((p >> uint(16)) & uint(0xff)), float(p >> uint(24))); 238: return clamp((v - vec4(127.0)) * vec4(0.00787401574), vec4(-1.0), vec4(1.0)); 239: } 240: 241: #define packUnorm4x8 godot_packUnorm4x8 242: #define unpackUnorm4x8 godot_unpackUnorm4x8 243: #define packSnorm4x8 godot_packSnorm4x8 244: #define unpackSnorm4x8 godot_unpackSnorm4x8 245: 246: /* texture unit usage, N is max_texture_unity-N 247: 248: 1-color correction // In tonemap_inc.glsl 249: 2-radiance 250: 3-directional_shadow 251: 4-positional_shadow 252: 5-screen 253: 6-depth 254: 255: */ 256: 257: #define M_PI 3.14159265359 258: /* clang-format on */ 259: 260: #define SHADER_IS_SRGB true 261: 262: /* Varyings */ 263: 264: #if defined(COLOR_USED) 265: in vec4 color_interp; 266: #endif 267: 268: #if defined(UV_USED) 269: in vec2 uv_interp; 270: #endif 271: 272: #if defined(UV2_USED) 273: in vec2 uv2_interp; 274: #else 275: #ifdef USE_LIGHTMAP 276: in vec2 uv2_interp; 277: #endif 278: #endif 279: 280: #if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) 281: in vec3 tangent_interp; 282: in vec3 binormal_interp; 283: #endif 284: 285: #ifdef NORMAL_USED 286: in vec3 normal_interp; 287: #endif 288: 289: in highp vec3 vertex_interp; 290: 291: #ifdef USE_RADIANCE_MAP 292: 293: #define RADIANCE_MAX_LOD 5.0 294: 295: uniform samplerCube radiance_map; // texunit:-2 296: 297: #endif 298: 299: layout(std140) uniform GlobalShaderUniformData { //ubo:1 300: vec4 global_shader_uniforms[MAX_GLOBAL_SHADER_UNIFORMS]; 301: }; 302: 303: /* Material Uniforms */ 304: 305: #ifdef MATERIAL_UNIFORMS_USED 306: 307: /* clang-format off */ 308: layout(std140) uniform MaterialUniforms { // ubo:3 309: 310: 311: }; 312: /* clang-format on */ 313: 314: #endif 315: 316: layout(std140) uniform SceneData { // ubo:2 317: highp mat4 projection_matrix; 318: highp mat4 inv_projection_matrix; 319: highp mat4 inv_view_matrix; 320: highp mat4 view_matrix; 321: 322: vec2 viewport_size; 323: vec2 screen_pixel_size; 324: 325: mediump vec4 ambient_light_color_energy; 326: 327: mediump float ambient_color_sky_mix; 328: bool material_uv2_mode; 329: float emissive_exposure_normalization; 330: bool use_ambient_light; 331: bool use_ambient_cubemap; 332: bool use_reflection_cubemap; 333: 334: float fog_aerial_perspective; 335: float time; 336: 337: mat3 radiance_inverse_xform; 338: 339: uint directional_light_count; 340: float z_far; 341: float z_near; 342: float IBL_exposure_normalization; 343: 344: bool fog_enabled; 345: float fog_density; 346: float fog_height; 347: float fog_height_density; 348: 349: vec3 fog_light_color; 350: float fog_sun_scatter; 351: uint camera_visible_layers; 352: uint pad3; 353: uint pad4; 354: uint pad5; 355: } 356: scene_data; 357: 358: #ifdef USE_MULTIVIEW 359: layout(std140) uniform MultiviewData { // ubo:8 360: highp mat4 projection_matrix_view[MAX_VIEWS]; 361: highp mat4 inv_projection_matrix_view[MAX_VIEWS]; 362: highp vec4 eye_offset[MAX_VIEWS]; 363: } 364: multiview_data; 365: #endif 366: 367: /* clang-format off */ 368: 369: 370: /* clang-format on */ 371: 372: // Directional light data. 373: #ifndef DISABLE_LIGHT_DIRECTIONAL 374: 375: struct DirectionalLightData { 376: mediump vec3 direction; 377: mediump float energy; 378: mediump vec3 color; 379: mediump float size; 380: mediump vec3 pad; 381: mediump float specular; 382: }; 383: 384: layout(std140) uniform DirectionalLights { // ubo:7 385: DirectionalLightData directional_lights[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS]; 386: }; 387: 388: #endif // !DISABLE_LIGHT_DIRECTIONAL 389: 390: // Omni and spot light data. 391: #if !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) 392: 393: struct LightData { // This structure needs to be as packed as possible. 394: highp vec3 position; 395: highp float inv_radius; 396: 397: mediump vec3 direction; 398: highp float size; 399: 400: mediump vec3 color; 401: mediump float attenuation; 402: 403: mediump float cone_attenuation; 404: mediump float cone_angle; 405: mediump float specular_amount; 406: mediump float shadow_opacity; 407: }; 408: 409: #ifndef DISABLE_LIGHT_OMNI 410: layout(std140) uniform OmniLightData { // ubo:5 411: LightData omni_lights[MAX_LIGHT_DATA_STRUCTS]; 412: }; 413: uniform uint omni_light_indices[MAX_FORWARD_LIGHTS]; 414: uniform uint omni_light_count; 415: #endif 416: 417: #ifndef DISABLE_LIGHT_SPOT 418: layout(std140) uniform SpotLightData { // ubo:6 419: LightData spot_lights[MAX_LIGHT_DATA_STRUCTS]; 420: }; 421: uniform uint spot_light_indices[MAX_FORWARD_LIGHTS]; 422: uniform uint spot_light_count; 423: #endif 424: 425: #ifdef USE_ADDITIVE_LIGHTING 426: uniform highp samplerCubeShadow positional_shadow; // texunit:-4 427: #endif 428: 429: #endif // !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) 430: 431: #ifdef USE_MULTIVIEW 432: uniform highp sampler2DArray depth_buffer; // texunit:-6 433: uniform highp sampler2DArray color_buffer; // texunit:-5 434: vec3 multiview_uv(vec2 uv) { 435: return vec3(uv, ViewIndex); 436: } 437: #else 438: uniform highp sampler2D depth_buffer; // texunit:-6 439: uniform highp sampler2D color_buffer; // texunit:-5 440: vec2 multiview_uv(vec2 uv) { 441: return uv; 442: } 443: #endif 444: 445: uniform highp mat4 world_transform; 446: uniform mediump float opaque_prepass_threshold; 447: 448: layout(location = 0) out vec4 frag_color; 449: 450: vec3 F0(float metallic, float specular, vec3 albedo) { 451: float dielectric = 0.16 * specular * specular; 452: // use albedo * metallic as colored specular reflectance at 0 angle for metallic materials; 453: // see https://google.github.io/filament/Filament.md.html 454: return mix(vec3(dielectric), albedo, vec3(metallic)); 455: } 456: 457: #if !defined(DISABLE_LIGHT_DIRECTIONAL) || !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) 458: 459: float D_GGX(float cos_theta_m, float alpha) { 460: float a = cos_theta_m * alpha; 461: float k = alpha / (1.0 - cos_theta_m * cos_theta_m + a * a); 462: return k * k * (1.0 / M_PI); 463: } 464: 465: // From Earl Hammon, Jr. "PBR Diffuse Lighting for GGX+Smith Microsurfaces" https://www.gdcvault.com/play/1024478/PBR-Diffuse-Lighting-for-GGX 466: float V_GGX(float NdotL, float NdotV, float alpha) { 467: return 0.5 / mix(2.0 * NdotL * NdotV, NdotL + NdotV, alpha); 468: } 469: 470: float D_GGX_anisotropic(float cos_theta_m, float alpha_x, float alpha_y, float cos_phi, float sin_phi) { 471: float alpha2 = alpha_x * alpha_y; 472: highp vec3 v = vec3(alpha_y * cos_phi, alpha_x * sin_phi, alpha2 * cos_theta_m); 473: highp float v2 = dot(v, v); 474: float w2 = alpha2 / v2; 475: float D = alpha2 * w2 * w2 * (1.0 / M_PI); 476: return D; 477: } 478: 479: float V_GGX_anisotropic(float alpha_x, float alpha_y, float TdotV, float TdotL, float BdotV, float BdotL, float NdotV, float NdotL) { 480: float Lambda_V = NdotL * length(vec3(alpha_x * TdotV, alpha_y * BdotV, NdotV)); 481: float Lambda_L = NdotV * length(vec3(alpha_x * TdotL, alpha_y * BdotL, NdotL)); 482: return 0.5 / (Lambda_V + Lambda_L); 483: } 484: 485: float SchlickFresnel(float u) { 486: float m = 1.0 - u; 487: float m2 = m * m; 488: return m2 * m2 * m; // pow(m,5) 489: } 490: 491: void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float attenuation, vec3 f0, float roughness, float metallic, float specular_amount, vec3 albedo, inout float alpha, 492: #ifdef LIGHT_BACKLIGHT_USED 493: vec3 backlight, 494: #endif 495: #ifdef LIGHT_RIM_USED 496: float rim, float rim_tint, 497: #endif 498: #ifdef LIGHT_CLEARCOAT_USED 499: float clearcoat, float clearcoat_roughness, vec3 vertex_normal, 500: #endif 501: #ifdef LIGHT_ANISOTROPY_USED 502: vec3 B, vec3 T, float anisotropy, 503: #endif 504: inout vec3 diffuse_light, inout vec3 specular_light) { 505: 506: #if defined(USE_LIGHT_SHADER_CODE) 507: // light is written by the light shader 508: 509: vec3 normal = N; 510: vec3 light = L; 511: vec3 view = V; 512: 513: /* clang-format off */ 514: 515: 516: /* clang-format on */ 517: 518: #else 519: float NdotL = min(A + dot(N, L), 1.0); 520: float cNdotL = max(NdotL, 0.0); // clamped NdotL 521: float NdotV = dot(N, V); 522: float cNdotV = max(NdotV, 1e-4); 523: 524: #if defined(DIFFUSE_BURLEY) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED) 525: vec3 H = normalize(V + L); 526: #endif 527: 528: #if defined(SPECULAR_SCHLICK_GGX) 529: float cNdotH = clamp(A + dot(N, H), 0.0, 1.0); 530: #endif 531: 532: #if defined(DIFFUSE_BURLEY) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED) 533: float cLdotH = clamp(A + dot(L, H), 0.0, 1.0); 534: #endif 535: 536: if (metallic < 1.0) { 537: float diffuse_brdf_NL; // BRDF times N.L for calculating diffuse radiance 538: 539: #if defined(DIFFUSE_LAMBERT_WRAP) 540: // Energy conserving lambert wrap shader. 541: // https://web.archive.org/web/20210228210901/http://blog.stevemcauley.com/2011/12/03/energy-conserving-wrapped-diffuse/ 542: diffuse_brdf_NL = max(0.0, (NdotL + roughness) / ((1.0 + roughness) * (1.0 + roughness))) * (1.0 / M_PI); 543: #elif defined(DIFFUSE_TOON) 544: diffuse_brdf_NL = smoothstep(-roughness, max(roughness, 0.01), NdotL) * (1.0 / M_PI); 545: #elif defined(DIFFUSE_BURLEY) 546: { 547: float FD90_minus_1 = 2.0 * cLdotH * cLdotH * roughness - 0.5; 548: float FdV = 1.0 + FD90_minus_1 * SchlickFresnel(cNdotV); 549: float FdL = 1.0 + FD90_minus_1 * SchlickFresnel(cNdotL); 550: diffuse_brdf_NL = (1.0 / M_PI) * FdV * FdL * cNdotL; 551: } 552: #else 553: // Lambert 554: diffuse_brdf_NL = cNdotL * (1.0 / M_PI); 555: #endif 556: 557: diffuse_light += light_color * diffuse_brdf_NL * attenuation; 558: 559: #if defined(LIGHT_BACKLIGHT_USED) 560: diffuse_light += light_color * (vec3(1.0 / M_PI) - diffuse_brdf_NL) * backlight * attenuation; 561: #endif 562: 563: #if defined(LIGHT_RIM_USED) 564: // Epsilon min to prevent pow(0, 0) singularity which results in undefined behavior. 565: float rim_light = pow(max(1e-4, 1.0 - cNdotV), max(0.0, (1.0 - roughness) * 16.0)); 566: diffuse_light += rim_light * rim * mix(vec3(1.0), albedo, rim_tint) * light_color; 567: #endif 568: } 569: 570: if (roughness > 0.0) { // FIXME: roughness == 0 should not disable specular light entirely 571: 572: // D 573: 574: #if defined(SPECULAR_TOON) 575: 576: vec3 R = normalize(-reflect(L, N)); 577: float RdotV = dot(R, V); 578: float mid = 1.0 - roughness; 579: mid *= mid; 580: float intensity = smoothstep(mid - roughness * 0.5, mid + roughness * 0.5, RdotV) * mid; 581: diffuse_light += light_color * intensity * attenuation * specular_amount; // write to diffuse_light, as in toon shading you generally want no reflection 582: 583: #elif defined(SPECULAR_DISABLED) 584: // none.. 585: 586: #elif defined(SPECULAR_SCHLICK_GGX) 587: // shlick+ggx as default 588: float alpha_ggx = roughness * roughness; 589: #if defined(LIGHT_ANISOTROPY_USED) 590: float aspect = sqrt(1.0 - anisotropy * 0.9); 591: float ax = alpha_ggx / aspect; 592: float ay = alpha_ggx * aspect; 593: float XdotH = dot(T, H); 594: float YdotH = dot(B, H); 595: float D = D_GGX_anisotropic(cNdotH, ax, ay, XdotH, YdotH); 596: float G = V_GGX_anisotropic(ax, ay, dot(T, V), dot(T, L), dot(B, V), dot(B, L), cNdotV, cNdotL); 597: #else 598: float D = D_GGX(cNdotH, alpha_ggx); 599: float G = V_GGX(cNdotL, cNdotV, alpha_ggx); 600: #endif // LIGHT_ANISOTROPY_USED 601: // F 602: float cLdotH5 = SchlickFresnel(cLdotH); 603: // Calculate Fresnel using cheap approximate specular occlusion term from Filament: 604: // https://google.github.io/filament/Filament.html#lighting/occlusion/specularocclusion 605: float f90 = clamp(50.0 * f0.g, 0.0, 1.0); 606: vec3 F = f0 + (f90 - f0) * cLdotH5; 607: 608: vec3 specular_brdf_NL = cNdotL * D * F * G; 609: 610: specular_light += specular_brdf_NL * light_color * attenuation * specular_amount; 611: #endif 612: 613: #if defined(LIGHT_CLEARCOAT_USED) 614: // Clearcoat ignores normal_map, use vertex normal instead 615: float ccNdotL = max(min(A + dot(vertex_normal, L), 1.0), 0.0); 616: float ccNdotH = clamp(A + dot(vertex_normal, H), 0.0, 1.0); 617: float ccNdotV = max(dot(vertex_normal, V), 1e-4); 618: 619: #if !defined(SPECULAR_SCHLICK_GGX) 620: float cLdotH5 = SchlickFresnel(cLdotH); 621: #endif 622: float Dr = D_GGX(ccNdotH, mix(0.001, 0.1, clearcoat_roughness)); 623: float Gr = 0.25 / (cLdotH * cLdotH); 624: float Fr = mix(.04, 1.0, cLdotH5); 625: float clearcoat_specular_brdf_NL = clearcoat * Gr * Fr * Dr * cNdotL; 626: 627: specular_light += clearcoat_specular_brdf_NL * light_color * attenuation * specular_amount; 628: // TODO: Clearcoat adds light to the scene right now (it is non-energy conserving), both diffuse and specular need to be scaled by (1.0 - FR) 629: // but to do so we need to rearrange this entire function 630: #endif // LIGHT_CLEARCOAT_USED 631: } 632: 633: #ifdef USE_SHADOW_TO_OPACITY 634: alpha = min(alpha, clamp(1.0 - attenuation, 0.0, 1.0)); 635: #endif 636: 637: #endif // LIGHT_CODE_USED 638: } 639: 640: float get_omni_spot_attenuation(float distance, float inv_range, float decay) { 641: float nd = distance * inv_range; 642: nd *= nd; 643: nd *= nd; // nd^4 644: nd = max(1.0 - nd, 0.0); 645: nd *= nd; // nd^2 646: return nd * pow(max(distance, 0.0001), -decay); 647: } 648: 649: #ifndef DISABLE_LIGHT_OMNI 650: void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f0, float roughness, float metallic, float shadow, vec3 albedo, inout float alpha, 651: #ifdef LIGHT_BACKLIGHT_USED 652: vec3 backlight, 653: #endif 654: #ifdef LIGHT_RIM_USED 655: float rim, float rim_tint, 656: #endif 657: #ifdef LIGHT_CLEARCOAT_USED 658: float clearcoat, float clearcoat_roughness, vec3 vertex_normal, 659: #endif 660: #ifdef LIGHT_ANISOTROPY_USED 661: vec3 binormal, vec3 tangent, float anisotropy, 662: #endif 663: inout vec3 diffuse_light, inout vec3 specular_light) { 664: vec3 light_rel_vec = omni_lights[idx].position - vertex; 665: float light_length = length(light_rel_vec); 666: float omni_attenuation = get_omni_spot_attenuation(light_length, omni_lights[idx].inv_radius, omni_lights[idx].attenuation); 667: vec3 color = omni_lights[idx].color; 668: float size_A = 0.0; 669: 670: if (omni_lights[idx].size > 0.0) { 671: float t = omni_lights[idx].size / max(0.001, light_length); 672: size_A = max(0.0, 1.0 - 1.0 / sqrt(1.0 + t * t)); 673: } 674: 675: light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color, omni_attenuation, f0, roughness, metallic, omni_lights[idx].specular_amount, albedo, alpha, 676: #ifdef LIGHT_BACKLIGHT_USED 677: backlight, 678: #endif 679: #ifdef LIGHT_RIM_USED 680: rim * omni_attenuation, rim_tint, 681: #endif 682: #ifdef LIGHT_CLEARCOAT_USED 683: clearcoat, clearcoat_roughness, vertex_normal, 684: #endif 685: #ifdef LIGHT_ANISOTROPY_USED 686: binormal, tangent, anisotropy, 687: #endif 688: diffuse_light, 689: specular_light); 690: } 691: #endif // !DISABLE_LIGHT_OMNI 692: 693: #ifndef DISABLE_LIGHT_SPOT 694: void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f0, float roughness, float metallic, float shadow, vec3 albedo, inout float alpha, 695: #ifdef LIGHT_BACKLIGHT_USED 696: vec3 backlight, 697: #endif 698: #ifdef LIGHT_RIM_USED 699: float rim, float rim_tint, 700: #endif 701: #ifdef LIGHT_CLEARCOAT_USED 702: float clearcoat, float clearcoat_roughness, vec3 vertex_normal, 703: #endif 704: #ifdef LIGHT_ANISOTROPY_USED 705: vec3 binormal, vec3 tangent, float anisotropy, 706: #endif 707: inout vec3 diffuse_light, 708: inout vec3 specular_light) { 709: 710: vec3 light_rel_vec = spot_lights[idx].position - vertex; 711: float light_length = length(light_rel_vec); 712: float spot_attenuation = get_omni_spot_attenuation(light_length, spot_lights[idx].inv_radius, spot_lights[idx].attenuation); 713: vec3 spot_dir = spot_lights[idx].direction; 714: float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_lights[idx].cone_angle); 715: float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_lights[idx].cone_angle)); 716: spot_attenuation *= 1.0 - pow(spot_rim, spot_lights[idx].cone_attenuation); 717: vec3 color = spot_lights[idx].color; 718: 719: float size_A = 0.0; 720: 721: if (spot_lights[idx].size > 0.0) { 722: float t = spot_lights[idx].size / max(0.001, light_length); 723: size_A = max(0.0, 1.0 - 1.0 / sqrt(1.0 + t * t)); 724: } 725: 726: light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color, spot_attenuation, f0, roughness, metallic, spot_lights[idx].specular_amount, albedo, alpha, 727: #ifdef LIGHT_BACKLIGHT_USED 728: backlight, 729: #endif 730: #ifdef LIGHT_RIM_USED 731: rim * spot_attenuation, rim_tint, 732: #endif 733: #ifdef LIGHT_CLEARCOAT_USED 734: clearcoat, clearcoat_roughness, vertex_normal, 735: #endif 736: #ifdef LIGHT_ANISOTROPY_USED 737: binormal, tangent, anisotropy, 738: #endif 739: diffuse_light, specular_light); 740: } 741: #endif // !DISABLE_LIGHT_SPOT 742: 743: #endif // !defined(DISABLE_LIGHT_DIRECTIONAL) || !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) 744: 745: #ifndef MODE_RENDER_DEPTH 746: vec4 fog_process(vec3 vertex) { 747: vec3 fog_color = scene_data.fog_light_color; 748: 749: #ifdef USE_RADIANCE_MAP 750: /* 751: if (scene_data.fog_aerial_perspective > 0.0) { 752: vec3 sky_fog_color = vec3(0.0); 753: vec3 cube_view = scene_data.radiance_inverse_xform * vertex; 754: // mip_level always reads from the second mipmap and higher so the fog is always slightly blurred 755: float mip_level = mix(1.0 / MAX_ROUGHNESS_LOD, 1.0, 1.0 - (abs(vertex.z) - scene_data.z_near) / (scene_data.z_far - scene_data.z_near)); 756: 757: sky_fog_color = textureLod(radiance_map, cube_view, mip_level * RADIANCE_MAX_LOD).rgb; 758: 759: fog_color = mix(fog_color, sky_fog_color, scene_data.fog_aerial_perspective); 760: } 761: */ 762: #endif 763: 764: #ifndef DISABLE_LIGHT_DIRECTIONAL 765: if (scene_data.fog_sun_scatter > 0.001) { 766: vec4 sun_scatter = vec4(0.0); 767: float sun_total = 0.0; 768: vec3 view = normalize(vertex); 769: for (uint i = uint(0); i < scene_data.directional_light_count; i++) { 770: vec3 light_color = directional_lights[i].color * directional_lights[i].energy; 771: float light_amount = pow(max(dot(view, directional_lights[i].direction), 0.0), 8.0); 772: fog_color += light_color * light_amount * scene_data.fog_sun_scatter; 773: } 774: } 775: #endif // !DISABLE_LIGHT_DIRECTIONAL 776: 777: float fog_amount = 1.0 - exp(min(0.0, -length(vertex) * scene_data.fog_density)); 778: 779: if (abs(scene_data.fog_height_density) >= 0.0001) { 780: float y = (scene_data.inv_view_matrix * vec4(vertex, 1.0)).y; 781: 782: float y_dist = y - scene_data.fog_height; 783: 784: float vfog_amount = 1.0 - exp(min(0.0, y_dist * scene_data.fog_height_density)); 785: 786: fog_amount = max(vfog_amount, fog_amount); 787: } 788: 789: return vec4(fog_color, fog_amount); 790: } 791: 792: #endif // !MODE_RENDER_DEPTH 793: 794: void main() { 795: //lay out everything, whatever is unused is optimized away anyway 796: vec3 vertex = vertex_interp; 797: #ifdef USE_MULTIVIEW 798: vec3 eye_offset = multiview_data.eye_offset[ViewIndex].xyz; 799: vec3 view = -normalize(vertex_interp - eye_offset); 800: mat4 projection_matrix = multiview_data.projection_matrix_view[ViewIndex]; 801: mat4 inv_projection_matrix = multiview_data.inv_projection_matrix_view[ViewIndex]; 802: #else 803: vec3 eye_offset = vec3(0.0, 0.0, 0.0); 804: vec3 view = -normalize(vertex_interp); 805: mat4 projection_matrix = scene_data.projection_matrix; 806: mat4 inv_projection_matrix = scene_data.inv_projection_matrix; 807: #endif 808: highp mat4 model_matrix = world_transform; 809: vec3 albedo = vec3(1.0); 810: vec3 backlight = vec3(0.0); 811: vec4 transmittance_color = vec4(0.0, 0.0, 0.0, 1.0); 812: float transmittance_depth = 0.0; 813: float transmittance_boost = 0.0; 814: float metallic = 0.0; 815: float specular = 0.5; 816: vec3 emission = vec3(0.0); 817: float roughness = 1.0; 818: float rim = 0.0; 819: float rim_tint = 0.0; 820: float clearcoat = 0.0; 821: float clearcoat_roughness = 0.0; 822: float anisotropy = 0.0; 823: vec2 anisotropy_flow = vec2(1.0, 0.0); 824: vec4 fog = vec4(0.0); 825: #if defined(CUSTOM_RADIANCE_USED) 826: vec4 custom_radiance = vec4(0.0); 827: #endif 828: #if defined(CUSTOM_IRRADIANCE_USED) 829: vec4 custom_irradiance = vec4(0.0); 830: #endif 831: 832: float ao = 1.0; 833: float ao_light_affect = 0.0; 834: 835: float alpha = 1.0; 836: 837: #if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) 838: vec3 binormal = normalize(binormal_interp); 839: vec3 tangent = normalize(tangent_interp); 840: #else 841: vec3 binormal = vec3(0.0); 842: vec3 tangent = vec3(0.0); 843: #endif 844: 845: #ifdef NORMAL_USED 846: vec3 normal = normalize(normal_interp); 847: 848: #if defined(DO_SIDE_CHECK) 849: if (!gl_FrontFacing) { 850: normal = -normal; 851: } 852: #endif 853: 854: #endif //NORMAL_USED 855: 856: #ifdef UV_USED 857: vec2 uv = uv_interp; 858: #endif 859: 860: #if defined(UV2_USED) || defined(USE_LIGHTMAP) 861: vec2 uv2 = uv2_interp; 862: #endif 863: 864: #if defined(COLOR_USED) 865: vec4 color = color_interp; 866: #endif 867: 868: #if defined(NORMAL_MAP_USED) 869: 870: vec3 normal_map = vec3(0.5); 871: #endif 872: 873: float normal_map_depth = 1.0; 874: 875: vec2 screen_uv = gl_FragCoord.xy * scene_data.screen_pixel_size; 876: 877: float sss_strength = 0.0; 878: 879: #ifdef ALPHA_SCISSOR_USED 880: float alpha_scissor_threshold = 1.0; 881: #endif // ALPHA_SCISSOR_USED 882: 883: #ifdef ALPHA_HASH_USED 884: float alpha_hash_scale = 1.0; 885: #endif // ALPHA_HASH_USED 886: 887: #ifdef ALPHA_ANTIALIASING_EDGE_USED 888: float alpha_antialiasing_edge = 0.0; 889: vec2 alpha_texture_coordinate = vec2(0.0, 0.0); 890: #endif // ALPHA_ANTIALIASING_EDGE_USED 891: { 892: } 893: 894: #ifndef USE_SHADOW_TO_OPACITY 895: 896: #if defined(ALPHA_SCISSOR_USED) 897: if (alpha < alpha_scissor_threshold) { 898: discard; 899: } 900: #endif // ALPHA_SCISSOR_USED 901: 902: #ifdef USE_OPAQUE_PREPASS 903: #if !defined(ALPHA_SCISSOR_USED) 904: 905: if (alpha < opaque_prepass_threshold) { 906: discard; 907: } 908: 909: #endif // not ALPHA_SCISSOR_USED 910: #endif // USE_OPAQUE_PREPASS 911: 912: #endif // !USE_SHADOW_TO_OPACITY 913: 914: #ifdef NORMAL_MAP_USED 915: 916: normal_map.xy = normal_map.xy * 2.0 - 1.0; 917: normal_map.z = sqrt(max(0.0, 1.0 - dot(normal_map.xy, normal_map.xy))); //always ignore Z, as it can be RG packed, Z may be pos/neg, etc. 918: 919: normal = normalize(mix(normal, tangent * normal_map.x + binormal * normal_map.y + normal * normal_map.z, normal_map_depth)); 920: 921: #endif 922: 923: #ifdef LIGHT_ANISOTROPY_USED 924: 925: if (anisotropy > 0.01) { 926: //rotation matrix 927: mat3 rot = mat3(tangent, binormal, normal); 928: //make local to space 929: tangent = normalize(rot * vec3(anisotropy_flow.x, anisotropy_flow.y, 0.0)); 930: binormal = normalize(rot * vec3(-anisotropy_flow.y, anisotropy_flow.x, 0.0)); 931: } 932: 933: #endif 934: 935: #ifndef MODE_RENDER_DEPTH 936: 937: #ifndef CUSTOM_FOG_USED 938: #ifndef DISABLE_FOG 939: // fog must be processed as early as possible and then packed. 940: // to maximize VGPR usage 941: 942: if (scene_data.fog_enabled) { 943: fog = fog_process(vertex); 944: } 945: #endif // !DISABLE_FOG 946: #endif // !CUSTOM_FOG_USED 947: 948: uint fog_rg = packHalf2x16(fog.rg); 949: uint fog_ba = packHalf2x16(fog.ba); 950: 951: // Convert colors to linear 952: albedo = srgb_to_linear(albedo); 953: emission = srgb_to_linear(emission); 954: // TODO Backlight and transmittance when used 955: #ifndef MODE_UNSHADED 956: vec3 f0 = F0(metallic, specular, albedo); 957: vec3 specular_light = vec3(0.0, 0.0, 0.0); 958: vec3 diffuse_light = vec3(0.0, 0.0, 0.0); 959: vec3 ambient_light = vec3(0.0, 0.0, 0.0); 960: 961: #ifdef BASE_PASS 962: /////////////////////// LIGHTING ////////////////////////////// 963: 964: // IBL precalculations 965: float ndotv = clamp(dot(normal, view), 0.0, 1.0); 966: vec3 F = f0 + (max(vec3(1.0 - roughness), f0) - f0) * pow(1.0 - ndotv, 5.0); 967: 968: #ifdef USE_RADIANCE_MAP 969: if (scene_data.use_reflection_cubemap) { 970: #ifdef LIGHT_ANISOTROPY_USED 971: // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy 972: vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent; 973: vec3 anisotropic_tangent = cross(anisotropic_direction, view); 974: vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction); 975: vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0))); 976: vec3 ref_vec = reflect(-view, bent_normal); 977: #else 978: vec3 ref_vec = reflect(-view, normal); 979: #endif 980: ref_vec = mix(ref_vec, normal, roughness * roughness); 981: float horizon = min(1.0 + dot(ref_vec, normal), 1.0); 982: ref_vec = scene_data.radiance_inverse_xform * ref_vec; 983: specular_light = textureLod(radiance_map, ref_vec, sqrt(roughness) * RADIANCE_MAX_LOD).rgb; 984: specular_light = srgb_to_linear(specular_light); 985: specular_light *= horizon * horizon; 986: specular_light *= scene_data.ambient_light_color_energy.a; 987: } 988: #endif 989: 990: // Calculate Reflection probes 991: // Calculate Lightmaps 992: 993: #if defined(CUSTOM_RADIANCE_USED) 994: specular_light = mix(specular_light, custom_radiance.rgb, custom_radiance.a); 995: #endif // CUSTOM_RADIANCE_USED 996: 997: #ifndef USE_LIGHTMAP 998: //lightmap overrides everything 999: if (scene_data.use_ambient_light) { 1000: ambient_light = scene_data.ambient_light_color_energy.rgb; 1001: #ifdef USE_RADIANCE_MAP 1002: if (scene_data.use_ambient_cubemap) { 1003: vec3 ambient_dir = scene_data.radiance_inverse_xform * normal; 1004: vec3 cubemap_ambient = textureLod(radiance_map, ambient_dir, RADIANCE_MAX_LOD).rgb; 1005: cubemap_ambient = srgb_to_linear(cubemap_ambient); 1006: ambient_light = mix(ambient_light, cubemap_ambient * scene_data.ambient_light_color_energy.a, scene_data.ambient_color_sky_mix); 1007: } 1008: #endif 1009: } 1010: #endif // USE_LIGHTMAP 1011: 1012: #if defined(CUSTOM_IRRADIANCE_USED) 1013: ambient_light = mix(ambient_light, custom_irradiance.rgb, custom_irradiance.a); 1014: #endif // CUSTOM_IRRADIANCE_USED 1015: 1016: { 1017: #if defined(AMBIENT_LIGHT_DISABLED) 1018: ambient_light = vec3(0.0, 0.0, 0.0); 1019: #else 1020: ambient_light *= albedo.rgb; 1021: ambient_light *= ao; 1022: #endif // AMBIENT_LIGHT_DISABLED 1023: } 1024: 1025: // convert ao to direct light ao 1026: ao = mix(1.0, ao, ao_light_affect); 1027: 1028: { 1029: #if defined(DIFFUSE_TOON) 1030: //simplify for toon, as 1031: specular_light *= specular * metallic * albedo * 2.0; 1032: #else 1033: 1034: // scales the specular reflections, needs to be be computed before lighting happens, 1035: // but after environment, GI, and reflection probes are added 1036: // Environment brdf approximation (Lazarov 2013) 1037: // see https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile 1038: const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022); 1039: const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04); 1040: vec4 r = roughness * c0 + c1; 1041: float ndotv = clamp(dot(normal, view), 0.0, 1.0); 1042: 1043: float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y; 1044: vec2 env = vec2(-1.04, 1.04) * a004 + r.zw; 1045: specular_light *= env.x * f0 + env.y * clamp(50.0 * f0.g, metallic, 1.0); 1046: #endif 1047: } 1048: 1049: #endif // BASE_PASS 1050: 1051: #ifndef DISABLE_LIGHT_DIRECTIONAL 1052: //diffuse_light = normal; // 1053: for (uint i = uint(0); i < scene_data.directional_light_count; i++) { 1054: light_compute(normal, normalize(directional_lights[i].direction), normalize(view), directional_lights[i].size, directional_lights[i].color * directional_lights[i].energy, 1.0, f0, roughness, metallic, 1.0, albedo, alpha, 1055: #ifdef LIGHT_BACKLIGHT_USED 1056: backlight, 1057: #endif 1058: #ifdef LIGHT_RIM_USED 1059: rim, rim_tint, 1060: #endif 1061: #ifdef LIGHT_CLEARCOAT_USED 1062: clearcoat, clearcoat_roughness, normalize(normal_interp), 1063: #endif 1064: #ifdef LIGHT_ANISOTROPY_USED 1065: binormal, 1066: tangent, anisotropy, 1067: #endif 1068: diffuse_light, 1069: specular_light); 1070: } 1071: #endif // !DISABLE_LIGHT_DIRECTIONAL 1072: 1073: #ifndef DISABLE_LIGHT_OMNI 1074: for (uint i = 0u; i < MAX_FORWARD_LIGHTS; i++) { 1075: if (i >= omni_light_count) { 1076: break; 1077: } 1078: light_process_omni(omni_light_indices[i], vertex, view, normal, f0, roughness, metallic, 0.0, albedo, alpha, 1079: #ifdef LIGHT_BACKLIGHT_USED 1080: backlight, 1081: #endif 1082: #ifdef LIGHT_RIM_USED 1083: rim, 1084: rim_tint, 1085: #endif 1086: #ifdef LIGHT_CLEARCOAT_USED 1087: clearcoat, clearcoat_roughness, normalize(normal_interp), 1088: #endif 1089: #ifdef LIGHT_ANISOTROPY_USED 1090: binormal, tangent, anisotropy, 1091: #endif 1092: diffuse_light, specular_light); 1093: } 1094: #endif // !DISABLE_LIGHT_OMNI 1095: 1096: #ifndef DISABLE_LIGHT_SPOT 1097: for (uint i = 0u; i < MAX_FORWARD_LIGHTS; i++) { 1098: if (i >= spot_light_count) { 1099: break; 1100: } 1101: light_process_spot(spot_light_indices[i], vertex, view, normal, f0, roughness, metallic, 0.0, albedo, alpha, 1102: #ifdef LIGHT_BACKLIGHT_USED 1103: backlight, 1104: #endif 1105: #ifdef LIGHT_RIM_USED 1106: rim, 1107: rim_tint, 1108: #endif 1109: #ifdef LIGHT_CLEARCOAT_USED 1110: clearcoat, clearcoat_roughness, normalize(normal_interp), 1111: #endif 1112: #ifdef LIGHT_ANISOTROPY_USED 1113: tangent, 1114: binormal, anisotropy, 1115: #endif 1116: diffuse_light, specular_light); 1117: } 1118: #endif // !DISABLE_LIGHT_SPOT 1119: 1120: #endif // !MODE_UNSHADED 1121: 1122: #endif // !MODE_RENDER_DEPTH 1123: 1124: #if defined(USE_SHADOW_TO_OPACITY) 1125: alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0)); 1126: 1127: #if defined(ALPHA_SCISSOR_USED) 1128: if (alpha < alpha_scissor) { 1129: discard; 1130: } 1131: #endif // ALPHA_SCISSOR_USED 1132: 1133: #ifdef USE_OPAQUE_PREPASS 1134: #if !defined(ALPHA_SCISSOR_USED) 1135: 1136: if (alpha < opaque_prepass_threshold) { 1137: discard; 1138: } 1139: 1140: #endif // not ALPHA_SCISSOR_USED 1141: #endif // USE_OPAQUE_PREPASS 1142: 1143: #endif // USE_SHADOW_TO_OPACITY 1144: 1145: #ifdef MODE_RENDER_DEPTH 1146: //nothing happens, so a tree-ssa optimizer will result in no fragment shader :) 1147: #else // !MODE_RENDER_DEPTH 1148: 1149: #ifdef MODE_UNSHADED 1150: frag_color = vec4(albedo, alpha); 1151: #else 1152: 1153: diffuse_light *= albedo; 1154: 1155: diffuse_light *= 1.0 - metallic; 1156: ambient_light *= 1.0 - metallic; 1157: 1158: frag_color = vec4(diffuse_light + specular_light, alpha); 1159: #ifdef BASE_PASS 1160: frag_color.rgb += emission + ambient_light; 1161: #endif 1162: #endif //MODE_UNSHADED 1163: fog = vec4(unpackHalf2x16(fog_rg), unpackHalf2x16(fog_ba)); 1164: 1165: #ifndef DISABLE_FOG 1166: if (scene_data.fog_enabled) { 1167: #ifdef BASE_PASS 1168: frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a); 1169: #else 1170: frag_color.rgb *= (1.0 - fog.a); 1171: #endif // BASE_PASS 1172: } 1173: #endif 1174: 1175: // Tonemap before writing as we are writing to an sRGB framebuffer 1176: frag_color.rgb *= exposure; 1177: frag_color.rgb = apply_tonemapping(frag_color.rgb, white); 1178: frag_color.rgb = linear_to_srgb(frag_color.rgb); 1179: 1180: #ifdef USE_BCS 1181: frag_color.rgb = apply_bcs(frag_color.rgb, bcs); 1182: #endif 1183: 1184: #ifdef USE_COLOR_CORRECTION 1185: frag_color.rgb = apply_color_correction(frag_color.rgb, color_correction); 1186: #endif 1187: 1188: #endif //!MODE_RENDER_DEPTH 1189: } 1190: 1191: 1: #version 330 2: #define USE_GLES_OVER_GL 3: #define USE_RADIANCE_MAP 4: 5: #define MAX_GLOBAL_SHADER_UNIFORMS 256 6: 7: #define MAX_LIGHT_DATA_STRUCTS 32 8: 9: #define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS 8 10: 11: #define MAX_FORWARD_LIGHTS uint(8) 12: #define BASE_PASS 13: #define USE_INSTANCING 14: 15: #ifdef USE_MULTIVIEW 16: #if defined(GL_OVR_multiview2) 17: #extension GL_OVR_multiview2 : require 18: #elif defined(GL_OVR_multiview) 19: #extension GL_OVR_multiview : require 20: #endif 21: #define ViewIndex gl_ViewID_OVR 22: #define MAX_VIEWS 2 23: #else 24: #define ViewIndex uint(0) 25: #define MAX_VIEWS 1 26: #endif 27: precision highp float; 28: precision highp int; 29: 30: // Default to SPECULAR_SCHLICK_GGX. 31: #if !defined(SPECULAR_DISABLED) && !defined(SPECULAR_SCHLICK_GGX) && !defined(SPECULAR_TOON) 32: #define SPECULAR_SCHLICK_GGX 33: #endif 34: 35: #if !defined(MODE_RENDER_DEPTH) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) ||defined(LIGHT_CLEARCOAT_USED) 36: #ifndef NORMAL_USED 37: #define NORMAL_USED 38: #endif 39: #endif 40: 41: #ifndef MODE_RENDER_DEPTH 42: #ifdef USE_BCS 43: uniform vec3 bcs; 44: #endif 45: 46: #ifdef USE_COLOR_CORRECTION 47: #ifdef USE_1D_LUT 48: uniform sampler2D source_color_correction; //texunit:-1 49: #else 50: uniform sampler3D source_color_correction; //texunit:-1 51: #endif 52: #endif 53: 54: layout(std140) uniform TonemapData { //ubo:0 55: float exposure; 56: float white; 57: int tonemapper; 58: int pad; 59: }; 60: 61: vec3 apply_bcs(vec3 color, vec3 bcs) { 62: color = mix(vec3(0.0), color, bcs.x); 63: color = mix(vec3(0.5), color, bcs.y); 64: color = mix(vec3(dot(vec3(1.0), color) * 0.33333), color, bcs.z); 65: 66: return color; 67: } 68: #ifdef USE_COLOR_CORRECTION 69: #ifdef USE_1D_LUT 70: vec3 apply_color_correction(vec3 color) { 71: color.r = texture(source_color_correction, vec2(color.r, 0.0f)).r; 72: color.g = texture(source_color_correction, vec2(color.g, 0.0f)).g; 73: color.b = texture(source_color_correction, vec2(color.b, 0.0f)).b; 74: return color; 75: } 76: #else 77: vec3 apply_color_correction(vec3 color) { 78: return textureLod(source_color_correction, color, 0.0).rgb; 79: } 80: #endif 81: #endif 82: 83: vec3 tonemap_filmic(vec3 color, float p_white) { 84: // exposure bias: input scale (color *= bias, white *= bias) to make the brightness consistent with other tonemappers 85: // also useful to scale the input to the range that the tonemapper is designed for (some require very high input values) 86: // has no effect on the curve's general shape or visual properties 87: const float exposure_bias = 2.0f; 88: const float A = 0.22f * exposure_bias * exposure_bias; // bias baked into constants for performance 89: const float B = 0.30f * exposure_bias; 90: const float C = 0.10f; 91: const float D = 0.20f; 92: const float E = 0.01f; 93: const float F = 0.30f; 94: 95: vec3 color_tonemapped = ((color * (A * color + C * B) + D * E) / (color * (A * color + B) + D * F)) - E / F; 96: float p_white_tonemapped = ((p_white * (A * p_white + C * B) + D * E) / (p_white * (A * p_white + B) + D * F)) - E / F; 97: 98: return color_tonemapped / p_white_tonemapped; 99: } 100: 101: // Adapted from https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl 102: // (MIT License). 103: vec3 tonemap_aces(vec3 color, float p_white) { 104: const float exposure_bias = 1.8f; 105: const float A = 0.0245786f; 106: const float B = 0.000090537f; 107: const float C = 0.983729f; 108: const float D = 0.432951f; 109: const float E = 0.238081f; 110: 111: // Exposure bias baked into transform to save shader instructions. Equivalent to `color *= exposure_bias` 112: const mat3 rgb_to_rrt = mat3( 113: vec3(0.59719f * exposure_bias, 0.35458f * exposure_bias, 0.04823f * exposure_bias), 114: vec3(0.07600f * exposure_bias, 0.90834f * exposure_bias, 0.01566f * exposure_bias), 115: vec3(0.02840f * exposure_bias, 0.13383f * exposure_bias, 0.83777f * exposure_bias)); 116: 117: const mat3 odt_to_rgb = mat3( 118: vec3(1.60475f, -0.53108f, -0.07367f), 119: vec3(-0.10208f, 1.10813f, -0.00605f), 120: vec3(-0.00327f, -0.07276f, 1.07602f)); 121: 122: color *= rgb_to_rrt; 123: vec3 color_tonemapped = (color * (color + A) - B) / (color * (C * color + D) + E); 124: color_tonemapped *= odt_to_rgb; 125: 126: p_white *= exposure_bias; 127: float p_white_tonemapped = (p_white * (p_white + A) - B) / (p_white * (C * p_white + D) + E); 128: 129: return color_tonemapped / p_white_tonemapped; 130: } 131: 132: vec3 tonemap_reinhard(vec3 color, float p_white) { 133: return (p_white * color + color) / (color * p_white + p_white); 134: } 135: 136: // This expects 0-1 range input. 137: vec3 linear_to_srgb(vec3 color) { 138: //color = clamp(color, vec3(0.0), vec3(1.0)); 139: //const vec3 a = vec3(0.055f); 140: //return mix((vec3(1.0f) + a) * pow(color.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * color.rgb, lessThan(color.rgb, vec3(0.0031308f))); 141: // Approximation from http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html 142: return max(vec3(1.055) * pow(color, vec3(0.416666667)) - vec3(0.055), vec3(0.0)); 143: } 144: 145: // This expects 0-1 range input, outside that range it behaves poorly. 146: vec3 srgb_to_linear(vec3 color) { 147: // Approximation from http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html 148: return color * (color * (color * 0.305306011 + 0.682171111) + 0.012522878); 149: } 150: 151: #define TONEMAPPER_LINEAR 0 152: #define TONEMAPPER_REINHARD 1 153: #define TONEMAPPER_FILMIC 2 154: #define TONEMAPPER_ACES 3 155: 156: vec3 apply_tonemapping(vec3 color, float p_white) { // inputs are LINEAR, always outputs clamped [0;1] color 157: // Ensure color values passed to tonemappers are positive. 158: // They can be negative in the case of negative lights, which leads to undesired behavior. 159: if (tonemapper == TONEMAPPER_LINEAR) { 160: return color; 161: } else if (tonemapper == TONEMAPPER_REINHARD) { 162: return tonemap_reinhard(max(vec3(0.0f), color), p_white); 163: } else if (tonemapper == TONEMAPPER_FILMIC) { 164: return tonemap_filmic(max(vec3(0.0f), color), p_white); 165: } else { // TONEMAPPER_ACES 166: return tonemap_aces(max(vec3(0.0f), color), p_white); 167: } 168: } 169: #endif 170: 171: #ifdef USE_GLES_OVER_GL 172: // Floating point pack/unpack functions are part of the GLSL ES 300 specification used by web and mobile. 173: uint float2half(uint f) { 174: uint e = f & uint(0x7f800000); 175: if (e <= uint(0x38000000)) { 176: return uint(0); 177: } else { 178: return ((f >> uint(16)) & uint(0x8000)) | 179: (((e - uint(0x38000000)) >> uint(13)) & uint(0x7c00)) | 180: ((f >> uint(13)) & uint(0x03ff)); 181: } 182: } 183: 184: uint half2float(uint h) { 185: uint h_e = h & uint(0x7c00); 186: return ((h & uint(0x8000)) << uint(16)) | uint((h_e >> uint(10)) != uint(0)) * (((h_e + uint(0x1c000)) << uint(13)) | ((h & uint(0x03ff)) << uint(13))); 187: } 188: 189: uint packHalf2x16(vec2 v) { 190: return float2half(floatBitsToUint(v.x)) | float2half(floatBitsToUint(v.y)) << uint(16); 191: } 192: 193: vec2 unpackHalf2x16(uint v) { 194: return vec2(uintBitsToFloat(half2float(v & uint(0xffff))), 195: uintBitsToFloat(half2float(v >> uint(16)))); 196: } 197: 198: uint packUnorm2x16(vec2 v) { 199: uvec2 uv = uvec2(round(clamp(v, vec2(0.0), vec2(1.0)) * 65535.0)); 200: return uv.x | uv.y << uint(16); 201: } 202: 203: vec2 unpackUnorm2x16(uint p) { 204: return vec2(float(p & uint(0xffff)), float(p >> uint(16))) * 0.000015259021; // 1.0 / 65535.0 optimization 205: } 206: 207: uint packSnorm2x16(vec2 v) { 208: uvec2 uv = uvec2(round(clamp(v, vec2(-1.0), vec2(1.0)) * 32767.0) + 32767.0); 209: return uv.x | uv.y << uint(16); 210: } 211: 212: vec2 unpackSnorm2x16(uint p) { 213: vec2 v = vec2(float(p & uint(0xffff)), float(p >> uint(16))); 214: return clamp((v - 32767.0) * vec2(0.00003051851), vec2(-1.0), vec2(1.0)); 215: } 216: 217: #endif 218: 219: // Compatibility renames. These are exposed with the "godot_" prefix 220: // to work around an Adreno bug which was exposing these ES310 functions 221: // in ES300 shaders. Internally, we must use the "godot_" prefix, but user shaders 222: // will be mapped automatically. 223: uint godot_packUnorm4x8(vec4 v) { 224: uvec4 uv = uvec4(round(clamp(v, vec4(0.0), vec4(1.0)) * 255.0)); 225: return uv.x | (uv.y << uint(8)) | (uv.z << uint(16)) | (uv.w << uint(24)); 226: } 227: 228: vec4 godot_unpackUnorm4x8(uint p) { 229: return vec4(float(p & uint(0xff)), float((p >> uint(8)) & uint(0xff)), float((p >> uint(16)) & uint(0xff)), float(p >> uint(24))) * 0.00392156862; // 1.0 / 255.0 230: } 231: 232: uint godot_packSnorm4x8(vec4 v) { 233: uvec4 uv = uvec4(round(clamp(v, vec4(-1.0), vec4(1.0)) * 127.0) + 127.0); 234: return uv.x | uv.y << uint(8) | uv.z << uint(16) | uv.w << uint(24); 235: } 236: 237: vec4 godot_unpackSnorm4x8(uint p) { 238: vec4 v = vec4(float(p & uint(0xff)), float((p >> uint(8)) & uint(0xff)), float((p >> uint(16)) & uint(0xff)), float(p >> uint(24))); 239: return clamp((v - vec4(127.0)) * vec4(0.00787401574), vec4(-1.0), vec4(1.0)); 240: } 241: 242: #define packUnorm4x8 godot_packUnorm4x8 243: #define unpackUnorm4x8 godot_unpackUnorm4x8 244: #define packSnorm4x8 godot_packSnorm4x8 245: #define unpackSnorm4x8 godot_unpackSnorm4x8 246: 247: /* texture unit usage, N is max_texture_unity-N 248: 249: 1-color correction // In tonemap_inc.glsl 250: 2-radiance 251: 3-directional_shadow 252: 4-positional_shadow 253: 5-screen 254: 6-depth 255: 256: */ 257: 258: #define M_PI 3.14159265359 259: /* clang-format on */ 260: 261: #define SHADER_IS_SRGB true 262: 263: /* Varyings */ 264: 265: #if defined(COLOR_USED) 266: in vec4 color_interp; 267: #endif 268: 269: #if defined(UV_USED) 270: in vec2 uv_interp; 271: #endif 272: 273: #if defined(UV2_USED) 274: in vec2 uv2_interp; 275: #else 276: #ifdef USE_LIGHTMAP 277: in vec2 uv2_interp; 278: #endif 279: #endif 280: 281: #if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) 282: in vec3 tangent_interp; 283: in vec3 binormal_interp; 284: #endif 285: 286: #ifdef NORMAL_USED 287: in vec3 normal_interp; 288: #endif 289: 290: in highp vec3 vertex_interp; 291: 292: #ifdef USE_RADIANCE_MAP 293: 294: #define RADIANCE_MAX_LOD 5.0 295: 296: uniform samplerCube radiance_map; // texunit:-2 297: 298: #endif 299: 300: layout(std140) uniform GlobalShaderUniformData { //ubo:1 301: vec4 global_shader_uniforms[MAX_GLOBAL_SHADER_UNIFORMS]; 302: }; 303: 304: /* Material Uniforms */ 305: 306: #ifdef MATERIAL_UNIFORMS_USED 307: 308: /* clang-format off */ 309: layout(std140) uniform MaterialUniforms { // ubo:3 310: 311: 312: }; 313: /* clang-format on */ 314: 315: #endif 316: 317: layout(std140) uniform SceneData { // ubo:2 318: highp mat4 projection_matrix; 319: highp mat4 inv_projection_matrix; 320: highp mat4 inv_view_matrix; 321: highp mat4 view_matrix; 322: 323: vec2 viewport_size; 324: vec2 screen_pixel_size; 325: 326: mediump vec4 ambient_light_color_energy; 327: 328: mediump float ambient_color_sky_mix; 329: bool material_uv2_mode; 330: float emissive_exposure_normalization; 331: bool use_ambient_light; 332: bool use_ambient_cubemap; 333: bool use_reflection_cubemap; 334: 335: float fog_aerial_perspective; 336: float time; 337: 338: mat3 radiance_inverse_xform; 339: 340: uint directional_light_count; 341: float z_far; 342: float z_near; 343: float IBL_exposure_normalization; 344: 345: bool fog_enabled; 346: float fog_density; 347: float fog_height; 348: float fog_height_density; 349: 350: vec3 fog_light_color; 351: float fog_sun_scatter; 352: uint camera_visible_layers; 353: uint pad3; 354: uint pad4; 355: uint pad5; 356: } 357: scene_data; 358: 359: #ifdef USE_MULTIVIEW 360: layout(std140) uniform MultiviewData { // ubo:8 361: highp mat4 projection_matrix_view[MAX_VIEWS]; 362: highp mat4 inv_projection_matrix_view[MAX_VIEWS]; 363: highp vec4 eye_offset[MAX_VIEWS]; 364: } 365: multiview_data; 366: #endif 367: 368: /* clang-format off */ 369: 370: 371: /* clang-format on */ 372: 373: // Directional light data. 374: #ifndef DISABLE_LIGHT_DIRECTIONAL 375: 376: struct DirectionalLightData { 377: mediump vec3 direction; 378: mediump float energy; 379: mediump vec3 color; 380: mediump float size; 381: mediump vec3 pad; 382: mediump float specular; 383: }; 384: 385: layout(std140) uniform DirectionalLights { // ubo:7 386: DirectionalLightData directional_lights[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS]; 387: }; 388: 389: #endif // !DISABLE_LIGHT_DIRECTIONAL 390: 391: // Omni and spot light data. 392: #if !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) 393: 394: struct LightData { // This structure needs to be as packed as possible. 395: highp vec3 position; 396: highp float inv_radius; 397: 398: mediump vec3 direction; 399: highp float size; 400: 401: mediump vec3 color; 402: mediump float attenuation; 403: 404: mediump float cone_attenuation; 405: mediump float cone_angle; 406: mediump float specular_amount; 407: mediump float shadow_opacity; 408: }; 409: 410: #ifndef DISABLE_LIGHT_OMNI 411: layout(std140) uniform OmniLightData { // ubo:5 412: LightData omni_lights[MAX_LIGHT_DATA_STRUCTS]; 413: }; 414: uniform uint omni_light_indices[MAX_FORWARD_LIGHTS]; 415: uniform uint omni_light_count; 416: #endif 417: 418: #ifndef DISABLE_LIGHT_SPOT 419: layout(std140) uniform SpotLightData { // ubo:6 420: LightData spot_lights[MAX_LIGHT_DATA_STRUCTS]; 421: }; 422: uniform uint spot_light_indices[MAX_FORWARD_LIGHTS]; 423: uniform uint spot_light_count; 424: #endif 425: 426: #ifdef USE_ADDITIVE_LIGHTING 427: uniform highp samplerCubeShadow positional_shadow; // texunit:-4 428: #endif 429: 430: #endif // !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) 431: 432: #ifdef USE_MULTIVIEW 433: uniform highp sampler2DArray depth_buffer; // texunit:-6 434: uniform highp sampler2DArray color_buffer; // texunit:-5 435: vec3 multiview_uv(vec2 uv) { 436: return vec3(uv, ViewIndex); 437: } 438: #else 439: uniform highp sampler2D depth_buffer; // texunit:-6 440: uniform highp sampler2D color_buffer; // texunit:-5 441: vec2 multiview_uv(vec2 uv) { 442: return uv; 443: } 444: #endif 445: 446: uniform highp mat4 world_transform; 447: uniform mediump float opaque_prepass_threshold; 448: 449: layout(location = 0) out vec4 frag_color; 450: 451: vec3 F0(float metallic, float specular, vec3 albedo) { 452: float dielectric = 0.16 * specular * specular; 453: // use albedo * metallic as colored specular reflectance at 0 angle for metallic materials; 454: // see https://google.github.io/filament/Filament.md.html 455: return mix(vec3(dielectric), albedo, vec3(metallic)); 456: } 457: 458: #if !defined(DISABLE_LIGHT_DIRECTIONAL) || !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) 459: 460: float D_GGX(float cos_theta_m, float alpha) { 461: float a = cos_theta_m * alpha; 462: float k = alpha / (1.0 - cos_theta_m * cos_theta_m + a * a); 463: return k * k * (1.0 / M_PI); 464: } 465: 466: // From Earl Hammon, Jr. "PBR Diffuse Lighting for GGX+Smith Microsurfaces" https://www.gdcvault.com/play/1024478/PBR-Diffuse-Lighting-for-GGX 467: float V_GGX(float NdotL, float NdotV, float alpha) { 468: return 0.5 / mix(2.0 * NdotL * NdotV, NdotL + NdotV, alpha); 469: } 470: 471: float D_GGX_anisotropic(float cos_theta_m, float alpha_x, float alpha_y, float cos_phi, float sin_phi) { 472: float alpha2 = alpha_x * alpha_y; 473: highp vec3 v = vec3(alpha_y * cos_phi, alpha_x * sin_phi, alpha2 * cos_theta_m); 474: highp float v2 = dot(v, v); 475: float w2 = alpha2 / v2; 476: float D = alpha2 * w2 * w2 * (1.0 / M_PI); 477: return D; 478: } 479: 480: float V_GGX_anisotropic(float alpha_x, float alpha_y, float TdotV, float TdotL, float BdotV, float BdotL, float NdotV, float NdotL) { 481: float Lambda_V = NdotL * length(vec3(alpha_x * TdotV, alpha_y * BdotV, NdotV)); 482: float Lambda_L = NdotV * length(vec3(alpha_x * TdotL, alpha_y * BdotL, NdotL)); 483: return 0.5 / (Lambda_V + Lambda_L); 484: } 485: 486: float SchlickFresnel(float u) { 487: float m = 1.0 - u; 488: float m2 = m * m; 489: return m2 * m2 * m; // pow(m,5) 490: } 491: 492: void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float attenuation, vec3 f0, float roughness, float metallic, float specular_amount, vec3 albedo, inout float alpha, 493: #ifdef LIGHT_BACKLIGHT_USED 494: vec3 backlight, 495: #endif 496: #ifdef LIGHT_RIM_USED 497: float rim, float rim_tint, 498: #endif 499: #ifdef LIGHT_CLEARCOAT_USED 500: float clearcoat, float clearcoat_roughness, vec3 vertex_normal, 501: #endif 502: #ifdef LIGHT_ANISOTROPY_USED 503: vec3 B, vec3 T, float anisotropy, 504: #endif 505: inout vec3 diffuse_light, inout vec3 specular_light) { 506: 507: #if defined(USE_LIGHT_SHADER_CODE) 508: // light is written by the light shader 509: 510: vec3 normal = N; 511: vec3 light = L; 512: vec3 view = V; 513: 514: /* clang-format off */ 515: 516: 517: /* clang-format on */ 518: 519: #else 520: float NdotL = min(A + dot(N, L), 1.0); 521: float cNdotL = max(NdotL, 0.0); // clamped NdotL 522: float NdotV = dot(N, V); 523: float cNdotV = max(NdotV, 1e-4); 524: 525: #if defined(DIFFUSE_BURLEY) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED) 526: vec3 H = normalize(V + L); 527: #endif 528: 529: #if defined(SPECULAR_SCHLICK_GGX) 530: float cNdotH = clamp(A + dot(N, H), 0.0, 1.0); 531: #endif 532: 533: #if defined(DIFFUSE_BURLEY) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED) 534: float cLdotH = clamp(A + dot(L, H), 0.0, 1.0); 535: #endif 536: 537: if (metallic < 1.0) { 538: float diffuse_brdf_NL; // BRDF times N.L for calculating diffuse radiance 539: 540: #if defined(DIFFUSE_LAMBERT_WRAP) 541: // Energy conserving lambert wrap shader. 542: // https://web.archive.org/web/20210228210901/http://blog.stevemcauley.com/2011/12/03/energy-conserving-wrapped-diffuse/ 543: diffuse_brdf_NL = max(0.0, (NdotL + roughness) / ((1.0 + roughness) * (1.0 + roughness))) * (1.0 / M_PI); 544: #elif defined(DIFFUSE_TOON) 545: diffuse_brdf_NL = smoothstep(-roughness, max(roughness, 0.01), NdotL) * (1.0 / M_PI); 546: #elif defined(DIFFUSE_BURLEY) 547: { 548: float FD90_minus_1 = 2.0 * cLdotH * cLdotH * roughness - 0.5; 549: float FdV = 1.0 + FD90_minus_1 * SchlickFresnel(cNdotV); 550: float FdL = 1.0 + FD90_minus_1 * SchlickFresnel(cNdotL); 551: diffuse_brdf_NL = (1.0 / M_PI) * FdV * FdL * cNdotL; 552: } 553: #else 554: // Lambert 555: diffuse_brdf_NL = cNdotL * (1.0 / M_PI); 556: #endif 557: 558: diffuse_light += light_color * diffuse_brdf_NL * attenuation; 559: 560: #if defined(LIGHT_BACKLIGHT_USED) 561: diffuse_light += light_color * (vec3(1.0 / M_PI) - diffuse_brdf_NL) * backlight * attenuation; 562: #endif 563: 564: #if defined(LIGHT_RIM_USED) 565: // Epsilon min to prevent pow(0, 0) singularity which results in undefined behavior. 566: float rim_light = pow(max(1e-4, 1.0 - cNdotV), max(0.0, (1.0 - roughness) * 16.0)); 567: diffuse_light += rim_light * rim * mix(vec3(1.0), albedo, rim_tint) * light_color; 568: #endif 569: } 570: 571: if (roughness > 0.0) { // FIXME: roughness == 0 should not disable specular light entirely 572: 573: // D 574: 575: #if defined(SPECULAR_TOON) 576: 577: vec3 R = normalize(-reflect(L, N)); 578: float RdotV = dot(R, V); 579: float mid = 1.0 - roughness; 580: mid *= mid; 581: float intensity = smoothstep(mid - roughness * 0.5, mid + roughness * 0.5, RdotV) * mid; 582: diffuse_light += light_color * intensity * attenuation * specular_amount; // write to diffuse_light, as in toon shading you generally want no reflection 583: 584: #elif defined(SPECULAR_DISABLED) 585: // none.. 586: 587: #elif defined(SPECULAR_SCHLICK_GGX) 588: // shlick+ggx as default 589: float alpha_ggx = roughness * roughness; 590: #if defined(LIGHT_ANISOTROPY_USED) 591: float aspect = sqrt(1.0 - anisotropy * 0.9); 592: float ax = alpha_ggx / aspect; 593: float ay = alpha_ggx * aspect; 594: float XdotH = dot(T, H); 595: float YdotH = dot(B, H); 596: float D = D_GGX_anisotropic(cNdotH, ax, ay, XdotH, YdotH); 597: float G = V_GGX_anisotropic(ax, ay, dot(T, V), dot(T, L), dot(B, V), dot(B, L), cNdotV, cNdotL); 598: #else 599: float D = D_GGX(cNdotH, alpha_ggx); 600: float G = V_GGX(cNdotL, cNdotV, alpha_ggx); 601: #endif // LIGHT_ANISOTROPY_USED 602: // F 603: float cLdotH5 = SchlickFresnel(cLdotH); 604: // Calculate Fresnel using cheap approximate specular occlusion term from Filament: 605: // https://google.github.io/filament/Filament.html#lighting/occlusion/specularocclusion 606: float f90 = clamp(50.0 * f0.g, 0.0, 1.0); 607: vec3 F = f0 + (f90 - f0) * cLdotH5; 608: 609: vec3 specular_brdf_NL = cNdotL * D * F * G; 610: 611: specular_light += specular_brdf_NL * light_color * attenuation * specular_amount; 612: #endif 613: 614: #if defined(LIGHT_CLEARCOAT_USED) 615: // Clearcoat ignores normal_map, use vertex normal instead 616: float ccNdotL = max(min(A + dot(vertex_normal, L), 1.0), 0.0); 617: float ccNdotH = clamp(A + dot(vertex_normal, H), 0.0, 1.0); 618: float ccNdotV = max(dot(vertex_normal, V), 1e-4); 619: 620: #if !defined(SPECULAR_SCHLICK_GGX) 621: float cLdotH5 = SchlickFresnel(cLdotH); 622: #endif 623: float Dr = D_GGX(ccNdotH, mix(0.001, 0.1, clearcoat_roughness)); 624: float Gr = 0.25 / (cLdotH * cLdotH); 625: float Fr = mix(.04, 1.0, cLdotH5); 626: float clearcoat_specular_brdf_NL = clearcoat * Gr * Fr * Dr * cNdotL; 627: 628: specular_light += clearcoat_specular_brdf_NL * light_color * attenuation * specular_amount; 629: // TODO: Clearcoat adds light to the scene right now (it is non-energy conserving), both diffuse and specular need to be scaled by (1.0 - FR) 630: // but to do so we need to rearrange this entire function 631: #endif // LIGHT_CLEARCOAT_USED 632: } 633: 634: #ifdef USE_SHADOW_TO_OPACITY 635: alpha = min(alpha, clamp(1.0 - attenuation, 0.0, 1.0)); 636: #endif 637: 638: #endif // LIGHT_CODE_USED 639: } 640: 641: float get_omni_spot_attenuation(float distance, float inv_range, float decay) { 642: float nd = distance * inv_range; 643: nd *= nd; 644: nd *= nd; // nd^4 645: nd = max(1.0 - nd, 0.0); 646: nd *= nd; // nd^2 647: return nd * pow(max(distance, 0.0001), -decay); 648: } 649: 650: #ifndef DISABLE_LIGHT_OMNI 651: void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f0, float roughness, float metallic, float shadow, vec3 albedo, inout float alpha, 652: #ifdef LIGHT_BACKLIGHT_USED 653: vec3 backlight, 654: #endif 655: #ifdef LIGHT_RIM_USED 656: float rim, float rim_tint, 657: #endif 658: #ifdef LIGHT_CLEARCOAT_USED 659: float clearcoat, float clearcoat_roughness, vec3 vertex_normal, 660: #endif 661: #ifdef LIGHT_ANISOTROPY_USED 662: vec3 binormal, vec3 tangent, float anisotropy, 663: #endif 664: inout vec3 diffuse_light, inout vec3 specular_light) { 665: vec3 light_rel_vec = omni_lights[idx].position - vertex; 666: float light_length = length(light_rel_vec); 667: float omni_attenuation = get_omni_spot_attenuation(light_length, omni_lights[idx].inv_radius, omni_lights[idx].attenuation); 668: vec3 color = omni_lights[idx].color; 669: float size_A = 0.0; 670: 671: if (omni_lights[idx].size > 0.0) { 672: float t = omni_lights[idx].size / max(0.001, light_length); 673: size_A = max(0.0, 1.0 - 1.0 / sqrt(1.0 + t * t)); 674: } 675: 676: light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color, omni_attenuation, f0, roughness, metallic, omni_lights[idx].specular_amount, albedo, alpha, 677: #ifdef LIGHT_BACKLIGHT_USED 678: backlight, 679: #endif 680: #ifdef LIGHT_RIM_USED 681: rim * omni_attenuation, rim_tint, 682: #endif 683: #ifdef LIGHT_CLEARCOAT_USED 684: clearcoat, clearcoat_roughness, vertex_normal, 685: #endif 686: #ifdef LIGHT_ANISOTROPY_USED 687: binormal, tangent, anisotropy, 688: #endif 689: diffuse_light, 690: specular_light); 691: } 692: #endif // !DISABLE_LIGHT_OMNI 693: 694: #ifndef DISABLE_LIGHT_SPOT 695: void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f0, float roughness, float metallic, float shadow, vec3 albedo, inout float alpha, 696: #ifdef LIGHT_BACKLIGHT_USED 697: vec3 backlight, 698: #endif 699: #ifdef LIGHT_RIM_USED 700: float rim, float rim_tint, 701: #endif 702: #ifdef LIGHT_CLEARCOAT_USED 703: float clearcoat, float clearcoat_roughness, vec3 vertex_normal, 704: #endif 705: #ifdef LIGHT_ANISOTROPY_USED 706: vec3 binormal, vec3 tangent, float anisotropy, 707: #endif 708: inout vec3 diffuse_light, 709: inout vec3 specular_light) { 710: 711: vec3 light_rel_vec = spot_lights[idx].position - vertex; 712: float light_length = length(light_rel_vec); 713: float spot_attenuation = get_omni_spot_attenuation(light_length, spot_lights[idx].inv_radius, spot_lights[idx].attenuation); 714: vec3 spot_dir = spot_lights[idx].direction; 715: float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_lights[idx].cone_angle); 716: float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_lights[idx].cone_angle)); 717: spot_attenuation *= 1.0 - pow(spot_rim, spot_lights[idx].cone_attenuation); 718: vec3 color = spot_lights[idx].color; 719: 720: float size_A = 0.0; 721: 722: if (spot_lights[idx].size > 0.0) { 723: float t = spot_lights[idx].size / max(0.001, light_length); 724: size_A = max(0.0, 1.0 - 1.0 / sqrt(1.0 + t * t)); 725: } 726: 727: light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color, spot_attenuation, f0, roughness, metallic, spot_lights[idx].specular_amount, albedo, alpha, 728: #ifdef LIGHT_BACKLIGHT_USED 729: backlight, 730: #endif 731: #ifdef LIGHT_RIM_USED 732: rim * spot_attenuation, rim_tint, 733: #endif 734: #ifdef LIGHT_CLEARCOAT_USED 735: clearcoat, clearcoat_roughness, vertex_normal, 736: #endif 737: #ifdef LIGHT_ANISOTROPY_USED 738: binormal, tangent, anisotropy, 739: #endif 740: diffuse_light, specular_light); 741: } 742: #endif // !DISABLE_LIGHT_SPOT 743: 744: #endif // !defined(DISABLE_LIGHT_DIRECTIONAL) || !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) 745: 746: #ifndef MODE_RENDER_DEPTH 747: vec4 fog_process(vec3 vertex) { 748: vec3 fog_color = scene_data.fog_light_color; 749: 750: #ifdef USE_RADIANCE_MAP 751: /* 752: if (scene_data.fog_aerial_perspective > 0.0) { 753: vec3 sky_fog_color = vec3(0.0); 754: vec3 cube_view = scene_data.radiance_inverse_xform * vertex; 755: // mip_level always reads from the second mipmap and higher so the fog is always slightly blurred 756: float mip_level = mix(1.0 / MAX_ROUGHNESS_LOD, 1.0, 1.0 - (abs(vertex.z) - scene_data.z_near) / (scene_data.z_far - scene_data.z_near)); 757: 758: sky_fog_color = textureLod(radiance_map, cube_view, mip_level * RADIANCE_MAX_LOD).rgb; 759: 760: fog_color = mix(fog_color, sky_fog_color, scene_data.fog_aerial_perspective); 761: } 762: */ 763: #endif 764: 765: #ifndef DISABLE_LIGHT_DIRECTIONAL 766: if (scene_data.fog_sun_scatter > 0.001) { 767: vec4 sun_scatter = vec4(0.0); 768: float sun_total = 0.0; 769: vec3 view = normalize(vertex); 770: for (uint i = uint(0); i < scene_data.directional_light_count; i++) { 771: vec3 light_color = directional_lights[i].color * directional_lights[i].energy; 772: float light_amount = pow(max(dot(view, directional_lights[i].direction), 0.0), 8.0); 773: fog_color += light_color * light_amount * scene_data.fog_sun_scatter; 774: } 775: } 776: #endif // !DISABLE_LIGHT_DIRECTIONAL 777: 778: float fog_amount = 1.0 - exp(min(0.0, -length(vertex) * scene_data.fog_density)); 779: 780: if (abs(scene_data.fog_height_density) >= 0.0001) { 781: float y = (scene_data.inv_view_matrix * vec4(vertex, 1.0)).y; 782: 783: float y_dist = y - scene_data.fog_height; 784: 785: float vfog_amount = 1.0 - exp(min(0.0, y_dist * scene_data.fog_height_density)); 786: 787: fog_amount = max(vfog_amount, fog_amount); 788: } 789: 790: return vec4(fog_color, fog_amount); 791: } 792: 793: #endif // !MODE_RENDER_DEPTH 794: 795: void main() { 796: //lay out everything, whatever is unused is optimized away anyway 797: vec3 vertex = vertex_interp; 798: #ifdef USE_MULTIVIEW 799: vec3 eye_offset = multiview_data.eye_offset[ViewIndex].xyz; 800: vec3 view = -normalize(vertex_interp - eye_offset); 801: mat4 projection_matrix = multiview_data.projection_matrix_view[ViewIndex]; 802: mat4 inv_projection_matrix = multiview_data.inv_projection_matrix_view[ViewIndex]; 803: #else 804: vec3 eye_offset = vec3(0.0, 0.0, 0.0); 805: vec3 view = -normalize(vertex_interp); 806: mat4 projection_matrix = scene_data.projection_matrix; 807: mat4 inv_projection_matrix = scene_data.inv_projection_matrix; 808: #endif 809: highp mat4 model_matrix = world_transform; 810: vec3 albedo = vec3(1.0); 811: vec3 backlight = vec3(0.0); 812: vec4 transmittance_color = vec4(0.0, 0.0, 0.0, 1.0); 813: float transmittance_depth = 0.0; 814: float transmittance_boost = 0.0; 815: float metallic = 0.0; 816: float specular = 0.5; 817: vec3 emission = vec3(0.0); 818: float roughness = 1.0; 819: float rim = 0.0; 820: float rim_tint = 0.0; 821: float clearcoat = 0.0; 822: float clearcoat_roughness = 0.0; 823: float anisotropy = 0.0; 824: vec2 anisotropy_flow = vec2(1.0, 0.0); 825: vec4 fog = vec4(0.0); 826: #if defined(CUSTOM_RADIANCE_USED) 827: vec4 custom_radiance = vec4(0.0); 828: #endif 829: #if defined(CUSTOM_IRRADIANCE_USED) 830: vec4 custom_irradiance = vec4(0.0); 831: #endif 832: 833: float ao = 1.0; 834: float ao_light_affect = 0.0; 835: 836: float alpha = 1.0; 837: 838: #if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) 839: vec3 binormal = normalize(binormal_interp); 840: vec3 tangent = normalize(tangent_interp); 841: #else 842: vec3 binormal = vec3(0.0); 843: vec3 tangent = vec3(0.0); 844: #endif 845: 846: #ifdef NORMAL_USED 847: vec3 normal = normalize(normal_interp); 848: 849: #if defined(DO_SIDE_CHECK) 850: if (!gl_FrontFacing) { 851: normal = -normal; 852: } 853: #endif 854: 855: #endif //NORMAL_USED 856: 857: #ifdef UV_USED 858: vec2 uv = uv_interp; 859: #endif 860: 861: #if defined(UV2_USED) || defined(USE_LIGHTMAP) 862: vec2 uv2 = uv2_interp; 863: #endif 864: 865: #if defined(COLOR_USED) 866: vec4 color = color_interp; 867: #endif 868: 869: #if defined(NORMAL_MAP_USED) 870: 871: vec3 normal_map = vec3(0.5); 872: #endif 873: 874: float normal_map_depth = 1.0; 875: 876: vec2 screen_uv = gl_FragCoord.xy * scene_data.screen_pixel_size; 877: 878: float sss_strength = 0.0; 879: 880: #ifdef ALPHA_SCISSOR_USED 881: float alpha_scissor_threshold = 1.0; 882: #endif // ALPHA_SCISSOR_USED 883: 884: #ifdef ALPHA_HASH_USED 885: float alpha_hash_scale = 1.0; 886: #endif // ALPHA_HASH_USED 887: 888: #ifdef ALPHA_ANTIALIASING_EDGE_USED 889: float alpha_antialiasing_edge = 0.0; 890: vec2 alpha_texture_coordinate = vec2(0.0, 0.0); 891: #endif // ALPHA_ANTIALIASING_EDGE_USED 892: { 893: } 894: 895: #ifndef USE_SHADOW_TO_OPACITY 896: 897: #if defined(ALPHA_SCISSOR_USED) 898: if (alpha < alpha_scissor_threshold) { 899: discard; 900: } 901: #endif // ALPHA_SCISSOR_USED 902: 903: #ifdef USE_OPAQUE_PREPASS 904: #if !defined(ALPHA_SCISSOR_USED) 905: 906: if (alpha < opaque_prepass_threshold) { 907: discard; 908: } 909: 910: #endif // not ALPHA_SCISSOR_USED 911: #endif // USE_OPAQUE_PREPASS 912: 913: #endif // !USE_SHADOW_TO_OPACITY 914: 915: #ifdef NORMAL_MAP_USED 916: 917: normal_map.xy = normal_map.xy * 2.0 - 1.0; 918: normal_map.z = sqrt(max(0.0, 1.0 - dot(normal_map.xy, normal_map.xy))); //always ignore Z, as it can be RG packed, Z may be pos/neg, etc. 919: 920: normal = normalize(mix(normal, tangent * normal_map.x + binormal * normal_map.y + normal * normal_map.z, normal_map_depth)); 921: 922: #endif 923: 924: #ifdef LIGHT_ANISOTROPY_USED 925: 926: if (anisotropy > 0.01) { 927: //rotation matrix 928: mat3 rot = mat3(tangent, binormal, normal); 929: //make local to space 930: tangent = normalize(rot * vec3(anisotropy_flow.x, anisotropy_flow.y, 0.0)); 931: binormal = normalize(rot * vec3(-anisotropy_flow.y, anisotropy_flow.x, 0.0)); 932: } 933: 934: #endif 935: 936: #ifndef MODE_RENDER_DEPTH 937: 938: #ifndef CUSTOM_FOG_USED 939: #ifndef DISABLE_FOG 940: // fog must be processed as early as possible and then packed. 941: // to maximize VGPR usage 942: 943: if (scene_data.fog_enabled) { 944: fog = fog_process(vertex); 945: } 946: #endif // !DISABLE_FOG 947: #endif // !CUSTOM_FOG_USED 948: 949: uint fog_rg = packHalf2x16(fog.rg); 950: uint fog_ba = packHalf2x16(fog.ba); 951: 952: // Convert colors to linear 953: albedo = srgb_to_linear(albedo); 954: emission = srgb_to_linear(emission); 955: // TODO Backlight and transmittance when used 956: #ifndef MODE_UNSHADED 957: vec3 f0 = F0(metallic, specular, albedo); 958: vec3 specular_light = vec3(0.0, 0.0, 0.0); 959: vec3 diffuse_light = vec3(0.0, 0.0, 0.0); 960: vec3 ambient_light = vec3(0.0, 0.0, 0.0); 961: 962: #ifdef BASE_PASS 963: /////////////////////// LIGHTING ////////////////////////////// 964: 965: // IBL precalculations 966: float ndotv = clamp(dot(normal, view), 0.0, 1.0); 967: vec3 F = f0 + (max(vec3(1.0 - roughness), f0) - f0) * pow(1.0 - ndotv, 5.0); 968: 969: #ifdef USE_RADIANCE_MAP 970: if (scene_data.use_reflection_cubemap) { 971: #ifdef LIGHT_ANISOTROPY_USED 972: // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy 973: vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent; 974: vec3 anisotropic_tangent = cross(anisotropic_direction, view); 975: vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction); 976: vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0))); 977: vec3 ref_vec = reflect(-view, bent_normal); 978: #else 979: vec3 ref_vec = reflect(-view, normal); 980: #endif 981: ref_vec = mix(ref_vec, normal, roughness * roughness); 982: float horizon = min(1.0 + dot(ref_vec, normal), 1.0); 983: ref_vec = scene_data.radiance_inverse_xform * ref_vec; 984: specular_light = textureLod(radiance_map, ref_vec, sqrt(roughness) * RADIANCE_MAX_LOD).rgb; 985: specular_light = srgb_to_linear(specular_light); 986: specular_light *= horizon * horizon; 987: specular_light *= scene_data.ambient_light_color_energy.a; 988: } 989: #endif 990: 991: // Calculate Reflection probes 992: // Calculate Lightmaps 993: 994: #if defined(CUSTOM_RADIANCE_USED) 995: specular_light = mix(specular_light, custom_radiance.rgb, custom_radiance.a); 996: #endif // CUSTOM_RADIANCE_USED 997: 998: #ifndef USE_LIGHTMAP 999: //lightmap overrides everything 1000: if (scene_data.use_ambient_light) { 1001: ambient_light = scene_data.ambient_light_color_energy.rgb; 1002: #ifdef USE_RADIANCE_MAP 1003: if (scene_data.use_ambient_cubemap) { 1004: vec3 ambient_dir = scene_data.radiance_inverse_xform * normal; 1005: vec3 cubemap_ambient = textureLod(radiance_map, ambient_dir, RADIANCE_MAX_LOD).rgb; 1006: cubemap_ambient = srgb_to_linear(cubemap_ambient); 1007: ambient_light = mix(ambient_light, cubemap_ambient * scene_data.ambient_light_color_energy.a, scene_data.ambient_color_sky_mix); 1008: } 1009: #endif 1010: } 1011: #endif // USE_LIGHTMAP 1012: 1013: #if defined(CUSTOM_IRRADIANCE_USED) 1014: ambient_light = mix(ambient_light, custom_irradiance.rgb, custom_irradiance.a); 1015: #endif // CUSTOM_IRRADIANCE_USED 1016: 1017: { 1018: #if defined(AMBIENT_LIGHT_DISABLED) 1019: ambient_light = vec3(0.0, 0.0, 0.0); 1020: #else 1021: ambient_light *= albedo.rgb; 1022: ambient_light *= ao; 1023: #endif // AMBIENT_LIGHT_DISABLED 1024: } 1025: 1026: // convert ao to direct light ao 1027: ao = mix(1.0, ao, ao_light_affect); 1028: 1029: { 1030: #if defined(DIFFUSE_TOON) 1031: //simplify for toon, as 1032: specular_light *= specular * metallic * albedo * 2.0; 1033: #else 1034: 1035: // scales the specular reflections, needs to be be computed before lighting happens, 1036: // but after environment, GI, and reflection probes are added 1037: // Environment brdf approximation (Lazarov 2013) 1038: // see https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile 1039: const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022); 1040: const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04); 1041: vec4 r = roughness * c0 + c1; 1042: float ndotv = clamp(dot(normal, view), 0.0, 1.0); 1043: 1044: float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y; 1045: vec2 env = vec2(-1.04, 1.04) * a004 + r.zw; 1046: specular_light *= env.x * f0 + env.y * clamp(50.0 * f0.g, metallic, 1.0); 1047: #endif 1048: } 1049: 1050: #endif // BASE_PASS 1051: 1052: #ifndef DISABLE_LIGHT_DIRECTIONAL 1053: //diffuse_light = normal; // 1054: for (uint i = uint(0); i < scene_data.directional_light_count; i++) { 1055: light_compute(normal, normalize(directional_lights[i].direction), normalize(view), directional_lights[i].size, directional_lights[i].color * directional_lights[i].energy, 1.0, f0, roughness, metallic, 1.0, albedo, alpha, 1056: #ifdef LIGHT_BACKLIGHT_USED 1057: backlight, 1058: #endif 1059: #ifdef LIGHT_RIM_USED 1060: rim, rim_tint, 1061: #endif 1062: #ifdef LIGHT_CLEARCOAT_USED 1063: clearcoat, clearcoat_roughness, normalize(normal_interp), 1064: #endif 1065: #ifdef LIGHT_ANISOTROPY_USED 1066: binormal, 1067: tangent, anisotropy, 1068: #endif 1069: diffuse_light, 1070: specular_light); 1071: } 1072: #endif // !DISABLE_LIGHT_DIRECTIONAL 1073: 1074: #ifndef DISABLE_LIGHT_OMNI 1075: for (uint i = 0u; i < MAX_FORWARD_LIGHTS; i++) { 1076: if (i >= omni_light_count) { 1077: break; 1078: } 1079: light_process_omni(omni_light_indices[i], vertex, view, normal, f0, roughness, metallic, 0.0, albedo, alpha, 1080: #ifdef LIGHT_BACKLIGHT_USED 1081: backlight, 1082: #endif 1083: #ifdef LIGHT_RIM_USED 1084: rim, 1085: rim_tint, 1086: #endif 1087: #ifdef LIGHT_CLEARCOAT_USED 1088: clearcoat, clearcoat_roughness, normalize(normal_interp), 1089: #endif 1090: #ifdef LIGHT_ANISOTROPY_USED 1091: binormal, tangent, anisotropy, 1092: #endif 1093: diffuse_light, specular_light); 1094: } 1095: #endif // !DISABLE_LIGHT_OMNI 1096: 1097: #ifndef DISABLE_LIGHT_SPOT 1098: for (uint i = 0u; i < MAX_FORWARD_LIGHTS; i++) { 1099: if (i >= spot_light_count) { 1100: break; 1101: } 1102: light_process_spot(spot_light_indices[i], vertex, view, normal, f0, roughness, metallic, 0.0, albedo, alpha, 1103: #ifdef LIGHT_BACKLIGHT_USED 1104: backlight, 1105: #endif 1106: #ifdef LIGHT_RIM_USED 1107: rim, 1108: rim_tint, 1109: #endif 1110: #ifdef LIGHT_CLEARCOAT_USED 1111: clearcoat, clearcoat_roughness, normalize(normal_interp), 1112: #endif 1113: #ifdef LIGHT_ANISOTROPY_USED 1114: tangent, 1115: binormal, anisotropy, 1116: #endif 1117: diffuse_light, specular_light); 1118: } 1119: #endif // !DISABLE_LIGHT_SPOT 1120: 1121: #endif // !MODE_UNSHADED 1122: 1123: #endif // !MODE_RENDER_DEPTH 1124: 1125: #if defined(USE_SHADOW_TO_OPACITY) 1126: alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0)); 1127: 1128: #if defined(ALPHA_SCISSOR_USED) 1129: if (alpha < alpha_scissor) { 1130: discard; 1131: } 1132: #endif // ALPHA_SCISSOR_USED 1133: 1134: #ifdef USE_OPAQUE_PREPASS 1135: #if !defined(ALPHA_SCISSOR_USED) 1136: 1137: if (alpha < opaque_prepass_threshold) { 1138: discard; 1139: } 1140: 1141: #endif // not ALPHA_SCISSOR_USED 1142: #endif // USE_OPAQUE_PREPASS 1143: 1144: #endif // USE_SHADOW_TO_OPACITY 1145: 1146: #ifdef MODE_RENDER_DEPTH 1147: //nothing happens, so a tree-ssa optimizer will result in no fragment shader :) 1148: #else // !MODE_RENDER_DEPTH 1149: 1150: #ifdef MODE_UNSHADED 1151: frag_color = vec4(albedo, alpha); 1152: #else 1153: 1154: diffuse_light *= albedo; 1155: 1156: diffuse_light *= 1.0 - metallic; 1157: ambient_light *= 1.0 - metallic; 1158: 1159: frag_color = vec4(diffuse_light + specular_light, alpha); 1160: #ifdef BASE_PASS 1161: frag_color.rgb += emission + ambient_light; 1162: #endif 1163: #endif //MODE_UNSHADED 1164: fog = vec4(unpackHalf2x16(fog_rg), unpackHalf2x16(fog_ba)); 1165: 1166: #ifndef DISABLE_FOG 1167: if (scene_data.fog_enabled) { 1168: #ifdef BASE_PASS 1169: frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a); 1170: #else 1171: frag_color.rgb *= (1.0 - fog.a); 1172: #endif // BASE_PASS 1173: } 1174: #endif 1175: 1176: // Tonemap before writing as we are writing to an sRGB framebuffer 1177: frag_color.rgb *= exposure; 1178: frag_color.rgb = apply_tonemapping(frag_color.rgb, white); 1179: frag_color.rgb = linear_to_srgb(frag_color.rgb); 1180: 1181: #ifdef USE_BCS 1182: frag_color.rgb = apply_bcs(frag_color.rgb, bcs); 1183: #endif 1184: 1185: #ifdef USE_COLOR_CORRECTION 1186: frag_color.rgb = apply_color_correction(frag_color.rgb, color_correction); 1187: #endif 1188: 1189: #endif //!MODE_RENDER_DEPTH 1190: } 1191: 1192: 1: #version 330 2: #define USE_GLES_OVER_GL 3: #define USE_RADIANCE_MAP 4: 5: #define MAX_GLOBAL_SHADER_UNIFORMS 256 6: 7: #define MAX_LIGHT_DATA_STRUCTS 32 8: 9: #define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS 8 10: 11: #define MAX_FORWARD_LIGHTS uint(8) 12: #define USE_ADDITIVE_LIGHTING 13: 14: #ifdef USE_MULTIVIEW 15: #if defined(GL_OVR_multiview2) 16: #extension GL_OVR_multiview2 : require 17: #elif defined(GL_OVR_multiview) 18: #extension GL_OVR_multiview : require 19: #endif 20: #define ViewIndex gl_ViewID_OVR 21: #define MAX_VIEWS 2 22: #else 23: #define ViewIndex uint(0) 24: #define MAX_VIEWS 1 25: #endif 26: precision highp float; 27: precision highp int; 28: 29: // Default to SPECULAR_SCHLICK_GGX. 30: #if !defined(SPECULAR_DISABLED) && !defined(SPECULAR_SCHLICK_GGX) && !defined(SPECULAR_TOON) 31: #define SPECULAR_SCHLICK_GGX 32: #endif 33: 34: #if !defined(MODE_RENDER_DEPTH) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) ||defined(LIGHT_CLEARCOAT_USED) 35: #ifndef NORMAL_USED 36: #define NORMAL_USED 37: #endif 38: #endif 39: 40: #ifndef MODE_RENDER_DEPTH 41: #ifdef USE_BCS 42: uniform vec3 bcs; 43: #endif 44: 45: #ifdef USE_COLOR_CORRECTION 46: #ifdef USE_1D_LUT 47: uniform sampler2D source_color_correction; //texunit:-1 48: #else 49: uniform sampler3D source_color_correction; //texunit:-1 50: #endif 51: #endif 52: 53: layout(std140) uniform TonemapData { //ubo:0 54: float exposure; 55: float white; 56: int tonemapper; 57: int pad; 58: }; 59: 60: vec3 apply_bcs(vec3 color, vec3 bcs) { 61: color = mix(vec3(0.0), color, bcs.x); 62: color = mix(vec3(0.5), color, bcs.y); 63: color = mix(vec3(dot(vec3(1.0), color) * 0.33333), color, bcs.z); 64: 65: return color; 66: } 67: #ifdef USE_COLOR_CORRECTION 68: #ifdef USE_1D_LUT 69: vec3 apply_color_correction(vec3 color) { 70: color.r = texture(source_color_correction, vec2(color.r, 0.0f)).r; 71: color.g = texture(source_color_correction, vec2(color.g, 0.0f)).g; 72: color.b = texture(source_color_correction, vec2(color.b, 0.0f)).b; 73: return color; 74: } 75: #else 76: vec3 apply_color_correction(vec3 color) { 77: return textureLod(source_color_correction, color, 0.0).rgb; 78: } 79: #endif 80: #endif 81: 82: vec3 tonemap_filmic(vec3 color, float p_white) { 83: // exposure bias: input scale (color *= bias, white *= bias) to make the brightness consistent with other tonemappers 84: // also useful to scale the input to the range that the tonemapper is designed for (some require very high input values) 85: // has no effect on the curve's general shape or visual properties 86: const float exposure_bias = 2.0f; 87: const float A = 0.22f * exposure_bias * exposure_bias; // bias baked into constants for performance 88: const float B = 0.30f * exposure_bias; 89: const float C = 0.10f; 90: const float D = 0.20f; 91: const float E = 0.01f; 92: const float F = 0.30f; 93: 94: vec3 color_tonemapped = ((color * (A * color + C * B) + D * E) / (color * (A * color + B) + D * F)) - E / F; 95: float p_white_tonemapped = ((p_white * (A * p_white + C * B) + D * E) / (p_white * (A * p_white + B) + D * F)) - E / F; 96: 97: return color_tonemapped / p_white_tonemapped; 98: } 99: 100: // Adapted from https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl 101: // (MIT License). 102: vec3 tonemap_aces(vec3 color, float p_white) { 103: const float exposure_bias = 1.8f; 104: const float A = 0.0245786f; 105: const float B = 0.000090537f; 106: const float C = 0.983729f; 107: const float D = 0.432951f; 108: const float E = 0.238081f; 109: 110: // Exposure bias baked into transform to save shader instructions. Equivalent to `color *= exposure_bias` 111: const mat3 rgb_to_rrt = mat3( 112: vec3(0.59719f * exposure_bias, 0.35458f * exposure_bias, 0.04823f * exposure_bias), 113: vec3(0.07600f * exposure_bias, 0.90834f * exposure_bias, 0.01566f * exposure_bias), 114: vec3(0.02840f * exposure_bias, 0.13383f * exposure_bias, 0.83777f * exposure_bias)); 115: 116: const mat3 odt_to_rgb = mat3( 117: vec3(1.60475f, -0.53108f, -0.07367f), 118: vec3(-0.10208f, 1.10813f, -0.00605f), 119: vec3(-0.00327f, -0.07276f, 1.07602f)); 120: 121: color *= rgb_to_rrt; 122: vec3 color_tonemapped = (color * (color + A) - B) / (color * (C * color + D) + E); 123: color_tonemapped *= odt_to_rgb; 124: 125: p_white *= exposure_bias; 126: float p_white_tonemapped = (p_white * (p_white + A) - B) / (p_white * (C * p_white + D) + E); 127: 128: return color_tonemapped / p_white_tonemapped; 129: } 130: 131: vec3 tonemap_reinhard(vec3 color, float p_white) { 132: return (p_white * color + color) / (color * p_white + p_white); 133: } 134: 135: // This expects 0-1 range input. 136: vec3 linear_to_srgb(vec3 color) { 137: //color = clamp(color, vec3(0.0), vec3(1.0)); 138: //const vec3 a = vec3(0.055f); 139: //return mix((vec3(1.0f) + a) * pow(color.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * color.rgb, lessThan(color.rgb, vec3(0.0031308f))); 140: // Approximation from http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html 141: return max(vec3(1.055) * pow(color, vec3(0.416666667)) - vec3(0.055), vec3(0.0)); 142: } 143: 144: // This expects 0-1 range input, outside that range it behaves poorly. 145: vec3 srgb_to_linear(vec3 color) { 146: // Approximation from http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html 147: return color * (color * (color * 0.305306011 + 0.682171111) + 0.012522878); 148: } 149: 150: #define TONEMAPPER_LINEAR 0 151: #define TONEMAPPER_REINHARD 1 152: #define TONEMAPPER_FILMIC 2 153: #define TONEMAPPER_ACES 3 154: 155: vec3 apply_tonemapping(vec3 color, float p_white) { // inputs are LINEAR, always outputs clamped [0;1] color 156: // Ensure color values passed to tonemappers are positive. 157: // They can be negative in the case of negative lights, which leads to undesired behavior. 158: if (tonemapper == TONEMAPPER_LINEAR) { 159: return color; 160: } else if (tonemapper == TONEMAPPER_REINHARD) { 161: return tonemap_reinhard(max(vec3(0.0f), color), p_white); 162: } else if (tonemapper == TONEMAPPER_FILMIC) { 163: return tonemap_filmic(max(vec3(0.0f), color), p_white); 164: } else { // TONEMAPPER_ACES 165: return tonemap_aces(max(vec3(0.0f), color), p_white); 166: } 167: } 168: #endif 169: 170: #ifdef USE_GLES_OVER_GL 171: // Floating point pack/unpack functions are part of the GLSL ES 300 specification used by web and mobile. 172: uint float2half(uint f) { 173: uint e = f & uint(0x7f800000); 174: if (e <= uint(0x38000000)) { 175: return uint(0); 176: } else { 177: return ((f >> uint(16)) & uint(0x8000)) | 178: (((e - uint(0x38000000)) >> uint(13)) & uint(0x7c00)) | 179: ((f >> uint(13)) & uint(0x03ff)); 180: } 181: } 182: 183: uint half2float(uint h) { 184: uint h_e = h & uint(0x7c00); 185: return ((h & uint(0x8000)) << uint(16)) | uint((h_e >> uint(10)) != uint(0)) * (((h_e + uint(0x1c000)) << uint(13)) | ((h & uint(0x03ff)) << uint(13))); 186: } 187: 188: uint packHalf2x16(vec2 v) { 189: return float2half(floatBitsToUint(v.x)) | float2half(floatBitsToUint(v.y)) << uint(16); 190: } 191: 192: vec2 unpackHalf2x16(uint v) { 193: return vec2(uintBitsToFloat(half2float(v & uint(0xffff))), 194: uintBitsToFloat(half2float(v >> uint(16)))); 195: } 196: 197: uint packUnorm2x16(vec2 v) { 198: uvec2 uv = uvec2(round(clamp(v, vec2(0.0), vec2(1.0)) * 65535.0)); 199: return uv.x | uv.y << uint(16); 200: } 201: 202: vec2 unpackUnorm2x16(uint p) { 203: return vec2(float(p & uint(0xffff)), float(p >> uint(16))) * 0.000015259021; // 1.0 / 65535.0 optimization 204: } 205: 206: uint packSnorm2x16(vec2 v) { 207: uvec2 uv = uvec2(round(clamp(v, vec2(-1.0), vec2(1.0)) * 32767.0) + 32767.0); 208: return uv.x | uv.y << uint(16); 209: } 210: 211: vec2 unpackSnorm2x16(uint p) { 212: vec2 v = vec2(float(p & uint(0xffff)), float(p >> uint(16))); 213: return clamp((v - 32767.0) * vec2(0.00003051851), vec2(-1.0), vec2(1.0)); 214: } 215: 216: #endif 217: 218: // Compatibility renames. These are exposed with the "godot_" prefix 219: // to work around an Adreno bug which was exposing these ES310 functions 220: // in ES300 shaders. Internally, we must use the "godot_" prefix, but user shaders 221: // will be mapped automatically. 222: uint godot_packUnorm4x8(vec4 v) { 223: uvec4 uv = uvec4(round(clamp(v, vec4(0.0), vec4(1.0)) * 255.0)); 224: return uv.x | (uv.y << uint(8)) | (uv.z << uint(16)) | (uv.w << uint(24)); 225: } 226: 227: vec4 godot_unpackUnorm4x8(uint p) { 228: return vec4(float(p & uint(0xff)), float((p >> uint(8)) & uint(0xff)), float((p >> uint(16)) & uint(0xff)), float(p >> uint(24))) * 0.00392156862; // 1.0 / 255.0 229: } 230: 231: uint godot_packSnorm4x8(vec4 v) { 232: uvec4 uv = uvec4(round(clamp(v, vec4(-1.0), vec4(1.0)) * 127.0) + 127.0); 233: return uv.x | uv.y << uint(8) | uv.z << uint(16) | uv.w << uint(24); 234: } 235: 236: vec4 godot_unpackSnorm4x8(uint p) { 237: vec4 v = vec4(float(p & uint(0xff)), float((p >> uint(8)) & uint(0xff)), float((p >> uint(16)) & uint(0xff)), float(p >> uint(24))); 238: return clamp((v - vec4(127.0)) * vec4(0.00787401574), vec4(-1.0), vec4(1.0)); 239: } 240: 241: #define packUnorm4x8 godot_packUnorm4x8 242: #define unpackUnorm4x8 godot_unpackUnorm4x8 243: #define packSnorm4x8 godot_packSnorm4x8 244: #define unpackSnorm4x8 godot_unpackSnorm4x8 245: 246: /* texture unit usage, N is max_texture_unity-N 247: 248: 1-color correction // In tonemap_inc.glsl 249: 2-radiance 250: 3-directional_shadow 251: 4-positional_shadow 252: 5-screen 253: 6-depth 254: 255: */ 256: 257: #define M_PI 3.14159265359 258: /* clang-format on */ 259: 260: #define SHADER_IS_SRGB true 261: 262: /* Varyings */ 263: 264: #if defined(COLOR_USED) 265: in vec4 color_interp; 266: #endif 267: 268: #if defined(UV_USED) 269: in vec2 uv_interp; 270: #endif 271: 272: #if defined(UV2_USED) 273: in vec2 uv2_interp; 274: #else 275: #ifdef USE_LIGHTMAP 276: in vec2 uv2_interp; 277: #endif 278: #endif 279: 280: #if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) 281: in vec3 tangent_interp; 282: in vec3 binormal_interp; 283: #endif 284: 285: #ifdef NORMAL_USED 286: in vec3 normal_interp; 287: #endif 288: 289: in highp vec3 vertex_interp; 290: 291: #ifdef USE_RADIANCE_MAP 292: 293: #define RADIANCE_MAX_LOD 5.0 294: 295: uniform samplerCube radiance_map; // texunit:-2 296: 297: #endif 298: 299: layout(std140) uniform GlobalShaderUniformData { //ubo:1 300: vec4 global_shader_uniforms[MAX_GLOBAL_SHADER_UNIFORMS]; 301: }; 302: 303: /* Material Uniforms */ 304: 305: #ifdef MATERIAL_UNIFORMS_USED 306: 307: /* clang-format off */ 308: layout(std140) uniform MaterialUniforms { // ubo:3 309: 310: 311: }; 312: /* clang-format on */ 313: 314: #endif 315: 316: layout(std140) uniform SceneData { // ubo:2 317: highp mat4 projection_matrix; 318: highp mat4 inv_projection_matrix; 319: highp mat4 inv_view_matrix; 320: highp mat4 view_matrix; 321: 322: vec2 viewport_size; 323: vec2 screen_pixel_size; 324: 325: mediump vec4 ambient_light_color_energy; 326: 327: mediump float ambient_color_sky_mix; 328: bool material_uv2_mode; 329: float emissive_exposure_normalization; 330: bool use_ambient_light; 331: bool use_ambient_cubemap; 332: bool use_reflection_cubemap; 333: 334: float fog_aerial_perspective; 335: float time; 336: 337: mat3 radiance_inverse_xform; 338: 339: uint directional_light_count; 340: float z_far; 341: float z_near; 342: float IBL_exposure_normalization; 343: 344: bool fog_enabled; 345: float fog_density; 346: float fog_height; 347: float fog_height_density; 348: 349: vec3 fog_light_color; 350: float fog_sun_scatter; 351: uint camera_visible_layers; 352: uint pad3; 353: uint pad4; 354: uint pad5; 355: } 356: scene_data; 357: 358: #ifdef USE_MULTIVIEW 359: layout(std140) uniform MultiviewData { // ubo:8 360: highp mat4 projection_matrix_view[MAX_VIEWS]; 361: highp mat4 inv_projection_matrix_view[MAX_VIEWS]; 362: highp vec4 eye_offset[MAX_VIEWS]; 363: } 364: multiview_data; 365: #endif 366: 367: /* clang-format off */ 368: 369: 370: /* clang-format on */ 371: 372: // Directional light data. 373: #ifndef DISABLE_LIGHT_DIRECTIONAL 374: 375: struct DirectionalLightData { 376: mediump vec3 direction; 377: mediump float energy; 378: mediump vec3 color; 379: mediump float size; 380: mediump vec3 pad; 381: mediump float specular; 382: }; 383: 384: layout(std140) uniform DirectionalLights { // ubo:7 385: DirectionalLightData directional_lights[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS]; 386: }; 387: 388: #endif // !DISABLE_LIGHT_DIRECTIONAL 389: 390: // Omni and spot light data. 391: #if !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) 392: 393: struct LightData { // This structure needs to be as packed as possible. 394: highp vec3 position; 395: highp float inv_radius; 396: 397: mediump vec3 direction; 398: highp float size; 399: 400: mediump vec3 color; 401: mediump float attenuation; 402: 403: mediump float cone_attenuation; 404: mediump float cone_angle; 405: mediump float specular_amount; 406: mediump float shadow_opacity; 407: }; 408: 409: #ifndef DISABLE_LIGHT_OMNI 410: layout(std140) uniform OmniLightData { // ubo:5 411: LightData omni_lights[MAX_LIGHT_DATA_STRUCTS]; 412: }; 413: uniform uint omni_light_indices[MAX_FORWARD_LIGHTS]; 414: uniform uint omni_light_count; 415: #endif 416: 417: #ifndef DISABLE_LIGHT_SPOT 418: layout(std140) uniform SpotLightData { // ubo:6 419: LightData spot_lights[MAX_LIGHT_DATA_STRUCTS]; 420: }; 421: uniform uint spot_light_indices[MAX_FORWARD_LIGHTS]; 422: uniform uint spot_light_count; 423: #endif 424: 425: #ifdef USE_ADDITIVE_LIGHTING 426: uniform highp samplerCubeShadow positional_shadow; // texunit:-4 427: #endif 428: 429: #endif // !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) 430: 431: #ifdef USE_MULTIVIEW 432: uniform highp sampler2DArray depth_buffer; // texunit:-6 433: uniform highp sampler2DArray color_buffer; // texunit:-5 434: vec3 multiview_uv(vec2 uv) { 435: return vec3(uv, ViewIndex); 436: } 437: #else 438: uniform highp sampler2D depth_buffer; // texunit:-6 439: uniform highp sampler2D color_buffer; // texunit:-5 440: vec2 multiview_uv(vec2 uv) { 441: return uv; 442: } 443: #endif 444: 445: uniform highp mat4 world_transform; 446: uniform mediump float opaque_prepass_threshold; 447: 448: layout(location = 0) out vec4 frag_color; 449: 450: vec3 F0(float metallic, float specular, vec3 albedo) { 451: float dielectric = 0.16 * specular * specular; 452: // use albedo * metallic as colored specular reflectance at 0 angle for metallic materials; 453: // see https://google.github.io/filament/Filament.md.html 454: return mix(vec3(dielectric), albedo, vec3(metallic)); 455: } 456: 457: #if !defined(DISABLE_LIGHT_DIRECTIONAL) || !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) 458: 459: float D_GGX(float cos_theta_m, float alpha) { 460: float a = cos_theta_m * alpha; 461: float k = alpha / (1.0 - cos_theta_m * cos_theta_m + a * a); 462: return k * k * (1.0 / M_PI); 463: } 464: 465: // From Earl Hammon, Jr. "PBR Diffuse Lighting for GGX+Smith Microsurfaces" https://www.gdcvault.com/play/1024478/PBR-Diffuse-Lighting-for-GGX 466: float V_GGX(float NdotL, float NdotV, float alpha) { 467: return 0.5 / mix(2.0 * NdotL * NdotV, NdotL + NdotV, alpha); 468: } 469: 470: float D_GGX_anisotropic(float cos_theta_m, float alpha_x, float alpha_y, float cos_phi, float sin_phi) { 471: float alpha2 = alpha_x * alpha_y; 472: highp vec3 v = vec3(alpha_y * cos_phi, alpha_x * sin_phi, alpha2 * cos_theta_m); 473: highp float v2 = dot(v, v); 474: float w2 = alpha2 / v2; 475: float D = alpha2 * w2 * w2 * (1.0 / M_PI); 476: return D; 477: } 478: 479: float V_GGX_anisotropic(float alpha_x, float alpha_y, float TdotV, float TdotL, float BdotV, float BdotL, float NdotV, float NdotL) { 480: float Lambda_V = NdotL * length(vec3(alpha_x * TdotV, alpha_y * BdotV, NdotV)); 481: float Lambda_L = NdotV * length(vec3(alpha_x * TdotL, alpha_y * BdotL, NdotL)); 482: return 0.5 / (Lambda_V + Lambda_L); 483: } 484: 485: float SchlickFresnel(float u) { 486: float m = 1.0 - u; 487: float m2 = m * m; 488: return m2 * m2 * m; // pow(m,5) 489: } 490: 491: void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float attenuation, vec3 f0, float roughness, float metallic, float specular_amount, vec3 albedo, inout float alpha, 492: #ifdef LIGHT_BACKLIGHT_USED 493: vec3 backlight, 494: #endif 495: #ifdef LIGHT_RIM_USED 496: float rim, float rim_tint, 497: #endif 498: #ifdef LIGHT_CLEARCOAT_USED 499: float clearcoat, float clearcoat_roughness, vec3 vertex_normal, 500: #endif 501: #ifdef LIGHT_ANISOTROPY_USED 502: vec3 B, vec3 T, float anisotropy, 503: #endif 504: inout vec3 diffuse_light, inout vec3 specular_light) { 505: 506: #if defined(USE_LIGHT_SHADER_CODE) 507: // light is written by the light shader 508: 509: vec3 normal = N; 510: vec3 light = L; 511: vec3 view = V; 512: 513: /* clang-format off */ 514: 515: 516: /* clang-format on */ 517: 518: #else 519: float NdotL = min(A + dot(N, L), 1.0); 520: float cNdotL = max(NdotL, 0.0); // clamped NdotL 521: float NdotV = dot(N, V); 522: float cNdotV = max(NdotV, 1e-4); 523: 524: #if defined(DIFFUSE_BURLEY) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED) 525: vec3 H = normalize(V + L); 526: #endif 527: 528: #if defined(SPECULAR_SCHLICK_GGX) 529: float cNdotH = clamp(A + dot(N, H), 0.0, 1.0); 530: #endif 531: 532: #if defined(DIFFUSE_BURLEY) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED) 533: float cLdotH = clamp(A + dot(L, H), 0.0, 1.0); 534: #endif 535: 536: if (metallic < 1.0) { 537: float diffuse_brdf_NL; // BRDF times N.L for calculating diffuse radiance 538: 539: #if defined(DIFFUSE_LAMBERT_WRAP) 540: // Energy conserving lambert wrap shader. 541: // https://web.archive.org/web/20210228210901/http://blog.stevemcauley.com/2011/12/03/energy-conserving-wrapped-diffuse/ 542: diffuse_brdf_NL = max(0.0, (NdotL + roughness) / ((1.0 + roughness) * (1.0 + roughness))) * (1.0 / M_PI); 543: #elif defined(DIFFUSE_TOON) 544: diffuse_brdf_NL = smoothstep(-roughness, max(roughness, 0.01), NdotL) * (1.0 / M_PI); 545: #elif defined(DIFFUSE_BURLEY) 546: { 547: float FD90_minus_1 = 2.0 * cLdotH * cLdotH * roughness - 0.5; 548: float FdV = 1.0 + FD90_minus_1 * SchlickFresnel(cNdotV); 549: float FdL = 1.0 + FD90_minus_1 * SchlickFresnel(cNdotL); 550: diffuse_brdf_NL = (1.0 / M_PI) * FdV * FdL * cNdotL; 551: } 552: #else 553: // Lambert 554: diffuse_brdf_NL = cNdotL * (1.0 / M_PI); 555: #endif 556: 557: diffuse_light += light_color * diffuse_brdf_NL * attenuation; 558: 559: #if defined(LIGHT_BACKLIGHT_USED) 560: diffuse_light += light_color * (vec3(1.0 / M_PI) - diffuse_brdf_NL) * backlight * attenuation; 561: #endif 562: 563: #if defined(LIGHT_RIM_USED) 564: // Epsilon min to prevent pow(0, 0) singularity which results in undefined behavior. 565: float rim_light = pow(max(1e-4, 1.0 - cNdotV), max(0.0, (1.0 - roughness) * 16.0)); 566: diffuse_light += rim_light * rim * mix(vec3(1.0), albedo, rim_tint) * light_color; 567: #endif 568: } 569: 570: if (roughness > 0.0) { // FIXME: roughness == 0 should not disable specular light entirely 571: 572: // D 573: 574: #if defined(SPECULAR_TOON) 575: 576: vec3 R = normalize(-reflect(L, N)); 577: float RdotV = dot(R, V); 578: float mid = 1.0 - roughness; 579: mid *= mid; 580: float intensity = smoothstep(mid - roughness * 0.5, mid + roughness * 0.5, RdotV) * mid; 581: diffuse_light += light_color * intensity * attenuation * specular_amount; // write to diffuse_light, as in toon shading you generally want no reflection 582: 583: #elif defined(SPECULAR_DISABLED) 584: // none.. 585: 586: #elif defined(SPECULAR_SCHLICK_GGX) 587: // shlick+ggx as default 588: float alpha_ggx = roughness * roughness; 589: #if defined(LIGHT_ANISOTROPY_USED) 590: float aspect = sqrt(1.0 - anisotropy * 0.9); 591: float ax = alpha_ggx / aspect; 592: float ay = alpha_ggx * aspect; 593: float XdotH = dot(T, H); 594: float YdotH = dot(B, H); 595: float D = D_GGX_anisotropic(cNdotH, ax, ay, XdotH, YdotH); 596: float G = V_GGX_anisotropic(ax, ay, dot(T, V), dot(T, L), dot(B, V), dot(B, L), cNdotV, cNdotL); 597: #else 598: float D = D_GGX(cNdotH, alpha_ggx); 599: float G = V_GGX(cNdotL, cNdotV, alpha_ggx); 600: #endif // LIGHT_ANISOTROPY_USED 601: // F 602: float cLdotH5 = SchlickFresnel(cLdotH); 603: // Calculate Fresnel using cheap approximate specular occlusion term from Filament: 604: // https://google.github.io/filament/Filament.html#lighting/occlusion/specularocclusion 605: float f90 = clamp(50.0 * f0.g, 0.0, 1.0); 606: vec3 F = f0 + (f90 - f0) * cLdotH5; 607: 608: vec3 specular_brdf_NL = cNdotL * D * F * G; 609: 610: specular_light += specular_brdf_NL * light_color * attenuation * specular_amount; 611: #endif 612: 613: #if defined(LIGHT_CLEARCOAT_USED) 614: // Clearcoat ignores normal_map, use vertex normal instead 615: float ccNdotL = max(min(A + dot(vertex_normal, L), 1.0), 0.0); 616: float ccNdotH = clamp(A + dot(vertex_normal, H), 0.0, 1.0); 617: float ccNdotV = max(dot(vertex_normal, V), 1e-4); 618: 619: #if !defined(SPECULAR_SCHLICK_GGX) 620: float cLdotH5 = SchlickFresnel(cLdotH); 621: #endif 622: float Dr = D_GGX(ccNdotH, mix(0.001, 0.1, clearcoat_roughness)); 623: float Gr = 0.25 / (cLdotH * cLdotH); 624: float Fr = mix(.04, 1.0, cLdotH5); 625: float clearcoat_specular_brdf_NL = clearcoat * Gr * Fr * Dr * cNdotL; 626: 627: specular_light += clearcoat_specular_brdf_NL * light_color * attenuation * specular_amount; 628: // TODO: Clearcoat adds light to the scene right now (it is non-energy conserving), both diffuse and specular need to be scaled by (1.0 - FR) 629: // but to do so we need to rearrange this entire function 630: #endif // LIGHT_CLEARCOAT_USED 631: } 632: 633: #ifdef USE_SHADOW_TO_OPACITY 634: alpha = min(alpha, clamp(1.0 - attenuation, 0.0, 1.0)); 635: #endif 636: 637: #endif // LIGHT_CODE_USED 638: } 639: 640: float get_omni_spot_attenuation(float distance, float inv_range, float decay) { 641: float nd = distance * inv_range; 642: nd *= nd; 643: nd *= nd; // nd^4 644: nd = max(1.0 - nd, 0.0); 645: nd *= nd; // nd^2 646: return nd * pow(max(distance, 0.0001), -decay); 647: } 648: 649: #ifndef DISABLE_LIGHT_OMNI 650: void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f0, float roughness, float metallic, float shadow, vec3 albedo, inout float alpha, 651: #ifdef LIGHT_BACKLIGHT_USED 652: vec3 backlight, 653: #endif 654: #ifdef LIGHT_RIM_USED 655: float rim, float rim_tint, 656: #endif 657: #ifdef LIGHT_CLEARCOAT_USED 658: float clearcoat, float clearcoat_roughness, vec3 vertex_normal, 659: #endif 660: #ifdef LIGHT_ANISOTROPY_USED 661: vec3 binormal, vec3 tangent, float anisotropy, 662: #endif 663: inout vec3 diffuse_light, inout vec3 specular_light) { 664: vec3 light_rel_vec = omni_lights[idx].position - vertex; 665: float light_length = length(light_rel_vec); 666: float omni_attenuation = get_omni_spot_attenuation(light_length, omni_lights[idx].inv_radius, omni_lights[idx].attenuation); 667: vec3 color = omni_lights[idx].color; 668: float size_A = 0.0; 669: 670: if (omni_lights[idx].size > 0.0) { 671: float t = omni_lights[idx].size / max(0.001, light_length); 672: size_A = max(0.0, 1.0 - 1.0 / sqrt(1.0 + t * t)); 673: } 674: 675: light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color, omni_attenuation, f0, roughness, metallic, omni_lights[idx].specular_amount, albedo, alpha, 676: #ifdef LIGHT_BACKLIGHT_USED 677: backlight, 678: #endif 679: #ifdef LIGHT_RIM_USED 680: rim * omni_attenuation, rim_tint, 681: #endif 682: #ifdef LIGHT_CLEARCOAT_USED 683: clearcoat, clearcoat_roughness, vertex_normal, 684: #endif 685: #ifdef LIGHT_ANISOTROPY_USED 686: binormal, tangent, anisotropy, 687: #endif 688: diffuse_light, 689: specular_light); 690: } 691: #endif // !DISABLE_LIGHT_OMNI 692: 693: #ifndef DISABLE_LIGHT_SPOT 694: void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f0, float roughness, float metallic, float shadow, vec3 albedo, inout float alpha, 695: #ifdef LIGHT_BACKLIGHT_USED 696: vec3 backlight, 697: #endif 698: #ifdef LIGHT_RIM_USED 699: float rim, float rim_tint, 700: #endif 701: #ifdef LIGHT_CLEARCOAT_USED 702: float clearcoat, float clearcoat_roughness, vec3 vertex_normal, 703: #endif 704: #ifdef LIGHT_ANISOTROPY_USED 705: vec3 binormal, vec3 tangent, float anisotropy, 706: #endif 707: inout vec3 diffuse_light, 708: inout vec3 specular_light) { 709: 710: vec3 light_rel_vec = spot_lights[idx].position - vertex; 711: float light_length = length(light_rel_vec); 712: float spot_attenuation = get_omni_spot_attenuation(light_length, spot_lights[idx].inv_radius, spot_lights[idx].attenuation); 713: vec3 spot_dir = spot_lights[idx].direction; 714: float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_lights[idx].cone_angle); 715: float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_lights[idx].cone_angle)); 716: spot_attenuation *= 1.0 - pow(spot_rim, spot_lights[idx].cone_attenuation); 717: vec3 color = spot_lights[idx].color; 718: 719: float size_A = 0.0; 720: 721: if (spot_lights[idx].size > 0.0) { 722: float t = spot_lights[idx].size / max(0.001, light_length); 723: size_A = max(0.0, 1.0 - 1.0 / sqrt(1.0 + t * t)); 724: } 725: 726: light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color, spot_attenuation, f0, roughness, metallic, spot_lights[idx].specular_amount, albedo, alpha, 727: #ifdef LIGHT_BACKLIGHT_USED 728: backlight, 729: #endif 730: #ifdef LIGHT_RIM_USED 731: rim * spot_attenuation, rim_tint, 732: #endif 733: #ifdef LIGHT_CLEARCOAT_USED 734: clearcoat, clearcoat_roughness, vertex_normal, 735: #endif 736: #ifdef LIGHT_ANISOTROPY_USED 737: binormal, tangent, anisotropy, 738: #endif 739: diffuse_light, specular_light); 740: } 741: #endif // !DISABLE_LIGHT_SPOT 742: 743: #endif // !defined(DISABLE_LIGHT_DIRECTIONAL) || !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) 744: 745: #ifndef MODE_RENDER_DEPTH 746: vec4 fog_process(vec3 vertex) { 747: vec3 fog_color = scene_data.fog_light_color; 748: 749: #ifdef USE_RADIANCE_MAP 750: /* 751: if (scene_data.fog_aerial_perspective > 0.0) { 752: vec3 sky_fog_color = vec3(0.0); 753: vec3 cube_view = scene_data.radiance_inverse_xform * vertex; 754: // mip_level always reads from the second mipmap and higher so the fog is always slightly blurred 755: float mip_level = mix(1.0 / MAX_ROUGHNESS_LOD, 1.0, 1.0 - (abs(vertex.z) - scene_data.z_near) / (scene_data.z_far - scene_data.z_near)); 756: 757: sky_fog_color = textureLod(radiance_map, cube_view, mip_level * RADIANCE_MAX_LOD).rgb; 758: 759: fog_color = mix(fog_color, sky_fog_color, scene_data.fog_aerial_perspective); 760: } 761: */ 762: #endif 763: 764: #ifndef DISABLE_LIGHT_DIRECTIONAL 765: if (scene_data.fog_sun_scatter > 0.001) { 766: vec4 sun_scatter = vec4(0.0); 767: float sun_total = 0.0; 768: vec3 view = normalize(vertex); 769: for (uint i = uint(0); i < scene_data.directional_light_count; i++) { 770: vec3 light_color = directional_lights[i].color * directional_lights[i].energy; 771: float light_amount = pow(max(dot(view, directional_lights[i].direction), 0.0), 8.0); 772: fog_color += light_color * light_amount * scene_data.fog_sun_scatter; 773: } 774: } 775: #endif // !DISABLE_LIGHT_DIRECTIONAL 776: 777: float fog_amount = 1.0 - exp(min(0.0, -length(vertex) * scene_data.fog_density)); 778: 779: if (abs(scene_data.fog_height_density) >= 0.0001) { 780: float y = (scene_data.inv_view_matrix * vec4(vertex, 1.0)).y; 781: 782: float y_dist = y - scene_data.fog_height; 783: 784: float vfog_amount = 1.0 - exp(min(0.0, y_dist * scene_data.fog_height_density)); 785: 786: fog_amount = max(vfog_amount, fog_amount); 787: } 788: 789: return vec4(fog_color, fog_amount); 790: } 791: 792: #endif // !MODE_RENDER_DEPTH 793: 794: void main() { 795: //lay out everything, whatever is unused is optimized away anyway 796: vec3 vertex = vertex_interp; 797: #ifdef USE_MULTIVIEW 798: vec3 eye_offset = multiview_data.eye_offset[ViewIndex].xyz; 799: vec3 view = -normalize(vertex_interp - eye_offset); 800: mat4 projection_matrix = multiview_data.projection_matrix_view[ViewIndex]; 801: mat4 inv_projection_matrix = multiview_data.inv_projection_matrix_view[ViewIndex]; 802: #else 803: vec3 eye_offset = vec3(0.0, 0.0, 0.0); 804: vec3 view = -normalize(vertex_interp); 805: mat4 projection_matrix = scene_data.projection_matrix; 806: mat4 inv_projection_matrix = scene_data.inv_projection_matrix; 807: #endif 808: highp mat4 model_matrix = world_transform; 809: vec3 albedo = vec3(1.0); 810: vec3 backlight = vec3(0.0); 811: vec4 transmittance_color = vec4(0.0, 0.0, 0.0, 1.0); 812: float transmittance_depth = 0.0; 813: float transmittance_boost = 0.0; 814: float metallic = 0.0; 815: float specular = 0.5; 816: vec3 emission = vec3(0.0); 817: float roughness = 1.0; 818: float rim = 0.0; 819: float rim_tint = 0.0; 820: float clearcoat = 0.0; 821: float clearcoat_roughness = 0.0; 822: float anisotropy = 0.0; 823: vec2 anisotropy_flow = vec2(1.0, 0.0); 824: vec4 fog = vec4(0.0); 825: #if defined(CUSTOM_RADIANCE_USED) 826: vec4 custom_radiance = vec4(0.0); 827: #endif 828: #if defined(CUSTOM_IRRADIANCE_USED) 829: vec4 custom_irradiance = vec4(0.0); 830: #endif 831: 832: float ao = 1.0; 833: float ao_light_affect = 0.0; 834: 835: float alpha = 1.0; 836: 837: #if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) 838: vec3 binormal = normalize(binormal_interp); 839: vec3 tangent = normalize(tangent_interp); 840: #else 841: vec3 binormal = vec3(0.0); 842: vec3 tangent = vec3(0.0); 843: #endif 844: 845: #ifdef NORMAL_USED 846: vec3 normal = normalize(normal_interp); 847: 848: #if defined(DO_SIDE_CHECK) 849: if (!gl_FrontFacing) { 850: normal = -normal; 851: } 852: #endif 853: 854: #endif //NORMAL_USED 855: 856: #ifdef UV_USED 857: vec2 uv = uv_interp; 858: #endif 859: 860: #if defined(UV2_USED) || defined(USE_LIGHTMAP) 861: vec2 uv2 = uv2_interp; 862: #endif 863: 864: #if defined(COLOR_USED) 865: vec4 color = color_interp; 866: #endif 867: 868: #if defined(NORMAL_MAP_USED) 869: 870: vec3 normal_map = vec3(0.5); 871: #endif 872: 873: float normal_map_depth = 1.0; 874: 875: vec2 screen_uv = gl_FragCoord.xy * scene_data.screen_pixel_size; 876: 877: float sss_strength = 0.0; 878: 879: #ifdef ALPHA_SCISSOR_USED 880: float alpha_scissor_threshold = 1.0; 881: #endif // ALPHA_SCISSOR_USED 882: 883: #ifdef ALPHA_HASH_USED 884: float alpha_hash_scale = 1.0; 885: #endif // ALPHA_HASH_USED 886: 887: #ifdef ALPHA_ANTIALIASING_EDGE_USED 888: float alpha_antialiasing_edge = 0.0; 889: vec2 alpha_texture_coordinate = vec2(0.0, 0.0); 890: #endif // ALPHA_ANTIALIASING_EDGE_USED 891: { 892: } 893: 894: #ifndef USE_SHADOW_TO_OPACITY 895: 896: #if defined(ALPHA_SCISSOR_USED) 897: if (alpha < alpha_scissor_threshold) { 898: discard; 899: } 900: #endif // ALPHA_SCISSOR_USED 901: 902: #ifdef USE_OPAQUE_PREPASS 903: #if !defined(ALPHA_SCISSOR_USED) 904: 905: if (alpha < opaque_prepass_threshold) { 906: discard; 907: } 908: 909: #endif // not ALPHA_SCISSOR_USED 910: #endif // USE_OPAQUE_PREPASS 911: 912: #endif // !USE_SHADOW_TO_OPACITY 913: 914: #ifdef NORMAL_MAP_USED 915: 916: normal_map.xy = normal_map.xy * 2.0 - 1.0; 917: normal_map.z = sqrt(max(0.0, 1.0 - dot(normal_map.xy, normal_map.xy))); //always ignore Z, as it can be RG packed, Z may be pos/neg, etc. 918: 919: normal = normalize(mix(normal, tangent * normal_map.x + binormal * normal_map.y + normal * normal_map.z, normal_map_depth)); 920: 921: #endif 922: 923: #ifdef LIGHT_ANISOTROPY_USED 924: 925: if (anisotropy > 0.01) { 926: //rotation matrix 927: mat3 rot = mat3(tangent, binormal, normal); 928: //make local to space 929: tangent = normalize(rot * vec3(anisotropy_flow.x, anisotropy_flow.y, 0.0)); 930: binormal = normalize(rot * vec3(-anisotropy_flow.y, anisotropy_flow.x, 0.0)); 931: } 932: 933: #endif 934: 935: #ifndef MODE_RENDER_DEPTH 936: 937: #ifndef CUSTOM_FOG_USED 938: #ifndef DISABLE_FOG 939: // fog must be processed as early as possible and then packed. 940: // to maximize VGPR usage 941: 942: if (scene_data.fog_enabled) { 943: fog = fog_process(vertex); 944: } 945: #endif // !DISABLE_FOG 946: #endif // !CUSTOM_FOG_USED 947: 948: uint fog_rg = packHalf2x16(fog.rg); 949: uint fog_ba = packHalf2x16(fog.ba); 950: 951: // Convert colors to linear 952: albedo = srgb_to_linear(albedo); 953: emission = srgb_to_linear(emission); 954: // TODO Backlight and transmittance when used 955: #ifndef MODE_UNSHADED 956: vec3 f0 = F0(metallic, specular, albedo); 957: vec3 specular_light = vec3(0.0, 0.0, 0.0); 958: vec3 diffuse_light = vec3(0.0, 0.0, 0.0); 959: vec3 ambient_light = vec3(0.0, 0.0, 0.0); 960: 961: #ifdef BASE_PASS 962: /////////////////////// LIGHTING ////////////////////////////// 963: 964: // IBL precalculations 965: float ndotv = clamp(dot(normal, view), 0.0, 1.0); 966: vec3 F = f0 + (max(vec3(1.0 - roughness), f0) - f0) * pow(1.0 - ndotv, 5.0); 967: 968: #ifdef USE_RADIANCE_MAP 969: if (scene_data.use_reflection_cubemap) { 970: #ifdef LIGHT_ANISOTROPY_USED 971: // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy 972: vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent; 973: vec3 anisotropic_tangent = cross(anisotropic_direction, view); 974: vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction); 975: vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0))); 976: vec3 ref_vec = reflect(-view, bent_normal); 977: #else 978: vec3 ref_vec = reflect(-view, normal); 979: #endif 980: ref_vec = mix(ref_vec, normal, roughness * roughness); 981: float horizon = min(1.0 + dot(ref_vec, normal), 1.0); 982: ref_vec = scene_data.radiance_inverse_xform * ref_vec; 983: specular_light = textureLod(radiance_map, ref_vec, sqrt(roughness) * RADIANCE_MAX_LOD).rgb; 984: specular_light = srgb_to_linear(specular_light); 985: specular_light *= horizon * horizon; 986: specular_light *= scene_data.ambient_light_color_energy.a; 987: } 988: #endif 989: 990: // Calculate Reflection probes 991: // Calculate Lightmaps 992: 993: #if defined(CUSTOM_RADIANCE_USED) 994: specular_light = mix(specular_light, custom_radiance.rgb, custom_radiance.a); 995: #endif // CUSTOM_RADIANCE_USED 996: 997: #ifndef USE_LIGHTMAP 998: //lightmap overrides everything 999: if (scene_data.use_ambient_light) { 1000: ambient_light = scene_data.ambient_light_color_energy.rgb; 1001: #ifdef USE_RADIANCE_MAP 1002: if (scene_data.use_ambient_cubemap) { 1003: vec3 ambient_dir = scene_data.radiance_inverse_xform * normal; 1004: vec3 cubemap_ambient = textureLod(radiance_map, ambient_dir, RADIANCE_MAX_LOD).rgb; 1005: cubemap_ambient = srgb_to_linear(cubemap_ambient); 1006: ambient_light = mix(ambient_light, cubemap_ambient * scene_data.ambient_light_color_energy.a, scene_data.ambient_color_sky_mix); 1007: } 1008: #endif 1009: } 1010: #endif // USE_LIGHTMAP 1011: 1012: #if defined(CUSTOM_IRRADIANCE_USED) 1013: ambient_light = mix(ambient_light, custom_irradiance.rgb, custom_irradiance.a); 1014: #endif // CUSTOM_IRRADIANCE_USED 1015: 1016: { 1017: #if defined(AMBIENT_LIGHT_DISABLED) 1018: ambient_light = vec3(0.0, 0.0, 0.0); 1019: #else 1020: ambient_light *= albedo.rgb; 1021: ambient_light *= ao; 1022: #endif // AMBIENT_LIGHT_DISABLED 1023: } 1024: 1025: // convert ao to direct light ao 1026: ao = mix(1.0, ao, ao_light_affect); 1027: 1028: { 1029: #if defined(DIFFUSE_TOON) 1030: //simplify for toon, as 1031: specular_light *= specular * metallic * albedo * 2.0; 1032: #else 1033: 1034: // scales the specular reflections, needs to be be computed before lighting happens, 1035: // but after environment, GI, and reflection probes are added 1036: // Environment brdf approximation (Lazarov 2013) 1037: // see https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile 1038: const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022); 1039: const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04); 1040: vec4 r = roughness * c0 + c1; 1041: float ndotv = clamp(dot(normal, view), 0.0, 1.0); 1042: 1043: float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y; 1044: vec2 env = vec2(-1.04, 1.04) * a004 + r.zw; 1045: specular_light *= env.x * f0 + env.y * clamp(50.0 * f0.g, metallic, 1.0); 1046: #endif 1047: } 1048: 1049: #endif // BASE_PASS 1050: 1051: #ifndef DISABLE_LIGHT_DIRECTIONAL 1052: //diffuse_light = normal; // 1053: for (uint i = uint(0); i < scene_data.directional_light_count; i++) { 1054: light_compute(normal, normalize(directional_lights[i].direction), normalize(view), directional_lights[i].size, directional_lights[i].color * directional_lights[i].energy, 1.0, f0, roughness, metallic, 1.0, albedo, alpha, 1055: #ifdef LIGHT_BACKLIGHT_USED 1056: backlight, 1057: #endif 1058: #ifdef LIGHT_RIM_USED 1059: rim, rim_tint, 1060: #endif 1061: #ifdef LIGHT_CLEARCOAT_USED 1062: clearcoat, clearcoat_roughness, normalize(normal_interp), 1063: #endif 1064: #ifdef LIGHT_ANISOTROPY_USED 1065: binormal, 1066: tangent, anisotropy, 1067: #endif 1068: diffuse_light, 1069: specular_light); 1070: } 1071: #endif // !DISABLE_LIGHT_DIRECTIONAL 1072: 1073: #ifndef DISABLE_LIGHT_OMNI 1074: for (uint i = 0u; i < MAX_FORWARD_LIGHTS; i++) { 1075: if (i >= omni_light_count) { 1076: break; 1077: } 1078: light_process_omni(omni_light_indices[i], vertex, view, normal, f0, roughness, metallic, 0.0, albedo, alpha, 1079: #ifdef LIGHT_BACKLIGHT_USED 1080: backlight, 1081: #endif 1082: #ifdef LIGHT_RIM_USED 1083: rim, 1084: rim_tint, 1085: #endif 1086: #ifdef LIGHT_CLEARCOAT_USED 1087: clearcoat, clearcoat_roughness, normalize(normal_interp), 1088: #endif 1089: #ifdef LIGHT_ANISOTROPY_USED 1090: binormal, tangent, anisotropy, 1091: #endif 1092: diffuse_light, specular_light); 1093: } 1094: #endif // !DISABLE_LIGHT_OMNI 1095: 1096: #ifndef DISABLE_LIGHT_SPOT 1097: for (uint i = 0u; i < MAX_FORWARD_LIGHTS; i++) { 1098: if (i >= spot_light_count) { 1099: break; 1100: } 1101: light_process_spot(spot_light_indices[i], vertex, view, normal, f0, roughness, metallic, 0.0, albedo, alpha, 1102: #ifdef LIGHT_BACKLIGHT_USED 1103: backlight, 1104: #endif 1105: #ifdef LIGHT_RIM_USED 1106: rim, 1107: rim_tint, 1108: #endif 1109: #ifdef LIGHT_CLEARCOAT_USED 1110: clearcoat, clearcoat_roughness, normalize(normal_interp), 1111: #endif 1112: #ifdef LIGHT_ANISOTROPY_USED 1113: tangent, 1114: binormal, anisotropy, 1115: #endif 1116: diffuse_light, specular_light); 1117: } 1118: #endif // !DISABLE_LIGHT_SPOT 1119: 1120: #endif // !MODE_UNSHADED 1121: 1122: #endif // !MODE_RENDER_DEPTH 1123: 1124: #if defined(USE_SHADOW_TO_OPACITY) 1125: alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0)); 1126: 1127: #if defined(ALPHA_SCISSOR_USED) 1128: if (alpha < alpha_scissor) { 1129: discard; 1130: } 1131: #endif // ALPHA_SCISSOR_USED 1132: 1133: #ifdef USE_OPAQUE_PREPASS 1134: #if !defined(ALPHA_SCISSOR_USED) 1135: 1136: if (alpha < opaque_prepass_threshold) { 1137: discard; 1138: } 1139: 1140: #endif // not ALPHA_SCISSOR_USED 1141: #endif // USE_OPAQUE_PREPASS 1142: 1143: #endif // USE_SHADOW_TO_OPACITY 1144: 1145: #ifdef MODE_RENDER_DEPTH 1146: //nothing happens, so a tree-ssa optimizer will result in no fragment shader :) 1147: #else // !MODE_RENDER_DEPTH 1148: 1149: #ifdef MODE_UNSHADED 1150: frag_color = vec4(albedo, alpha); 1151: #else 1152: 1153: diffuse_light *= albedo; 1154: 1155: diffuse_light *= 1.0 - metallic; 1156: ambient_light *= 1.0 - metallic; 1157: 1158: frag_color = vec4(diffuse_light + specular_light, alpha); 1159: #ifdef BASE_PASS 1160: frag_color.rgb += emission + ambient_light; 1161: #endif 1162: #endif //MODE_UNSHADED 1163: fog = vec4(unpackHalf2x16(fog_rg), unpackHalf2x16(fog_ba)); 1164: 1165: #ifndef DISABLE_FOG 1166: if (scene_data.fog_enabled) { 1167: #ifdef BASE_PASS 1168: frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a); 1169: #else 1170: frag_color.rgb *= (1.0 - fog.a); 1171: #endif // BASE_PASS 1172: } 1173: #endif 1174: 1175: // Tonemap before writing as we are writing to an sRGB framebuffer 1176: frag_color.rgb *= exposure; 1177: frag_color.rgb = apply_tonemapping(frag_color.rgb, white); 1178: frag_color.rgb = linear_to_srgb(frag_color.rgb); 1179: 1180: #ifdef USE_BCS 1181: frag_color.rgb = apply_bcs(frag_color.rgb, bcs); 1182: #endif 1183: 1184: #ifdef USE_COLOR_CORRECTION 1185: frag_color.rgb = apply_color_correction(frag_color.rgb, color_correction); 1186: #endif 1187: 1188: #endif //!MODE_RENDER_DEPTH 1189: } 1190: 1191: 1: #version 330 2: #define USE_GLES_OVER_GL 3: #define USE_RADIANCE_MAP 4: 5: #define MAX_GLOBAL_SHADER_UNIFORMS 256 6: 7: #define MAX_LIGHT_DATA_STRUCTS 32 8: 9: #define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS 8 10: 11: #define MAX_FORWARD_LIGHTS uint(8) 12: #define USE_ADDITIVE_LIGHTING 13: #define USE_INSTANCING 14: 15: #ifdef USE_MULTIVIEW 16: #if defined(GL_OVR_multiview2) 17: #extension GL_OVR_multiview2 : require 18: #elif defined(GL_OVR_multiview) 19: #extension GL_OVR_multiview : require 20: #endif 21: #define ViewIndex gl_ViewID_OVR 22: #define MAX_VIEWS 2 23: #else 24: #define ViewIndex uint(0) 25: #define MAX_VIEWS 1 26: #endif 27: precision highp float; 28: precision highp int; 29: 30: // Default to SPECULAR_SCHLICK_GGX. 31: #if !defined(SPECULAR_DISABLED) && !defined(SPECULAR_SCHLICK_GGX) && !defined(SPECULAR_TOON) 32: #define SPECULAR_SCHLICK_GGX 33: #endif 34: 35: #if !defined(MODE_RENDER_DEPTH) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) ||defined(LIGHT_CLEARCOAT_USED) 36: #ifndef NORMAL_USED 37: #define NORMAL_USED 38: #endif 39: #endif 40: 41: #ifndef MODE_RENDER_DEPTH 42: #ifdef USE_BCS 43: uniform vec3 bcs; 44: #endif 45: 46: #ifdef USE_COLOR_CORRECTION 47: #ifdef USE_1D_LUT 48: uniform sampler2D source_color_correction; //texunit:-1 49: #else 50: uniform sampler3D source_color_correction; //texunit:-1 51: #endif 52: #endif 53: 54: layout(std140) uniform TonemapData { //ubo:0 55: float exposure; 56: float white; 57: int tonemapper; 58: int pad; 59: }; 60: 61: vec3 apply_bcs(vec3 color, vec3 bcs) { 62: color = mix(vec3(0.0), color, bcs.x); 63: color = mix(vec3(0.5), color, bcs.y); 64: color = mix(vec3(dot(vec3(1.0), color) * 0.33333), color, bcs.z); 65: 66: return color; 67: } 68: #ifdef USE_COLOR_CORRECTION 69: #ifdef USE_1D_LUT 70: vec3 apply_color_correction(vec3 color) { 71: color.r = texture(source_color_correction, vec2(color.r, 0.0f)).r; 72: color.g = texture(source_color_correction, vec2(color.g, 0.0f)).g; 73: color.b = texture(source_color_correction, vec2(color.b, 0.0f)).b; 74: return color; 75: } 76: #else 77: vec3 apply_color_correction(vec3 color) { 78: return textureLod(source_color_correction, color, 0.0).rgb; 79: } 80: #endif 81: #endif 82: 83: vec3 tonemap_filmic(vec3 color, float p_white) { 84: // exposure bias: input scale (color *= bias, white *= bias) to make the brightness consistent with other tonemappers 85: // also useful to scale the input to the range that the tonemapper is designed for (some require very high input values) 86: // has no effect on the curve's general shape or visual properties 87: const float exposure_bias = 2.0f; 88: const float A = 0.22f * exposure_bias * exposure_bias; // bias baked into constants for performance 89: const float B = 0.30f * exposure_bias; 90: const float C = 0.10f; 91: const float D = 0.20f; 92: const float E = 0.01f; 93: const float F = 0.30f; 94: 95: vec3 color_tonemapped = ((color * (A * color + C * B) + D * E) / (color * (A * color + B) + D * F)) - E / F; 96: float p_white_tonemapped = ((p_white * (A * p_white + C * B) + D * E) / (p_white * (A * p_white + B) + D * F)) - E / F; 97: 98: return color_tonemapped / p_white_tonemapped; 99: } 100: 101: // Adapted from https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl 102: // (MIT License). 103: vec3 tonemap_aces(vec3 color, float p_white) { 104: const float exposure_bias = 1.8f; 105: const float A = 0.0245786f; 106: const float B = 0.000090537f; 107: const float C = 0.983729f; 108: const float D = 0.432951f; 109: const float E = 0.238081f; 110: 111: // Exposure bias baked into transform to save shader instructions. Equivalent to `color *= exposure_bias` 112: const mat3 rgb_to_rrt = mat3( 113: vec3(0.59719f * exposure_bias, 0.35458f * exposure_bias, 0.04823f * exposure_bias), 114: vec3(0.07600f * exposure_bias, 0.90834f * exposure_bias, 0.01566f * exposure_bias), 115: vec3(0.02840f * exposure_bias, 0.13383f * exposure_bias, 0.83777f * exposure_bias)); 116: 117: const mat3 odt_to_rgb = mat3( 118: vec3(1.60475f, -0.53108f, -0.07367f), 119: vec3(-0.10208f, 1.10813f, -0.00605f), 120: vec3(-0.00327f, -0.07276f, 1.07602f)); 121: 122: color *= rgb_to_rrt; 123: vec3 color_tonemapped = (color * (color + A) - B) / (color * (C * color + D) + E); 124: color_tonemapped *= odt_to_rgb; 125: 126: p_white *= exposure_bias; 127: float p_white_tonemapped = (p_white * (p_white + A) - B) / (p_white * (C * p_white + D) + E); 128: 129: return color_tonemapped / p_white_tonemapped; 130: } 131: 132: vec3 tonemap_reinhard(vec3 color, float p_white) { 133: return (p_white * color + color) / (color * p_white + p_white); 134: } 135: 136: // This expects 0-1 range input. 137: vec3 linear_to_srgb(vec3 color) { 138: //color = clamp(color, vec3(0.0), vec3(1.0)); 139: //const vec3 a = vec3(0.055f); 140: //return mix((vec3(1.0f) + a) * pow(color.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * color.rgb, lessThan(color.rgb, vec3(0.0031308f))); 141: // Approximation from http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html 142: return max(vec3(1.055) * pow(color, vec3(0.416666667)) - vec3(0.055), vec3(0.0)); 143: } 144: 145: // This expects 0-1 range input, outside that range it behaves poorly. 146: vec3 srgb_to_linear(vec3 color) { 147: // Approximation from http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html 148: return color * (color * (color * 0.305306011 + 0.682171111) + 0.012522878); 149: } 150: 151: #define TONEMAPPER_LINEAR 0 152: #define TONEMAPPER_REINHARD 1 153: #define TONEMAPPER_FILMIC 2 154: #define TONEMAPPER_ACES 3 155: 156: vec3 apply_tonemapping(vec3 color, float p_white) { // inputs are LINEAR, always outputs clamped [0;1] color 157: // Ensure color values passed to tonemappers are positive. 158: // They can be negative in the case of negative lights, which leads to undesired behavior. 159: if (tonemapper == TONEMAPPER_LINEAR) { 160: return color; 161: } else if (tonemapper == TONEMAPPER_REINHARD) { 162: return tonemap_reinhard(max(vec3(0.0f), color), p_white); 163: } else if (tonemapper == TONEMAPPER_FILMIC) { 164: return tonemap_filmic(max(vec3(0.0f), color), p_white); 165: } else { // TONEMAPPER_ACES 166: return tonemap_aces(max(vec3(0.0f), color), p_white); 167: } 168: } 169: #endif 170: 171: #ifdef USE_GLES_OVER_GL 172: // Floating point pack/unpack functions are part of the GLSL ES 300 specification used by web and mobile. 173: uint float2half(uint f) { 174: uint e = f & uint(0x7f800000); 175: if (e <= uint(0x38000000)) { 176: return uint(0); 177: } else { 178: return ((f >> uint(16)) & uint(0x8000)) | 179: (((e - uint(0x38000000)) >> uint(13)) & uint(0x7c00)) | 180: ((f >> uint(13)) & uint(0x03ff)); 181: } 182: } 183: 184: uint half2float(uint h) { 185: uint h_e = h & uint(0x7c00); 186: return ((h & uint(0x8000)) << uint(16)) | uint((h_e >> uint(10)) != uint(0)) * (((h_e + uint(0x1c000)) << uint(13)) | ((h & uint(0x03ff)) << uint(13))); 187: } 188: 189: uint packHalf2x16(vec2 v) { 190: return float2half(floatBitsToUint(v.x)) | float2half(floatBitsToUint(v.y)) << uint(16); 191: } 192: 193: vec2 unpackHalf2x16(uint v) { 194: return vec2(uintBitsToFloat(half2float(v & uint(0xffff))), 195: uintBitsToFloat(half2float(v >> uint(16)))); 196: } 197: 198: uint packUnorm2x16(vec2 v) { 199: uvec2 uv = uvec2(round(clamp(v, vec2(0.0), vec2(1.0)) * 65535.0)); 200: return uv.x | uv.y << uint(16); 201: } 202: 203: vec2 unpackUnorm2x16(uint p) { 204: return vec2(float(p & uint(0xffff)), float(p >> uint(16))) * 0.000015259021; // 1.0 / 65535.0 optimization 205: } 206: 207: uint packSnorm2x16(vec2 v) { 208: uvec2 uv = uvec2(round(clamp(v, vec2(-1.0), vec2(1.0)) * 32767.0) + 32767.0); 209: return uv.x | uv.y << uint(16); 210: } 211: 212: vec2 unpackSnorm2x16(uint p) { 213: vec2 v = vec2(float(p & uint(0xffff)), float(p >> uint(16))); 214: return clamp((v - 32767.0) * vec2(0.00003051851), vec2(-1.0), vec2(1.0)); 215: } 216: 217: #endif 218: 219: // Compatibility renames. These are exposed with the "godot_" prefix 220: // to work around an Adreno bug which was exposing these ES310 functions 221: // in ES300 shaders. Internally, we must use the "godot_" prefix, but user shaders 222: // will be mapped automatically. 223: uint godot_packUnorm4x8(vec4 v) { 224: uvec4 uv = uvec4(round(clamp(v, vec4(0.0), vec4(1.0)) * 255.0)); 225: return uv.x | (uv.y << uint(8)) | (uv.z << uint(16)) | (uv.w << uint(24)); 226: } 227: 228: vec4 godot_unpackUnorm4x8(uint p) { 229: return vec4(float(p & uint(0xff)), float((p >> uint(8)) & uint(0xff)), float((p >> uint(16)) & uint(0xff)), float(p >> uint(24))) * 0.00392156862; // 1.0 / 255.0 230: } 231: 232: uint godot_packSnorm4x8(vec4 v) { 233: uvec4 uv = uvec4(round(clamp(v, vec4(-1.0), vec4(1.0)) * 127.0) + 127.0); 234: return uv.x | uv.y << uint(8) | uv.z << uint(16) | uv.w << uint(24); 235: } 236: 237: vec4 godot_unpackSnorm4x8(uint p) { 238: vec4 v = vec4(float(p & uint(0xff)), float((p >> uint(8)) & uint(0xff)), float((p >> uint(16)) & uint(0xff)), float(p >> uint(24))); 239: return clamp((v - vec4(127.0)) * vec4(0.00787401574), vec4(-1.0), vec4(1.0)); 240: } 241: 242: #define packUnorm4x8 godot_packUnorm4x8 243: #define unpackUnorm4x8 godot_unpackUnorm4x8 244: #define packSnorm4x8 godot_packSnorm4x8 245: #define unpackSnorm4x8 godot_unpackSnorm4x8 246: 247: /* texture unit usage, N is max_texture_unity-N 248: 249: 1-color correction // In tonemap_inc.glsl 250: 2-radiance 251: 3-directional_shadow 252: 4-positional_shadow 253: 5-screen 254: 6-depth 255: 256: */ 257: 258: #define M_PI 3.14159265359 259: /* clang-format on */ 260: 261: #define SHADER_IS_SRGB true 262: 263: /* Varyings */ 264: 265: #if defined(COLOR_USED) 266: in vec4 color_interp; 267: #endif 268: 269: #if defined(UV_USED) 270: in vec2 uv_interp; 271: #endif 272: 273: #if defined(UV2_USED) 274: in vec2 uv2_interp; 275: #else 276: #ifdef USE_LIGHTMAP 277: in vec2 uv2_interp; 278: #endif 279: #endif 280: 281: #if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) 282: in vec3 tangent_interp; 283: in vec3 binormal_interp; 284: #endif 285: 286: #ifdef NORMAL_USED 287: in vec3 normal_interp; 288: #endif 289: 290: in highp vec3 vertex_interp; 291: 292: #ifdef USE_RADIANCE_MAP 293: 294: #define RADIANCE_MAX_LOD 5.0 295: 296: uniform samplerCube radiance_map; // texunit:-2 297: 298: #endif 299: 300: layout(std140) uniform GlobalShaderUniformData { //ubo:1 301: vec4 global_shader_uniforms[MAX_GLOBAL_SHADER_UNIFORMS]; 302: }; 303: 304: /* Material Uniforms */ 305: 306: #ifdef MATERIAL_UNIFORMS_USED 307: 308: /* clang-format off */ 309: layout(std140) uniform MaterialUniforms { // ubo:3 310: 311: 312: }; 313: /* clang-format on */ 314: 315: #endif 316: 317: layout(std140) uniform SceneData { // ubo:2 318: highp mat4 projection_matrix; 319: highp mat4 inv_projection_matrix; 320: highp mat4 inv_view_matrix; 321: highp mat4 view_matrix; 322: 323: vec2 viewport_size; 324: vec2 screen_pixel_size; 325: 326: mediump vec4 ambient_light_color_energy; 327: 328: mediump float ambient_color_sky_mix; 329: bool material_uv2_mode; 330: float emissive_exposure_normalization; 331: bool use_ambient_light; 332: bool use_ambient_cubemap; 333: bool use_reflection_cubemap; 334: 335: float fog_aerial_perspective; 336: float time; 337: 338: mat3 radiance_inverse_xform; 339: 340: uint directional_light_count; 341: float z_far; 342: float z_near; 343: float IBL_exposure_normalization; 344: 345: bool fog_enabled; 346: float fog_density; 347: float fog_height; 348: float fog_height_density; 349: 350: vec3 fog_light_color; 351: float fog_sun_scatter; 352: uint camera_visible_layers; 353: uint pad3; 354: uint pad4; 355: uint pad5; 356: } 357: scene_data; 358: 359: #ifdef USE_MULTIVIEW 360: layout(std140) uniform MultiviewData { // ubo:8 361: highp mat4 projection_matrix_view[MAX_VIEWS]; 362: highp mat4 inv_projection_matrix_view[MAX_VIEWS]; 363: highp vec4 eye_offset[MAX_VIEWS]; 364: } 365: multiview_data; 366: #endif 367: 368: /* clang-format off */ 369: 370: 371: /* clang-format on */ 372: 373: // Directional light data. 374: #ifndef DISABLE_LIGHT_DIRECTIONAL 375: 376: struct DirectionalLightData { 377: mediump vec3 direction; 378: mediump float energy; 379: mediump vec3 color; 380: mediump float size; 381: mediump vec3 pad; 382: mediump float specular; 383: }; 384: 385: layout(std140) uniform DirectionalLights { // ubo:7 386: DirectionalLightData directional_lights[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS]; 387: }; 388: 389: #endif // !DISABLE_LIGHT_DIRECTIONAL 390: 391: // Omni and spot light data. 392: #if !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) 393: 394: struct LightData { // This structure needs to be as packed as possible. 395: highp vec3 position; 396: highp float inv_radius; 397: 398: mediump vec3 direction; 399: highp float size; 400: 401: mediump vec3 color; 402: mediump float attenuation; 403: 404: mediump float cone_attenuation; 405: mediump float cone_angle; 406: mediump float specular_amount; 407: mediump float shadow_opacity; 408: }; 409: 410: #ifndef DISABLE_LIGHT_OMNI 411: layout(std140) uniform OmniLightData { // ubo:5 412: LightData omni_lights[MAX_LIGHT_DATA_STRUCTS]; 413: }; 414: uniform uint omni_light_indices[MAX_FORWARD_LIGHTS]; 415: uniform uint omni_light_count; 416: #endif 417: 418: #ifndef DISABLE_LIGHT_SPOT 419: layout(std140) uniform SpotLightData { // ubo:6 420: LightData spot_lights[MAX_LIGHT_DATA_STRUCTS]; 421: }; 422: uniform uint spot_light_indices[MAX_FORWARD_LIGHTS]; 423: uniform uint spot_light_count; 424: #endif 425: 426: #ifdef USE_ADDITIVE_LIGHTING 427: uniform highp samplerCubeShadow positional_shadow; // texunit:-4 428: #endif 429: 430: #endif // !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) 431: 432: #ifdef USE_MULTIVIEW 433: uniform highp sampler2DArray depth_buffer; // texunit:-6 434: uniform highp sampler2DArray color_buffer; // texunit:-5 435: vec3 multiview_uv(vec2 uv) { 436: return vec3(uv, ViewIndex); 437: } 438: #else 439: uniform highp sampler2D depth_buffer; // texunit:-6 440: uniform highp sampler2D color_buffer; // texunit:-5 441: vec2 multiview_uv(vec2 uv) { 442: return uv; 443: } 444: #endif 445: 446: uniform highp mat4 world_transform; 447: uniform mediump float opaque_prepass_threshold; 448: 449: layout(location = 0) out vec4 frag_color; 450: 451: vec3 F0(float metallic, float specular, vec3 albedo) { 452: float dielectric = 0.16 * specular * specular; 453: // use albedo * metallic as colored specular reflectance at 0 angle for metallic materials; 454: // see https://google.github.io/filament/Filament.md.html 455: return mix(vec3(dielectric), albedo, vec3(metallic)); 456: } 457: 458: #if !defined(DISABLE_LIGHT_DIRECTIONAL) || !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) 459: 460: float D_GGX(float cos_theta_m, float alpha) { 461: float a = cos_theta_m * alpha; 462: float k = alpha / (1.0 - cos_theta_m * cos_theta_m + a * a); 463: return k * k * (1.0 / M_PI); 464: } 465: 466: // From Earl Hammon, Jr. "PBR Diffuse Lighting for GGX+Smith Microsurfaces" https://www.gdcvault.com/play/1024478/PBR-Diffuse-Lighting-for-GGX 467: float V_GGX(float NdotL, float NdotV, float alpha) { 468: return 0.5 / mix(2.0 * NdotL * NdotV, NdotL + NdotV, alpha); 469: } 470: 471: float D_GGX_anisotropic(float cos_theta_m, float alpha_x, float alpha_y, float cos_phi, float sin_phi) { 472: float alpha2 = alpha_x * alpha_y; 473: highp vec3 v = vec3(alpha_y * cos_phi, alpha_x * sin_phi, alpha2 * cos_theta_m); 474: highp float v2 = dot(v, v); 475: float w2 = alpha2 / v2; 476: float D = alpha2 * w2 * w2 * (1.0 / M_PI); 477: return D; 478: } 479: 480: float V_GGX_anisotropic(float alpha_x, float alpha_y, float TdotV, float TdotL, float BdotV, float BdotL, float NdotV, float NdotL) { 481: float Lambda_V = NdotL * length(vec3(alpha_x * TdotV, alpha_y * BdotV, NdotV)); 482: float Lambda_L = NdotV * length(vec3(alpha_x * TdotL, alpha_y * BdotL, NdotL)); 483: return 0.5 / (Lambda_V + Lambda_L); 484: } 485: 486: float SchlickFresnel(float u) { 487: float m = 1.0 - u; 488: float m2 = m * m; 489: return m2 * m2 * m; // pow(m,5) 490: } 491: 492: void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float attenuation, vec3 f0, float roughness, float metallic, float specular_amount, vec3 albedo, inout float alpha, 493: #ifdef LIGHT_BACKLIGHT_USED 494: vec3 backlight, 495: #endif 496: #ifdef LIGHT_RIM_USED 497: float rim, float rim_tint, 498: #endif 499: #ifdef LIGHT_CLEARCOAT_USED 500: float clearcoat, float clearcoat_roughness, vec3 vertex_normal, 501: #endif 502: #ifdef LIGHT_ANISOTROPY_USED 503: vec3 B, vec3 T, float anisotropy, 504: #endif 505: inout vec3 diffuse_light, inout vec3 specular_light) { 506: 507: #if defined(USE_LIGHT_SHADER_CODE) 508: // light is written by the light shader 509: 510: vec3 normal = N; 511: vec3 light = L; 512: vec3 view = V; 513: 514: /* clang-format off */ 515: 516: 517: /* clang-format on */ 518: 519: #else 520: float NdotL = min(A + dot(N, L), 1.0); 521: float cNdotL = max(NdotL, 0.0); // clamped NdotL 522: float NdotV = dot(N, V); 523: float cNdotV = max(NdotV, 1e-4); 524: 525: #if defined(DIFFUSE_BURLEY) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED) 526: vec3 H = normalize(V + L); 527: #endif 528: 529: #if defined(SPECULAR_SCHLICK_GGX) 530: float cNdotH = clamp(A + dot(N, H), 0.0, 1.0); 531: #endif 532: 533: #if defined(DIFFUSE_BURLEY) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED) 534: float cLdotH = clamp(A + dot(L, H), 0.0, 1.0); 535: #endif 536: 537: if (metallic < 1.0) { 538: float diffuse_brdf_NL; // BRDF times N.L for calculating diffuse radiance 539: 540: #if defined(DIFFUSE_LAMBERT_WRAP) 541: // Energy conserving lambert wrap shader. 542: // https://web.archive.org/web/20210228210901/http://blog.stevemcauley.com/2011/12/03/energy-conserving-wrapped-diffuse/ 543: diffuse_brdf_NL = max(0.0, (NdotL + roughness) / ((1.0 + roughness) * (1.0 + roughness))) * (1.0 / M_PI); 544: #elif defined(DIFFUSE_TOON) 545: diffuse_brdf_NL = smoothstep(-roughness, max(roughness, 0.01), NdotL) * (1.0 / M_PI); 546: #elif defined(DIFFUSE_BURLEY) 547: { 548: float FD90_minus_1 = 2.0 * cLdotH * cLdotH * roughness - 0.5; 549: float FdV = 1.0 + FD90_minus_1 * SchlickFresnel(cNdotV); 550: float FdL = 1.0 + FD90_minus_1 * SchlickFresnel(cNdotL); 551: diffuse_brdf_NL = (1.0 / M_PI) * FdV * FdL * cNdotL; 552: } 553: #else 554: // Lambert 555: diffuse_brdf_NL = cNdotL * (1.0 / M_PI); 556: #endif 557: 558: diffuse_light += light_color * diffuse_brdf_NL * attenuation; 559: 560: #if defined(LIGHT_BACKLIGHT_USED) 561: diffuse_light += light_color * (vec3(1.0 / M_PI) - diffuse_brdf_NL) * backlight * attenuation; 562: #endif 563: 564: #if defined(LIGHT_RIM_USED) 565: // Epsilon min to prevent pow(0, 0) singularity which results in undefined behavior. 566: float rim_light = pow(max(1e-4, 1.0 - cNdotV), max(0.0, (1.0 - roughness) * 16.0)); 567: diffuse_light += rim_light * rim * mix(vec3(1.0), albedo, rim_tint) * light_color; 568: #endif 569: } 570: 571: if (roughness > 0.0) { // FIXME: roughness == 0 should not disable specular light entirely 572: 573: // D 574: 575: #if defined(SPECULAR_TOON) 576: 577: vec3 R = normalize(-reflect(L, N)); 578: float RdotV = dot(R, V); 579: float mid = 1.0 - roughness; 580: mid *= mid; 581: float intensity = smoothstep(mid - roughness * 0.5, mid + roughness * 0.5, RdotV) * mid; 582: diffuse_light += light_color * intensity * attenuation * specular_amount; // write to diffuse_light, as in toon shading you generally want no reflection 583: 584: #elif defined(SPECULAR_DISABLED) 585: // none.. 586: 587: #elif defined(SPECULAR_SCHLICK_GGX) 588: // shlick+ggx as default 589: float alpha_ggx = roughness * roughness; 590: #if defined(LIGHT_ANISOTROPY_USED) 591: float aspect = sqrt(1.0 - anisotropy * 0.9); 592: float ax = alpha_ggx / aspect; 593: float ay = alpha_ggx * aspect; 594: float XdotH = dot(T, H); 595: float YdotH = dot(B, H); 596: float D = D_GGX_anisotropic(cNdotH, ax, ay, XdotH, YdotH); 597: float G = V_GGX_anisotropic(ax, ay, dot(T, V), dot(T, L), dot(B, V), dot(B, L), cNdotV, cNdotL); 598: #else 599: float D = D_GGX(cNdotH, alpha_ggx); 600: float G = V_GGX(cNdotL, cNdotV, alpha_ggx); 601: #endif // LIGHT_ANISOTROPY_USED 602: // F 603: float cLdotH5 = SchlickFresnel(cLdotH); 604: // Calculate Fresnel using cheap approximate specular occlusion term from Filament: 605: // https://google.github.io/filament/Filament.html#lighting/occlusion/specularocclusion 606: float f90 = clamp(50.0 * f0.g, 0.0, 1.0); 607: vec3 F = f0 + (f90 - f0) * cLdotH5; 608: 609: vec3 specular_brdf_NL = cNdotL * D * F * G; 610: 611: specular_light += specular_brdf_NL * light_color * attenuation * specular_amount; 612: #endif 613: 614: #if defined(LIGHT_CLEARCOAT_USED) 615: // Clearcoat ignores normal_map, use vertex normal instead 616: float ccNdotL = max(min(A + dot(vertex_normal, L), 1.0), 0.0); 617: float ccNdotH = clamp(A + dot(vertex_normal, H), 0.0, 1.0); 618: float ccNdotV = max(dot(vertex_normal, V), 1e-4); 619: 620: #if !defined(SPECULAR_SCHLICK_GGX) 621: float cLdotH5 = SchlickFresnel(cLdotH); 622: #endif 623: float Dr = D_GGX(ccNdotH, mix(0.001, 0.1, clearcoat_roughness)); 624: float Gr = 0.25 / (cLdotH * cLdotH); 625: float Fr = mix(.04, 1.0, cLdotH5); 626: float clearcoat_specular_brdf_NL = clearcoat * Gr * Fr * Dr * cNdotL; 627: 628: specular_light += clearcoat_specular_brdf_NL * light_color * attenuation * specular_amount; 629: // TODO: Clearcoat adds light to the scene right now (it is non-energy conserving), both diffuse and specular need to be scaled by (1.0 - FR) 630: // but to do so we need to rearrange this entire function 631: #endif // LIGHT_CLEARCOAT_USED 632: } 633: 634: #ifdef USE_SHADOW_TO_OPACITY 635: alpha = min(alpha, clamp(1.0 - attenuation, 0.0, 1.0)); 636: #endif 637: 638: #endif // LIGHT_CODE_USED 639: } 640: 641: float get_omni_spot_attenuation(float distance, float inv_range, float decay) { 642: float nd = distance * inv_range; 643: nd *= nd; 644: nd *= nd; // nd^4 645: nd = max(1.0 - nd, 0.0); 646: nd *= nd; // nd^2 647: return nd * pow(max(distance, 0.0001), -decay); 648: } 649: 650: #ifndef DISABLE_LIGHT_OMNI 651: void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f0, float roughness, float metallic, float shadow, vec3 albedo, inout float alpha, 652: #ifdef LIGHT_BACKLIGHT_USED 653: vec3 backlight, 654: #endif 655: #ifdef LIGHT_RIM_USED 656: float rim, float rim_tint, 657: #endif 658: #ifdef LIGHT_CLEARCOAT_USED 659: float clearcoat, float clearcoat_roughness, vec3 vertex_normal, 660: #endif 661: #ifdef LIGHT_ANISOTROPY_USED 662: vec3 binormal, vec3 tangent, float anisotropy, 663: #endif 664: inout vec3 diffuse_light, inout vec3 specular_light) { 665: vec3 light_rel_vec = omni_lights[idx].position - vertex; 666: float light_length = length(light_rel_vec); 667: float omni_attenuation = get_omni_spot_attenuation(light_length, omni_lights[idx].inv_radius, omni_lights[idx].attenuation); 668: vec3 color = omni_lights[idx].color; 669: float size_A = 0.0; 670: 671: if (omni_lights[idx].size > 0.0) { 672: float t = omni_lights[idx].size / max(0.001, light_length); 673: size_A = max(0.0, 1.0 - 1.0 / sqrt(1.0 + t * t)); 674: } 675: 676: light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color, omni_attenuation, f0, roughness, metallic, omni_lights[idx].specular_amount, albedo, alpha, 677: #ifdef LIGHT_BACKLIGHT_USED 678: backlight, 679: #endif 680: #ifdef LIGHT_RIM_USED 681: rim * omni_attenuation, rim_tint, 682: #endif 683: #ifdef LIGHT_CLEARCOAT_USED 684: clearcoat, clearcoat_roughness, vertex_normal, 685: #endif 686: #ifdef LIGHT_ANISOTROPY_USED 687: binormal, tangent, anisotropy, 688: #endif 689: diffuse_light, 690: specular_light); 691: } 692: #endif // !DISABLE_LIGHT_OMNI 693: 694: #ifndef DISABLE_LIGHT_SPOT 695: void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f0, float roughness, float metallic, float shadow, vec3 albedo, inout float alpha, 696: #ifdef LIGHT_BACKLIGHT_USED 697: vec3 backlight, 698: #endif 699: #ifdef LIGHT_RIM_USED 700: float rim, float rim_tint, 701: #endif 702: #ifdef LIGHT_CLEARCOAT_USED 703: float clearcoat, float clearcoat_roughness, vec3 vertex_normal, 704: #endif 705: #ifdef LIGHT_ANISOTROPY_USED 706: vec3 binormal, vec3 tangent, float anisotropy, 707: #endif 708: inout vec3 diffuse_light, 709: inout vec3 specular_light) { 710: 711: vec3 light_rel_vec = spot_lights[idx].position - vertex; 712: float light_length = length(light_rel_vec); 713: float spot_attenuation = get_omni_spot_attenuation(light_length, spot_lights[idx].inv_radius, spot_lights[idx].attenuation); 714: vec3 spot_dir = spot_lights[idx].direction; 715: float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_lights[idx].cone_angle); 716: float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_lights[idx].cone_angle)); 717: spot_attenuation *= 1.0 - pow(spot_rim, spot_lights[idx].cone_attenuation); 718: vec3 color = spot_lights[idx].color; 719: 720: float size_A = 0.0; 721: 722: if (spot_lights[idx].size > 0.0) { 723: float t = spot_lights[idx].size / max(0.001, light_length); 724: size_A = max(0.0, 1.0 - 1.0 / sqrt(1.0 + t * t)); 725: } 726: 727: light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color, spot_attenuation, f0, roughness, metallic, spot_lights[idx].specular_amount, albedo, alpha, 728: #ifdef LIGHT_BACKLIGHT_USED 729: backlight, 730: #endif 731: #ifdef LIGHT_RIM_USED 732: rim * spot_attenuation, rim_tint, 733: #endif 734: #ifdef LIGHT_CLEARCOAT_USED 735: clearcoat, clearcoat_roughness, vertex_normal, 736: #endif 737: #ifdef LIGHT_ANISOTROPY_USED 738: binormal, tangent, anisotropy, 739: #endif 740: diffuse_light, specular_light); 741: } 742: #endif // !DISABLE_LIGHT_SPOT 743: 744: #endif // !defined(DISABLE_LIGHT_DIRECTIONAL) || !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) 745: 746: #ifndef MODE_RENDER_DEPTH 747: vec4 fog_process(vec3 vertex) { 748: vec3 fog_color = scene_data.fog_light_color; 749: 750: #ifdef USE_RADIANCE_MAP 751: /* 752: if (scene_data.fog_aerial_perspective > 0.0) { 753: vec3 sky_fog_color = vec3(0.0); 754: vec3 cube_view = scene_data.radiance_inverse_xform * vertex; 755: // mip_level always reads from the second mipmap and higher so the fog is always slightly blurred 756: float mip_level = mix(1.0 / MAX_ROUGHNESS_LOD, 1.0, 1.0 - (abs(vertex.z) - scene_data.z_near) / (scene_data.z_far - scene_data.z_near)); 757: 758: sky_fog_color = textureLod(radiance_map, cube_view, mip_level * RADIANCE_MAX_LOD).rgb; 759: 760: fog_color = mix(fog_color, sky_fog_color, scene_data.fog_aerial_perspective); 761: } 762: */ 763: #endif 764: 765: #ifndef DISABLE_LIGHT_DIRECTIONAL 766: if (scene_data.fog_sun_scatter > 0.001) { 767: vec4 sun_scatter = vec4(0.0); 768: float sun_total = 0.0; 769: vec3 view = normalize(vertex); 770: for (uint i = uint(0); i < scene_data.directional_light_count; i++) { 771: vec3 light_color = directional_lights[i].color * directional_lights[i].energy; 772: float light_amount = pow(max(dot(view, directional_lights[i].direction), 0.0), 8.0); 773: fog_color += light_color * light_amount * scene_data.fog_sun_scatter; 774: } 775: } 776: #endif // !DISABLE_LIGHT_DIRECTIONAL 777: 778: float fog_amount = 1.0 - exp(min(0.0, -length(vertex) * scene_data.fog_density)); 779: 780: if (abs(scene_data.fog_height_density) >= 0.0001) { 781: float y = (scene_data.inv_view_matrix * vec4(vertex, 1.0)).y; 782: 783: float y_dist = y - scene_data.fog_height; 784: 785: float vfog_amount = 1.0 - exp(min(0.0, y_dist * scene_data.fog_height_density)); 786: 787: fog_amount = max(vfog_amount, fog_amount); 788: } 789: 790: return vec4(fog_color, fog_amount); 791: } 792: 793: #endif // !MODE_RENDER_DEPTH 794: 795: void main() { 796: //lay out everything, whatever is unused is optimized away anyway 797: vec3 vertex = vertex_interp; 798: #ifdef USE_MULTIVIEW 799: vec3 eye_offset = multiview_data.eye_offset[ViewIndex].xyz; 800: vec3 view = -normalize(vertex_interp - eye_offset); 801: mat4 projection_matrix = multiview_data.projection_matrix_view[ViewIndex]; 802: mat4 inv_projection_matrix = multiview_data.inv_projection_matrix_view[ViewIndex]; 803: #else 804: vec3 eye_offset = vec3(0.0, 0.0, 0.0); 805: vec3 view = -normalize(vertex_interp); 806: mat4 projection_matrix = scene_data.projection_matrix; 807: mat4 inv_projection_matrix = scene_data.inv_projection_matrix; 808: #endif 809: highp mat4 model_matrix = world_transform; 810: vec3 albedo = vec3(1.0); 811: vec3 backlight = vec3(0.0); 812: vec4 transmittance_color = vec4(0.0, 0.0, 0.0, 1.0); 813: float transmittance_depth = 0.0; 814: float transmittance_boost = 0.0; 815: float metallic = 0.0; 816: float specular = 0.5; 817: vec3 emission = vec3(0.0); 818: float roughness = 1.0; 819: float rim = 0.0; 820: float rim_tint = 0.0; 821: float clearcoat = 0.0; 822: float clearcoat_roughness = 0.0; 823: float anisotropy = 0.0; 824: vec2 anisotropy_flow = vec2(1.0, 0.0); 825: vec4 fog = vec4(0.0); 826: #if defined(CUSTOM_RADIANCE_USED) 827: vec4 custom_radiance = vec4(0.0); 828: #endif 829: #if defined(CUSTOM_IRRADIANCE_USED) 830: vec4 custom_irradiance = vec4(0.0); 831: #endif 832: 833: float ao = 1.0; 834: float ao_light_affect = 0.0; 835: 836: float alpha = 1.0; 837: 838: #if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) 839: vec3 binormal = normalize(binormal_interp); 840: vec3 tangent = normalize(tangent_interp); 841: #else 842: vec3 binormal = vec3(0.0); 843: vec3 tangent = vec3(0.0); 844: #endif 845: 846: #ifdef NORMAL_USED 847: vec3 normal = normalize(normal_interp); 848: 849: #if defined(DO_SIDE_CHECK) 850: if (!gl_FrontFacing) { 851: normal = -normal; 852: } 853: #endif 854: 855: #endif //NORMAL_USED 856: 857: #ifdef UV_USED 858: vec2 uv = uv_interp; 859: #endif 860: 861: #if defined(UV2_USED) || defined(USE_LIGHTMAP) 862: vec2 uv2 = uv2_interp; 863: #endif 864: 865: #if defined(COLOR_USED) 866: vec4 color = color_interp; 867: #endif 868: 869: #if defined(NORMAL_MAP_USED) 870: 871: vec3 normal_map = vec3(0.5); 872: #endif 873: 874: float normal_map_depth = 1.0; 875: 876: vec2 screen_uv = gl_FragCoord.xy * scene_data.screen_pixel_size; 877: 878: float sss_strength = 0.0; 879: 880: #ifdef ALPHA_SCISSOR_USED 881: float alpha_scissor_threshold = 1.0; 882: #endif // ALPHA_SCISSOR_USED 883: 884: #ifdef ALPHA_HASH_USED 885: float alpha_hash_scale = 1.0; 886: #endif // ALPHA_HASH_USED 887: 888: #ifdef ALPHA_ANTIALIASING_EDGE_USED 889: float alpha_antialiasing_edge = 0.0; 890: vec2 alpha_texture_coordinate = vec2(0.0, 0.0); 891: #endif // ALPHA_ANTIALIASING_EDGE_USED 892: { 893: } 894: 895: #ifndef USE_SHADOW_TO_OPACITY 896: 897: #if defined(ALPHA_SCISSOR_USED) 898: if (alpha < alpha_scissor_threshold) { 899: discard; 900: } 901: #endif // ALPHA_SCISSOR_USED 902: 903: #ifdef USE_OPAQUE_PREPASS 904: #if !defined(ALPHA_SCISSOR_USED) 905: 906: if (alpha < opaque_prepass_threshold) { 907: discard; 908: } 909: 910: #endif // not ALPHA_SCISSOR_USED 911: #endif // USE_OPAQUE_PREPASS 912: 913: #endif // !USE_SHADOW_TO_OPACITY 914: 915: #ifdef NORMAL_MAP_USED 916: 917: normal_map.xy = normal_map.xy * 2.0 - 1.0; 918: normal_map.z = sqrt(max(0.0, 1.0 - dot(normal_map.xy, normal_map.xy))); //always ignore Z, as it can be RG packed, Z may be pos/neg, etc. 919: 920: normal = normalize(mix(normal, tangent * normal_map.x + binormal * normal_map.y + normal * normal_map.z, normal_map_depth)); 921: 922: #endif 923: 924: #ifdef LIGHT_ANISOTROPY_USED 925: 926: if (anisotropy > 0.01) { 927: //rotation matrix 928: mat3 rot = mat3(tangent, binormal, normal); 929: //make local to space 930: tangent = normalize(rot * vec3(anisotropy_flow.x, anisotropy_flow.y, 0.0)); 931: binormal = normalize(rot * vec3(-anisotropy_flow.y, anisotropy_flow.x, 0.0)); 932: } 933: 934: #endif 935: 936: #ifndef MODE_RENDER_DEPTH 937: 938: #ifndef CUSTOM_FOG_USED 939: #ifndef DISABLE_FOG 940: // fog must be processed as early as possible and then packed. 941: // to maximize VGPR usage 942: 943: if (scene_data.fog_enabled) { 944: fog = fog_process(vertex); 945: } 946: #endif // !DISABLE_FOG 947: #endif // !CUSTOM_FOG_USED 948: 949: uint fog_rg = packHalf2x16(fog.rg); 950: uint fog_ba = packHalf2x16(fog.ba); 951: 952: // Convert colors to linear 953: albedo = srgb_to_linear(albedo); 954: emission = srgb_to_linear(emission); 955: // TODO Backlight and transmittance when used 956: #ifndef MODE_UNSHADED 957: vec3 f0 = F0(metallic, specular, albedo); 958: vec3 specular_light = vec3(0.0, 0.0, 0.0); 959: vec3 diffuse_light = vec3(0.0, 0.0, 0.0); 960: vec3 ambient_light = vec3(0.0, 0.0, 0.0); 961: 962: #ifdef BASE_PASS 963: /////////////////////// LIGHTING ////////////////////////////// 964: 965: // IBL precalculations 966: float ndotv = clamp(dot(normal, view), 0.0, 1.0); 967: vec3 F = f0 + (max(vec3(1.0 - roughness), f0) - f0) * pow(1.0 - ndotv, 5.0); 968: 969: #ifdef USE_RADIANCE_MAP 970: if (scene_data.use_reflection_cubemap) { 971: #ifdef LIGHT_ANISOTROPY_USED 972: // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy 973: vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent; 974: vec3 anisotropic_tangent = cross(anisotropic_direction, view); 975: vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction); 976: vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0))); 977: vec3 ref_vec = reflect(-view, bent_normal); 978: #else 979: vec3 ref_vec = reflect(-view, normal); 980: #endif 981: ref_vec = mix(ref_vec, normal, roughness * roughness); 982: float horizon = min(1.0 + dot(ref_vec, normal), 1.0); 983: ref_vec = scene_data.radiance_inverse_xform * ref_vec; 984: specular_light = textureLod(radiance_map, ref_vec, sqrt(roughness) * RADIANCE_MAX_LOD).rgb; 985: specular_light = srgb_to_linear(specular_light); 986: specular_light *= horizon * horizon; 987: specular_light *= scene_data.ambient_light_color_energy.a; 988: } 989: #endif 990: 991: // Calculate Reflection probes 992: // Calculate Lightmaps 993: 994: #if defined(CUSTOM_RADIANCE_USED) 995: specular_light = mix(specular_light, custom_radiance.rgb, custom_radiance.a); 996: #endif // CUSTOM_RADIANCE_USED 997: 998: #ifndef USE_LIGHTMAP 999: //lightmap overrides everything 1000: if (scene_data.use_ambient_light) { 1001: ambient_light = scene_data.ambient_light_color_energy.rgb; 1002: #ifdef USE_RADIANCE_MAP 1003: if (scene_data.use_ambient_cubemap) { 1004: vec3 ambient_dir = scene_data.radiance_inverse_xform * normal; 1005: vec3 cubemap_ambient = textureLod(radiance_map, ambient_dir, RADIANCE_MAX_LOD).rgb; 1006: cubemap_ambient = srgb_to_linear(cubemap_ambient); 1007: ambient_light = mix(ambient_light, cubemap_ambient * scene_data.ambient_light_color_energy.a, scene_data.ambient_color_sky_mix); 1008: } 1009: #endif 1010: } 1011: #endif // USE_LIGHTMAP 1012: 1013: #if defined(CUSTOM_IRRADIANCE_USED) 1014: ambient_light = mix(ambient_light, custom_irradiance.rgb, custom_irradiance.a); 1015: #endif // CUSTOM_IRRADIANCE_USED 1016: 1017: { 1018: #if defined(AMBIENT_LIGHT_DISABLED) 1019: ambient_light = vec3(0.0, 0.0, 0.0); 1020: #else 1021: ambient_light *= albedo.rgb; 1022: ambient_light *= ao; 1023: #endif // AMBIENT_LIGHT_DISABLED 1024: } 1025: 1026: // convert ao to direct light ao 1027: ao = mix(1.0, ao, ao_light_affect); 1028: 1029: { 1030: #if defined(DIFFUSE_TOON) 1031: //simplify for toon, as 1032: specular_light *= specular * metallic * albedo * 2.0; 1033: #else 1034: 1035: // scales the specular reflections, needs to be be computed before lighting happens, 1036: // but after environment, GI, and reflection probes are added 1037: // Environment brdf approximation (Lazarov 2013) 1038: // see https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile 1039: const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022); 1040: const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04); 1041: vec4 r = roughness * c0 + c1; 1042: float ndotv = clamp(dot(normal, view), 0.0, 1.0); 1043: 1044: float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y; 1045: vec2 env = vec2(-1.04, 1.04) * a004 + r.zw; 1046: specular_light *= env.x * f0 + env.y * clamp(50.0 * f0.g, metallic, 1.0); 1047: #endif 1048: } 1049: 1050: #endif // BASE_PASS 1051: 1052: #ifndef DISABLE_LIGHT_DIRECTIONAL 1053: //diffuse_light = normal; // 1054: for (uint i = uint(0); i < scene_data.directional_light_count; i++) { 1055: light_compute(normal, normalize(directional_lights[i].direction), normalize(view), directional_lights[i].size, directional_lights[i].color * directional_lights[i].energy, 1.0, f0, roughness, metallic, 1.0, albedo, alpha, 1056: #ifdef LIGHT_BACKLIGHT_USED 1057: backlight, 1058: #endif 1059: #ifdef LIGHT_RIM_USED 1060: rim, rim_tint, 1061: #endif 1062: #ifdef LIGHT_CLEARCOAT_USED 1063: clearcoat, clearcoat_roughness, normalize(normal_interp), 1064: #endif 1065: #ifdef LIGHT_ANISOTROPY_USED 1066: binormal, 1067: tangent, anisotropy, 1068: #endif 1069: diffuse_light, 1070: specular_light); 1071: } 1072: #endif // !DISABLE_LIGHT_DIRECTIONAL 1073: 1074: #ifndef DISABLE_LIGHT_OMNI 1075: for (uint i = 0u; i < MAX_FORWARD_LIGHTS; i++) { 1076: if (i >= omni_light_count) { 1077: break; 1078: } 1079: light_process_omni(omni_light_indices[i], vertex, view, normal, f0, roughness, metallic, 0.0, albedo, alpha, 1080: #ifdef LIGHT_BACKLIGHT_USED 1081: backlight, 1082: #endif 1083: #ifdef LIGHT_RIM_USED 1084: rim, 1085: rim_tint, 1086: #endif 1087: #ifdef LIGHT_CLEARCOAT_USED 1088: clearcoat, clearcoat_roughness, normalize(normal_interp), 1089: #endif 1090: #ifdef LIGHT_ANISOTROPY_USED 1091: binormal, tangent, anisotropy, 1092: #endif 1093: diffuse_light, specular_light); 1094: } 1095: #endif // !DISABLE_LIGHT_OMNI 1096: 1097: #ifndef DISABLE_LIGHT_SPOT 1098: for (uint i = 0u; i < MAX_FORWARD_LIGHTS; i++) { 1099: if (i >= spot_light_count) { 1100: break; 1101: } 1102: light_process_spot(spot_light_indices[i], vertex, view, normal, f0, roughness, metallic, 0.0, albedo, alpha, 1103: #ifdef LIGHT_BACKLIGHT_USED 1104: backlight, 1105: #endif 1106: #ifdef LIGHT_RIM_USED 1107: rim, 1108: rim_tint, 1109: #endif 1110: #ifdef LIGHT_CLEARCOAT_USED 1111: clearcoat, clearcoat_roughness, normalize(normal_interp), 1112: #endif 1113: #ifdef LIGHT_ANISOTROPY_USED 1114: tangent, 1115: binormal, anisotropy, 1116: #endif 1117: diffuse_light, specular_light); 1118: } 1119: #endif // !DISABLE_LIGHT_SPOT 1120: 1121: #endif // !MODE_UNSHADED 1122: 1123: #endif // !MODE_RENDER_DEPTH 1124: 1125: #if defined(USE_SHADOW_TO_OPACITY) 1126: alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0)); 1127: 1128: #if defined(ALPHA_SCISSOR_USED) 1129: if (alpha < alpha_scissor) { 1130: discard; 1131: } 1132: #endif // ALPHA_SCISSOR_USED 1133: 1134: #ifdef USE_OPAQUE_PREPASS 1135: #if !defined(ALPHA_SCISSOR_USED) 1136: 1137: if (alpha < opaque_prepass_threshold) { 1138: discard; 1139: } 1140: 1141: #endif // not ALPHA_SCISSOR_USED 1142: #endif // USE_OPAQUE_PREPASS 1143: 1144: #endif // USE_SHADOW_TO_OPACITY 1145: 1146: #ifdef MODE_RENDER_DEPTH 1147: //nothing happens, so a tree-ssa optimizer will result in no fragment shader :) 1148: #else // !MODE_RENDER_DEPTH 1149: 1150: #ifdef MODE_UNSHADED 1151: frag_color = vec4(albedo, alpha); 1152: #else 1153: 1154: diffuse_light *= albedo; 1155: 1156: diffuse_light *= 1.0 - metallic; 1157: ambient_light *= 1.0 - metallic; 1158: 1159: frag_color = vec4(diffuse_light + specular_light, alpha); 1160: #ifdef BASE_PASS 1161: frag_color.rgb += emission + ambient_light; 1162: #endif 1163: #endif //MODE_UNSHADED 1164: fog = vec4(unpackHalf2x16(fog_rg), unpackHalf2x16(fog_ba)); 1165: 1166: #ifndef DISABLE_FOG 1167: if (scene_data.fog_enabled) { 1168: #ifdef BASE_PASS 1169: frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a); 1170: #else 1171: frag_color.rgb *= (1.0 - fog.a); 1172: #endif // BASE_PASS 1173: } 1174: #endif 1175: 1176: // Tonemap before writing as we are writing to an sRGB framebuffer 1177: frag_color.rgb *= exposure; 1178: frag_color.rgb = apply_tonemapping(frag_color.rgb, white); 1179: frag_color.rgb = linear_to_srgb(frag_color.rgb); 1180: 1181: #ifdef USE_BCS 1182: frag_color.rgb = apply_bcs(frag_color.rgb, bcs); 1183: #endif 1184: 1185: #ifdef USE_COLOR_CORRECTION 1186: frag_color.rgb = apply_color_correction(frag_color.rgb, color_correction); 1187: #endif 1188: 1189: #endif //!MODE_RENDER_DEPTH 1190: } 1191: 1192: 1: #version 330 2: #define USE_GLES_OVER_GL 3: #define USE_RADIANCE_MAP 4: 5: #define MAX_GLOBAL_SHADER_UNIFORMS 256 6: 7: #define MAX_LIGHT_DATA_STRUCTS 32 8: 9: #define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS 8 10: 11: #define MAX_FORWARD_LIGHTS uint(8) 12: #define MODE_RENDER_DEPTH 13: 14: #ifdef USE_MULTIVIEW 15: #if defined(GL_OVR_multiview2) 16: #extension GL_OVR_multiview2 : require 17: #elif defined(GL_OVR_multiview) 18: #extension GL_OVR_multiview : require 19: #endif 20: #define ViewIndex gl_ViewID_OVR 21: #define MAX_VIEWS 2 22: #else 23: #define ViewIndex uint(0) 24: #define MAX_VIEWS 1 25: #endif 26: precision highp float; 27: precision highp int; 28: 29: // Default to SPECULAR_SCHLICK_GGX. 30: #if !defined(SPECULAR_DISABLED) && !defined(SPECULAR_SCHLICK_GGX) && !defined(SPECULAR_TOON) 31: #define SPECULAR_SCHLICK_GGX 32: #endif 33: 34: #if !defined(MODE_RENDER_DEPTH) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) ||defined(LIGHT_CLEARCOAT_USED) 35: #ifndef NORMAL_USED 36: #define NORMAL_USED 37: #endif 38: #endif 39: 40: #ifndef MODE_RENDER_DEPTH 41: #ifdef USE_BCS 42: uniform vec3 bcs; 43: #endif 44: 45: #ifdef USE_COLOR_CORRECTION 46: #ifdef USE_1D_LUT 47: uniform sampler2D source_color_correction; //texunit:-1 48: #else 49: uniform sampler3D source_color_correction; //texunit:-1 50: #endif 51: #endif 52: 53: layout(std140) uniform TonemapData { //ubo:0 54: float exposure; 55: float white; 56: int tonemapper; 57: int pad; 58: }; 59: 60: vec3 apply_bcs(vec3 color, vec3 bcs) { 61: color = mix(vec3(0.0), color, bcs.x); 62: color = mix(vec3(0.5), color, bcs.y); 63: color = mix(vec3(dot(vec3(1.0), color) * 0.33333), color, bcs.z); 64: 65: return color; 66: } 67: #ifdef USE_COLOR_CORRECTION 68: #ifdef USE_1D_LUT 69: vec3 apply_color_correction(vec3 color) { 70: color.r = texture(source_color_correction, vec2(color.r, 0.0f)).r; 71: color.g = texture(source_color_correction, vec2(color.g, 0.0f)).g; 72: color.b = texture(source_color_correction, vec2(color.b, 0.0f)).b; 73: return color; 74: } 75: #else 76: vec3 apply_color_correction(vec3 color) { 77: return textureLod(source_color_correction, color, 0.0).rgb; 78: } 79: #endif 80: #endif 81: 82: vec3 tonemap_filmic(vec3 color, float p_white) { 83: // exposure bias: input scale (color *= bias, white *= bias) to make the brightness consistent with other tonemappers 84: // also useful to scale the input to the range that the tonemapper is designed for (some require very high input values) 85: // has no effect on the curve's general shape or visual properties 86: const float exposure_bias = 2.0f; 87: const float A = 0.22f * exposure_bias * exposure_bias; // bias baked into constants for performance 88: const float B = 0.30f * exposure_bias; 89: const float C = 0.10f; 90: const float D = 0.20f; 91: const float E = 0.01f; 92: const float F = 0.30f; 93: 94: vec3 color_tonemapped = ((color * (A * color + C * B) + D * E) / (color * (A * color + B) + D * F)) - E / F; 95: float p_white_tonemapped = ((p_white * (A * p_white + C * B) + D * E) / (p_white * (A * p_white + B) + D * F)) - E / F; 96: 97: return color_tonemapped / p_white_tonemapped; 98: } 99: 100: // Adapted from https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl 101: // (MIT License). 102: vec3 tonemap_aces(vec3 color, float p_white) { 103: const float exposure_bias = 1.8f; 104: const float A = 0.0245786f; 105: const float B = 0.000090537f; 106: const float C = 0.983729f; 107: const float D = 0.432951f; 108: const float E = 0.238081f; 109: 110: // Exposure bias baked into transform to save shader instructions. Equivalent to `color *= exposure_bias` 111: const mat3 rgb_to_rrt = mat3( 112: vec3(0.59719f * exposure_bias, 0.35458f * exposure_bias, 0.04823f * exposure_bias), 113: vec3(0.07600f * exposure_bias, 0.90834f * exposure_bias, 0.01566f * exposure_bias), 114: vec3(0.02840f * exposure_bias, 0.13383f * exposure_bias, 0.83777f * exposure_bias)); 115: 116: const mat3 odt_to_rgb = mat3( 117: vec3(1.60475f, -0.53108f, -0.07367f), 118: vec3(-0.10208f, 1.10813f, -0.00605f), 119: vec3(-0.00327f, -0.07276f, 1.07602f)); 120: 121: color *= rgb_to_rrt; 122: vec3 color_tonemapped = (color * (color + A) - B) / (color * (C * color + D) + E); 123: color_tonemapped *= odt_to_rgb; 124: 125: p_white *= exposure_bias; 126: float p_white_tonemapped = (p_white * (p_white + A) - B) / (p_white * (C * p_white + D) + E); 127: 128: return color_tonemapped / p_white_tonemapped; 129: } 130: 131: vec3 tonemap_reinhard(vec3 color, float p_white) { 132: return (p_white * color + color) / (color * p_white + p_white); 133: } 134: 135: // This expects 0-1 range input. 136: vec3 linear_to_srgb(vec3 color) { 137: //color = clamp(color, vec3(0.0), vec3(1.0)); 138: //const vec3 a = vec3(0.055f); 139: //return mix((vec3(1.0f) + a) * pow(color.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * color.rgb, lessThan(color.rgb, vec3(0.0031308f))); 140: // Approximation from http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html 141: return max(vec3(1.055) * pow(color, vec3(0.416666667)) - vec3(0.055), vec3(0.0)); 142: } 143: 144: // This expects 0-1 range input, outside that range it behaves poorly. 145: vec3 srgb_to_linear(vec3 color) { 146: // Approximation from http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html 147: return color * (color * (color * 0.305306011 + 0.682171111) + 0.012522878); 148: } 149: 150: #define TONEMAPPER_LINEAR 0 151: #define TONEMAPPER_REINHARD 1 152: #define TONEMAPPER_FILMIC 2 153: #define TONEMAPPER_ACES 3 154: 155: vec3 apply_tonemapping(vec3 color, float p_white) { // inputs are LINEAR, always outputs clamped [0;1] color 156: // Ensure color values passed to tonemappers are positive. 157: // They can be negative in the case of negative lights, which leads to undesired behavior. 158: if (tonemapper == TONEMAPPER_LINEAR) { 159: return color; 160: } else if (tonemapper == TONEMAPPER_REINHARD) { 161: return tonemap_reinhard(max(vec3(0.0f), color), p_white); 162: } else if (tonemapper == TONEMAPPER_FILMIC) { 163: return tonemap_filmic(max(vec3(0.0f), color), p_white); 164: } else { // TONEMAPPER_ACES 165: return tonemap_aces(max(vec3(0.0f), color), p_white); 166: } 167: } 168: #endif 169: 170: #ifdef USE_GLES_OVER_GL 171: // Floating point pack/unpack functions are part of the GLSL ES 300 specification used by web and mobile. 172: uint float2half(uint f) { 173: uint e = f & uint(0x7f800000); 174: if (e <= uint(0x38000000)) { 175: return uint(0); 176: } else { 177: return ((f >> uint(16)) & uint(0x8000)) | 178: (((e - uint(0x38000000)) >> uint(13)) & uint(0x7c00)) | 179: ((f >> uint(13)) & uint(0x03ff)); 180: } 181: } 182: 183: uint half2float(uint h) { 184: uint h_e = h & uint(0x7c00); 185: return ((h & uint(0x8000)) << uint(16)) | uint((h_e >> uint(10)) != uint(0)) * (((h_e + uint(0x1c000)) << uint(13)) | ((h & uint(0x03ff)) << uint(13))); 186: } 187: 188: uint packHalf2x16(vec2 v) { 189: return float2half(floatBitsToUint(v.x)) | float2half(floatBitsToUint(v.y)) << uint(16); 190: } 191: 192: vec2 unpackHalf2x16(uint v) { 193: return vec2(uintBitsToFloat(half2float(v & uint(0xffff))), 194: uintBitsToFloat(half2float(v >> uint(16)))); 195: } 196: 197: uint packUnorm2x16(vec2 v) { 198: uvec2 uv = uvec2(round(clamp(v, vec2(0.0), vec2(1.0)) * 65535.0)); 199: return uv.x | uv.y << uint(16); 200: } 201: 202: vec2 unpackUnorm2x16(uint p) { 203: return vec2(float(p & uint(0xffff)), float(p >> uint(16))) * 0.000015259021; // 1.0 / 65535.0 optimization 204: } 205: 206: uint packSnorm2x16(vec2 v) { 207: uvec2 uv = uvec2(round(clamp(v, vec2(-1.0), vec2(1.0)) * 32767.0) + 32767.0); 208: return uv.x | uv.y << uint(16); 209: } 210: 211: vec2 unpackSnorm2x16(uint p) { 212: vec2 v = vec2(float(p & uint(0xffff)), float(p >> uint(16))); 213: return clamp((v - 32767.0) * vec2(0.00003051851), vec2(-1.0), vec2(1.0)); 214: } 215: 216: #endif 217: 218: // Compatibility renames. These are exposed with the "godot_" prefix 219: // to work around an Adreno bug which was exposing these ES310 functions 220: // in ES300 shaders. Internally, we must use the "godot_" prefix, but user shaders 221: // will be mapped automatically. 222: uint godot_packUnorm4x8(vec4 v) { 223: uvec4 uv = uvec4(round(clamp(v, vec4(0.0), vec4(1.0)) * 255.0)); 224: return uv.x | (uv.y << uint(8)) | (uv.z << uint(16)) | (uv.w << uint(24)); 225: } 226: 227: vec4 godot_unpackUnorm4x8(uint p) { 228: return vec4(float(p & uint(0xff)), float((p >> uint(8)) & uint(0xff)), float((p >> uint(16)) & uint(0xff)), float(p >> uint(24))) * 0.00392156862; // 1.0 / 255.0 229: } 230: 231: uint godot_packSnorm4x8(vec4 v) { 232: uvec4 uv = uvec4(round(clamp(v, vec4(-1.0), vec4(1.0)) * 127.0) + 127.0); 233: return uv.x | uv.y << uint(8) | uv.z << uint(16) | uv.w << uint(24); 234: } 235: 236: vec4 godot_unpackSnorm4x8(uint p) { 237: vec4 v = vec4(float(p & uint(0xff)), float((p >> uint(8)) & uint(0xff)), float((p >> uint(16)) & uint(0xff)), float(p >> uint(24))); 238: return clamp((v - vec4(127.0)) * vec4(0.00787401574), vec4(-1.0), vec4(1.0)); 239: } 240: 241: #define packUnorm4x8 godot_packUnorm4x8 242: #define unpackUnorm4x8 godot_unpackUnorm4x8 243: #define packSnorm4x8 godot_packSnorm4x8 244: #define unpackSnorm4x8 godot_unpackSnorm4x8 245: 246: /* texture unit usage, N is max_texture_unity-N 247: 248: 1-color correction // In tonemap_inc.glsl 249: 2-radiance 250: 3-directional_shadow 251: 4-positional_shadow 252: 5-screen 253: 6-depth 254: 255: */ 256: 257: #define M_PI 3.14159265359 258: /* clang-format on */ 259: 260: #define SHADER_IS_SRGB true 261: 262: /* Varyings */ 263: 264: #if defined(COLOR_USED) 265: in vec4 color_interp; 266: #endif 267: 268: #if defined(UV_USED) 269: in vec2 uv_interp; 270: #endif 271: 272: #if defined(UV2_USED) 273: in vec2 uv2_interp; 274: #else 275: #ifdef USE_LIGHTMAP 276: in vec2 uv2_interp; 277: #endif 278: #endif 279: 280: #if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) 281: in vec3 tangent_interp; 282: in vec3 binormal_interp; 283: #endif 284: 285: #ifdef NORMAL_USED 286: in vec3 normal_interp; 287: #endif 288: 289: in highp vec3 vertex_interp; 290: 291: #ifdef USE_RADIANCE_MAP 292: 293: #define RADIANCE_MAX_LOD 5.0 294: 295: uniform samplerCube radiance_map; // texunit:-2 296: 297: #endif 298: 299: layout(std140) uniform GlobalShaderUniformData { //ubo:1 300: vec4 global_shader_uniforms[MAX_GLOBAL_SHADER_UNIFORMS]; 301: }; 302: 303: /* Material Uniforms */ 304: 305: #ifdef MATERIAL_UNIFORMS_USED 306: 307: /* clang-format off */ 308: layout(std140) uniform MaterialUniforms { // ubo:3 309: 310: 311: }; 312: /* clang-format on */ 313: 314: #endif 315: 316: layout(std140) uniform SceneData { // ubo:2 317: highp mat4 projection_matrix; 318: highp mat4 inv_projection_matrix; 319: highp mat4 inv_view_matrix; 320: highp mat4 view_matrix; 321: 322: vec2 viewport_size; 323: vec2 screen_pixel_size; 324: 325: mediump vec4 ambient_light_color_energy; 326: 327: mediump float ambient_color_sky_mix; 328: bool material_uv2_mode; 329: float emissive_exposure_normalization; 330: bool use_ambient_light; 331: bool use_ambient_cubemap; 332: bool use_reflection_cubemap; 333: 334: float fog_aerial_perspective; 335: float time; 336: 337: mat3 radiance_inverse_xform; 338: 339: uint directional_light_count; 340: float z_far; 341: float z_near; 342: float IBL_exposure_normalization; 343: 344: bool fog_enabled; 345: float fog_density; 346: float fog_height; 347: float fog_height_density; 348: 349: vec3 fog_light_color; 350: float fog_sun_scatter; 351: uint camera_visible_layers; 352: uint pad3; 353: uint pad4; 354: uint pad5; 355: } 356: scene_data; 357: 358: #ifdef USE_MULTIVIEW 359: layout(std140) uniform MultiviewData { // ubo:8 360: highp mat4 projection_matrix_view[MAX_VIEWS]; 361: highp mat4 inv_projection_matrix_view[MAX_VIEWS]; 362: highp vec4 eye_offset[MAX_VIEWS]; 363: } 364: multiview_data; 365: #endif 366: 367: /* clang-format off */ 368: 369: 370: /* clang-format on */ 371: 372: // Directional light data. 373: #ifndef DISABLE_LIGHT_DIRECTIONAL 374: 375: struct DirectionalLightData { 376: mediump vec3 direction; 377: mediump float energy; 378: mediump vec3 color; 379: mediump float size; 380: mediump vec3 pad; 381: mediump float specular; 382: }; 383: 384: layout(std140) uniform DirectionalLights { // ubo:7 385: DirectionalLightData directional_lights[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS]; 386: }; 387: 388: #endif // !DISABLE_LIGHT_DIRECTIONAL 389: 390: // Omni and spot light data. 391: #if !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) 392: 393: struct LightData { // This structure needs to be as packed as possible. 394: highp vec3 position; 395: highp float inv_radius; 396: 397: mediump vec3 direction; 398: highp float size; 399: 400: mediump vec3 color; 401: mediump float attenuation; 402: 403: mediump float cone_attenuation; 404: mediump float cone_angle; 405: mediump float specular_amount; 406: mediump float shadow_opacity; 407: }; 408: 409: #ifndef DISABLE_LIGHT_OMNI 410: layout(std140) uniform OmniLightData { // ubo:5 411: LightData omni_lights[MAX_LIGHT_DATA_STRUCTS]; 412: }; 413: uniform uint omni_light_indices[MAX_FORWARD_LIGHTS]; 414: uniform uint omni_light_count; 415: #endif 416: 417: #ifndef DISABLE_LIGHT_SPOT 418: layout(std140) uniform SpotLightData { // ubo:6 419: LightData spot_lights[MAX_LIGHT_DATA_STRUCTS]; 420: }; 421: uniform uint spot_light_indices[MAX_FORWARD_LIGHTS]; 422: uniform uint spot_light_count; 423: #endif 424: 425: #ifdef USE_ADDITIVE_LIGHTING 426: uniform highp samplerCubeShadow positional_shadow; // texunit:-4 427: #endif 428: 429: #endif // !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) 430: 431: #ifdef USE_MULTIVIEW 432: uniform highp sampler2DArray depth_buffer; // texunit:-6 433: uniform highp sampler2DArray color_buffer; // texunit:-5 434: vec3 multiview_uv(vec2 uv) { 435: return vec3(uv, ViewIndex); 436: } 437: #else 438: uniform highp sampler2D depth_buffer; // texunit:-6 439: uniform highp sampler2D color_buffer; // texunit:-5 440: vec2 multiview_uv(vec2 uv) { 441: return uv; 442: } 443: #endif 444: 445: uniform highp mat4 world_transform; 446: uniform mediump float opaque_prepass_threshold; 447: 448: layout(location = 0) out vec4 frag_color; 449: 450: vec3 F0(float metallic, float specular, vec3 albedo) { 451: float dielectric = 0.16 * specular * specular; 452: // use albedo * metallic as colored specular reflectance at 0 angle for metallic materials; 453: // see https://google.github.io/filament/Filament.md.html 454: return mix(vec3(dielectric), albedo, vec3(metallic)); 455: } 456: 457: #if !defined(DISABLE_LIGHT_DIRECTIONAL) || !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) 458: 459: float D_GGX(float cos_theta_m, float alpha) { 460: float a = cos_theta_m * alpha; 461: float k = alpha / (1.0 - cos_theta_m * cos_theta_m + a * a); 462: return k * k * (1.0 / M_PI); 463: } 464: 465: // From Earl Hammon, Jr. "PBR Diffuse Lighting for GGX+Smith Microsurfaces" https://www.gdcvault.com/play/1024478/PBR-Diffuse-Lighting-for-GGX 466: float V_GGX(float NdotL, float NdotV, float alpha) { 467: return 0.5 / mix(2.0 * NdotL * NdotV, NdotL + NdotV, alpha); 468: } 469: 470: float D_GGX_anisotropic(float cos_theta_m, float alpha_x, float alpha_y, float cos_phi, float sin_phi) { 471: float alpha2 = alpha_x * alpha_y; 472: highp vec3 v = vec3(alpha_y * cos_phi, alpha_x * sin_phi, alpha2 * cos_theta_m); 473: highp float v2 = dot(v, v); 474: float w2 = alpha2 / v2; 475: float D = alpha2 * w2 * w2 * (1.0 / M_PI); 476: return D; 477: } 478: 479: float V_GGX_anisotropic(float alpha_x, float alpha_y, float TdotV, float TdotL, float BdotV, float BdotL, float NdotV, float NdotL) { 480: float Lambda_V = NdotL * length(vec3(alpha_x * TdotV, alpha_y * BdotV, NdotV)); 481: float Lambda_L = NdotV * length(vec3(alpha_x * TdotL, alpha_y * BdotL, NdotL)); 482: return 0.5 / (Lambda_V + Lambda_L); 483: } 484: 485: float SchlickFresnel(float u) { 486: float m = 1.0 - u; 487: float m2 = m * m; 488: return m2 * m2 * m; // pow(m,5) 489: } 490: 491: void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float attenuation, vec3 f0, float roughness, float metallic, float specular_amount, vec3 albedo, inout float alpha, 492: #ifdef LIGHT_BACKLIGHT_USED 493: vec3 backlight, 494: #endif 495: #ifdef LIGHT_RIM_USED 496: float rim, float rim_tint, 497: #endif 498: #ifdef LIGHT_CLEARCOAT_USED 499: float clearcoat, float clearcoat_roughness, vec3 vertex_normal, 500: #endif 501: #ifdef LIGHT_ANISOTROPY_USED 502: vec3 B, vec3 T, float anisotropy, 503: #endif 504: inout vec3 diffuse_light, inout vec3 specular_light) { 505: 506: #if defined(USE_LIGHT_SHADER_CODE) 507: // light is written by the light shader 508: 509: vec3 normal = N; 510: vec3 light = L; 511: vec3 view = V; 512: 513: /* clang-format off */ 514: 515: 516: /* clang-format on */ 517: 518: #else 519: float NdotL = min(A + dot(N, L), 1.0); 520: float cNdotL = max(NdotL, 0.0); // clamped NdotL 521: float NdotV = dot(N, V); 522: float cNdotV = max(NdotV, 1e-4); 523: 524: #if defined(DIFFUSE_BURLEY) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED) 525: vec3 H = normalize(V + L); 526: #endif 527: 528: #if defined(SPECULAR_SCHLICK_GGX) 529: float cNdotH = clamp(A + dot(N, H), 0.0, 1.0); 530: #endif 531: 532: #if defined(DIFFUSE_BURLEY) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED) 533: float cLdotH = clamp(A + dot(L, H), 0.0, 1.0); 534: #endif 535: 536: if (metallic < 1.0) { 537: float diffuse_brdf_NL; // BRDF times N.L for calculating diffuse radiance 538: 539: #if defined(DIFFUSE_LAMBERT_WRAP) 540: // Energy conserving lambert wrap shader. 541: // https://web.archive.org/web/20210228210901/http://blog.stevemcauley.com/2011/12/03/energy-conserving-wrapped-diffuse/ 542: diffuse_brdf_NL = max(0.0, (NdotL + roughness) / ((1.0 + roughness) * (1.0 + roughness))) * (1.0 / M_PI); 543: #elif defined(DIFFUSE_TOON) 544: diffuse_brdf_NL = smoothstep(-roughness, max(roughness, 0.01), NdotL) * (1.0 / M_PI); 545: #elif defined(DIFFUSE_BURLEY) 546: { 547: float FD90_minus_1 = 2.0 * cLdotH * cLdotH * roughness - 0.5; 548: float FdV = 1.0 + FD90_minus_1 * SchlickFresnel(cNdotV); 549: float FdL = 1.0 + FD90_minus_1 * SchlickFresnel(cNdotL); 550: diffuse_brdf_NL = (1.0 / M_PI) * FdV * FdL * cNdotL; 551: } 552: #else 553: // Lambert 554: diffuse_brdf_NL = cNdotL * (1.0 / M_PI); 555: #endif 556: 557: diffuse_light += light_color * diffuse_brdf_NL * attenuation; 558: 559: #if defined(LIGHT_BACKLIGHT_USED) 560: diffuse_light += light_color * (vec3(1.0 / M_PI) - diffuse_brdf_NL) * backlight * attenuation; 561: #endif 562: 563: #if defined(LIGHT_RIM_USED) 564: // Epsilon min to prevent pow(0, 0) singularity which results in undefined behavior. 565: float rim_light = pow(max(1e-4, 1.0 - cNdotV), max(0.0, (1.0 - roughness) * 16.0)); 566: diffuse_light += rim_light * rim * mix(vec3(1.0), albedo, rim_tint) * light_color; 567: #endif 568: } 569: 570: if (roughness > 0.0) { // FIXME: roughness == 0 should not disable specular light entirely 571: 572: // D 573: 574: #if defined(SPECULAR_TOON) 575: 576: vec3 R = normalize(-reflect(L, N)); 577: float RdotV = dot(R, V); 578: float mid = 1.0 - roughness; 579: mid *= mid; 580: float intensity = smoothstep(mid - roughness * 0.5, mid + roughness * 0.5, RdotV) * mid; 581: diffuse_light += light_color * intensity * attenuation * specular_amount; // write to diffuse_light, as in toon shading you generally want no reflection 582: 583: #elif defined(SPECULAR_DISABLED) 584: // none.. 585: 586: #elif defined(SPECULAR_SCHLICK_GGX) 587: // shlick+ggx as default 588: float alpha_ggx = roughness * roughness; 589: #if defined(LIGHT_ANISOTROPY_USED) 590: float aspect = sqrt(1.0 - anisotropy * 0.9); 591: float ax = alpha_ggx / aspect; 592: float ay = alpha_ggx * aspect; 593: float XdotH = dot(T, H); 594: float YdotH = dot(B, H); 595: float D = D_GGX_anisotropic(cNdotH, ax, ay, XdotH, YdotH); 596: float G = V_GGX_anisotropic(ax, ay, dot(T, V), dot(T, L), dot(B, V), dot(B, L), cNdotV, cNdotL); 597: #else 598: float D = D_GGX(cNdotH, alpha_ggx); 599: float G = V_GGX(cNdotL, cNdotV, alpha_ggx); 600: #endif // LIGHT_ANISOTROPY_USED 601: // F 602: float cLdotH5 = SchlickFresnel(cLdotH); 603: // Calculate Fresnel using cheap approximate specular occlusion term from Filament: 604: // https://google.github.io/filament/Filament.html#lighting/occlusion/specularocclusion 605: float f90 = clamp(50.0 * f0.g, 0.0, 1.0); 606: vec3 F = f0 + (f90 - f0) * cLdotH5; 607: 608: vec3 specular_brdf_NL = cNdotL * D * F * G; 609: 610: specular_light += specular_brdf_NL * light_color * attenuation * specular_amount; 611: #endif 612: 613: #if defined(LIGHT_CLEARCOAT_USED) 614: // Clearcoat ignores normal_map, use vertex normal instead 615: float ccNdotL = max(min(A + dot(vertex_normal, L), 1.0), 0.0); 616: float ccNdotH = clamp(A + dot(vertex_normal, H), 0.0, 1.0); 617: float ccNdotV = max(dot(vertex_normal, V), 1e-4); 618: 619: #if !defined(SPECULAR_SCHLICK_GGX) 620: float cLdotH5 = SchlickFresnel(cLdotH); 621: #endif 622: float Dr = D_GGX(ccNdotH, mix(0.001, 0.1, clearcoat_roughness)); 623: float Gr = 0.25 / (cLdotH * cLdotH); 624: float Fr = mix(.04, 1.0, cLdotH5); 625: float clearcoat_specular_brdf_NL = clearcoat * Gr * Fr * Dr * cNdotL; 626: 627: specular_light += clearcoat_specular_brdf_NL * light_color * attenuation * specular_amount; 628: // TODO: Clearcoat adds light to the scene right now (it is non-energy conserving), both diffuse and specular need to be scaled by (1.0 - FR) 629: // but to do so we need to rearrange this entire function 630: #endif // LIGHT_CLEARCOAT_USED 631: } 632: 633: #ifdef USE_SHADOW_TO_OPACITY 634: alpha = min(alpha, clamp(1.0 - attenuation, 0.0, 1.0)); 635: #endif 636: 637: #endif // LIGHT_CODE_USED 638: } 639: 640: float get_omni_spot_attenuation(float distance, float inv_range, float decay) { 641: float nd = distance * inv_range; 642: nd *= nd; 643: nd *= nd; // nd^4 644: nd = max(1.0 - nd, 0.0); 645: nd *= nd; // nd^2 646: return nd * pow(max(distance, 0.0001), -decay); 647: } 648: 649: #ifndef DISABLE_LIGHT_OMNI 650: void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f0, float roughness, float metallic, float shadow, vec3 albedo, inout float alpha, 651: #ifdef LIGHT_BACKLIGHT_USED 652: vec3 backlight, 653: #endif 654: #ifdef LIGHT_RIM_USED 655: float rim, float rim_tint, 656: #endif 657: #ifdef LIGHT_CLEARCOAT_USED 658: float clearcoat, float clearcoat_roughness, vec3 vertex_normal, 659: #endif 660: #ifdef LIGHT_ANISOTROPY_USED 661: vec3 binormal, vec3 tangent, float anisotropy, 662: #endif 663: inout vec3 diffuse_light, inout vec3 specular_light) { 664: vec3 light_rel_vec = omni_lights[idx].position - vertex; 665: float light_length = length(light_rel_vec); 666: float omni_attenuation = get_omni_spot_attenuation(light_length, omni_lights[idx].inv_radius, omni_lights[idx].attenuation); 667: vec3 color = omni_lights[idx].color; 668: float size_A = 0.0; 669: 670: if (omni_lights[idx].size > 0.0) { 671: float t = omni_lights[idx].size / max(0.001, light_length); 672: size_A = max(0.0, 1.0 - 1.0 / sqrt(1.0 + t * t)); 673: } 674: 675: light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color, omni_attenuation, f0, roughness, metallic, omni_lights[idx].specular_amount, albedo, alpha, 676: #ifdef LIGHT_BACKLIGHT_USED 677: backlight, 678: #endif 679: #ifdef LIGHT_RIM_USED 680: rim * omni_attenuation, rim_tint, 681: #endif 682: #ifdef LIGHT_CLEARCOAT_USED 683: clearcoat, clearcoat_roughness, vertex_normal, 684: #endif 685: #ifdef LIGHT_ANISOTROPY_USED 686: binormal, tangent, anisotropy, 687: #endif 688: diffuse_light, 689: specular_light); 690: } 691: #endif // !DISABLE_LIGHT_OMNI 692: 693: #ifndef DISABLE_LIGHT_SPOT 694: void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f0, float roughness, float metallic, float shadow, vec3 albedo, inout float alpha, 695: #ifdef LIGHT_BACKLIGHT_USED 696: vec3 backlight, 697: #endif 698: #ifdef LIGHT_RIM_USED 699: float rim, float rim_tint, 700: #endif 701: #ifdef LIGHT_CLEARCOAT_USED 702: float clearcoat, float clearcoat_roughness, vec3 vertex_normal, 703: #endif 704: #ifdef LIGHT_ANISOTROPY_USED 705: vec3 binormal, vec3 tangent, float anisotropy, 706: #endif 707: inout vec3 diffuse_light, 708: inout vec3 specular_light) { 709: 710: vec3 light_rel_vec = spot_lights[idx].position - vertex; 711: float light_length = length(light_rel_vec); 712: float spot_attenuation = get_omni_spot_attenuation(light_length, spot_lights[idx].inv_radius, spot_lights[idx].attenuation); 713: vec3 spot_dir = spot_lights[idx].direction; 714: float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_lights[idx].cone_angle); 715: float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_lights[idx].cone_angle)); 716: spot_attenuation *= 1.0 - pow(spot_rim, spot_lights[idx].cone_attenuation); 717: vec3 color = spot_lights[idx].color; 718: 719: float size_A = 0.0; 720: 721: if (spot_lights[idx].size > 0.0) { 722: float t = spot_lights[idx].size / max(0.001, light_length); 723: size_A = max(0.0, 1.0 - 1.0 / sqrt(1.0 + t * t)); 724: } 725: 726: light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color, spot_attenuation, f0, roughness, metallic, spot_lights[idx].specular_amount, albedo, alpha, 727: #ifdef LIGHT_BACKLIGHT_USED 728: backlight, 729: #endif 730: #ifdef LIGHT_RIM_USED 731: rim * spot_attenuation, rim_tint, 732: #endif 733: #ifdef LIGHT_CLEARCOAT_USED 734: clearcoat, clearcoat_roughness, vertex_normal, 735: #endif 736: #ifdef LIGHT_ANISOTROPY_USED 737: binormal, tangent, anisotropy, 738: #endif 739: diffuse_light, specular_light); 740: } 741: #endif // !DISABLE_LIGHT_SPOT 742: 743: #endif // !defined(DISABLE_LIGHT_DIRECTIONAL) || !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) 744: 745: #ifndef MODE_RENDER_DEPTH 746: vec4 fog_process(vec3 vertex) { 747: vec3 fog_color = scene_data.fog_light_color; 748: 749: #ifdef USE_RADIANCE_MAP 750: /* 751: if (scene_data.fog_aerial_perspective > 0.0) { 752: vec3 sky_fog_color = vec3(0.0); 753: vec3 cube_view = scene_data.radiance_inverse_xform * vertex; 754: // mip_level always reads from the second mipmap and higher so the fog is always slightly blurred 755: float mip_level = mix(1.0 / MAX_ROUGHNESS_LOD, 1.0, 1.0 - (abs(vertex.z) - scene_data.z_near) / (scene_data.z_far - scene_data.z_near)); 756: 757: sky_fog_color = textureLod(radiance_map, cube_view, mip_level * RADIANCE_MAX_LOD).rgb; 758: 759: fog_color = mix(fog_color, sky_fog_color, scene_data.fog_aerial_perspective); 760: } 761: */ 762: #endif 763: 764: #ifndef DISABLE_LIGHT_DIRECTIONAL 765: if (scene_data.fog_sun_scatter > 0.001) { 766: vec4 sun_scatter = vec4(0.0); 767: float sun_total = 0.0; 768: vec3 view = normalize(vertex); 769: for (uint i = uint(0); i < scene_data.directional_light_count; i++) { 770: vec3 light_color = directional_lights[i].color * directional_lights[i].energy; 771: float light_amount = pow(max(dot(view, directional_lights[i].direction), 0.0), 8.0); 772: fog_color += light_color * light_amount * scene_data.fog_sun_scatter; 773: } 774: } 775: #endif // !DISABLE_LIGHT_DIRECTIONAL 776: 777: float fog_amount = 1.0 - exp(min(0.0, -length(vertex) * scene_data.fog_density)); 778: 779: if (abs(scene_data.fog_height_density) >= 0.0001) { 780: float y = (scene_data.inv_view_matrix * vec4(vertex, 1.0)).y; 781: 782: float y_dist = y - scene_data.fog_height; 783: 784: float vfog_amount = 1.0 - exp(min(0.0, y_dist * scene_data.fog_height_density)); 785: 786: fog_amount = max(vfog_amount, fog_amount); 787: } 788: 789: return vec4(fog_color, fog_amount); 790: } 791: 792: #endif // !MODE_RENDER_DEPTH 793: 794: void main() { 795: //lay out everything, whatever is unused is optimized away anyway 796: vec3 vertex = vertex_interp; 797: #ifdef USE_MULTIVIEW 798: vec3 eye_offset = multiview_data.eye_offset[ViewIndex].xyz; 799: vec3 view = -normalize(vertex_interp - eye_offset); 800: mat4 projection_matrix = multiview_data.projection_matrix_view[ViewIndex]; 801: mat4 inv_projection_matrix = multiview_data.inv_projection_matrix_view[ViewIndex]; 802: #else 803: vec3 eye_offset = vec3(0.0, 0.0, 0.0); 804: vec3 view = -normalize(vertex_interp); 805: mat4 projection_matrix = scene_data.projection_matrix; 806: mat4 inv_projection_matrix = scene_data.inv_projection_matrix; 807: #endif 808: highp mat4 model_matrix = world_transform; 809: vec3 albedo = vec3(1.0); 810: vec3 backlight = vec3(0.0); 811: vec4 transmittance_color = vec4(0.0, 0.0, 0.0, 1.0); 812: float transmittance_depth = 0.0; 813: float transmittance_boost = 0.0; 814: float metallic = 0.0; 815: float specular = 0.5; 816: vec3 emission = vec3(0.0); 817: float roughness = 1.0; 818: float rim = 0.0; 819: float rim_tint = 0.0; 820: float clearcoat = 0.0; 821: float clearcoat_roughness = 0.0; 822: float anisotropy = 0.0; 823: vec2 anisotropy_flow = vec2(1.0, 0.0); 824: vec4 fog = vec4(0.0); 825: #if defined(CUSTOM_RADIANCE_USED) 826: vec4 custom_radiance = vec4(0.0); 827: #endif 828: #if defined(CUSTOM_IRRADIANCE_USED) 829: vec4 custom_irradiance = vec4(0.0); 830: #endif 831: 832: float ao = 1.0; 833: float ao_light_affect = 0.0; 834: 835: float alpha = 1.0; 836: 837: #if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) 838: vec3 binormal = normalize(binormal_interp); 839: vec3 tangent = normalize(tangent_interp); 840: #else 841: vec3 binormal = vec3(0.0); 842: vec3 tangent = vec3(0.0); 843: #endif 844: 845: #ifdef NORMAL_USED 846: vec3 normal = normalize(normal_interp); 847: 848: #if defined(DO_SIDE_CHECK) 849: if (!gl_FrontFacing) { 850: normal = -normal; 851: } 852: #endif 853: 854: #endif //NORMAL_USED 855: 856: #ifdef UV_USED 857: vec2 uv = uv_interp; 858: #endif 859: 860: #if defined(UV2_USED) || defined(USE_LIGHTMAP) 861: vec2 uv2 = uv2_interp; 862: #endif 863: 864: #if defined(COLOR_USED) 865: vec4 color = color_interp; 866: #endif 867: 868: #if defined(NORMAL_MAP_USED) 869: 870: vec3 normal_map = vec3(0.5); 871: #endif 872: 873: float normal_map_depth = 1.0; 874: 875: vec2 screen_uv = gl_FragCoord.xy * scene_data.screen_pixel_size; 876: 877: float sss_strength = 0.0; 878: 879: #ifdef ALPHA_SCISSOR_USED 880: float alpha_scissor_threshold = 1.0; 881: #endif // ALPHA_SCISSOR_USED 882: 883: #ifdef ALPHA_HASH_USED 884: float alpha_hash_scale = 1.0; 885: #endif // ALPHA_HASH_USED 886: 887: #ifdef ALPHA_ANTIALIASING_EDGE_USED 888: float alpha_antialiasing_edge = 0.0; 889: vec2 alpha_texture_coordinate = vec2(0.0, 0.0); 890: #endif // ALPHA_ANTIALIASING_EDGE_USED 891: { 892: } 893: 894: #ifndef USE_SHADOW_TO_OPACITY 895: 896: #if defined(ALPHA_SCISSOR_USED) 897: if (alpha < alpha_scissor_threshold) { 898: discard; 899: } 900: #endif // ALPHA_SCISSOR_USED 901: 902: #ifdef USE_OPAQUE_PREPASS 903: #if !defined(ALPHA_SCISSOR_USED) 904: 905: if (alpha < opaque_prepass_threshold) { 906: discard; 907: } 908: 909: #endif // not ALPHA_SCISSOR_USED 910: #endif // USE_OPAQUE_PREPASS 911: 912: #endif // !USE_SHADOW_TO_OPACITY 913: 914: #ifdef NORMAL_MAP_USED 915: 916: normal_map.xy = normal_map.xy * 2.0 - 1.0; 917: normal_map.z = sqrt(max(0.0, 1.0 - dot(normal_map.xy, normal_map.xy))); //always ignore Z, as it can be RG packed, Z may be pos/neg, etc. 918: 919: normal = normalize(mix(normal, tangent * normal_map.x + binormal * normal_map.y + normal * normal_map.z, normal_map_depth)); 920: 921: #endif 922: 923: #ifdef LIGHT_ANISOTROPY_USED 924: 925: if (anisotropy > 0.01) { 926: //rotation matrix 927: mat3 rot = mat3(tangent, binormal, normal); 928: //make local to space 929: tangent = normalize(rot * vec3(anisotropy_flow.x, anisotropy_flow.y, 0.0)); 930: binormal = normalize(rot * vec3(-anisotropy_flow.y, anisotropy_flow.x, 0.0)); 931: } 932: 933: #endif 934: 935: #ifndef MODE_RENDER_DEPTH 936: 937: #ifndef CUSTOM_FOG_USED 938: #ifndef DISABLE_FOG 939: // fog must be processed as early as possible and then packed. 940: // to maximize VGPR usage 941: 942: if (scene_data.fog_enabled) { 943: fog = fog_process(vertex); 944: } 945: #endif // !DISABLE_FOG 946: #endif // !CUSTOM_FOG_USED 947: 948: uint fog_rg = packHalf2x16(fog.rg); 949: uint fog_ba = packHalf2x16(fog.ba); 950: 951: // Convert colors to linear 952: albedo = srgb_to_linear(albedo); 953: emission = srgb_to_linear(emission); 954: // TODO Backlight and transmittance when used 955: #ifndef MODE_UNSHADED 956: vec3 f0 = F0(metallic, specular, albedo); 957: vec3 specular_light = vec3(0.0, 0.0, 0.0); 958: vec3 diffuse_light = vec3(0.0, 0.0, 0.0); 959: vec3 ambient_light = vec3(0.0, 0.0, 0.0); 960: 961: #ifdef BASE_PASS 962: /////////////////////// LIGHTING ////////////////////////////// 963: 964: // IBL precalculations 965: float ndotv = clamp(dot(normal, view), 0.0, 1.0); 966: vec3 F = f0 + (max(vec3(1.0 - roughness), f0) - f0) * pow(1.0 - ndotv, 5.0); 967: 968: #ifdef USE_RADIANCE_MAP 969: if (scene_data.use_reflection_cubemap) { 970: #ifdef LIGHT_ANISOTROPY_USED 971: // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy 972: vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent; 973: vec3 anisotropic_tangent = cross(anisotropic_direction, view); 974: vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction); 975: vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0))); 976: vec3 ref_vec = reflect(-view, bent_normal); 977: #else 978: vec3 ref_vec = reflect(-view, normal); 979: #endif 980: ref_vec = mix(ref_vec, normal, roughness * roughness); 981: float horizon = min(1.0 + dot(ref_vec, normal), 1.0); 982: ref_vec = scene_data.radiance_inverse_xform * ref_vec; 983: specular_light = textureLod(radiance_map, ref_vec, sqrt(roughness) * RADIANCE_MAX_LOD).rgb; 984: specular_light = srgb_to_linear(specular_light); 985: specular_light *= horizon * horizon; 986: specular_light *= scene_data.ambient_light_color_energy.a; 987: } 988: #endif 989: 990: // Calculate Reflection probes 991: // Calculate Lightmaps 992: 993: #if defined(CUSTOM_RADIANCE_USED) 994: specular_light = mix(specular_light, custom_radiance.rgb, custom_radiance.a); 995: #endif // CUSTOM_RADIANCE_USED 996: 997: #ifndef USE_LIGHTMAP 998: //lightmap overrides everything 999: if (scene_data.use_ambient_light) { 1000: ambient_light = scene_data.ambient_light_color_energy.rgb; 1001: #ifdef USE_RADIANCE_MAP 1002: if (scene_data.use_ambient_cubemap) { 1003: vec3 ambient_dir = scene_data.radiance_inverse_xform * normal; 1004: vec3 cubemap_ambient = textureLod(radiance_map, ambient_dir, RADIANCE_MAX_LOD).rgb; 1005: cubemap_ambient = srgb_to_linear(cubemap_ambient); 1006: ambient_light = mix(ambient_light, cubemap_ambient * scene_data.ambient_light_color_energy.a, scene_data.ambient_color_sky_mix); 1007: } 1008: #endif 1009: } 1010: #endif // USE_LIGHTMAP 1011: 1012: #if defined(CUSTOM_IRRADIANCE_USED) 1013: ambient_light = mix(ambient_light, custom_irradiance.rgb, custom_irradiance.a); 1014: #endif // CUSTOM_IRRADIANCE_USED 1015: 1016: { 1017: #if defined(AMBIENT_LIGHT_DISABLED) 1018: ambient_light = vec3(0.0, 0.0, 0.0); 1019: #else 1020: ambient_light *= albedo.rgb; 1021: ambient_light *= ao; 1022: #endif // AMBIENT_LIGHT_DISABLED 1023: } 1024: 1025: // convert ao to direct light ao 1026: ao = mix(1.0, ao, ao_light_affect); 1027: 1028: { 1029: #if defined(DIFFUSE_TOON) 1030: //simplify for toon, as 1031: specular_light *= specular * metallic * albedo * 2.0; 1032: #else 1033: 1034: // scales the specular reflections, needs to be be computed before lighting happens, 1035: // but after environment, GI, and reflection probes are added 1036: // Environment brdf approximation (Lazarov 2013) 1037: // see https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile 1038: const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022); 1039: const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04); 1040: vec4 r = roughness * c0 + c1; 1041: float ndotv = clamp(dot(normal, view), 0.0, 1.0); 1042: 1043: float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y; 1044: vec2 env = vec2(-1.04, 1.04) * a004 + r.zw; 1045: specular_light *= env.x * f0 + env.y * clamp(50.0 * f0.g, metallic, 1.0); 1046: #endif 1047: } 1048: 1049: #endif // BASE_PASS 1050: 1051: #ifndef DISABLE_LIGHT_DIRECTIONAL 1052: //diffuse_light = normal; // 1053: for (uint i = uint(0); i < scene_data.directional_light_count; i++) { 1054: light_compute(normal, normalize(directional_lights[i].direction), normalize(view), directional_lights[i].size, directional_lights[i].color * directional_lights[i].energy, 1.0, f0, roughness, metallic, 1.0, albedo, alpha, 1055: #ifdef LIGHT_BACKLIGHT_USED 1056: backlight, 1057: #endif 1058: #ifdef LIGHT_RIM_USED 1059: rim, rim_tint, 1060: #endif 1061: #ifdef LIGHT_CLEARCOAT_USED 1062: clearcoat, clearcoat_roughness, normalize(normal_interp), 1063: #endif 1064: #ifdef LIGHT_ANISOTROPY_USED 1065: binormal, 1066: tangent, anisotropy, 1067: #endif 1068: diffuse_light, 1069: specular_light); 1070: } 1071: #endif // !DISABLE_LIGHT_DIRECTIONAL 1072: 1073: #ifndef DISABLE_LIGHT_OMNI 1074: for (uint i = 0u; i < MAX_FORWARD_LIGHTS; i++) { 1075: if (i >= omni_light_count) { 1076: break; 1077: } 1078: light_process_omni(omni_light_indices[i], vertex, view, normal, f0, roughness, metallic, 0.0, albedo, alpha, 1079: #ifdef LIGHT_BACKLIGHT_USED 1080: backlight, 1081: #endif 1082: #ifdef LIGHT_RIM_USED 1083: rim, 1084: rim_tint, 1085: #endif 1086: #ifdef LIGHT_CLEARCOAT_USED 1087: clearcoat, clearcoat_roughness, normalize(normal_interp), 1088: #endif 1089: #ifdef LIGHT_ANISOTROPY_USED 1090: binormal, tangent, anisotropy, 1091: #endif 1092: diffuse_light, specular_light); 1093: } 1094: #endif // !DISABLE_LIGHT_OMNI 1095: 1096: #ifndef DISABLE_LIGHT_SPOT 1097: for (uint i = 0u; i < MAX_FORWARD_LIGHTS; i++) { 1098: if (i >= spot_light_count) { 1099: break; 1100: } 1101: light_process_spot(spot_light_indices[i], vertex, view, normal, f0, roughness, metallic, 0.0, albedo, alpha, 1102: #ifdef LIGHT_BACKLIGHT_USED 1103: backlight, 1104: #endif 1105: #ifdef LIGHT_RIM_USED 1106: rim, 1107: rim_tint, 1108: #endif 1109: #ifdef LIGHT_CLEARCOAT_USED 1110: clearcoat, clearcoat_roughness, normalize(normal_interp), 1111: #endif 1112: #ifdef LIGHT_ANISOTROPY_USED 1113: tangent, 1114: binormal, anisotropy, 1115: #endif 1116: diffuse_light, specular_light); 1117: } 1118: #endif // !DISABLE_LIGHT_SPOT 1119: 1120: #endif // !MODE_UNSHADED 1121: 1122: #endif // !MODE_RENDER_DEPTH 1123: 1124: #if defined(USE_SHADOW_TO_OPACITY) 1125: alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0)); 1126: 1127: #if defined(ALPHA_SCISSOR_USED) 1128: if (alpha < alpha_scissor) { 1129: discard; 1130: } 1131: #endif // ALPHA_SCISSOR_USED 1132: 1133: #ifdef USE_OPAQUE_PREPASS 1134: #if !defined(ALPHA_SCISSOR_USED) 1135: 1136: if (alpha < opaque_prepass_threshold) { 1137: discard; 1138: } 1139: 1140: #endif // not ALPHA_SCISSOR_USED 1141: #endif // USE_OPAQUE_PREPASS 1142: 1143: #endif // USE_SHADOW_TO_OPACITY 1144: 1145: #ifdef MODE_RENDER_DEPTH 1146: //nothing happens, so a tree-ssa optimizer will result in no fragment shader :) 1147: #else // !MODE_RENDER_DEPTH 1148: 1149: #ifdef MODE_UNSHADED 1150: frag_color = vec4(albedo, alpha); 1151: #else 1152: 1153: diffuse_light *= albedo; 1154: 1155: diffuse_light *= 1.0 - metallic; 1156: ambient_light *= 1.0 - metallic; 1157: 1158: frag_color = vec4(diffuse_light + specular_light, alpha); 1159: #ifdef BASE_PASS 1160: frag_color.rgb += emission + ambient_light; 1161: #endif 1162: #endif //MODE_UNSHADED 1163: fog = vec4(unpackHalf2x16(fog_rg), unpackHalf2x16(fog_ba)); 1164: 1165: #ifndef DISABLE_FOG 1166: if (scene_data.fog_enabled) { 1167: #ifdef BASE_PASS 1168: frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a); 1169: #else 1170: frag_color.rgb *= (1.0 - fog.a); 1171: #endif // BASE_PASS 1172: } 1173: #endif 1174: 1175: // Tonemap before writing as we are writing to an sRGB framebuffer 1176: frag_color.rgb *= exposure; 1177: frag_color.rgb = apply_tonemapping(frag_color.rgb, white); 1178: frag_color.rgb = linear_to_srgb(frag_color.rgb); 1179: 1180: #ifdef USE_BCS 1181: frag_color.rgb = apply_bcs(frag_color.rgb, bcs); 1182: #endif 1183: 1184: #ifdef USE_COLOR_CORRECTION 1185: frag_color.rgb = apply_color_correction(frag_color.rgb, color_correction); 1186: #endif 1187: 1188: #endif //!MODE_RENDER_DEPTH 1189: } 1190: 1191: 1: #version 330 2: #define USE_GLES_OVER_GL 3: #define USE_RADIANCE_MAP 4: 5: #define MAX_GLOBAL_SHADER_UNIFORMS 256 6: 7: #define MAX_LIGHT_DATA_STRUCTS 32 8: 9: #define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS 8 10: 11: #define MAX_FORWARD_LIGHTS uint(8) 12: #define MODE_RENDER_DEPTH 13: #define USE_INSTANCING 14: 15: #ifdef USE_MULTIVIEW 16: #if defined(GL_OVR_multiview2) 17: #extension GL_OVR_multiview2 : require 18: #elif defined(GL_OVR_multiview) 19: #extension GL_OVR_multiview : require 20: #endif 21: #define ViewIndex gl_ViewID_OVR 22: #define MAX_VIEWS 2 23: #else 24: #define ViewIndex uint(0) 25: #define MAX_VIEWS 1 26: #endif 27: precision highp float; 28: precision highp int; 29: 30: // Default to SPECULAR_SCHLICK_GGX. 31: #if !defined(SPECULAR_DISABLED) && !defined(SPECULAR_SCHLICK_GGX) && !defined(SPECULAR_TOON) 32: #define SPECULAR_SCHLICK_GGX 33: #endif 34: 35: #if !defined(MODE_RENDER_DEPTH) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) ||defined(LIGHT_CLEARCOAT_USED) 36: #ifndef NORMAL_USED 37: #define NORMAL_USED 38: #endif 39: #endif 40: 41: #ifndef MODE_RENDER_DEPTH 42: #ifdef USE_BCS 43: uniform vec3 bcs; 44: #endif 45: 46: #ifdef USE_COLOR_CORRECTION 47: #ifdef USE_1D_LUT 48: uniform sampler2D source_color_correction; //texunit:-1 49: #else 50: uniform sampler3D source_color_correction; //texunit:-1 51: #endif 52: #endif 53: 54: layout(std140) uniform TonemapData { //ubo:0 55: float exposure; 56: float white; 57: int tonemapper; 58: int pad; 59: }; 60: 61: vec3 apply_bcs(vec3 color, vec3 bcs) { 62: color = mix(vec3(0.0), color, bcs.x); 63: color = mix(vec3(0.5), color, bcs.y); 64: color = mix(vec3(dot(vec3(1.0), color) * 0.33333), color, bcs.z); 65: 66: return color; 67: } 68: #ifdef USE_COLOR_CORRECTION 69: #ifdef USE_1D_LUT 70: vec3 apply_color_correction(vec3 color) { 71: color.r = texture(source_color_correction, vec2(color.r, 0.0f)).r; 72: color.g = texture(source_color_correction, vec2(color.g, 0.0f)).g; 73: color.b = texture(source_color_correction, vec2(color.b, 0.0f)).b; 74: return color; 75: } 76: #else 77: vec3 apply_color_correction(vec3 color) { 78: return textureLod(source_color_correction, color, 0.0).rgb; 79: } 80: #endif 81: #endif 82: 83: vec3 tonemap_filmic(vec3 color, float p_white) { 84: // exposure bias: input scale (color *= bias, white *= bias) to make the brightness consistent with other tonemappers 85: // also useful to scale the input to the range that the tonemapper is designed for (some require very high input values) 86: // has no effect on the curve's general shape or visual properties 87: const float exposure_bias = 2.0f; 88: const float A = 0.22f * exposure_bias * exposure_bias; // bias baked into constants for performance 89: const float B = 0.30f * exposure_bias; 90: const float C = 0.10f; 91: const float D = 0.20f; 92: const float E = 0.01f; 93: const float F = 0.30f; 94: 95: vec3 color_tonemapped = ((color * (A * color + C * B) + D * E) / (color * (A * color + B) + D * F)) - E / F; 96: float p_white_tonemapped = ((p_white * (A * p_white + C * B) + D * E) / (p_white * (A * p_white + B) + D * F)) - E / F; 97: 98: return color_tonemapped / p_white_tonemapped; 99: } 100: 101: // Adapted from https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl 102: // (MIT License). 103: vec3 tonemap_aces(vec3 color, float p_white) { 104: const float exposure_bias = 1.8f; 105: const float A = 0.0245786f; 106: const float B = 0.000090537f; 107: const float C = 0.983729f; 108: const float D = 0.432951f; 109: const float E = 0.238081f; 110: 111: // Exposure bias baked into transform to save shader instructions. Equivalent to `color *= exposure_bias` 112: const mat3 rgb_to_rrt = mat3( 113: vec3(0.59719f * exposure_bias, 0.35458f * exposure_bias, 0.04823f * exposure_bias), 114: vec3(0.07600f * exposure_bias, 0.90834f * exposure_bias, 0.01566f * exposure_bias), 115: vec3(0.02840f * exposure_bias, 0.13383f * exposure_bias, 0.83777f * exposure_bias)); 116: 117: const mat3 odt_to_rgb = mat3( 118: vec3(1.60475f, -0.53108f, -0.07367f), 119: vec3(-0.10208f, 1.10813f, -0.00605f), 120: vec3(-0.00327f, -0.07276f, 1.07602f)); 121: 122: color *= rgb_to_rrt; 123: vec3 color_tonemapped = (color * (color + A) - B) / (color * (C * color + D) + E); 124: color_tonemapped *= odt_to_rgb; 125: 126: p_white *= exposure_bias; 127: float p_white_tonemapped = (p_white * (p_white + A) - B) / (p_white * (C * p_white + D) + E); 128: 129: return color_tonemapped / p_white_tonemapped; 130: } 131: 132: vec3 tonemap_reinhard(vec3 color, float p_white) { 133: return (p_white * color + color) / (color * p_white + p_white); 134: } 135: 136: // This expects 0-1 range input. 137: vec3 linear_to_srgb(vec3 color) { 138: //color = clamp(color, vec3(0.0), vec3(1.0)); 139: //const vec3 a = vec3(0.055f); 140: //return mix((vec3(1.0f) + a) * pow(color.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * color.rgb, lessThan(color.rgb, vec3(0.0031308f))); 141: // Approximation from http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html 142: return max(vec3(1.055) * pow(color, vec3(0.416666667)) - vec3(0.055), vec3(0.0)); 143: } 144: 145: // This expects 0-1 range input, outside that range it behaves poorly. 146: vec3 srgb_to_linear(vec3 color) { 147: // Approximation from http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html 148: return color * (color * (color * 0.305306011 + 0.682171111) + 0.012522878); 149: } 150: 151: #define TONEMAPPER_LINEAR 0 152: #define TONEMAPPER_REINHARD 1 153: #define TONEMAPPER_FILMIC 2 154: #define TONEMAPPER_ACES 3 155: 156: vec3 apply_tonemapping(vec3 color, float p_white) { // inputs are LINEAR, always outputs clamped [0;1] color 157: // Ensure color values passed to tonemappers are positive. 158: // They can be negative in the case of negative lights, which leads to undesired behavior. 159: if (tonemapper == TONEMAPPER_LINEAR) { 160: return color; 161: } else if (tonemapper == TONEMAPPER_REINHARD) { 162: return tonemap_reinhard(max(vec3(0.0f), color), p_white); 163: } else if (tonemapper == TONEMAPPER_FILMIC) { 164: return tonemap_filmic(max(vec3(0.0f), color), p_white); 165: } else { // TONEMAPPER_ACES 166: return tonemap_aces(max(vec3(0.0f), color), p_white); 167: } 168: } 169: #endif 170: 171: #ifdef USE_GLES_OVER_GL 172: // Floating point pack/unpack functions are part of the GLSL ES 300 specification used by web and mobile. 173: uint float2half(uint f) { 174: uint e = f & uint(0x7f800000); 175: if (e <= uint(0x38000000)) { 176: return uint(0); 177: } else { 178: return ((f >> uint(16)) & uint(0x8000)) | 179: (((e - uint(0x38000000)) >> uint(13)) & uint(0x7c00)) | 180: ((f >> uint(13)) & uint(0x03ff)); 181: } 182: } 183: 184: uint half2float(uint h) { 185: uint h_e = h & uint(0x7c00); 186: return ((h & uint(0x8000)) << uint(16)) | uint((h_e >> uint(10)) != uint(0)) * (((h_e + uint(0x1c000)) << uint(13)) | ((h & uint(0x03ff)) << uint(13))); 187: } 188: 189: uint packHalf2x16(vec2 v) { 190: return float2half(floatBitsToUint(v.x)) | float2half(floatBitsToUint(v.y)) << uint(16); 191: } 192: 193: vec2 unpackHalf2x16(uint v) { 194: return vec2(uintBitsToFloat(half2float(v & uint(0xffff))), 195: uintBitsToFloat(half2float(v >> uint(16)))); 196: } 197: 198: uint packUnorm2x16(vec2 v) { 199: uvec2 uv = uvec2(round(clamp(v, vec2(0.0), vec2(1.0)) * 65535.0)); 200: return uv.x | uv.y << uint(16); 201: } 202: 203: vec2 unpackUnorm2x16(uint p) { 204: return vec2(float(p & uint(0xffff)), float(p >> uint(16))) * 0.000015259021; // 1.0 / 65535.0 optimization 205: } 206: 207: uint packSnorm2x16(vec2 v) { 208: uvec2 uv = uvec2(round(clamp(v, vec2(-1.0), vec2(1.0)) * 32767.0) + 32767.0); 209: return uv.x | uv.y << uint(16); 210: } 211: 212: vec2 unpackSnorm2x16(uint p) { 213: vec2 v = vec2(float(p & uint(0xffff)), float(p >> uint(16))); 214: return clamp((v - 32767.0) * vec2(0.00003051851), vec2(-1.0), vec2(1.0)); 215: } 216: 217: #endif 218: 219: // Compatibility renames. These are exposed with the "godot_" prefix 220: // to work around an Adreno bug which was exposing these ES310 functions 221: // in ES300 shaders. Internally, we must use the "godot_" prefix, but user shaders 222: // will be mapped automatically. 223: uint godot_packUnorm4x8(vec4 v) { 224: uvec4 uv = uvec4(round(clamp(v, vec4(0.0), vec4(1.0)) * 255.0)); 225: return uv.x | (uv.y << uint(8)) | (uv.z << uint(16)) | (uv.w << uint(24)); 226: } 227: 228: vec4 godot_unpackUnorm4x8(uint p) { 229: return vec4(float(p & uint(0xff)), float((p >> uint(8)) & uint(0xff)), float((p >> uint(16)) & uint(0xff)), float(p >> uint(24))) * 0.00392156862; // 1.0 / 255.0 230: } 231: 232: uint godot_packSnorm4x8(vec4 v) { 233: uvec4 uv = uvec4(round(clamp(v, vec4(-1.0), vec4(1.0)) * 127.0) + 127.0); 234: return uv.x | uv.y << uint(8) | uv.z << uint(16) | uv.w << uint(24); 235: } 236: 237: vec4 godot_unpackSnorm4x8(uint p) { 238: vec4 v = vec4(float(p & uint(0xff)), float((p >> uint(8)) & uint(0xff)), float((p >> uint(16)) & uint(0xff)), float(p >> uint(24))); 239: return clamp((v - vec4(127.0)) * vec4(0.00787401574), vec4(-1.0), vec4(1.0)); 240: } 241: 242: #define packUnorm4x8 godot_packUnorm4x8 243: #define unpackUnorm4x8 godot_unpackUnorm4x8 244: #define packSnorm4x8 godot_packSnorm4x8 245: #define unpackSnorm4x8 godot_unpackSnorm4x8 246: 247: /* texture unit usage, N is max_texture_unity-N 248: 249: 1-color correction // In tonemap_inc.glsl 250: 2-radiance 251: 3-directional_shadow 252: 4-positional_shadow 253: 5-screen 254: 6-depth 255: 256: */ 257: 258: #define M_PI 3.14159265359 259: /* clang-format on */ 260: 261: #define SHADER_IS_SRGB true 262: 263: /* Varyings */ 264: 265: #if defined(COLOR_USED) 266: in vec4 color_interp; 267: #endif 268: 269: #if defined(UV_USED) 270: in vec2 uv_interp; 271: #endif 272: 273: #if defined(UV2_USED) 274: in vec2 uv2_interp; 275: #else 276: #ifdef USE_LIGHTMAP 277: in vec2 uv2_interp; 278: #endif 279: #endif 280: 281: #if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) 282: in vec3 tangent_interp; 283: in vec3 binormal_interp; 284: #endif 285: 286: #ifdef NORMAL_USED 287: in vec3 normal_interp; 288: #endif 289: 290: in highp vec3 vertex_interp; 291: 292: #ifdef USE_RADIANCE_MAP 293: 294: #define RADIANCE_MAX_LOD 5.0 295: 296: uniform samplerCube radiance_map; // texunit:-2 297: 298: #endif 299: 300: layout(std140) uniform GlobalShaderUniformData { //ubo:1 301: vec4 global_shader_uniforms[MAX_GLOBAL_SHADER_UNIFORMS]; 302: }; 303: 304: /* Material Uniforms */ 305: 306: #ifdef MATERIAL_UNIFORMS_USED 307: 308: /* clang-format off */ 309: layout(std140) uniform MaterialUniforms { // ubo:3 310: 311: 312: }; 313: /* clang-format on */ 314: 315: #endif 316: 317: layout(std140) uniform SceneData { // ubo:2 318: highp mat4 projection_matrix; 319: highp mat4 inv_projection_matrix; 320: highp mat4 inv_view_matrix; 321: highp mat4 view_matrix; 322: 323: vec2 viewport_size; 324: vec2 screen_pixel_size; 325: 326: mediump vec4 ambient_light_color_energy; 327: 328: mediump float ambient_color_sky_mix; 329: bool material_uv2_mode; 330: float emissive_exposure_normalization; 331: bool use_ambient_light; 332: bool use_ambient_cubemap; 333: bool use_reflection_cubemap; 334: 335: float fog_aerial_perspective; 336: float time; 337: 338: mat3 radiance_inverse_xform; 339: 340: uint directional_light_count; 341: float z_far; 342: float z_near; 343: float IBL_exposure_normalization; 344: 345: bool fog_enabled; 346: float fog_density; 347: float fog_height; 348: float fog_height_density; 349: 350: vec3 fog_light_color; 351: float fog_sun_scatter; 352: uint camera_visible_layers; 353: uint pad3; 354: uint pad4; 355: uint pad5; 356: } 357: scene_data; 358: 359: #ifdef USE_MULTIVIEW 360: layout(std140) uniform MultiviewData { // ubo:8 361: highp mat4 projection_matrix_view[MAX_VIEWS]; 362: highp mat4 inv_projection_matrix_view[MAX_VIEWS]; 363: highp vec4 eye_offset[MAX_VIEWS]; 364: } 365: multiview_data; 366: #endif 367: 368: /* clang-format off */ 369: 370: 371: /* clang-format on */ 372: 373: // Directional light data. 374: #ifndef DISABLE_LIGHT_DIRECTIONAL 375: 376: struct DirectionalLightData { 377: mediump vec3 direction; 378: mediump float energy; 379: mediump vec3 color; 380: mediump float size; 381: mediump vec3 pad; 382: mediump float specular; 383: }; 384: 385: layout(std140) uniform DirectionalLights { // ubo:7 386: DirectionalLightData directional_lights[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS]; 387: }; 388: 389: #endif // !DISABLE_LIGHT_DIRECTIONAL 390: 391: // Omni and spot light data. 392: #if !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) 393: 394: struct LightData { // This structure needs to be as packed as possible. 395: highp vec3 position; 396: highp float inv_radius; 397: 398: mediump vec3 direction; 399: highp float size; 400: 401: mediump vec3 color; 402: mediump float attenuation; 403: 404: mediump float cone_attenuation; 405: mediump float cone_angle; 406: mediump float specular_amount; 407: mediump float shadow_opacity; 408: }; 409: 410: #ifndef DISABLE_LIGHT_OMNI 411: layout(std140) uniform OmniLightData { // ubo:5 412: LightData omni_lights[MAX_LIGHT_DATA_STRUCTS]; 413: }; 414: uniform uint omni_light_indices[MAX_FORWARD_LIGHTS]; 415: uniform uint omni_light_count; 416: #endif 417: 418: #ifndef DISABLE_LIGHT_SPOT 419: layout(std140) uniform SpotLightData { // ubo:6 420: LightData spot_lights[MAX_LIGHT_DATA_STRUCTS]; 421: }; 422: uniform uint spot_light_indices[MAX_FORWARD_LIGHTS]; 423: uniform uint spot_light_count; 424: #endif 425: 426: #ifdef USE_ADDITIVE_LIGHTING 427: uniform highp samplerCubeShadow positional_shadow; // texunit:-4 428: #endif 429: 430: #endif // !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) 431: 432: #ifdef USE_MULTIVIEW 433: uniform highp sampler2DArray depth_buffer; // texunit:-6 434: uniform highp sampler2DArray color_buffer; // texunit:-5 435: vec3 multiview_uv(vec2 uv) { 436: return vec3(uv, ViewIndex); 437: } 438: #else 439: uniform highp sampler2D depth_buffer; // texunit:-6 440: uniform highp sampler2D color_buffer; // texunit:-5 441: vec2 multiview_uv(vec2 uv) { 442: return uv; 443: } 444: #endif 445: 446: uniform highp mat4 world_transform; 447: uniform mediump float opaque_prepass_threshold; 448: 449: layout(location = 0) out vec4 frag_color; 450: 451: vec3 F0(float metallic, float specular, vec3 albedo) { 452: float dielectric = 0.16 * specular * specular; 453: // use albedo * metallic as colored specular reflectance at 0 angle for metallic materials; 454: // see https://google.github.io/filament/Filament.md.html 455: return mix(vec3(dielectric), albedo, vec3(metallic)); 456: } 457: 458: #if !defined(DISABLE_LIGHT_DIRECTIONAL) || !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) 459: 460: float D_GGX(float cos_theta_m, float alpha) { 461: float a = cos_theta_m * alpha; 462: float k = alpha / (1.0 - cos_theta_m * cos_theta_m + a * a); 463: return k * k * (1.0 / M_PI); 464: } 465: 466: // From Earl Hammon, Jr. "PBR Diffuse Lighting for GGX+Smith Microsurfaces" https://www.gdcvault.com/play/1024478/PBR-Diffuse-Lighting-for-GGX 467: float V_GGX(float NdotL, float NdotV, float alpha) { 468: return 0.5 / mix(2.0 * NdotL * NdotV, NdotL + NdotV, alpha); 469: } 470: 471: float D_GGX_anisotropic(float cos_theta_m, float alpha_x, float alpha_y, float cos_phi, float sin_phi) { 472: float alpha2 = alpha_x * alpha_y; 473: highp vec3 v = vec3(alpha_y * cos_phi, alpha_x * sin_phi, alpha2 * cos_theta_m); 474: highp float v2 = dot(v, v); 475: float w2 = alpha2 / v2; 476: float D = alpha2 * w2 * w2 * (1.0 / M_PI); 477: return D; 478: } 479: 480: float V_GGX_anisotropic(float alpha_x, float alpha_y, float TdotV, float TdotL, float BdotV, float BdotL, float NdotV, float NdotL) { 481: float Lambda_V = NdotL * length(vec3(alpha_x * TdotV, alpha_y * BdotV, NdotV)); 482: float Lambda_L = NdotV * length(vec3(alpha_x * TdotL, alpha_y * BdotL, NdotL)); 483: return 0.5 / (Lambda_V + Lambda_L); 484: } 485: 486: float SchlickFresnel(float u) { 487: float m = 1.0 - u; 488: float m2 = m * m; 489: return m2 * m2 * m; // pow(m,5) 490: } 491: 492: void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float attenuation, vec3 f0, float roughness, float metallic, float specular_amount, vec3 albedo, inout float alpha, 493: #ifdef LIGHT_BACKLIGHT_USED 494: vec3 backlight, 495: #endif 496: #ifdef LIGHT_RIM_USED 497: float rim, float rim_tint, 498: #endif 499: #ifdef LIGHT_CLEARCOAT_USED 500: float clearcoat, float clearcoat_roughness, vec3 vertex_normal, 501: #endif 502: #ifdef LIGHT_ANISOTROPY_USED 503: vec3 B, vec3 T, float anisotropy, 504: #endif 505: inout vec3 diffuse_light, inout vec3 specular_light) { 506: 507: #if defined(USE_LIGHT_SHADER_CODE) 508: // light is written by the light shader 509: 510: vec3 normal = N; 511: vec3 light = L; 512: vec3 view = V; 513: 514: /* clang-format off */ 515: 516: 517: /* clang-format on */ 518: 519: #else 520: float NdotL = min(A + dot(N, L), 1.0); 521: float cNdotL = max(NdotL, 0.0); // clamped NdotL 522: float NdotV = dot(N, V); 523: float cNdotV = max(NdotV, 1e-4); 524: 525: #if defined(DIFFUSE_BURLEY) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED) 526: vec3 H = normalize(V + L); 527: #endif 528: 529: #if defined(SPECULAR_SCHLICK_GGX) 530: float cNdotH = clamp(A + dot(N, H), 0.0, 1.0); 531: #endif 532: 533: #if defined(DIFFUSE_BURLEY) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED) 534: float cLdotH = clamp(A + dot(L, H), 0.0, 1.0); 535: #endif 536: 537: if (metallic < 1.0) { 538: float diffuse_brdf_NL; // BRDF times N.L for calculating diffuse radiance 539: 540: #if defined(DIFFUSE_LAMBERT_WRAP) 541: // Energy conserving lambert wrap shader. 542: // https://web.archive.org/web/20210228210901/http://blog.stevemcauley.com/2011/12/03/energy-conserving-wrapped-diffuse/ 543: diffuse_brdf_NL = max(0.0, (NdotL + roughness) / ((1.0 + roughness) * (1.0 + roughness))) * (1.0 / M_PI); 544: #elif defined(DIFFUSE_TOON) 545: diffuse_brdf_NL = smoothstep(-roughness, max(roughness, 0.01), NdotL) * (1.0 / M_PI); 546: #elif defined(DIFFUSE_BURLEY) 547: { 548: float FD90_minus_1 = 2.0 * cLdotH * cLdotH * roughness - 0.5; 549: float FdV = 1.0 + FD90_minus_1 * SchlickFresnel(cNdotV); 550: float FdL = 1.0 + FD90_minus_1 * SchlickFresnel(cNdotL); 551: diffuse_brdf_NL = (1.0 / M_PI) * FdV * FdL * cNdotL; 552: } 553: #else 554: // Lambert 555: diffuse_brdf_NL = cNdotL * (1.0 / M_PI); 556: #endif 557: 558: diffuse_light += light_color * diffuse_brdf_NL * attenuation; 559: 560: #if defined(LIGHT_BACKLIGHT_USED) 561: diffuse_light += light_color * (vec3(1.0 / M_PI) - diffuse_brdf_NL) * backlight * attenuation; 562: #endif 563: 564: #if defined(LIGHT_RIM_USED) 565: // Epsilon min to prevent pow(0, 0) singularity which results in undefined behavior. 566: float rim_light = pow(max(1e-4, 1.0 - cNdotV), max(0.0, (1.0 - roughness) * 16.0)); 567: diffuse_light += rim_light * rim * mix(vec3(1.0), albedo, rim_tint) * light_color; 568: #endif 569: } 570: 571: if (roughness > 0.0) { // FIXME: roughness == 0 should not disable specular light entirely 572: 573: // D 574: 575: #if defined(SPECULAR_TOON) 576: 577: vec3 R = normalize(-reflect(L, N)); 578: float RdotV = dot(R, V); 579: float mid = 1.0 - roughness; 580: mid *= mid; 581: float intensity = smoothstep(mid - roughness * 0.5, mid + roughness * 0.5, RdotV) * mid; 582: diffuse_light += light_color * intensity * attenuation * specular_amount; // write to diffuse_light, as in toon shading you generally want no reflection 583: 584: #elif defined(SPECULAR_DISABLED) 585: // none.. 586: 587: #elif defined(SPECULAR_SCHLICK_GGX) 588: // shlick+ggx as default 589: float alpha_ggx = roughness * roughness; 590: #if defined(LIGHT_ANISOTROPY_USED) 591: float aspect = sqrt(1.0 - anisotropy * 0.9); 592: float ax = alpha_ggx / aspect; 593: float ay = alpha_ggx * aspect; 594: float XdotH = dot(T, H); 595: float YdotH = dot(B, H); 596: float D = D_GGX_anisotropic(cNdotH, ax, ay, XdotH, YdotH); 597: float G = V_GGX_anisotropic(ax, ay, dot(T, V), dot(T, L), dot(B, V), dot(B, L), cNdotV, cNdotL); 598: #else 599: float D = D_GGX(cNdotH, alpha_ggx); 600: float G = V_GGX(cNdotL, cNdotV, alpha_ggx); 601: #endif // LIGHT_ANISOTROPY_USED 602: // F 603: float cLdotH5 = SchlickFresnel(cLdotH); 604: // Calculate Fresnel using cheap approximate specular occlusion term from Filament: 605: // https://google.github.io/filament/Filament.html#lighting/occlusion/specularocclusion 606: float f90 = clamp(50.0 * f0.g, 0.0, 1.0); 607: vec3 F = f0 + (f90 - f0) * cLdotH5; 608: 609: vec3 specular_brdf_NL = cNdotL * D * F * G; 610: 611: specular_light += specular_brdf_NL * light_color * attenuation * specular_amount; 612: #endif 613: 614: #if defined(LIGHT_CLEARCOAT_USED) 615: // Clearcoat ignores normal_map, use vertex normal instead 616: float ccNdotL = max(min(A + dot(vertex_normal, L), 1.0), 0.0); 617: float ccNdotH = clamp(A + dot(vertex_normal, H), 0.0, 1.0); 618: float ccNdotV = max(dot(vertex_normal, V), 1e-4); 619: 620: #if !defined(SPECULAR_SCHLICK_GGX) 621: float cLdotH5 = SchlickFresnel(cLdotH); 622: #endif 623: float Dr = D_GGX(ccNdotH, mix(0.001, 0.1, clearcoat_roughness)); 624: float Gr = 0.25 / (cLdotH * cLdotH); 625: float Fr = mix(.04, 1.0, cLdotH5); 626: float clearcoat_specular_brdf_NL = clearcoat * Gr * Fr * Dr * cNdotL; 627: 628: specular_light += clearcoat_specular_brdf_NL * light_color * attenuation * specular_amount; 629: // TODO: Clearcoat adds light to the scene right now (it is non-energy conserving), both diffuse and specular need to be scaled by (1.0 - FR) 630: // but to do so we need to rearrange this entire function 631: #endif // LIGHT_CLEARCOAT_USED 632: } 633: 634: #ifdef USE_SHADOW_TO_OPACITY 635: alpha = min(alpha, clamp(1.0 - attenuation, 0.0, 1.0)); 636: #endif 637: 638: #endif // LIGHT_CODE_USED 639: } 640: 641: float get_omni_spot_attenuation(float distance, float inv_range, float decay) { 642: float nd = distance * inv_range; 643: nd *= nd; 644: nd *= nd; // nd^4 645: nd = max(1.0 - nd, 0.0); 646: nd *= nd; // nd^2 647: return nd * pow(max(distance, 0.0001), -decay); 648: } 649: 650: #ifndef DISABLE_LIGHT_OMNI 651: void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f0, float roughness, float metallic, float shadow, vec3 albedo, inout float alpha, 652: #ifdef LIGHT_BACKLIGHT_USED 653: vec3 backlight, 654: #endif 655: #ifdef LIGHT_RIM_USED 656: float rim, float rim_tint, 657: #endif 658: #ifdef LIGHT_CLEARCOAT_USED 659: float clearcoat, float clearcoat_roughness, vec3 vertex_normal, 660: #endif 661: #ifdef LIGHT_ANISOTROPY_USED 662: vec3 binormal, vec3 tangent, float anisotropy, 663: #endif 664: inout vec3 diffuse_light, inout vec3 specular_light) { 665: vec3 light_rel_vec = omni_lights[idx].position - vertex; 666: float light_length = length(light_rel_vec); 667: float omni_attenuation = get_omni_spot_attenuation(light_length, omni_lights[idx].inv_radius, omni_lights[idx].attenuation); 668: vec3 color = omni_lights[idx].color; 669: float size_A = 0.0; 670: 671: if (omni_lights[idx].size > 0.0) { 672: float t = omni_lights[idx].size / max(0.001, light_length); 673: size_A = max(0.0, 1.0 - 1.0 / sqrt(1.0 + t * t)); 674: } 675: 676: light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color, omni_attenuation, f0, roughness, metallic, omni_lights[idx].specular_amount, albedo, alpha, 677: #ifdef LIGHT_BACKLIGHT_USED 678: backlight, 679: #endif 680: #ifdef LIGHT_RIM_USED 681: rim * omni_attenuation, rim_tint, 682: #endif 683: #ifdef LIGHT_CLEARCOAT_USED 684: clearcoat, clearcoat_roughness, vertex_normal, 685: #endif 686: #ifdef LIGHT_ANISOTROPY_USED 687: binormal, tangent, anisotropy, 688: #endif 689: diffuse_light, 690: specular_light); 691: } 692: #endif // !DISABLE_LIGHT_OMNI 693: 694: #ifndef DISABLE_LIGHT_SPOT 695: void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f0, float roughness, float metallic, float shadow, vec3 albedo, inout float alpha, 696: #ifdef LIGHT_BACKLIGHT_USED 697: vec3 backlight, 698: #endif 699: #ifdef LIGHT_RIM_USED 700: float rim, float rim_tint, 701: #endif 702: #ifdef LIGHT_CLEARCOAT_USED 703: float clearcoat, float clearcoat_roughness, vec3 vertex_normal, 704: #endif 705: #ifdef LIGHT_ANISOTROPY_USED 706: vec3 binormal, vec3 tangent, float anisotropy, 707: #endif 708: inout vec3 diffuse_light, 709: inout vec3 specular_light) { 710: 711: vec3 light_rel_vec = spot_lights[idx].position - vertex; 712: float light_length = length(light_rel_vec); 713: float spot_attenuation = get_omni_spot_attenuation(light_length, spot_lights[idx].inv_radius, spot_lights[idx].attenuation); 714: vec3 spot_dir = spot_lights[idx].direction; 715: float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_lights[idx].cone_angle); 716: float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_lights[idx].cone_angle)); 717: spot_attenuation *= 1.0 - pow(spot_rim, spot_lights[idx].cone_attenuation); 718: vec3 color = spot_lights[idx].color; 719: 720: float size_A = 0.0; 721: 722: if (spot_lights[idx].size > 0.0) { 723: float t = spot_lights[idx].size / max(0.001, light_length); 724: size_A = max(0.0, 1.0 - 1.0 / sqrt(1.0 + t * t)); 725: } 726: 727: light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color, spot_attenuation, f0, roughness, metallic, spot_lights[idx].specular_amount, albedo, alpha, 728: #ifdef LIGHT_BACKLIGHT_USED 729: backlight, 730: #endif 731: #ifdef LIGHT_RIM_USED 732: rim * spot_attenuation, rim_tint, 733: #endif 734: #ifdef LIGHT_CLEARCOAT_USED 735: clearcoat, clearcoat_roughness, vertex_normal, 736: #endif 737: #ifdef LIGHT_ANISOTROPY_USED 738: binormal, tangent, anisotropy, 739: #endif 740: diffuse_light, specular_light); 741: } 742: #endif // !DISABLE_LIGHT_SPOT 743: 744: #endif // !defined(DISABLE_LIGHT_DIRECTIONAL) || !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) 745: 746: #ifndef MODE_RENDER_DEPTH 747: vec4 fog_process(vec3 vertex) { 748: vec3 fog_color = scene_data.fog_light_color; 749: 750: #ifdef USE_RADIANCE_MAP 751: /* 752: if (scene_data.fog_aerial_perspective > 0.0) { 753: vec3 sky_fog_color = vec3(0.0); 754: vec3 cube_view = scene_data.radiance_inverse_xform * vertex; 755: // mip_level always reads from the second mipmap and higher so the fog is always slightly blurred 756: float mip_level = mix(1.0 / MAX_ROUGHNESS_LOD, 1.0, 1.0 - (abs(vertex.z) - scene_data.z_near) / (scene_data.z_far - scene_data.z_near)); 757: 758: sky_fog_color = textureLod(radiance_map, cube_view, mip_level * RADIANCE_MAX_LOD).rgb; 759: 760: fog_color = mix(fog_color, sky_fog_color, scene_data.fog_aerial_perspective); 761: } 762: */ 763: #endif 764: 765: #ifndef DISABLE_LIGHT_DIRECTIONAL 766: if (scene_data.fog_sun_scatter > 0.001) { 767: vec4 sun_scatter = vec4(0.0); 768: float sun_total = 0.0; 769: vec3 view = normalize(vertex); 770: for (uint i = uint(0); i < scene_data.directional_light_count; i++) { 771: vec3 light_color = directional_lights[i].color * directional_lights[i].energy; 772: float light_amount = pow(max(dot(view, directional_lights[i].direction), 0.0), 8.0); 773: fog_color += light_color * light_amount * scene_data.fog_sun_scatter; 774: } 775: } 776: #endif // !DISABLE_LIGHT_DIRECTIONAL 777: 778: float fog_amount = 1.0 - exp(min(0.0, -length(vertex) * scene_data.fog_density)); 779: 780: if (abs(scene_data.fog_height_density) >= 0.0001) { 781: float y = (scene_data.inv_view_matrix * vec4(vertex, 1.0)).y; 782: 783: float y_dist = y - scene_data.fog_height; 784: 785: float vfog_amount = 1.0 - exp(min(0.0, y_dist * scene_data.fog_height_density)); 786: 787: fog_amount = max(vfog_amount, fog_amount); 788: } 789: 790: return vec4(fog_color, fog_amount); 791: } 792: 793: #endif // !MODE_RENDER_DEPTH 794: 795: void main() { 796: //lay out everything, whatever is unused is optimized away anyway 797: vec3 vertex = vertex_interp; 798: #ifdef USE_MULTIVIEW 799: vec3 eye_offset = multiview_data.eye_offset[ViewIndex].xyz; 800: vec3 view = -normalize(vertex_interp - eye_offset); 801: mat4 projection_matrix = multiview_data.projection_matrix_view[ViewIndex]; 802: mat4 inv_projection_matrix = multiview_data.inv_projection_matrix_view[ViewIndex]; 803: #else 804: vec3 eye_offset = vec3(0.0, 0.0, 0.0); 805: vec3 view = -normalize(vertex_interp); 806: mat4 projection_matrix = scene_data.projection_matrix; 807: mat4 inv_projection_matrix = scene_data.inv_projection_matrix; 808: #endif 809: highp mat4 model_matrix = world_transform; 810: vec3 albedo = vec3(1.0); 811: vec3 backlight = vec3(0.0); 812: vec4 transmittance_color = vec4(0.0, 0.0, 0.0, 1.0); 813: float transmittance_depth = 0.0; 814: float transmittance_boost = 0.0; 815: float metallic = 0.0; 816: float specular = 0.5; 817: vec3 emission = vec3(0.0); 818: float roughness = 1.0; 819: float rim = 0.0; 820: float rim_tint = 0.0; 821: float clearcoat = 0.0; 822: float clearcoat_roughness = 0.0; 823: float anisotropy = 0.0; 824: vec2 anisotropy_flow = vec2(1.0, 0.0); 825: vec4 fog = vec4(0.0); 826: #if defined(CUSTOM_RADIANCE_USED) 827: vec4 custom_radiance = vec4(0.0); 828: #endif 829: #if defined(CUSTOM_IRRADIANCE_USED) 830: vec4 custom_irradiance = vec4(0.0); 831: #endif 832: 833: float ao = 1.0; 834: float ao_light_affect = 0.0; 835: 836: float alpha = 1.0; 837: 838: #if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) 839: vec3 binormal = normalize(binormal_interp); 840: vec3 tangent = normalize(tangent_interp); 841: #else 842: vec3 binormal = vec3(0.0); 843: vec3 tangent = vec3(0.0); 844: #endif 845: 846: #ifdef NORMAL_USED 847: vec3 normal = normalize(normal_interp); 848: 849: #if defined(DO_SIDE_CHECK) 850: if (!gl_FrontFacing) { 851: normal = -normal; 852: } 853: #endif 854: 855: #endif //NORMAL_USED 856: 857: #ifdef UV_USED 858: vec2 uv = uv_interp; 859: #endif 860: 861: #if defined(UV2_USED) || defined(USE_LIGHTMAP) 862: vec2 uv2 = uv2_interp; 863: #endif 864: 865: #if defined(COLOR_USED) 866: vec4 color = color_interp; 867: #endif 868: 869: #if defined(NORMAL_MAP_USED) 870: 871: vec3 normal_map = vec3(0.5); 872: #endif 873: 874: float normal_map_depth = 1.0; 875: 876: vec2 screen_uv = gl_FragCoord.xy * scene_data.screen_pixel_size; 877: 878: float sss_strength = 0.0; 879: 880: #ifdef ALPHA_SCISSOR_USED 881: float alpha_scissor_threshold = 1.0; 882: #endif // ALPHA_SCISSOR_USED 883: 884: #ifdef ALPHA_HASH_USED 885: float alpha_hash_scale = 1.0; 886: #endif // ALPHA_HASH_USED 887: 888: #ifdef ALPHA_ANTIALIASING_EDGE_USED 889: float alpha_antialiasing_edge = 0.0; 890: vec2 alpha_texture_coordinate = vec2(0.0, 0.0); 891: #endif // ALPHA_ANTIALIASING_EDGE_USED 892: { 893: } 894: 895: #ifndef USE_SHADOW_TO_OPACITY 896: 897: #if defined(ALPHA_SCISSOR_USED) 898: if (alpha < alpha_scissor_threshold) { 899: discard; 900: } 901: #endif // ALPHA_SCISSOR_USED 902: 903: #ifdef USE_OPAQUE_PREPASS 904: #if !defined(ALPHA_SCISSOR_USED) 905: 906: if (alpha < opaque_prepass_threshold) { 907: discard; 908: } 909: 910: #endif // not ALPHA_SCISSOR_USED 911: #endif // USE_OPAQUE_PREPASS 912: 913: #endif // !USE_SHADOW_TO_OPACITY 914: 915: #ifdef NORMAL_MAP_USED 916: 917: normal_map.xy = normal_map.xy * 2.0 - 1.0; 918: normal_map.z = sqrt(max(0.0, 1.0 - dot(normal_map.xy, normal_map.xy))); //always ignore Z, as it can be RG packed, Z may be pos/neg, etc. 919: 920: normal = normalize(mix(normal, tangent * normal_map.x + binormal * normal_map.y + normal * normal_map.z, normal_map_depth)); 921: 922: #endif 923: 924: #ifdef LIGHT_ANISOTROPY_USED 925: 926: if (anisotropy > 0.01) { 927: //rotation matrix 928: mat3 rot = mat3(tangent, binormal, normal); 929: //make local to space 930: tangent = normalize(rot * vec3(anisotropy_flow.x, anisotropy_flow.y, 0.0)); 931: binormal = normalize(rot * vec3(-anisotropy_flow.y, anisotropy_flow.x, 0.0)); 932: } 933: 934: #endif 935: 936: #ifndef MODE_RENDER_DEPTH 937: 938: #ifndef CUSTOM_FOG_USED 939: #ifndef DISABLE_FOG 940: // fog must be processed as early as possible and then packed. 941: // to maximize VGPR usage 942: 943: if (scene_data.fog_enabled) { 944: fog = fog_process(vertex); 945: } 946: #endif // !DISABLE_FOG 947: #endif // !CUSTOM_FOG_USED 948: 949: uint fog_rg = packHalf2x16(fog.rg); 950: uint fog_ba = packHalf2x16(fog.ba); 951: 952: // Convert colors to linear 953: albedo = srgb_to_linear(albedo); 954: emission = srgb_to_linear(emission); 955: // TODO Backlight and transmittance when used 956: #ifndef MODE_UNSHADED 957: vec3 f0 = F0(metallic, specular, albedo); 958: vec3 specular_light = vec3(0.0, 0.0, 0.0); 959: vec3 diffuse_light = vec3(0.0, 0.0, 0.0); 960: vec3 ambient_light = vec3(0.0, 0.0, 0.0); 961: 962: #ifdef BASE_PASS 963: /////////////////////// LIGHTING ////////////////////////////// 964: 965: // IBL precalculations 966: float ndotv = clamp(dot(normal, view), 0.0, 1.0); 967: vec3 F = f0 + (max(vec3(1.0 - roughness), f0) - f0) * pow(1.0 - ndotv, 5.0); 968: 969: #ifdef USE_RADIANCE_MAP 970: if (scene_data.use_reflection_cubemap) { 971: #ifdef LIGHT_ANISOTROPY_USED 972: // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy 973: vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent; 974: vec3 anisotropic_tangent = cross(anisotropic_direction, view); 975: vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction); 976: vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0))); 977: vec3 ref_vec = reflect(-view, bent_normal); 978: #else 979: vec3 ref_vec = reflect(-view, normal); 980: #endif 981: ref_vec = mix(ref_vec, normal, roughness * roughness); 982: float horizon = min(1.0 + dot(ref_vec, normal), 1.0); 983: ref_vec = scene_data.radiance_inverse_xform * ref_vec; 984: specular_light = textureLod(radiance_map, ref_vec, sqrt(roughness) * RADIANCE_MAX_LOD).rgb; 985: specular_light = srgb_to_linear(specular_light); 986: specular_light *= horizon * horizon; 987: specular_light *= scene_data.ambient_light_color_energy.a; 988: } 989: #endif 990: 991: // Calculate Reflection probes 992: // Calculate Lightmaps 993: 994: #if defined(CUSTOM_RADIANCE_USED) 995: specular_light = mix(specular_light, custom_radiance.rgb, custom_radiance.a); 996: #endif // CUSTOM_RADIANCE_USED 997: 998: #ifndef USE_LIGHTMAP 999: //lightmap overrides everything 1000: if (scene_data.use_ambient_light) { 1001: ambient_light = scene_data.ambient_light_color_energy.rgb; 1002: #ifdef USE_RADIANCE_MAP 1003: if (scene_data.use_ambient_cubemap) { 1004: vec3 ambient_dir = scene_data.radiance_inverse_xform * normal; 1005: vec3 cubemap_ambient = textureLod(radiance_map, ambient_dir, RADIANCE_MAX_LOD).rgb; 1006: cubemap_ambient = srgb_to_linear(cubemap_ambient); 1007: ambient_light = mix(ambient_light, cubemap_ambient * scene_data.ambient_light_color_energy.a, scene_data.ambient_color_sky_mix); 1008: } 1009: #endif 1010: } 1011: #endif // USE_LIGHTMAP 1012: 1013: #if defined(CUSTOM_IRRADIANCE_USED) 1014: ambient_light = mix(ambient_light, custom_irradiance.rgb, custom_irradiance.a); 1015: #endif // CUSTOM_IRRADIANCE_USED 1016: 1017: { 1018: #if defined(AMBIENT_LIGHT_DISABLED) 1019: ambient_light = vec3(0.0, 0.0, 0.0); 1020: #else 1021: ambient_light *= albedo.rgb; 1022: ambient_light *= ao; 1023: #endif // AMBIENT_LIGHT_DISABLED 1024: } 1025: 1026: // convert ao to direct light ao 1027: ao = mix(1.0, ao, ao_light_affect); 1028: 1029: { 1030: #if defined(DIFFUSE_TOON) 1031: //simplify for toon, as 1032: specular_light *= specular * metallic * albedo * 2.0; 1033: #else 1034: 1035: // scales the specular reflections, needs to be be computed before lighting happens, 1036: // but after environment, GI, and reflection probes are added 1037: // Environment brdf approximation (Lazarov 2013) 1038: // see https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile 1039: const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022); 1040: const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04); 1041: vec4 r = roughness * c0 + c1; 1042: float ndotv = clamp(dot(normal, view), 0.0, 1.0); 1043: 1044: float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y; 1045: vec2 env = vec2(-1.04, 1.04) * a004 + r.zw; 1046: specular_light *= env.x * f0 + env.y * clamp(50.0 * f0.g, metallic, 1.0); 1047: #endif 1048: } 1049: 1050: #endif // BASE_PASS 1051: 1052: #ifndef DISABLE_LIGHT_DIRECTIONAL 1053: //diffuse_light = normal; // 1054: for (uint i = uint(0); i < scene_data.directional_light_count; i++) { 1055: light_compute(normal, normalize(directional_lights[i].direction), normalize(view), directional_lights[i].size, directional_lights[i].color * directional_lights[i].energy, 1.0, f0, roughness, metallic, 1.0, albedo, alpha, 1056: #ifdef LIGHT_BACKLIGHT_USED 1057: backlight, 1058: #endif 1059: #ifdef LIGHT_RIM_USED 1060: rim, rim_tint, 1061: #endif 1062: #ifdef LIGHT_CLEARCOAT_USED 1063: clearcoat, clearcoat_roughness, normalize(normal_interp), 1064: #endif 1065: #ifdef LIGHT_ANISOTROPY_USED 1066: binormal, 1067: tangent, anisotropy, 1068: #endif 1069: diffuse_light, 1070: specular_light); 1071: } 1072: #endif // !DISABLE_LIGHT_DIRECTIONAL 1073: 1074: #ifndef DISABLE_LIGHT_OMNI 1075: for (uint i = 0u; i < MAX_FORWARD_LIGHTS; i++) { 1076: if (i >= omni_light_count) { 1077: break; 1078: } 1079: light_process_omni(omni_light_indices[i], vertex, view, normal, f0, roughness, metallic, 0.0, albedo, alpha, 1080: #ifdef LIGHT_BACKLIGHT_USED 1081: backlight, 1082: #endif 1083: #ifdef LIGHT_RIM_USED 1084: rim, 1085: rim_tint, 1086: #endif 1087: #ifdef LIGHT_CLEARCOAT_USED 1088: clearcoat, clearcoat_roughness, normalize(normal_interp), 1089: #endif 1090: #ifdef LIGHT_ANISOTROPY_USED 1091: binormal, tangent, anisotropy, 1092: #endif 1093: diffuse_light, specular_light); 1094: } 1095: #endif // !DISABLE_LIGHT_OMNI 1096: 1097: #ifndef DISABLE_LIGHT_SPOT 1098: for (uint i = 0u; i < MAX_FORWARD_LIGHTS; i++) { 1099: if (i >= spot_light_count) { 1100: break; 1101: } 1102: light_process_spot(spot_light_indices[i], vertex, view, normal, f0, roughness, metallic, 0.0, albedo, alpha, 1103: #ifdef LIGHT_BACKLIGHT_USED 1104: backlight, 1105: #endif 1106: #ifdef LIGHT_RIM_USED 1107: rim, 1108: rim_tint, 1109: #endif 1110: #ifdef LIGHT_CLEARCOAT_USED 1111: clearcoat, clearcoat_roughness, normalize(normal_interp), 1112: #endif 1113: #ifdef LIGHT_ANISOTROPY_USED 1114: tangent, 1115: binormal, anisotropy, 1116: #endif 1117: diffuse_light, specular_light); 1118: } 1119: #endif // !DISABLE_LIGHT_SPOT 1120: 1121: #endif // !MODE_UNSHADED 1122: 1123: #endif // !MODE_RENDER_DEPTH 1124: 1125: #if defined(USE_SHADOW_TO_OPACITY) 1126: alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0)); 1127: 1128: #if defined(ALPHA_SCISSOR_USED) 1129: if (alpha < alpha_scissor) { 1130: discard; 1131: } 1132: #endif // ALPHA_SCISSOR_USED 1133: 1134: #ifdef USE_OPAQUE_PREPASS 1135: #if !defined(ALPHA_SCISSOR_USED) 1136: 1137: if (alpha < opaque_prepass_threshold) { 1138: discard; 1139: } 1140: 1141: #endif // not ALPHA_SCISSOR_USED 1142: #endif // USE_OPAQUE_PREPASS 1143: 1144: #endif // USE_SHADOW_TO_OPACITY 1145: 1146: #ifdef MODE_RENDER_DEPTH 1147: //nothing happens, so a tree-ssa optimizer will result in no fragment shader :) 1148: #else // !MODE_RENDER_DEPTH 1149: 1150: #ifdef MODE_UNSHADED 1151: frag_color = vec4(albedo, alpha); 1152: #else 1153: 1154: diffuse_light *= albedo; 1155: 1156: diffuse_light *= 1.0 - metallic; 1157: ambient_light *= 1.0 - metallic; 1158: 1159: frag_color = vec4(diffuse_light + specular_light, alpha); 1160: #ifdef BASE_PASS 1161: frag_color.rgb += emission + ambient_light; 1162: #endif 1163: #endif //MODE_UNSHADED 1164: fog = vec4(unpackHalf2x16(fog_rg), unpackHalf2x16(fog_ba)); 1165: 1166: #ifndef DISABLE_FOG 1167: if (scene_data.fog_enabled) { 1168: #ifdef BASE_PASS 1169: frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a); 1170: #else 1171: frag_color.rgb *= (1.0 - fog.a); 1172: #endif // BASE_PASS 1173: } 1174: #endif 1175: 1176: // Tonemap before writing as we are writing to an sRGB framebuffer 1177: frag_color.rgb *= exposure; 1178: frag_color.rgb = apply_tonemapping(frag_color.rgb, white); 1179: frag_color.rgb = linear_to_srgb(frag_color.rgb); 1180: 1181: #ifdef USE_BCS 1182: frag_color.rgb = apply_bcs(frag_color.rgb, bcs); 1183: #endif 1184: 1185: #ifdef USE_COLOR_CORRECTION 1186: frag_color.rgb = apply_color_correction(frag_color.rgb, color_correction); 1187: #endif 1188: 1189: #endif //!MODE_RENDER_DEPTH 1190: } 1191: 1192: OpenGL API 3.3.11672 Core Profile Forward-Compatible Context - Compatibility - Using Device: ATI Technologies Inc. - ATI Radeon HD 3600 Series WASAPI: Activated output_device using IAudioClient3 interface WASAPI: wFormatTag = 65534 WASAPI: nChannels = 2 WASAPI: nSamplesPerSec = 48000 WASAPI: nAvgBytesPerSec = 384000 WASAPI: nBlockAlign = 8 WASAPI: wBitsPerSample = 32 WASAPI: cbSize = 22 WASAPI: mix_rate = 48000 WASAPI: fundamental_period_frames = 480 WASAPI: min_period_frames = 480 WASAPI: max_period_frames = 480 WASAPI: selected a period frame size of 480 WASAPI: detected 2 channels WASAPI: audio buffer frames: 480 calculated latency: 10ms TextServer: Primary interface set to: "ICU / HarfBuzz / Graphite (Built-in)". CORE API HASH: 3567874092 EDITOR API HASH: 3726538258 Loaded builtin certs EditorSettings: Save OK! EditorSettings: Save OK! XR: Clearing primary interface XR: Removed interfaceNative mobile XR: Removed interfaceOpenXR Orphan StringName: OP_MODULE Orphan StringName: KEY_SYSREQ Orphan StringName: PROPERTY_HINT_NONE Orphan StringName: PROPERTY_USAGE_DEFERRED_SET_RESOURCE Orphan StringName: INLINE_ALIGNMENT_TO_BASELINE Orphan StringName: JOY_BUTTON_DPAD_LEFT Orphan StringName: KEY_KP_SUBTRACT Orphan StringName: OP_LESS Orphan StringName: ERR_ALREADY_IN_USE Orphan StringName: ERR_CANT_FORK Orphan StringName: MIDI_MESSAGE_CONTINUE Orphan StringName: MOUSE_BUTTON_MASK_LEFT Orphan StringName: ERR_SKIP Orphan StringName: KEY_ENTER Orphan StringName: JOY_BUTTON_LEFT_STICK Orphan StringName: JOY_BUTTON_BACK Orphan StringName: KEY_GLOBE Orphan StringName: PROPERTY_HINT_LAYERS_2D_PHYSICS Orphan StringName: MethodFlags Orphan StringName: OP_IN Orphan StringName: METHOD_FLAG_OBJECT_CORE Orphan StringName: TYPE_PACKED_VECTOR3_ARRAY Orphan StringName: OP_OR Orphan StringName: JOY_BUTTON_INVALID Orphan StringName: TYPE_RID Orphan StringName: HORIZONTAL_ALIGNMENT_RIGHT Orphan StringName: PROPERTY_HINT_ENUM Orphan StringName: MIDI_MESSAGE_AFTERTOUCH Orphan StringName: KEY_MASK_SHIFT Orphan StringName: METHOD_FLAG_CONST Orphan StringName: ERR_DATABASE_CANT_WRITE Orphan StringName: ERR_DOES_NOT_EXIST Orphan StringName: MOUSE_BUTTON_WHEEL_DOWN Orphan StringName: JoyAxis Orphan StringName: ERR_PARSE_ERROR Orphan StringName: KEY_SEMICOLON Orphan StringName: TYPE_PACKED_STRING_ARRAY Orphan StringName: KEY_MASK_CTRL Orphan StringName: ERR_FILE_MISSING_DEPENDENCIES Orphan StringName: Error Orphan StringName: KEY_SCROLLLOCK Orphan StringName: PROPERTY_HINT_TYPE_STRING Orphan StringName: KEY_BACKSPACE Orphan StringName: GroupViewport Orphan StringName: KEY_HOME Orphan StringName: JOY_AXIS_SDL_MAX Orphan StringName: ERR_BUG Orphan StringName: METHOD_FLAGS_DEFAULT Orphan StringName: MOUSE_BUTTON_MASK_MIDDLE Orphan StringName: Variant.Operator Orphan StringName: MouseButtonMask Orphan StringName: KEY_ALT Orphan StringName: MIDI_MESSAGE_QUARTER_FRAME Orphan StringName: PROPERTY_HINT_LAYERS_3D_RENDER Orphan StringName: KEY_PRINT Orphan StringName: ERR_QUERY_FAILED Orphan StringName: KEY_LEFT Orphan StringName: KEY_BAR Orphan StringName: KEY_QUESTION Orphan StringName: INLINE_ALIGNMENT_TO_CENTER Orphan StringName: TYPE_DICTIONARY Orphan StringName: PROPERTY_USAGE_NONE Orphan StringName: KEY_BRACKETLEFT Orphan StringName: KEY_FORWARD Orphan StringName: KEY_LESS Orphan StringName: PROPERTY_USAGE_ARRAY Orphan StringName: PROPERTY_HINT_SAVE_FILE Orphan StringName: HORIZONTAL Orphan StringName: TYPE_PROJECTION Orphan StringName: PROPERTY_HINT_ENUM_SUGGESTION Orphan StringName: ERR_LINK_FAILED Orphan StringName: TYPE_BASIS Orphan StringName: Sky Orphan StringName: KEY_QUOTELEFT Orphan StringName: KEY_MEDIAPREVIOUS Orphan StringName: KEY_NUMBERSIGN Orphan StringName: OP_SHIFT_LEFT Orphan StringName: KEY_UNKNOWN Orphan StringName: JOY_BUTTON_DPAD_UP Orphan StringName: KEY_SPACE Orphan StringName: MIDI_MESSAGE_SONG_POSITION_POINTER Orphan StringName: PROPERTY_USAGE_STORAGE Orphan StringName: KEY_INSERT Orphan StringName: KEY_ESCAPE Orphan StringName: MIDI_MESSAGE_SYSTEM_EXCLUSIVE Orphan StringName: KEY_END Orphan StringName: KEY_F10 Orphan StringName: KEY_F11 Orphan StringName: KEY_F12 Orphan StringName: KEY_F13 Orphan StringName: KEY_F14 Orphan StringName: KEY_F15 Orphan StringName: KEY_F16 Orphan StringName: KEY_F17 Orphan StringName: KEY_F18 Orphan StringName: KEY_F19 Orphan StringName: KEY_F20 Orphan StringName: KEY_F21 Orphan StringName: KEY_F22 Orphan StringName: KEY_F23 Orphan StringName: KEY_F24 Orphan StringName: KEY_F25 Orphan StringName: KEY_F26 Orphan StringName: KEY_F27 Orphan StringName: KEY_F28 Orphan StringName: KEY_F29 Orphan StringName: KEY_F30 Orphan StringName: KEY_F31 Orphan StringName: KEY_F32 Orphan StringName: KEY_F33 Orphan StringName: KEY_F34 Orphan StringName: KEY_F35 Orphan StringName: PROPERTY_HINT_EXP_EASING Orphan StringName: INLINE_ALIGNMENT_TOP_TO Orphan StringName: KEY_KP_ADD Orphan StringName: KEY_CAPSLOCK Orphan StringName: CORNER_BOTTOM_LEFT Orphan StringName: JOY_BUTTON_A Orphan StringName: JOY_BUTTON_B Orphan StringName: PROPERTY_HINT_GLOBAL_SAVE_FILE Orphan StringName: JOY_BUTTON_X Orphan StringName: JOY_BUTTON_Y Orphan StringName: ERR_INVALID_PARAMETER Orphan StringName: HORIZONTAL_ALIGNMENT_LEFT Orphan StringName: Editor3DHandle Orphan StringName: KEY_STOP Orphan StringName: PROPERTY_HINT_GLOBAL_DIR Orphan StringName: INLINE_ALIGNMENT_TO_BOTTOM Orphan StringName: TYPE_BOOL Orphan StringName: JOY_BUTTON_TOUCHPAD Orphan StringName: TYPE_PLANE Orphan StringName: StatusSuccess Orphan StringName: INLINE_ALIGNMENT_TO_TOP Orphan StringName: METHOD_FLAG_VIRTUAL Orphan StringName: ERR_COMPILATION_FAILED Orphan StringName: KEY_SEARCH Orphan StringName: HORIZONTAL_ALIGNMENT_CENTER Orphan StringName: PROPERTY_HINT_DIR Orphan StringName: PROPERTY_HINT_NODE_TYPE Orphan StringName: ERR_INVALID_DECLARATION Orphan StringName: INLINE_ALIGNMENT_CENTER Orphan StringName: PROPERTY_USAGE_CLASS_IS_BITFIELD Orphan StringName: KEY_PARENRIGHT Orphan StringName: KEY_BACKTAB Orphan StringName: INLINE_ALIGNMENT_IMAGE_MASK Orphan StringName: ERR_FILE_BAD_PATH Orphan StringName: GuiResizer Orphan StringName: JOY_BUTTON_DPAD_RIGHT Orphan StringName: KEY_VOLUMEUP Orphan StringName: JOY_BUTTON_START Orphan StringName: SIDE_RIGHT Orphan StringName: PROPERTY_HINT_OBJECT_TOO_BIG Orphan StringName: ERR_ALREADY_EXISTS Orphan StringName: PROPERTY_USAGE_CATEGORY Orphan StringName: PROPERTY_USAGE_NEVER_DUPLICATE Orphan StringName: VERTICAL_ALIGNMENT_TOP Orphan StringName: KEY_PARENLEFT Orphan StringName: TYPE_PACKED_INT64_ARRAY Orphan StringName: KEY_COLON Orphan StringName: ERR_OUT_OF_MEMORY Orphan StringName: KEY_ASCIICIRCUM Orphan StringName: PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE Orphan StringName: KEY_SPECIAL Orphan StringName: GuiChecked Orphan StringName: KEY_ASTERISK Orphan StringName: KEY_COMMA Orphan StringName: MOUSE_BUTTON_WHEEL_LEFT Orphan StringName: GuiIndeterminate Orphan StringName: KEY_HYPER Orphan StringName: ERR_FILE_NOT_FOUND Orphan StringName: TYPE_PACKED_INT32_ARRAY Orphan StringName: EulerOrder Orphan StringName: ERR_SCRIPT_FAILED Orphan StringName: TYPE_PACKED_BYTE_ARRAY Orphan StringName: KEY_AMPERSAND Orphan StringName: PROPERTY_HINT_RESOURCE_TYPE Orphan StringName: KEY_MASK_META Orphan StringName: MOUSE_BUTTON_LEFT Orphan StringName: ERR_FILE_CORRUPT Orphan StringName: PROPERTY_USAGE_ALWAYS_DUPLICATE Orphan StringName: JOY_AXIS_TRIGGER_LEFT Orphan StringName: KEY_RIGHT Orphan StringName: INLINE_ALIGNMENT_BOTTOM Orphan StringName: JOY_AXIS_TRIGGER_RIGHT Orphan StringName: PROPERTY_HINT_HIDE_QUATERNION_EDIT Orphan StringName: CodeFoldedRightArrow Orphan StringName: MIDI_MESSAGE_NOTE_ON Orphan StringName: EditorBoneHandle Orphan StringName: PROPERTY_USAGE_INTERNAL Orphan StringName: ERR_UNAUTHORIZED Orphan StringName: KEY_MEDIARECORD Orphan StringName: INLINE_ALIGNMENT_CENTER_TO Orphan StringName: TYPE_ARRAY Orphan StringName: PropertyHint Orphan StringName: JOY_BUTTON_SDL_MAX Orphan StringName: PROPERTY_USAGE_NO_INSTANCE_STATE Orphan StringName: TYPE_STRING_NAME Orphan StringName: MIDI_MESSAGE_CHANNEL_PRESSURE Orphan StringName: KEY_FAVORITES Orphan StringName: PROPERTY_USAGE_DEFAULT Orphan StringName: ERR_PRINTER_ON_FIRE Orphan StringName: TYPE_SIGNAL Orphan StringName: PROPERTY_HINT_MAX Orphan StringName: Side Orphan StringName: KEY_NONE Orphan StringName: MOUSE_BUTTON_XBUTTON1 Orphan StringName: MOUSE_BUTTON_XBUTTON2 Orphan StringName: TYPE_NODE_PATH Orphan StringName: TYPE_STRING Orphan StringName: KEY_MASK_KPAD Orphan StringName: Godot Orphan StringName: KEY_MASK_ALT Orphan StringName: ERR_FILE_CANT_READ Orphan StringName: PROPERTY_USAGE_RESTART_IF_CHANGED Orphan StringName: ERR_TIMEOUT Orphan StringName: SIDE_BOTTOM Orphan StringName: KEY_TAB Orphan StringName: VERTICAL Orphan StringName: ZoomReset Orphan StringName: JOY_BUTTON_RIGHT_STICK Orphan StringName: TYPE_AABB Orphan StringName: EULER_ORDER_XYZ Orphan StringName: EULER_ORDER_XZY Orphan StringName: KEY_MEDIASTOP Orphan StringName: TYPE_VECTOR2 Orphan StringName: TYPE_VECTOR3 Orphan StringName: TYPE_VECTOR4 Orphan StringName: OP_ADD Orphan StringName: KEY_PLUS Orphan StringName: JOY_BUTTON_MAX Orphan StringName: KEY_CTRL Orphan StringName: OP_AND Orphan StringName: KEY_MEDIANEXT Orphan StringName: EULER_ORDER_YXZ Orphan StringName: EULER_ORDER_YZX Orphan StringName: PROPERTY_USAGE_CHECKED Orphan StringName: MIDIMessage Orphan StringName: KEY_PAGEUP Orphan StringName: EULER_ORDER_ZXY Orphan StringName: EULER_ORDER_ZYX Orphan StringName: OK Orphan StringName: PROPERTY_USAGE_EDITOR Orphan StringName: TYPE_TRANSFORM2D Orphan StringName: TYPE_TRANSFORM3D Orphan StringName: ERR_CANT_CONNECT Orphan StringName: INLINE_ALIGNMENT_TEXT_MASK Orphan StringName: KEY_BRACKETRIGHT Orphan StringName: OverbrightIndicator Orphan StringName: KEY_STANDBY Orphan StringName: JOY_BUTTON_LEFT_SHOULDER Orphan StringName: ERR_CONNECTION_ERROR Orphan StringName: OP_BIT_AND Orphan StringName: KEY_QUOTEDBL Orphan StringName: TYPE_FLOAT Orphan StringName: GuiCloseCustomizable Orphan StringName: ERR_CANT_CREATE Orphan StringName: KEY_YEN Orphan StringName: MIDI_MESSAGE_PITCH_BEND Orphan StringName: KEY_CLEAR Orphan StringName: JoyButton Orphan StringName: Variant.Type Orphan StringName: OP_POWER Orphan StringName: CodeFoldDownArrow Orphan StringName: CORNER_BOTTOM_RIGHT Orphan StringName: OP_SHIFT_RIGHT Orphan StringName: InlineAlignment Orphan StringName: GuiTab Orphan StringName: OP_EQUAL Orphan StringName: OP_GREATER Orphan StringName: OP_LESS_EQUAL Orphan StringName: ERR_METHOD_NOT_FOUND Orphan StringName: StatusWarning Orphan StringName: PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE Orphan StringName: KEY_KP_DIVIDE Orphan StringName: PROPERTY_HINT_FILE Orphan StringName: OP_NEGATE Orphan StringName: PROPERTY_HINT_LOCALE_ID Orphan StringName: PROPERTY_HINT_PASSWORD Orphan StringName: ERR_CANT_ACQUIRE_RESOURCE Orphan StringName: KEY_0 Orphan StringName: KEY_1 Orphan StringName: KEY_2 Orphan StringName: KEY_3 Orphan StringName: KEY_4 Orphan StringName: KEY_5 Orphan StringName: KEY_6 Orphan StringName: KEY_7 Orphan StringName: KEY_8 Orphan StringName: KEY_9 Orphan StringName: KEY_A Orphan StringName: KEY_B Orphan StringName: KEY_C Orphan StringName: KEY_D Orphan StringName: KEY_E Orphan StringName: KEY_F Orphan StringName: KEY_G Orphan StringName: KEY_H Orphan StringName: KEY_I Orphan StringName: KEY_J Orphan StringName: KEY_K Orphan StringName: KEY_L Orphan StringName: KEY_M Orphan StringName: KEY_N Orphan StringName: KEY_O Orphan StringName: KEY_P Orphan StringName: KEY_Q Orphan StringName: KEY_R Orphan StringName: KEY_S Orphan StringName: KEY_T Orphan StringName: KEY_U Orphan StringName: KEY_V Orphan StringName: KEY_W Orphan StringName: KEY_X Orphan StringName: KEY_Y Orphan StringName: KEY_Z Orphan StringName: KEY_REFRESH Orphan StringName: PROPERTY_USAGE_STORE_IF_NULL Orphan StringName: KEY_BACK Orphan StringName: KEY_OPENURL Orphan StringName: SIDE_TOP Orphan StringName: PROPERTY_HINT_LAYERS_2D_NAVIGATION Orphan StringName: TYPE_OBJECT Orphan StringName: ERR_LOCKED Orphan StringName: KEY_APOSTROPHE Orphan StringName: MOUSE_BUTTON_NONE Orphan StringName: JOY_BUTTON_PADDLE1 Orphan StringName: JOY_BUTTON_PADDLE2 Orphan StringName: JOY_BUTTON_PADDLE3 Orphan StringName: JOY_BUTTON_PADDLE4 Orphan StringName: EditorHandle Orphan StringName: GuiMiniCheckerboard Orphan StringName: OP_GREATER_EQUAL Orphan StringName: ERR_CYCLIC_LINK Orphan StringName: KEY_LAUNCHMEDIA Orphan StringName: KEY_JIS_EISU Orphan StringName: COUNTERCLOCKWISE Orphan StringName: ERR_CANT_RESOLVE Orphan StringName: PROPERTY_USAGE_HIGH_END_GFX Orphan StringName: PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED Orphan StringName: TYPE_RECT2 Orphan StringName: ERR_FILE_CANT_WRITE Orphan StringName: PROPERTY_HINT_LAYERS_3D_NAVIGATION Orphan StringName: KEY_KP_ENTER Orphan StringName: ERR_UNAVAILABLE Orphan StringName: LockViewport Orphan StringName: PROPERTY_HINT_LAYERS_3D_PHYSICS Orphan StringName: ClockDirection Orphan StringName: GuiGraphNodePort Orphan StringName: PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT Orphan StringName: KEY_VOLUMEDOWN Orphan StringName: METHOD_FLAG_EDITOR Orphan StringName: OP_MAX Orphan StringName: PROPERTY_HINT_FLAGS Orphan StringName: ERR_FILE_NO_PERMISSION Orphan StringName: KEY_ASCIITILDE Orphan StringName: OP_BIT_OR Orphan StringName: VERTICAL_ALIGNMENT_CENTER Orphan StringName: ERR_FILE_UNRECOGNIZED Orphan StringName: KEY_MEDIAPLAY Orphan StringName: VERTICAL_ALIGNMENT_FILL Orphan StringName: OP_NOT Orphan StringName: KEY_VOLUMEMUTE Orphan StringName: ZoomMore Orphan StringName: CORNER_TOP_RIGHT Orphan StringName: PROPERTY_USAGE_GROUP Orphan StringName: METHOD_FLAG_VARARG Orphan StringName: KEY_MASK_GROUP_SWITCH Orphan StringName: PROPERTY_HINT_ARRAY_TYPE Orphan StringName: PROPERTY_HINT_LAYERS_2D_RENDER Orphan StringName: PROPERTY_USAGE_CHECKABLE Orphan StringName: KEY_MENU Orphan StringName: EditorControlAnchor Orphan StringName: KEY_SECTION Orphan StringName: KEY_META Orphan StringName: PROPERTY_USAGE_SCRIPT_VARIABLE Orphan StringName: KEY_DELETE Orphan StringName: PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT Orphan StringName: Corner Orphan StringName: PROPERTY_USAGE_SUBGROUP Orphan StringName: OP_DIVIDE Orphan StringName: StatusError Orphan StringName: KEY_NUMLOCK Orphan StringName: FAILED Orphan StringName: JOY_AXIS_RIGHT_X Orphan StringName: JOY_AXIS_RIGHT_Y Orphan StringName: OP_NOT_EQUAL Orphan StringName: PROPERTY_HINT_NODE_PATH_VALID_TYPES Orphan StringName: KEY_EQUAL Orphan StringName: KEY_LAUNCH0 Orphan StringName: KEY_LAUNCH1 Orphan StringName: KEY_LAUNCH2 Orphan StringName: KEY_LAUNCH3 Orphan StringName: KEY_LAUNCH4 Orphan StringName: KEY_LAUNCH5 Orphan StringName: KEY_LAUNCH6 Orphan StringName: KEY_LAUNCH7 Orphan StringName: KEY_LAUNCH8 Orphan StringName: KEY_LAUNCH9 Orphan StringName: KEY_LAUNCHA Orphan StringName: KEY_LAUNCHB Orphan StringName: KEY_LAUNCHC Orphan StringName: KEY_LAUNCHD Orphan StringName: KEY_LAUNCHE Orphan StringName: KEY_LAUNCHF Orphan StringName: PROPERTY_HINT_OBJECT_ID Orphan StringName: MIDI_MESSAGE_SYSTEM_RESET Orphan StringName: PropertyUsageFlags Orphan StringName: OP_MULTIPLY Orphan StringName: MIDI_MESSAGE_PROGRAM_CHANGE Orphan StringName: VERTICAL_ALIGNMENT_BOTTOM Orphan StringName: PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT Orphan StringName: CORNER_TOP_LEFT Orphan StringName: TYPE_RECT2I Orphan StringName: KEY_DOLLAR Orphan StringName: MouseButton Orphan StringName: JOY_BUTTON_RIGHT_SHOULDER Orphan StringName: KEY_UNDERSCORE Orphan StringName: KEY_JIS_KANA Orphan StringName: MOUSE_BUTTON_MASK_RIGHT Orphan StringName: KEY_KP_0 Orphan StringName: KEY_KP_1 Orphan StringName: KEY_KP_2 Orphan StringName: KEY_KP_3 Orphan StringName: KEY_KP_4 Orphan StringName: KEY_KP_5 Orphan StringName: KEY_KP_6 Orphan StringName: KEY_KP_7 Orphan StringName: KEY_KP_8 Orphan StringName: KEY_KP_9 Orphan StringName: OP_POSITIVE Orphan StringName: PROPERTY_USAGE_EDITOR_BASIC_SETTING Orphan StringName: KEY_BRACERIGHT Orphan StringName: MIDI_MESSAGE_NOTE_OFF Orphan StringName: JOY_BUTTON_GUIDE Orphan StringName: GuiSpace Orphan StringName: OP_BIT_NEGATE Orphan StringName: PROPERTY_USAGE_READ_ONLY Orphan StringName: OP_SUBTRACT Orphan StringName: JOY_AXIS_INVALID Orphan StringName: TYPE_COLOR Orphan StringName: MIDI_MESSAGE_STOP Orphan StringName: ERR_UNCONFIGURED Orphan StringName: ERR_DATABASE_CANT_READ Orphan StringName: KEY_HOMEPAGE Orphan StringName: INLINE_ALIGNMENT_TOP Orphan StringName: JOY_BUTTON_DPAD_DOWN Orphan StringName: PROPERTY_HINT_GLOBAL_FILE Orphan StringName: PROPERTY_HINT_EXPRESSION Orphan StringName: PROPERTY_HINT_INT_IS_POINTER Orphan StringName: OP_XOR Orphan StringName: PROPERTY_HINT_LINK Orphan StringName: TYPE_PACKED_VECTOR2_ARRAY Orphan StringName: KEY_EXCLAM Orphan StringName: ERR_FILE_BAD_DRIVE Orphan StringName: EditorPivot Orphan StringName: KEY_GREATER Orphan StringName: DefaultProjectIcon Orphan StringName: PROPERTY_USAGE_NIL_IS_VARIANT Orphan StringName: ERR_DUPLICATE_SYMBOL Orphan StringName: KEY_PAGEDOWN Orphan StringName: CLOCKWISE Orphan StringName: PROPERTY_USAGE_NO_EDITOR Orphan StringName: INLINE_ALIGNMENT_BOTTOM_TO Orphan StringName: KEY_KP_PERIOD Orphan StringName: MIDI_MESSAGE_ACTIVE_SENSING Orphan StringName: OP_BIT_XOR Orphan StringName: JOY_AXIS_LEFT_X Orphan StringName: JOY_AXIS_LEFT_Y Orphan StringName: MIDI_MESSAGE_CONTROL_CHANGE Orphan StringName: TYPE_CALLABLE Orphan StringName: KeyModifierMask Orphan StringName: MIDI_MESSAGE_TIMING_CLOCK Orphan StringName: MOUSE_BUTTON_WHEEL_UP Orphan StringName: KEY_MASK_CMD_OR_CTRL Orphan StringName: TYPE_VECTOR2I Orphan StringName: TextEditorPlay Orphan StringName: TYPE_VECTOR3I Orphan StringName: ERR_BUSY Orphan StringName: TYPE_VECTOR4I Orphan StringName: PROPERTY_HINT_LOCALIZABLE_STRING Orphan StringName: PROPERTY_HINT_COLOR_NO_ALPHA Orphan StringName: ERR_FILE_ALREADY_IN_USE Orphan StringName: KEY_BACKSLASH Orphan StringName: Orientation Orphan StringName: MOUSE_BUTTON_RIGHT Orphan StringName: TYPE_PACKED_FLOAT64_ARRAY Orphan StringName: PROPERTY_USAGE_CLASS_IS_ENUM Orphan StringName: KEY_DOWN Orphan StringName: ERR_FILE_EOF Orphan StringName: TYPE_QUATERNION Orphan StringName: KEY_SHIFT Orphan StringName: ERR_HELP Orphan StringName: MOUSE_BUTTON_MASK_MB_XBUTTON1 Orphan StringName: MOUSE_BUTTON_MASK_MB_XBUTTON2 Orphan StringName: MIDI_MESSAGE_TUNE_REQUEST Orphan StringName: TYPE_INT Orphan StringName: ERR_PARAMETER_RANGE_ERROR Orphan StringName: METHOD_FLAG_NORMAL Orphan StringName: KEY_HELP Orphan StringName: KEY_PERIOD Orphan StringName: SIDE_LEFT Orphan StringName: TYPE_PACKED_FLOAT32_ARRAY Orphan StringName: JOY_BUTTON_MISC1 Orphan StringName: ERR_FILE_CANT_OPEN Orphan StringName: KEY_KP_MULTIPLY Orphan StringName: MOUSE_BUTTON_MIDDLE Orphan StringName: ZoomLess Orphan StringName: KEY_AT Orphan StringName: VerticalAlignment Orphan StringName: KEY_F1 Orphan StringName: KEY_F2 Orphan StringName: KEY_F3 Orphan StringName: KEY_F4 Orphan StringName: KEY_F5 Orphan StringName: KEY_F6 Orphan StringName: KEY_F7 Orphan StringName: KEY_F8 Orphan StringName: KEY_F9 Orphan StringName: INLINE_ALIGNMENT_BASELINE_TO Orphan StringName: MIDI_MESSAGE_START Orphan StringName: KEY_UP Orphan StringName: KEY_CODE_MASK Orphan StringName: PROPERTY_HINT_RANGE Orphan StringName: TYPE_PACKED_COLOR_ARRAY Orphan StringName: JOY_AXIS_MAX Orphan StringName: KEY_MINUS Orphan StringName: ERR_CANT_OPEN Orphan StringName: KEY_SLASH Orphan StringName: ERR_INVALID_DATA Orphan StringName: MOUSE_BUTTON_WHEEL_RIGHT Orphan StringName: MIDI_MESSAGE_NONE Orphan StringName: HORIZONTAL_ALIGNMENT_FILL Orphan StringName: TYPE_MAX Orphan StringName: PROPERTY_HINT_MULTILINE_TEXT Orphan StringName: MIDI_MESSAGE_SONG_SELECT Orphan StringName: KEY_MODIFIER_MASK Orphan StringName: PROPERTY_USAGE_KEYING_INCREMENTS Orphan StringName: KEY_PAUSE Orphan StringName: METHOD_FLAG_STATIC Orphan StringName: KEY_LAUNCHMAIL Orphan StringName: PROPERTY_HINT_INT_IS_OBJECTID Orphan StringName: Breakpoint Orphan StringName: TYPE_NIL Orphan StringName: HorizontalAlignment Orphan StringName: KEY_KEYBOARD Orphan StringName: GuiRadioChecked Orphan StringName: KEY_PERCENT Orphan StringName: Key Orphan StringName: KEY_BRACELEFT Orphan StringName: PROPERTY_HINT_PLACEHOLDER_TEXT StringName: 550 unclaimed string names at exit.