polyadvent

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

commit 9f66964e39c327a807f748b41dc36dedb465b1fa
parent dcf01285acec1b3b5d3ee1da827979d535c1512b
Author: William Casarin <jb55@jb55.com>
Date:   Sun, 11 Nov 2018 10:26:31 -0800

wip: pbr

Diffstat:
Metc/shaders/lighting.glsl | 50+++++++++++++++++++++++++++++++++++++++++++++++++-
Metc/shaders/standard_vtxos.glsl | 3+++
Metc/shaders/test.f.glsl | 26+++++++++++++++++++-------
Msrc/game.c | 4++--
4 files changed, 73 insertions(+), 10 deletions(-)

diff --git a/etc/shaders/lighting.glsl b/etc/shaders/lighting.glsl @@ -14,6 +14,7 @@ // return clouds; // } +const float pi = 3.14159265; vec3 gamma_correct(vec3 color) { return pow(color, vec3(1.0/2.2)); @@ -31,7 +32,6 @@ vec3 uncharted_tonemap(const vec3 x) { vec3 standard_light(vec3 color, vec4 position, vec4 normal) { // vec3 light_dir = vec3() - const float pi = 3.14159265; const float shiny = 14.0; const float exposure = 0.3; float ambient_str = 0.2; @@ -85,4 +85,52 @@ vec3 standard_light(vec3 color, vec4 position, vec4 normal) { return final; } +float dist_ggx(vec3 N, vec3 H, float a) +{ + float a2 = a*a; + float NdotH = max(dot(N, H), 0.0); + float NdotH2 = NdotH*NdotH; + float nom = a2; + float denom = (NdotH2 * (a2 - 1.0) + 1.0); + denom = pi * denom * denom; + + return nom / denom; +} + + +float geom_schlick_ggx(float NdotV, float k) +{ + float nom = NdotV; + float denom = NdotV * (1.0 - k) + k; + + return nom / denom; +} + +float geom_smith(vec3 N, vec3 V, vec3 L, float k) +{ + float NdotV = max(dot(N, V), 0.0); + float NdotL = max(dot(N, L), 0.0); + float ggx1 = geom_schlick_ggx(NdotV, k); + float ggx2 = geom_schlick_ggx(NdotL, k); + + 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 V, vec3 normal) { + const float albedo = 0.2; + const float metallic = 0.8; + vec3 N = normalize(normal); + vec3 L = normalize(light_dir); + vec3 H = normalize(V + L); + vec3 F0 = vec3(0.04); + F0 = mix(F0, albedo, metallic); + float cos_theta = max(dot(H, V)) + vec3 F = fresnel_schlick(cos_theta, ) + +} diff --git a/etc/shaders/standard_vtxos.glsl b/etc/shaders/standard_vtxos.glsl @@ -1,4 +1,7 @@ vec4 v4_pos = vec4(position, 1.0); +// data_out.normal = normal; +// data_out.position = position; + data_out.normal = mat3(transpose(inverse(model))) * normal; data_out.position = vec3(model * v4_pos); data_out.color_smooth = data_out.color = color; diff --git a/etc/shaders/test.f.glsl b/etc/shaders/test.f.glsl @@ -15,25 +15,37 @@ uniform samplerCube skybox; #include shadows.glsl #include fog.glsl +vec3 reflect_env(vec3 vert_pos) { + vec3 I = normalize(vert_pos - camera_position); + vec3 R = reflect(I, normalize(vertex.normal)); + vec3 color = texture(skybox, R).rgb; + return color; +} + +vec3 refract_env(vec3 vert_pos) { + const float ratio = 1.00 / 1.52; + + vec3 I = normalize(vert_pos - camera_position); + vec3 R = refract(I, normalize(vertex.normal), ratio); + vec3 color = texture(skybox, R).rgb; + return color; +} + void main() { - vec3 v_ray = camera_position - vertex.frag_pos; + vec3 V = camera_position - vertex.frag_pos; vec4 v4_pos = vec4(vertex.position, 1.0); vec4 v4_normal = vec4(vertex.normal, 1.0); - // vec3 color = vertex.color * (1.0-smoothness) - // + color_smooth * smoothness; // vec3 color = standard_light(vertex.color, v4_pos, v4_normal); + vec3 color = pbr(normalize(V)); // 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 *= shadow_strength(v4_pos, v4_normal, vertex.shadow_coord); - vec3 I = normalize(vertex.position - camera_position); - vec3 R = reflect(I, normalize(vertex.normal)); - vec3 color = texture(skybox, R).rgb; + // vec3 color = reflect_env(vertex.position); frag_color = vec4(gamma_correct(color), 1.0); } diff --git a/src/game.c b/src/game.c @@ -119,14 +119,14 @@ void game_init(struct game *game, int width, int height) { res->camera.coords.azimuth = -quat_yaw(player->node.orientation) - RAD(90.0); res->camera.coords.inclination = RAD(60); - res->camera.coords.radius = 2.0; + res->camera.coords.radius = 5.0; struct entity *tower = new_entity(NULL); ok = load_model(&tower->model, "tower"); assert(ok); tower->node.label = "tower"; node_attach(&tower->node, &player->node); - node_translate(&tower->node, V3(0.0, 100.0, 0.0)); + node_translate(&tower->node, V3(0.0, 50.0, 0.0)); // END ENTITIES