polyadvent

A game engine from scratch in C
git clone git://jb55.com/polyadvent
Log | Files | Refs | README

commit abb67a77d710c242521dd9823bfa55ba55ac1ad1
parent 3e3c5e978dfc12d5ee7d768a5c5ed74760899352
Author: William Casarin <jb55@jb55.com>
Date:   Sun,  4 Nov 2018 02:17:17 -0800

fix shadow issues

Diffstat:
Metc/shaders/test.f.glsl | 29+++++++++++++++++++----------
Metc/shaders/uniforms.glsl | 2+-
Msrc/game.c | 4++--
Msrc/main.c | 8++++----
Msrc/render.c | 36++++++++++++++++++++----------------
Msrc/render.h | 2+-
Msrc/update.c | 16++++++++--------
7 files changed, 55 insertions(+), 42 deletions(-)

diff --git a/etc/shaders/test.f.glsl b/etc/shaders/test.f.glsl @@ -24,18 +24,27 @@ void main() { // + color_smooth * smoothness; vec3 color = standard_light(vertex.color, vertex.position, vertex.normal); - // if (fog_on) { - // vec3 fog = apply_fog(color, length(v_ray), camera_position, v_ray); - // // vec3 fog = depth_fog(color, shadow_sample); - // color = fog; - // } - - if (light_dir.z > 0.0 && shadow_sample.z < vertex.shadow_coord.z ) { - float factor = 1.0/dot(light_dir, vec3(0.0, 0.0, 1.0)); - visibility = clamp(0.2 * factor, 0.5, 1.0); + if (fog_on) { + vec3 fog = apply_fog(color, length(v_ray), camera_position, v_ray); + // vec3 fog = depth_fog(color, shadow_sample); + color = fog; } - color = color * visibility; + float bias = 0.006; + bool in_shadow = + shadow_sample.z < vertex.shadow_coord.z - bias + && shadow_sample.y < 1.0; + + if (light_dir.z > 0.0 && in_shadow) { + float factor = 1.0/(dot(light_dir, vec3(0.0, 0.0, 1.0))); + // float factor = 1.0; + visibility = clamp(0.2 * factor, 0.5, 1.0); + // visibility = shadow_sample; + } + + // float factor = 1.0/(dot(light_dir, vec3(0.0, 0.0, 1.0))); + color *= visibility; + // color += shadow_sample.z * factor; // float dist = length(camera_position - vertex.position); frag_color = vec4(color, 1.0); diff --git a/etc/shaders/uniforms.glsl b/etc/shaders/uniforms.glsl @@ -4,7 +4,7 @@ uniform bool fog_on; uniform float sky_intensity; uniform float light_intensity; uniform mat4 depth_mvp; -// uniform mat4 model_view; +uniform mat4 model_view; uniform mat4 mvp; uniform mat4 normal_matrix; uniform mat4 world; diff --git a/src/game.c b/src/game.c @@ -40,7 +40,7 @@ void game_init(struct game *game, int width, int height) { mat4 *light_dir = res->light_dir; int ok = 0; - const double size = 10000; + const double size = 10000.0; terrain->settings = (struct perlin_settings){ .depth = 1, @@ -106,7 +106,7 @@ void game_init(struct game *game, int width, int height) { terrain->entity.casts_shadows = 0; // player init - ok = load_model(&player->model, "tower"); + ok = load_model(&player->model, "pirate-officer"); assert(ok); player->model.shading = SHADING_VERT_COLOR; player->node.label = "player"; diff --git a/src/main.c b/src/main.c @@ -44,15 +44,15 @@ int main(void) check_gl(); double last = hires_time_in_seconds(); - static float depth_mvp[MAT4_ELEMS]; - mat4_id(depth_mvp); + static float depth_vp[MAT4_ELEMS]; + mat4_id(depth_vp); struct render_config fbo_render_config = { .draw_ui = 0, .is_depth_pass = 1, .camera = game.test_resources.sun_camera.mat, .projection = game.test_resources.proj_ortho, - .depth_mvp = depth_mvp + .depth_vp = depth_vp }; struct render_config default_config = { @@ -60,7 +60,7 @@ int main(void) .is_depth_pass = 0, .camera = game.test_resources.camera.mat, .projection = game.test_resources.proj_persp, - .depth_mvp = depth_mvp + .depth_vp = depth_vp }; while (1) { diff --git a/src/render.c b/src/render.c @@ -180,8 +180,8 @@ init_gl(struct resources *resources, int width, int height) { glGetUniformLocation(handle, "mvp"); check_gl(); - /* resources->uniforms.model_view = */ - /* glGetUniformLocation(handle, "model_view"); */ + resources->uniforms.model_view = + glGetUniformLocation(handle, "model_view"); resources->uniforms.normal_matrix = glGetUniformLocation(handle, "normal_matrix"); @@ -241,6 +241,7 @@ void render (struct game *game, struct render_config *config) { static float view_proj[MAT4_ELEMS] = { 0 }; static float normal_matrix[MAT4_ELEMS] = { 0 }; static float model_view[MAT4_ELEMS] = { 0 }; + static float depth_mvp[MAT4_ELEMS] = { 0 }; mat4_id(id); mat4_id(model_view); @@ -263,6 +264,17 @@ void render (struct game *game, struct render_config *config) { struct gpu_program *default_program = &game->test_resources.programs[DEFAULT_PROGRAM]; + mat4_inverse(camera, view); + mat4_multiply(projection, view, view_proj); + + if (config->is_depth_pass) { + /* glCullFace(GL_FRONT); */ + mat4_multiply(bias_matrix, view_proj, config->depth_vp); + } + else { + glCullFace(GL_BACK); + } + for (size_t i = 0; i < ARRAY_SIZE(entities); ++i) { struct entity *entity = entities[i]; if (config->is_depth_pass && !entity->casts_shadows) @@ -273,18 +285,6 @@ void render (struct game *game, struct render_config *config) { glUseProgram(current_program->handle); check_gl(); - mat4_inverse(camera, view); - mat4_multiply(projection, view, view_proj); - - if (config->is_depth_pass) { - mat4_multiply(bias_matrix, view_proj, config->depth_mvp); - /* glCullFace(GL_FRONT); */ - } - else { - glUniformMatrix4fv(res->uniforms.depth_mvp, 1, 0, config->depth_mvp); - glCullFace(GL_BACK); - } - check_gl(); glUniform3f(res->uniforms.camera_position, camera[M_X], @@ -309,11 +309,15 @@ void render (struct game *game, struct render_config *config) { mat4_multiply(view_proj, entity->node.mat, mvp); mat4_copy(entity->node.mat, model_view); + /* if (i == 1) */ + /* mat4_multiply(bias_matrix, mvp, config->depth_mvp); */ + mat4_multiply(config->depth_vp, model_view, depth_mvp); + glUniformMatrix4fv(res->uniforms.mvp, 1, 0, mvp); check_gl(); - glUniformMatrix4fv(res->uniforms.depth_mvp, 1, 0, config->depth_mvp); + glUniformMatrix4fv(res->uniforms.depth_mvp, 1, 0, depth_mvp); check_gl(); - /* glUniformMatrix4fv(res->uniforms.model_view, 1, 0, model_view); */ + glUniformMatrix4fv(res->uniforms.model_view, 1, 0, model_view); check_gl(); glUniformMatrix4fv(res->uniforms.world, 1, 0, entity->node.mat); check_gl(); diff --git a/src/render.h b/src/render.h @@ -10,7 +10,7 @@ struct render_config { int is_depth_pass; float *camera; float *projection; - float *depth_mvp; + float *depth_vp; }; void init_gl(struct resources *resources, int width, int height); diff --git a/src/update.c b/src/update.c @@ -221,14 +221,14 @@ void resize_fbos(struct game *game, int width, int height) { } // TODO: compute better bounds based - const float factor = 4.0; - float left = res->player.model.geom.min[0] * factor; - float right = res->player.model.geom.max[0] * factor; - float bottom = res->player.model.geom.min[1] * factor; - float top = res->player.model.geom.max[1] * factor; - - const float near = -10000.0; - const float far = 10000.0; + const float factor = 10.0; + float left = res->player.model.geom.min[0] - factor; + float right = res->player.model.geom.max[0] + factor; + float bottom = res->player.model.geom.min[1] - factor; + float top = res->player.model.geom.max[1] + factor; + + const float near = -50.0; + const float far = 50.0; // default ortho screenspace projection mat4_ortho(left, right, bottom, top, near, far, res->proj_ortho);