commit 635d96fefc2ed50d991870ccdd8d17552ec5cc1d
parent 95ef741994e05f68b7ce23885be1d7e8fda5a090
Author: William Casarin <jb55@jb55.com>
Date: Mon, 12 Nov 2018 18:53:09 -0800
refactor pbr a bit
Diffstat:
4 files changed, 101 insertions(+), 96 deletions(-)
diff --git a/etc/shaders/lighting.glsl b/etc/shaders/lighting.glsl
@@ -85,91 +85,5 @@ vec3 standard_light(vec3 color, vec4 position, vec4 normal) {
return final;
}
-float dist_ggx(vec3 N, vec3 H, float roughness)
-{
- float a = roughness * roughness;
- float NdotH = max(dot(N, H), 0.0);
- float NdotH2 = NdotH*NdotH;
- float num = a;
- float denom = (NdotH2 * (a - 1.0) + 1.0);
- denom = PI * denom * denom;
-
- return num / denom;
-}
-
-
-float geom_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 geom_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 ggx1 = geom_schlick_ggx(NdotV, roughness);
- float ggx2 = geom_schlick_ggx(NdotL, roughness);
-
- return ggx1 * ggx2;
-}
-
-vec3 fresnel_schlick(float cos_theta, vec3 F0)
-{
- return F0 + (1.0 - F0) * pow(1.0 - cos_theta, 5.0);
-}
-
-vec3 pbr(vec3 albedo, vec3 V, vec3 normal) {
- const float ao = 5.0;
- const float metallic = 0.6;
- const float roughness = 0.4;
- vec3 radiance = sun_color * light_intensity;
- // radiance += texture(skybox, vec3(0.0, 0.0, 1.0)).rgb;
- vec3 N = normalize(normal);
- vec3 L = normalize(light_dir);
- vec3 H = normalize(V + L);
- // non-metallic is always 0.04
- vec3 F0 = vec3(0.04);
- // while we do vary F0 based on the metalness of a surface by linearly
- // interpolating between the original F0 and the albedo value given the
- // metallic property
- F0 = mix(F0, albedo, metallic);
- float HdotV = max(0.0, dot(H, V));
- vec3 F = fresnel_schlick(HdotV, F0);
- float NDF = dist_ggx(N, H, roughness);
- float G = geom_smith(N, V, L, roughness);
-
- float NdotL = max(0.0, dot(N, L));
-
- // Cook-Torrance BRDF
- vec3 numerator = NDF * G * F;
- float denominator = 4.0 * max(0.0, dot(N, V)) * NdotL;
- vec3 specular = numerator / max(denominator, 0.001);
-
- // kS = energy of light that gets reflected
- // kD = remaining energy that gets refracted
- vec3 kS = F;
- vec3 kD = vec3(1.0) - kS;
- kD *= 1.0 - metallic;
-
- // because metallic surfaces don't refract light and thus have no diffuse
- // reflections we enforce this property by nullifying kD if the surface is
- // metallic
-
- // Lo = outgoing radiance
- // the result of the reflectance equation's integral ∫ over Ω
- vec3 Lo = (kD * albedo / PI + specular) * radiance * NdotL;
-
- vec3 ambient = vec3(0.03) * albedo * ao;
- vec3 color = ambient + Lo;
- // color = uncharted_tonemap(color);
- //color = color / (vec3(1.0) + color);
-
- return color;
-}
+#include pbr.glsl
diff --git a/etc/shaders/pbr.glsl b/etc/shaders/pbr.glsl
@@ -0,0 +1,89 @@
+
+float dist_ggx(vec3 N, vec3 H, float roughness)
+{
+ float a = roughness * roughness;
+ float NdotH = max(dot(N, H), 0.0);
+ float NdotH2 = NdotH*NdotH;
+
+ float num = a;
+ float denom = (NdotH2 * (a - 1.0) + 1.0);
+ denom = PI * denom * denom;
+
+ return num / denom;
+}
+
+
+float geom_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 geom_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 ggx1 = geom_schlick_ggx(NdotV, roughness);
+ float ggx2 = geom_schlick_ggx(NdotL, roughness);
+
+ return ggx1 * ggx2;
+}
+
+vec3 fresnel_schlick(float cos_theta, vec3 F0)
+{
+ return F0 + (1.0 - F0) * pow(1.0 - cos_theta, 5.0);
+}
+
+vec3 pbr(vec3 albedo, vec3 V, vec3 normal) {
+ const float ao = 5.0;
+ const float metallic = 0.6;
+ const float roughness = 0.4;
+ vec3 radiance = sun_color * light_intensity;
+ // radiance += texture(skybox, vec3(0.0, 0.0, 1.0)).rgb;
+ vec3 N = normalize(normal);
+ vec3 L = normalize(light_dir);
+ vec3 H = normalize(V + L);
+ // non-metallic is always 0.04
+ vec3 F0 = vec3(0.04);
+ // while we do vary F0 based on the metalness of a surface by linearly
+ // interpolating between the original F0 and the albedo value given the
+ // metallic property
+ F0 = mix(F0, albedo, metallic);
+ float HdotV = max(0.0, dot(H, V));
+ vec3 F = fresnel_schlick(HdotV, F0);
+ float NDF = dist_ggx(N, H, roughness);
+ float G = geom_smith(N, V, L, roughness);
+
+ float NdotL = max(0.0, dot(N, L));
+
+ // Cook-Torrance BRDF
+ vec3 numerator = NDF * G * F;
+ float denominator = 4.0 * max(0.0, dot(N, V)) * NdotL;
+ vec3 specular = numerator / max(denominator, 0.001);
+
+ // kS = energy of light that gets reflected
+ // kD = remaining energy that gets refracted
+ vec3 kS = F;
+ vec3 kD = vec3(1.0) - kS;
+ kD *= 1.0 - metallic;
+
+ // because metallic surfaces don't refract light and thus have no diffuse
+ // reflections we enforce this property by nullifying kD if the surface is
+ // metallic
+
+ // Lo = outgoing radiance
+ // the result of the reflectance equation's integral ∫ over Ω
+ vec3 Lo = (kD * albedo / PI + specular) * radiance * NdotL;
+
+ vec3 ambient = vec3(0.03) * albedo * ao;
+ vec3 color = ambient + Lo;
+ // color = uncharted_tonemap(color);
+ //color = color / (vec3(1.0) + color);
+
+ return color;
+}
diff --git a/etc/shaders/shadows.glsl b/etc/shaders/shadows.glsl
@@ -11,7 +11,7 @@ vec3 shadow_strength(vec4 position, vec4 normal, vec4 v_shadow_coord) {
vec4 shadow_sample = texture(shadow_map, v_shadow_coord.xy);
- float bias = 0.002;
+ float bias = 0.0002;
bool in_shadow =
shadow_sample.z < v_shadow_coord.z - bias
&& shadow_sample.y < 1.0;
diff --git a/src/update.c b/src/update.c
@@ -191,14 +191,14 @@ void resize_fbos(struct entity *player, struct fbo *shadow_buffer,
}
// TODO: compute better bounds based
- const float factor = 80.0;
+ const float factor = 1.5;
float left = player->model.geom.min[0] - factor;
float right = player->model.geom.max[0] + factor;
float bottom = player->model.geom.min[1] - factor;
- float top = player->model.geom.max[1] + factor;
+ float top = player->model.geom.max[1] + factor/2.0;
- const float near = -80.0;
- const float far = 80.0;
+ const float near = -1.0;
+ const float far = 5.0;
// default ortho screenspace projection
mat4_ortho(left, right, bottom, top, near, far, m4_ortho);
@@ -220,7 +220,7 @@ void resize_fbos(struct entity *player, struct fbo *shadow_buffer,
// TODO: match based on some real concept of time
static void day_night_cycle(float time, struct resources *res) {
float val = time * 0.0001;
- float intensity = max(0.0, vec3_dot(res->light_dir, V3(0.0, 0.0, 0.8)));
+ float intensity = 1.0;//max(0.0, vec3_dot(res->light_dir, V3(0.0, 0.0, 1.0))); */
struct entity *player = get_player(res);
float light_pos[3];
@@ -246,8 +246,10 @@ static void day_night_cycle(float time, struct resources *res) {
/* vec3_normalize(res->light_intensity, res->light_intensity); */
res->light_dir[0] = 0.0;
- res->light_dir[1] = sin(val);
- res->light_dir[2] = cos(val) + 1.0;
+ /* res->light_dir[1] = sin(val); */
+ /* res->light_dir[2] = cos(val) + 1.0; */
+ res->light_dir[1] = 0.8;
+ res->light_dir[2] = 0.8;
vec3_normalize(res->light_dir, res->light_dir);
@@ -320,7 +322,7 @@ static void orbit_keep_above_ground(struct game *game) {
float cam_terrain_z =
game->terrain.fn(&game->terrain, camera_world[0], camera_world[1]);
- const float bias = 5.0;
+ const float bias = 2.0;
if (camera_world[2] < cam_terrain_z + bias)
camera_world[2] = cam_terrain_z + bias;