pbr.glsl (1896B)
1 float normal_distribution_ggx( vec3 N, vec3 H, float roughness ) { 2 float a = roughness * roughness; 3 float a2 = a * a; 4 float NdotH = dot_sat( N, H ); 5 float NdotH2 = NdotH * NdotH; 6 7 float denom = ( NdotH2 * ( a2 - 1.0 ) + 1.0 ); 8 denom = PI * denom * denom; 9 10 return a2 / denom; 11 } 12 13 float geometry_distribution_schlick_ggx( float NdotV, float roughness ) { 14 float r = ( roughness + 1.0 ); 15 float k = ( r * r ) / 8.0; 16 17 return NdotV / ( NdotV * ( 1.0 - k ) + k ); 18 } 19 20 float geometry_distribution_smith( vec3 N, vec3 V, vec3 L, float roughness ) { 21 float NdotV = dot_sat( N, V ); 22 float NdotL = dot_sat( N, L ); 23 float ggx2 = geometry_distribution_schlick_ggx( NdotV, roughness ); 24 float ggx1 = geometry_distribution_schlick_ggx( NdotL, roughness ); 25 26 return ggx1 * ggx2; 27 } 28 29 vec3 fresnel_schlick( float cos_theta, vec3 F0 ) { 30 return F0 + ( 1.0 - F0 ) * pow( 1.0 - cos_theta, 5.0 ); 31 } 32 33 vec3 cook_torrance_brdf( vec3 to_camera, vec3 surface_position, vec3 surface_normal, vec3 light_position, vec3 light_colour, vec3 albedo, float roughness, float metalness ) { 34 vec3 L = normalize( light_position - surface_position ); 35 float distance = length( light_position - surface_position ); 36 float attenuation = 1.0 / ( distance * distance ); 37 vec3 radiance = light_colour * attenuation; 38 39 vec3 H = normalize( to_camera + L ); 40 41 vec3 F0 = vec3( 0.04 ); 42 F0 = mix( F0, albedo, metalness ); 43 44 float NdotL = dot_sat( surface_normal, L ); 45 46 float NDF = normal_distribution_ggx( surface_normal, H, roughness ); 47 float G = geometry_distribution_smith( surface_normal, to_camera, L, roughness ); 48 vec3 F = fresnel_schlick( dot_sat( H, to_camera ), F0 ); 49 vec3 diffuse_amount = ( vec3( 1.0 ) - F ) * ( 1.0 - metalness ); 50 51 float denom = 4.0 * dot_sat( to_camera, surface_normal ) * NdotL + 0.001; 52 vec3 specular = ( NDF * G * F ) / denom; 53 54 return ( diffuse_amount * albedo / PI + specular ) * radiance * NdotL; 55 }