pbr.glsl (2765B)
1 2 float dist_ggx(vec3 N, vec3 H, float roughness) 3 { 4 float a = roughness * roughness; 5 float NdotH = max(dot(N, H), 0.0); 6 float NdotH2 = NdotH*NdotH; 7 8 float num = a; 9 float denom = (NdotH2 * (a - 1.0) + 1.0); 10 denom = PI * denom * denom; 11 12 return num / denom; 13 } 14 15 16 float geom_schlick_ggx(float NdotV, float roughness) 17 { 18 float r = (roughness + 1.0); 19 float k = (r*r) / 8.0; 20 21 float num = NdotV; 22 float denom = NdotV * (1.0 - k) + k; 23 24 return num / denom; 25 } 26 27 float geom_smith(vec3 N, vec3 V, vec3 L, float roughness) 28 { 29 float NdotV = max(dot(N, V), 0.0); 30 float NdotL = max(dot(N, L), 0.0); 31 float ggx1 = geom_schlick_ggx(NdotV, roughness); 32 float ggx2 = geom_schlick_ggx(NdotL, roughness); 33 34 return ggx1 * ggx2; 35 } 36 37 vec3 fresnel_schlick(float cos_theta, vec3 F0) 38 { 39 return F0 + (1.0 - F0) * pow(1.0 - cos_theta, 5.0); 40 } 41 42 vec3 pbr(vec3 albedo, vec3 V, vec3 normal) { 43 const float ao = 15.0; 44 const float metallic = 0.6; 45 const float exposure = 0.05; 46 const float roughness = 0.6; 47 vec3 radiance = sun_color * light_intensity * 2.5; 48 // radiance += texture(skybox, vec3(0.0, 0.0, 1.0)).rgb; 49 vec3 N = normalize(normal); 50 vec3 L = normalize(light_dir); 51 vec3 H = normalize(V + L); 52 // non-metallic is always 0.04 53 vec3 F0 = vec3(0.04); 54 // while we do vary F0 based on the metalness of a surface by linearly 55 // interpolating between the original F0 and the albedo value given the 56 // metallic property 57 F0 = mix(F0, albedo, metallic); 58 float HdotV = max(0.0, dot(H, V)); 59 vec3 F = fresnel_schlick(HdotV, F0); 60 float NDF = dist_ggx(N, H, roughness); 61 float G = geom_smith(N, V, L, roughness); 62 63 float NdotL = max(0.0, dot(N, L)); 64 65 // Cook-Torrance BRDF 66 vec3 numerator = NDF * G * F; 67 float denominator = 4.0 * max(0.0, dot(N, V)) * NdotL; 68 vec3 specular = numerator / max(denominator, 0.001); 69 70 // kS = energy of light that gets reflected 71 // kD = remaining energy that gets refracted 72 vec3 kS = F; 73 vec3 kD = vec3(1.0) - kS; 74 kD *= 1.0 - metallic; 75 76 // because metallic surfaces don't refract light and thus have no diffuse 77 // reflections we enforce this property by nullifying kD if the surface is 78 // metallic 79 80 // Lo = outgoing radiance 81 // the result of the reflectance equation's integral ∫ over Ω 82 83 vec3 Lo = (kD * albedo / PI + specular) * radiance * NdotL; 84 85 vec3 ambient = vec3(0.03) * albedo * ao; 86 vec3 color = ambient + Lo; 87 // color = uncharted_tonemap(color); 88 89 // color = color / (vec3(1.0) - color * exposure); 90 // final = final / (vec3(1.0) + color); 91 // color = color / (vec3(1.0) + color); 92 93 return color; 94 }