Skip to content

Instantly share code, notes, and snippets.

@NotAPenguin0
Created July 27, 2020 15:03
Show Gist options
  • Select an option

  • Save NotAPenguin0/4523d10e4630ec60245b06edd81ab4fa to your computer and use it in GitHub Desktop.

Select an option

Save NotAPenguin0/4523d10e4630ec60245b06edd81ab4fa to your computer and use it in GitHub Desktop.
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