polyadvent

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

commit 4059ffe5baaa19c32f0ef6fea644a6cde673affd
parent 0c376a74dce59ab085ff95e890468268234cf881
Author: William Casarin <jb55@jb55.com>
Date:   Tue, 30 Oct 2018 22:29:54 -0700

semi energy conserved lighting

Diffstat:
Metc/shaders/fog.glsl | 8+++-----
Metc/shaders/lighting.glsl | 59++++++++++++++++++++++++++++++++++++++++++-----------------
Metc/shaders/uniforms.glsl | 2++
Msrc/game.c | 6++++++
Msrc/game.h | 2++
Msrc/render.c | 22++++++++++++++++++++--
Msrc/update.c | 7++++++-
7 files changed, 81 insertions(+), 25 deletions(-)

diff --git a/etc/shaders/fog.glsl b/etc/shaders/fog.glsl @@ -4,18 +4,16 @@ vec3 apply_fog(in vec3 rgb, in float distance, in vec3 ray_orig, in vec3 ray_dir float draw_dist = 1.4; float fog_amount = 1.0-exp(-pow(distance * (1.0/draw_dist) * b, 6.0)); - float sun_amount = max( dot( ray_dir, -light_dir ), 0.0 ) * b; - sun_amount = pow(sun_amount, 2.0); + // float sun_amount = max( dot( ray_dir, -light_dir ), 0.0 ) * b; + // sun_amount = pow(sun_amount, 0.0); - vec3 fog_color = sun_color; + vec3 fog_color = sun_color * sky_intensity; // vec3 fog_color = mix(vec3(0.5,0.6,0.7), // vec3(1.0,0.9,0.8), // smoothstep(0.1, 1.0, sun_amount) // ) * light_intensity; - fog_color = sun_color; - // vec3 final_color = rgb*(1.0-exp(-distance*b)) + fog_color*exp(-distance*b); vec3 final_color = mix( rgb, fog_color, fog_amount); diff --git a/etc/shaders/lighting.glsl b/etc/shaders/lighting.glsl @@ -3,17 +3,7 @@ #include noise.glsl - -vec3 standard_light(vec3 color, vec3 position) { - vec4 v4_normal = vec4(v_normal , 1); - vec4 trans_normal = normal_matrix * v4_normal; - - vec3 L = light_dir * light_intensity; - vec3 N = normalize(trans_normal.xyz); - - const float ambient_str = 0.1; - const float spec_str = 0.5; - +float clouds(vec3 position) { float cloud_speed = 20000.0; float cloud_pos = time * cloud_speed; float cloud_trans = vec3(cloud_pos, cloud_pos, 0.0); @@ -22,20 +12,55 @@ vec3 standard_light(vec3 color, vec3 position) { clouds *= max(0.0, dot(light_dir, vec3(0.0,0.0,1.0))); clouds *= 0.35 * exp(clouds * -0.3); - float brightness = max(0.0, dot(L,N)); + return clouds; +} + + +vec3 standard_light(vec3 color, vec3 position) { + vec4 v4_normal = vec4(v_normal , 1); + vec4 trans_normal = normal_matrix * v4_normal; - // brightness += clouds; + const float pi = 3.14159265; + const float shiny = 16.0; + float ambient_str = 0.1 + light_intensity * 0.1; + float spec_str = 0.5 * light_intensity; + + vec3 ray = camera_position - position; + vec3 view_dir = normalize(ray); + float distance = length(ray); + float attenuation = 1.0 / distance; + + vec3 L = light_dir; + vec3 N = normalize(trans_normal.xyz); + float brightness = max(0.0, dot(L,N)) * light_intensity; + + + // brightness += clouds(position); // brightness = clamp(brightness, 0.0, 1.0); vec3 diffuse = brightness * sun_color; vec3 ambient = ambient_str * sun_color; - vec3 view_dir = normalize(camera_position - v_frag_pos); - vec3 reflect_dir = normalize(light_dir + view_dir); // blin-phong - // vec3 reflect_dir = reflect(-light_dir, v_normal); // phong - float spec = pow(max(dot(view_dir, reflect_dir), 0.0), 16.0); + float spec; + bool blinn = true; + if (blinn) { + const float energy_conservation = ( 8.0 + shiny ) / ( 8.0 * pi ); + vec3 halfway_dir = normalize(light_dir + view_dir); // blinn-phong + spec = energy_conservation * pow(max(dot(v_normal, halfway_dir), 0.0), shiny); + } + else { + const float energy_conservation = ( 2.0 + shiny ) / ( 2.0 * pi ); + vec3 reflect_dir = reflect(-light_dir, v_normal); // phong + spec = energy_conservation * pow(max(dot(view_dir, reflect_dir), 0.0), shiny); + } + // spec += pow(max(dot(view_dir, reflect_dir), 0.0), 16.0) * 0.5; vec3 specular = spec_str * spec * sun_color; return (ambient + diffuse + specular) * color; } + + +vec3 gamma_correct(vec3 color) { + return pow(color, vec3(1.0/2.2)); +} diff --git a/etc/shaders/uniforms.glsl b/etc/shaders/uniforms.glsl @@ -2,12 +2,14 @@ uniform bool diffuse_on; uniform bool fog_on; uniform float light_intensity; +uniform float sky_intensity; uniform mat4 depth_mvp; uniform mat4 model_view; uniform mat4 mvp; uniform mat4 normal_matrix; uniform mat4 world; uniform float time; +// uniform float ambient_str; uniform vec3 sun_color; uniform vec3 camera_position; uniform vec3 light_dir; diff --git a/src/game.c b/src/game.c @@ -87,6 +87,12 @@ void game_init(struct game *game, int width, int height) { res->sun_color[1] = 0.9; res->sun_color[2] = 0.8; + res->sun_color[0] = 0.5; + res->sun_color[1] = 0.6; + res->sun_color[2] = 0.7; + + /* vec3(0.5,0.6,0.7); */ + // BRB: shadow mapping next! // FBO STUFF diff --git a/src/game.h b/src/game.h @@ -37,6 +37,8 @@ struct resources { GLint camera_position; GLint light_dir; GLint light_intensity; + GLint sky_intensity; + GLint ambient_str; GLint sun_color; GLint mvp; GLint depth_mvp; diff --git a/src/render.c b/src/render.c @@ -111,12 +111,18 @@ init_gl(struct resources *resources, int width, int height) { resources->uniforms.camera_position = glGetUniformLocation(handle, "camera_position"); + resources->uniforms.ambient_str = + glGetUniformLocation(handle, "ambient_str"); + resources->uniforms.depth_mvp = glGetUniformLocation(handle, "depth_mvp"); resources->uniforms.light_intensity = glGetUniformLocation(handle, "light_intensity"); + resources->uniforms.sky_intensity = + glGetUniformLocation(handle, "sky_intensity"); + resources->uniforms.time = glGetUniformLocation(handle, "time"); @@ -169,14 +175,25 @@ recalc_normals(GLint nm_uniform, mat4 *model_view, mat4 *normal) { glUniformMatrix4fv(nm_uniform, 1, 0, normal); } - +static void gamma_correct(float *c, float *d) { + float gamma = 1.0/2.2; + d[0] = powf(c[0], gamma); + d[1] = powf(c[1], gamma); + d[2] = powf(c[2], gamma); +} void render (struct game *game, struct render_config *config) { float adjust = game->test_resources.light_intensity; + float gtmp[3]; struct resources *res = &game->test_resources; glEnable(GL_DEPTH_TEST); - glClearColor( res->sun_color[0], res->sun_color[1], res->sun_color[2], 1.0 ); //clear background screen to black + + gamma_correct(res->sun_color, gtmp); + float sky_intensity = clamp(res->light_intensity, 0.2, 1.0); + vec3_scale(gtmp, sky_intensity, gtmp); + + glClearColor( gtmp[0], gtmp[1], gtmp[2], 1.0 ); //clear background screen to black /* glClearColor( 0.5294f * adjust, 0.8078f * adjust, 0.9216f * adjust, 1.0f ); //clear background screen to black */ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); check_gl(); @@ -236,6 +253,7 @@ void render (struct game *game, struct render_config *config) { glUniform3f(res->uniforms.light_dir, light[0], light[1], light[2]); glUniform1f(res->uniforms.light_intensity, res->light_intensity); glUniform1f(res->uniforms.time, res->time); + glUniform1f(res->uniforms.sky_intensity, sky_intensity); glUniform3f(res->uniforms.sun_color, res->sun_color[0], res->sun_color[1], diff --git a/src/update.c b/src/update.c @@ -243,13 +243,18 @@ void resize_fbos(struct game *game, int width, int height) { static void day_night_cycle(float time, struct resources *res) { float val = time * 50.0; float intensity = vec3_dot(res->light_dir, V3(0.0, 0.0, 1.0)); - intensity = clamp(intensity, 0.0, 0.9); + intensity = clamp(intensity, 0.0, 0.8); float light_pos[3]; res->sun_color[0] = 1.0; res->sun_color[1] = 0.9; res->sun_color[2] = 0.8; + /* res->sun_color[0] = 1.0; */ + /* res->sun_color[1] = 1.0; */ + /* res->sun_color[2] = 1.0; */ + + /* vec3_scale(res->sun_color, res->light_intensity, gtmp); */ /* float intensity = angle <= 0.5 */ /* ? clamp(roots, darkest, 1.0) */