polyadvent

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

commit 5492c60d3968e741955463e52ef07bef06c56edb
parent 21df97e0cbc1d9333d7291000fe11c78047794e3
Author: William Casarin <jb55@jb55.com>
Date:   Thu, 25 Oct 2018 18:48:00 -0700

hemispherical lightning for models

Diffstat:
Metc/shaders/terrain.glsl | 5+++--
Aetc/shaders/test-smooth.f.glsl | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Metc/shaders/test.f.glsl | 3+--
Metc/shaders/vertex-color.glsl | 31+++++++++++++++++++++----------
Msrc/game.h | 1+
Msrc/render.c | 17++++++++++++++++-
6 files changed, 105 insertions(+), 15 deletions(-)

diff --git a/etc/shaders/terrain.glsl b/etc/shaders/terrain.glsl @@ -35,9 +35,9 @@ void main() vec4 trans_normal = normal_matrix * v4_normal; vec4 v4_pos = vec4(position, 1.0); gl_Position = mvp * v4_pos; - v_light = dot(trans_normal.xyz, normalize(light_dir)) ; + float light = dot(trans_normal.xyz, normalize(light_dir)) ; - v_color = land[0].xyz; + v_color = land[0].xyz * light; for (int i = 0; i < nlands-1; i++) { v_color = @@ -50,6 +50,7 @@ void main() // v_color = vec3(position.z, position.z, position.z) * 0.005; + v_color *= light; v_normal = trans_normal.xyz; v_ray = camera_position - (world * v4_pos).xyz; } diff --git a/etc/shaders/test-smooth.f.glsl b/etc/shaders/test-smooth.f.glsl @@ -0,0 +1,63 @@ +#version 300 es + +precision mediump float; + +in float v_light; +in vec3 v_color; +in vec3 v_normal; +in vec3 v_ray; +out vec4 fragmentColor; + +uniform vec3 camera_position; +uniform bool fog_on; +uniform bool diffuse_on; +uniform mat4 normal_matrix; + +vec3 apply_fog(in vec3 rgb, in float distance, in vec3 ray_orig, in vec3 ray_dir) { + const float b = 0.00026; + const float v = 1.0; + const float zs = 1.0; + + + const float c = 1.0; + + // float fog_amount = + // exp(-ray_orig.z*b) * (1.0-exp( -distance*ray_dir.z*b))/ray_dir.z*b; + + float fog_amount = 1.0 - exp(-(pow(distance*b, 2.0))) ; + + vec3 fog_color = vec3(0.5,0.6,0.7); + return mix( rgb, fog_color, fog_amount); +} + +vec3 gamma_correct(vec3 color) { + return pow(color, vec3(1.0/2.2)); +} + +float lambert(vec3 N, vec3 L) +{ + vec3 nrmN = normalize(N); + vec3 nrmL = normalize(L); + float result = dot(nrmN, nrmL); + return max(result, 0.0); +} + + +void main() { + float distance = length(v_ray); + vec3 light_position = vec3(2.0,1.0,5.0); + + vec3 color; + + vec3 frag = v_color * v_light; + + if (fog_on) { + vec3 fog = apply_fog(frag, distance, camera_position, v_ray); + color = frag + (fog * 0.000001); + } + else + color = frag; + + // fragmentColor = vec4(color + diffuse, 1.0); + fragmentColor = vec4(gamma_correct(color), 1.0); +} diff --git a/etc/shaders/test.f.glsl b/etc/shaders/test.f.glsl @@ -2,7 +2,6 @@ precision mediump float; -flat in float v_light; flat in vec3 v_color; flat in vec3 v_normal; in vec3 v_ray; @@ -49,7 +48,7 @@ void main() { vec3 color; - vec3 frag = v_color * v_light; + vec3 frag = v_color; if (fog_on) { vec3 fog = apply_fog(frag, distance, camera_position, v_ray); diff --git a/etc/shaders/vertex-color.glsl b/etc/shaders/vertex-color.glsl @@ -1,3 +1,4 @@ + #version 300 es precision mediump float; @@ -21,14 +22,24 @@ out vec3 v_ray; void main() { - vec4 v4_normal = vec4(normal, 1); - vec4 trans_normal = normal_matrix * v4_normal; - vec4 v4_pos = vec4(position, 1.0); - gl_Position = mvp * v4_pos; - v_light = dot(trans_normal.xyz, normalize(light_dir)); - - v_color = color; - - // v_normal = trans_normal.xyz; - v_ray = camera_position - (world * v4_pos).xyz; + vec4 v4_normal = vec4(normal, 1); + vec4 trans_normal = normal_matrix * v4_normal; + vec4 v4_pos = vec4(position, 1.0); + gl_Position = mvp * v4_pos; + vec3 L = normalize(light_dir); + //float light = dot(trans_normal.xyz, L); + + //Make sure the normal is actually unit length, + //and isolate the important coordinates + vec3 N = normalize(trans_normal.xyz); + + //Calculate cosine of angle between light direction and normal + float costheta = dot(L,N); + + float a = 0.5+(0.5*costheta); + v_color = a * vec3(1.0, 1.0, 1.0) * color + + (1.0-a) * vec3(0.2, 0.2, 0.2) * color; + + // v_normal = trans_normal.xyz; + v_ray = camera_position - (world * v4_pos).xyz; } diff --git a/src/game.h b/src/game.h @@ -20,6 +20,7 @@ struct resources { struct vbo vertex_buffer, element_buffer, normal_buffer; struct gpu_program program; + struct gpu_program smooth_program; struct gpu_program terrain_program; struct uniforms { diff --git a/src/render.c b/src/render.c @@ -55,7 +55,7 @@ static const GLushort cube_indices[] = { void init_gl(struct resources *resources, int width, int height) { - struct shader vertex, terrain_vertex, fragment; + struct shader vertex, terrain_vertex, fragment, fragment_smooth; float tmp_matrix[16]; int ok = 0; @@ -79,6 +79,11 @@ init_gl(struct resources *resources, int width, int height) { assert(ok); + ok = + make_shader(GL_FRAGMENT_SHADER, SHADER("test-smooth.f.glsl"), &fragment_smooth); + + assert(ok); + // camera mat4_perspective(90 /* fov */, (float)width / height, @@ -97,6 +102,13 @@ init_gl(struct resources *resources, int width, int height) { ok = make_program(&vertex, &fragment, &resources->program); + assert(ok); + + ok = + make_program(&vertex, &fragment_smooth, &resources->smooth_program); + + assert(ok); + check_gl(); assert(ok); @@ -104,6 +116,7 @@ init_gl(struct resources *resources, int width, int height) { GLuint programs[] = { resources->terrain_program.handle , resources->program.handle + , resources->smooth_program.handle }; // uniforms shared between all shaders @@ -257,6 +270,8 @@ void render (struct game *game) { render_geom(res, &entity->model.geom, GL_TRIANGLES); + printf("i %ld\n", i); + check_gl(); }