From fe02c8f4019d00c095a65cbad316f02dc199a428 Mon Sep 17 00:00:00 2001 From: kichikuou Date: Sun, 10 Jul 2022 13:20:50 +0900 Subject: [PATCH] ReignEngine: Implement rim lighting Lighting parameters are per-material and are stored in the .amt file. --- shaders/reign.f.glsl | 9 ++++++++- src/3d/3d_internal.h | 9 +++++++++ src/3d/model.c | 6 ++++++ src/3d/renderer.c | 5 +++++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/shaders/reign.f.glsl b/shaders/reign.f.glsl index bafb563..c6275a6 100644 --- a/shaders/reign.f.glsl +++ b/shaders/reign.f.glsl @@ -30,6 +30,8 @@ uniform dir_light dir_lights[NR_DIR_LIGHTS]; uniform vec3 specular_light_dir; uniform float specular_strength; uniform float specular_shininess; +uniform float rim_exponent; +uniform vec3 rim_color; uniform vec3 view_pos; in vec2 tex_coord; @@ -39,6 +41,7 @@ out vec4 frag_color; void main() { vec3 norm = normalize(normal); + vec3 view_dir = normalize(view_pos - frag_pos); vec3 frag_rgb = ambient; // Diffuse lighting @@ -52,11 +55,15 @@ void main() { // Specular lighting if (specular_strength > 0.0) { - vec3 view_dir = normalize(view_pos - frag_pos); vec3 reflect_dir = reflect(specular_light_dir, norm); float specular = pow(max(dot(view_dir, reflect_dir), 0.0), specular_shininess) * specular_strength; frag_rgb += vec3(specular); } + // Rim lighting + if (rim_exponent > 0) { + frag_rgb += pow(1.0 - max(dot(norm, view_dir), 0.0), rim_exponent) * rim_color; + } + frag_color = vec4(frag_rgb, texel.a * alpha_mod); } diff --git a/src/3d/3d_internal.h b/src/3d/3d_internal.h index 5292d31..db1b22a 100644 --- a/src/3d/3d_internal.h +++ b/src/3d/3d_internal.h @@ -50,6 +50,8 @@ struct material { bool opaque; float specular_strength; float specular_shininess; + float rim_exponent; + vec3 rim_color; }; struct bone { @@ -90,6 +92,8 @@ struct RE_renderer { GLint specular_light_dir; GLint specular_strength; GLint specular_shininess; + GLint rim_exponent; + GLint rim_color; GLint view_pos; // Attribute variable locations @@ -220,6 +224,11 @@ struct amt_material { enum amt_field_index { AMT_SPECULAR_STRENGTH = 0, AMT_SPECULAR_SHININESS = 2, + // amt v5+ + AMT_RIM_EXPONENT = 7, + AMT_RIM_R = 8, + AMT_RIM_G = 9, + AMT_RIM_B = 10, }; struct pol *pol_parse(uint8_t *data, size_t size); diff --git a/src/3d/model.c b/src/3d/model.c index f8df832..c03ed4d 100644 --- a/src/3d/model.c +++ b/src/3d/model.c @@ -80,6 +80,12 @@ static bool init_material(struct material *material, const struct pol_material * if (amt_m) { material->specular_strength = amt_m->fields[AMT_SPECULAR_STRENGTH]; material->specular_shininess = amt_m->fields[AMT_SPECULAR_SHININESS]; + if (amt->version >= 5) { + material->rim_exponent = amt_m->fields[AMT_RIM_EXPONENT]; + material->rim_color[0] = amt_m->fields[AMT_RIM_R]; + material->rim_color[1] = amt_m->fields[AMT_RIM_G]; + material->rim_color[2] = amt_m->fields[AMT_RIM_B]; + } } return true; diff --git a/src/3d/renderer.c b/src/3d/renderer.c index e8e3d21..d577edd 100644 --- a/src/3d/renderer.c +++ b/src/3d/renderer.c @@ -82,6 +82,8 @@ struct RE_renderer *RE_renderer_new(struct texture *texture) r->specular_light_dir = glGetUniformLocation(r->shader.program, "specular_light_dir"); r->specular_strength = glGetUniformLocation(r->shader.program, "specular_strength"); r->specular_shininess = glGetUniformLocation(r->shader.program, "specular_shininess"); + r->rim_exponent = glGetUniformLocation(r->shader.program, "rim_exponent"); + r->rim_color = glGetUniformLocation(r->shader.program, "rim_color"); r->view_pos = glGetUniformLocation(r->shader.program, "view_pos"); r->vertex_normal = glGetAttribLocation(r->shader.program, "vertex_normal"); r->vertex_uv = glGetAttribLocation(r->shader.program, "vertex_uv"); @@ -273,6 +275,8 @@ static void render_model(struct RE_instance *inst, struct RE_renderer *r) glUniform1f(r->specular_strength, 0.0); glUniform1f(r->specular_shininess, 0.0); } + glUniform1f(r->rim_exponent, material->rim_exponent); + glUniform3fv(r->rim_color, 1, material->rim_color); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, material->color_map); @@ -336,6 +340,7 @@ static void render_billboard(struct RE_instance *inst, struct RE_renderer *r, ma glUniform1f(r->alpha_mod, inst->alpha); glUniform1f(r->specular_strength, 0.0); glUniform1f(r->specular_shininess, 0.0); + glUniform1f(r->rim_exponent, 0.0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, bt->texture);