/**
 * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
 *
 * @author Alexander Rose <alexander.rose@weirdbyte.de>
 *
 * adapted from three.js (https://github.com/mrdoob/three.js/)
 * which under the MIT License, Copyright © 2010-2021 three.js authors
 */
export declare const light_frag_params = "\n#if dLightCount != 0\n    uniform vec3 uLightDirection[dLightCount];\n    uniform vec3 uLightColor[dLightCount];\n#endif\nuniform vec3 uAmbientColor;\n\nstruct PhysicalMaterial {\n    vec3 diffuseColor;\n    float roughness;\n    vec3 specularColor;\n    float specularF90;\n};\n\nstruct IncidentLight {\n    vec3 color;\n    vec3 direction;\n};\n\nstruct ReflectedLight {\n    vec3 directDiffuse;\n    vec3 directSpecular;\n    vec3 indirectDiffuse;\n    vec3 indirectSpecular;\n};\n\nstruct GeometricContext {\n    vec3 position;\n    vec3 normal;\n    vec3 viewDir;\n};\n\nvec3 BRDF_Lambert(const in vec3 diffuseColor) {\n    return RECIPROCAL_PI * diffuseColor;\n}\n\nvec3 F_Schlick(const in vec3 f0, const in float f90, const in float dotVH) {\n    // Original approximation by Christophe Schlick '94\n    // float fresnel = pow( 1.0 - dotVH, 5.0 );\n    // Optimized variant (presented by Epic at SIGGRAPH '13)\n    // https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdf\n    float fresnel = exp2((-5.55473 * dotVH - 6.98316) * dotVH);\n    return f0 * (1.0 - fresnel) + (f90 * fresnel);\n}\n\n// Moving Frostbite to Physically Based Rendering 3.0 - page 12, listing 2\n// https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf\nfloat V_GGX_SmithCorrelated(const in float alpha, const in float dotNL, const in float dotNV) {\n    float a2 = pow2(alpha);\n    float gv = dotNL * sqrt(a2 + (1.0 - a2) * pow2(dotNV));\n    float gl = dotNV * sqrt(a2 + (1.0 - a2) * pow2(dotNL));\n    return 0.5 / max(gv + gl, EPSILON);\n}\n\n// Microfacet Models for Refraction through Rough Surfaces - equation (33)\n// http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html\n// alpha is \"roughness squared\" in Disney\u2019s reparameterization\nfloat D_GGX(const in float alpha, const in float dotNH) {\n    float a2 = pow2(alpha);\n    float denom = pow2(dotNH) * (a2 - 1.0) + 1.0; // avoid alpha = 0 with dotNH = 1\n    return RECIPROCAL_PI * a2 / pow2(denom);\n}\n\n// GGX Distribution, Schlick Fresnel, GGX_SmithCorrelated Visibility\nvec3 BRDF_GGX(const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 f0, const in float f90, const in float roughness) {\n    float alpha = pow2(roughness); // UE4's roughness\n    vec3 halfDir = normalize( lightDir + viewDir);\n    float dotNL = saturate(dot(normal, lightDir));\n    float dotNV = saturate(dot(normal, viewDir));\n    float dotNH = saturate(dot(normal, halfDir));\n    float dotVH = saturate(dot(viewDir, halfDir));\n    vec3 F = F_Schlick(f0, f90, dotVH);\n    float V = V_GGX_SmithCorrelated(alpha, dotNL, dotNV);\n    float D = D_GGX(alpha, dotNH);\n    return F * (V * D);\n}\n\n// Analytical approximation of the DFG LUT, one half of the\n// split-sum approximation used in indirect specular lighting.\n// via 'environmentBRDF' from \"Physically Based Shading on Mobile\"\n// https://www.unrealengine.com/blog/physically-based-shading-on-mobile\nvec2 DFGApprox(const in vec3 normal, const in vec3 viewDir, const in float roughness) {\n    float dotNV = saturate(dot(normal, viewDir));\n    const vec4 c0 = vec4(-1, -0.0275, -0.572, 0.022);\n    const vec4 c1 = vec4(1, 0.0425, 1.04, -0.04);\n    vec4 r = roughness * c0 + c1;\n    float a004 = min(r.x * r.x, exp2(-9.28 * dotNV)) * r.x + r.y;\n    vec2 fab = vec2(-1.04, 1.04) * a004 + r.zw;\n    return fab;\n}\n\n// Fdez-Ag\u00FCera's \"Multiple-Scattering Microfacet Model for Real-Time Image Based Lighting\"\n// Approximates multiscattering in order to preserve energy.\n// http://www.jcgt.org/published/0008/01/03/\nvoid computeMultiscattering(const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter) {\n    vec2 fab = DFGApprox(normal, viewDir, roughness);\n    vec3 FssEss = specularColor * fab.x + specularF90 * fab.y;\n    float Ess = fab.x + fab.y;\n    float Ems = 1.0 - Ess;\n    vec3 Favg = specularColor + (1.0 - specularColor) * 0.047619; // 1/21\n    vec3 Fms = FssEss * Favg / (1.0 - Ems * Favg);\n    singleScatter += FssEss;\n    multiScatter += Fms * Ems;\n}\n\nvoid RE_Direct_Physical(const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n    float dotNL = saturate(dot(geometry.normal, directLight.direction));\n    vec3 irradiance = dotNL * directLight.color;\n    reflectedLight.directSpecular += irradiance * BRDF_GGX(directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.roughness);\n    reflectedLight.directDiffuse += irradiance * BRDF_Lambert(material.diffuseColor);\n}\n\nvoid RE_IndirectDiffuse_Physical(const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n    reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert(material.diffuseColor);\n}\n\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n    // Both indirect specular and indirect diffuse light accumulate here\n    vec3 singleScattering = vec3(0.0);\n    vec3 multiScattering = vec3(0.0);\n    vec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n    computeMultiscattering(geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering);\n    vec3 diffuse = material.diffuseColor * (1.0 - ( singleScattering + multiScattering));\n    reflectedLight.indirectSpecular += radiance * singleScattering;\n    reflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance;\n    reflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n}\n";
