-
-
Save shadercoder/aee43813382141211843a02d59b2b254 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #define saturate(x) clamp(x, 0.0, 1.0) | |
| #define PI 3.14159265359 | |
| // OrenNayar diffuse | |
| vec3 getDiffuse( vec3 diffuseColor, float roughness4, float NoV, float NoL, float VoH ) | |
| { | |
| float VoL = 2.0 * VoH - 1.0; | |
| float c1 = 1.0 - 0.5 * roughness4 / (roughness4 + 0.33); | |
| float cosri = VoL - NoV * NoL; | |
| float c2 = 0.45 * roughness4 / (roughness4 + 0.09) * cosri * ( cosri >= 0.0 ? min( 1.0, NoL / NoV ) : NoL ); | |
| return diffuseColor / PI * ( NoL * c1 + c2 ); | |
| } | |
| // GGX Normal distribution | |
| float getNormalDistribution( float roughness4, float NoH ) | |
| { | |
| float d = ( NoH * roughness4 - NoH ) * NoH + 1.0; | |
| return roughness4 / ( d*d ); | |
| } | |
| // Smith GGX geometric shadowing from "Physically-Based Shading at Disney" | |
| float getGeometricShadowing( float roughness4, float NoV, float NoL, float VoH, vec3 L, vec3 V ) | |
| { | |
| float gSmithV = NoV + sqrt( NoV * (NoV - NoV * roughness4) + roughness4 ); | |
| float gSmithL = NoL + sqrt( NoL * (NoL - NoL * roughness4) + roughness4 ); | |
| return 1.0 / ( gSmithV * gSmithL ); | |
| } | |
| // Fresnel term | |
| vec3 getFresnel( vec3 specularColor, float VoH ) | |
| { | |
| vec3 specularColorSqrt = sqrt( clamp( vec3(0.0, 0.0, 0.0), vec3(0.99, 0.99, 0.99), specularColor ) ); | |
| vec3 n = ( 1.0 + specularColorSqrt ) / ( 1.0 - specularColorSqrt ); | |
| vec3 g = sqrt( n * n + VoH * VoH - 1.0 ); | |
| return 0.5 * pow( (g - VoH) / (g + VoH), vec3(2.0) ) * ( 1.0 + pow( ((g+VoH)*VoH - 1.0) / ((g-VoH)*VoH + 1.0), vec3(2.0) ) ); | |
| } | |
| const float A = 0.15; | |
| const float B = 0.50; | |
| const float C = 0.10; | |
| const float D = 0.20; | |
| const float E = 0.02; | |
| const float F = 0.30; | |
| vec3 Uncharted2Tonemap( vec3 x ) | |
| { | |
| return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F; | |
| } | |
| // From "I'm doing it wrong" | |
| // http://imdoingitwrong.wordpress.com/2011/01/31/light-attenuation/ | |
| float getAttenuation( vec3 lightPosition, vec3 vertexPosition, float lightRadius ) | |
| { | |
| float r = lightRadius; | |
| vec3 L = lightPosition - vertexPosition; | |
| float dist = length(L); | |
| float d = max( dist - r, 0.0 ); | |
| L /= dist; | |
| float denom = d / r + 1.0; | |
| float attenuation = 1.0 / (denom*denom); | |
| float cutoff = 0.0052; | |
| attenuation = (attenuation - cutoff) / (1.0 - cutoff); | |
| attenuation = max(attenuation, 0.0); | |
| return attenuation; | |
| } | |
| vec3 getPbrPointLight(vec3 normal, vec3 position, vec3 lightPosition, vec3 lightColor, float lightRadius) { | |
| // vLightPosition = ( uViewMatrix * vec4( uLightPosition, 1.0 ) ).xyz; | |
| vec3 N = normalize( normal ); | |
| vec3 L = normalize( lightPosition - position ); | |
| vec3 V = normalize( -position ); | |
| vec3 H = normalize(V + L); | |
| float NoL = saturate( dot( N, L ) ); | |
| float NoV = saturate( dot( N, V ) ); | |
| float VoH = saturate( dot( V, H ) ); | |
| float NoH = saturate( dot( N, H ) ); | |
| // deduce the diffuse and specular color from the baseColor and how metallic the material is | |
| vec3 diffuseColor = uBaseColor - uBaseColor * uMetallic; | |
| vec3 specularColor = mix( vec3( 0.8 * uSpecular ), uBaseColor, uMetallic ); | |
| // compute the brdf terms | |
| float distribution = getNormalDistribution( uRoughness, NoH ); | |
| vec3 fresnel = getFresnel( specularColor, VoH ); | |
| float geom = getGeometricShadowing( uRoughness, NoV, NoL, VoH, L, V ); | |
| // get the specular and diffuse and combine them | |
| vec3 diffuse = getDiffuse( diffuseColor, uRoughness, NoV, NoL, VoH ); | |
| vec3 specular = NoL * ( distribution * fresnel * geom ); | |
| vec3 color = lightColor * ( diffuse + specular ); | |
| // get the light attenuation from its radius | |
| float attenuation = getAttenuation( lightPosition, position, lightRadius ); | |
| color *= attenuation; | |
| return color; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment