Created
July 27, 2020 15:03
-
-
Save NotAPenguin0/4523d10e4630ec60245b06edd81ab4fa 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
| float saturate(float x) { | |
| return max(0.0, min(x, 1.0)); | |
| } | |
| float calculate_attenuation(PointLight light) { | |
| float dist = length(world_pos - light.transform.xyz); | |
| float radius = light.transform.w; | |
| float num = saturate(1 - pow(dist / radius, 4)); | |
| return light.color.a * num * num / (dist * dist + 1); | |
| } | |
| float distribution_ggx(vec3 N, vec3 H, float roughness) { | |
| float a = roughness * roughness; | |
| float a2 = a * a; | |
| float NdotH = max(dot(N, H), 0.0); | |
| float NdotH2 = NdotH * NdotH; | |
| float num = a2; | |
| float denom = (NdotH2 * (a2 - 1.0) + 1.0); | |
| denom = PI * denom * denom; | |
| return num / denom; | |
| } | |
| vec3 fresnel_schlick(float cos_theta, vec3 F0) { | |
| return F0 + (1.0 - F0) * pow(1.0 - cos_theta, 5.0); | |
| } | |
| vec3 fresnel_schlick_roughness(float cos_theta, vec3 F0, float roughness) { | |
| return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(1.0 - cos_theta, 5.0); | |
| } | |
| float geometry_schlick_ggx(float NdotV, float roughness) { | |
| float r = (roughness + 1.0); | |
| float k = (r * r) / 8.0; | |
| float num = NdotV; | |
| float denom = NdotV * (1.0 - k) + k; | |
| return num / denom; | |
| } | |
| float geometry_smith(vec3 N, vec3 V, vec3 L, float roughness) { | |
| float NdotV = max(dot(N, V), 0.0); | |
| float NdotL = max(dot(N, L), 0.0); | |
| float ggx2 = geometry_schlick_ggx(NdotV, roughness); | |
| float ggx1 = geometry_schlick_ggx(NdotL, roughness); | |
| return ggx1 * ggx2; | |
| } | |
| vec3 apply_point_light(PointLight light, vec3 norm, vec3 albedo, float roughness, float metallic) { | |
| vec3 light_dir = normalize(light.transform.xyz - world_pos); | |
| vec3 view_dir = normalize(camera.cam_pos - world_pos); | |
| vec3 halfway_dir = normalize(light_dir + view_dir); | |
| vec3 radiance = light.color.rgb * calculate_attenuation(light); | |
| vec3 F0 = vec3(0.04); | |
| F0 = mix(F0, albedo, metallic); | |
| vec3 F = fresnel_schlick(max(dot(halfway_dir, view_dir), 0.0), F0); | |
| // Calculate Cook-Torrance BRDF. | |
| float NDF = distribution_ggx(norm, halfway_dir, roughness); | |
| float G = geometry_smith(norm, view_dir, light_dir, roughness); | |
| vec3 num = NDF * G * F; | |
| float denom = 4.0 * max(dot(norm, view_dir), 0.0) * max(dot(norm, light_dir), 0.0); | |
| vec3 specular = num / max(denom, 0.001); // Make sure to not divide by zero | |
| vec3 kS = F; | |
| vec3 kD = vec3(1.0) - kS; | |
| kD *= 1.0 - metallic; | |
| float NdotL = max(dot(norm, light_dir), 0.0); | |
| return (kD * albedo / PI + specular) * radiance * NdotL; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment