Merge pull request #62 from kichikuou/lighting

ReignEngine: Implement rim lighting and specular mapping
This commit is contained in:
Nunuhara Cabbage
2022-07-10 21:47:49 -07:00
committed by GitHub
4 changed files with 82 additions and 16 deletions
+13 -1
View File
@@ -23,6 +23,7 @@ struct dir_light {
};
uniform sampler2D tex;
uniform sampler2D specular_texture;
uniform float alpha_mod;
uniform vec3 ambient;
@@ -30,6 +31,9 @@ uniform dir_light dir_lights[NR_DIR_LIGHTS];
uniform vec3 specular_light_dir;
uniform float specular_strength;
uniform float specular_shininess;
uniform bool use_specular_map;
uniform float rim_exponent;
uniform vec3 rim_color;
uniform vec3 view_pos;
in vec2 tex_coord;
@@ -39,6 +43,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 +57,18 @@ 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;
if (use_specular_map) {
specular *= texture(specular_texture, tex_coord).r;
}
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);
}
+13 -1
View File
@@ -47,9 +47,11 @@ struct mesh {
struct material {
GLuint color_map;
bool opaque;
GLuint specular_map;
float specular_strength;
float specular_shininess;
float rim_exponent;
vec3 rim_color;
};
struct bone {
@@ -90,6 +92,10 @@ struct RE_renderer {
GLint specular_light_dir;
GLint specular_strength;
GLint specular_shininess;
GLint use_specular_map;
GLint specular_texture;
GLint rim_exponent;
GLint rim_color;
GLint view_pos;
// Attribute variable locations
@@ -137,6 +143,7 @@ struct pol {
enum pol_texture_type {
COLOR_MAP = 1,
SPECULAR_MAP = 4,
MAX_TEXTURE_TYPE
};
@@ -220,6 +227,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);
+32 -12
View File
@@ -45,27 +45,24 @@ static struct archive_data *get_aar_entry(struct archive *aar, const char *dir,
return dfile;
}
static bool init_material(struct material *material, const struct pol_material *m, struct amt *amt, struct archive *aar, const char *path)
static GLuint load_texture(struct archive *aar, const char *path, const char *name)
{
if (!m->textures[COLOR_MAP]) {
WARNING("No color texture");
return false;
}
struct archive_data *dfile = get_aar_entry(aar, path, m->textures[COLOR_MAP], "");
struct archive_data *dfile = get_aar_entry(aar, path, name, "");
if (!dfile) {
WARNING("cannot load texture %s\\%s", path, m->textures[COLOR_MAP]);
return false;
WARNING("cannot load texture %s\\%s", path, name);
return 0;
}
struct cg *cg = cg_load_data(dfile);
if (!cg) {
WARNING("cg_load_data failed: %s", dfile->name);
archive_free_data(dfile);
return false;
return 0;
}
archive_free_data(dfile);
glGenTextures(1, &material->color_map);
glBindTexture(GL_TEXTURE_2D, material->color_map);
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cg->metrics.w, cg->metrics.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, cg->pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
@@ -73,13 +70,34 @@ static bool init_material(struct material *material, const struct pol_material *
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
material->opaque = !cg->metrics.has_alpha;
cg_free(cg);
return texture;
}
static bool init_material(struct material *material, const struct pol_material *m, struct amt *amt, struct archive *aar, const char *path)
{
if (!m->textures[COLOR_MAP]) {
WARNING("No color texture");
return false;
}
material->color_map = load_texture(aar, path, m->textures[COLOR_MAP]);
if (!material->color_map)
return false;
if (m->textures[SPECULAR_MAP]) {
material->specular_map = load_texture(aar, path, m->textures[SPECULAR_MAP]);
}
struct amt_material *amt_m = amt ? amt_find_material(amt, m->name) : NULL;
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;
@@ -89,6 +107,8 @@ static void destroy_material(struct material *material)
{
if (material->color_map)
glDeleteTextures(1, &material->color_map);
if (material->specular_map)
glDeleteTextures(1, &material->specular_map);
}
static int cmp_by_bone_weight(const void *lhs, const void *rhs)
+24 -2
View File
@@ -27,6 +27,11 @@
#include "sact.h"
#include "vm.h"
enum {
COLOR_TEXTURE_UNIT,
SPECULAR_TEXTURE_UNIT,
};
static void init_billboard_mesh(struct RE_renderer *r)
{
static const GLfloat vertices[] = {
@@ -82,6 +87,10 @@ 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->use_specular_map = glGetUniformLocation(r->shader.program, "use_specular_map");
r->specular_texture = glGetUniformLocation(r->shader.program, "specular_texture");
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");
@@ -266,17 +275,28 @@ static void render_model(struct RE_instance *inst, struct RE_renderer *r)
struct mesh *mesh = &model->meshes[i];
struct material *material = &model->materials[mesh->material];
GLboolean use_specular_map = GL_FALSE;
if (inst->plugin->specular_mode) {
glUniform1f(r->specular_strength, material->specular_strength);
glUniform1f(r->specular_shininess, material->specular_shininess);
if (material->specular_map) {
glActiveTexture(GL_TEXTURE0 + SPECULAR_TEXTURE_UNIT);
glBindTexture(GL_TEXTURE_2D, material->specular_map);
glUniform1i(r->specular_texture, SPECULAR_TEXTURE_UNIT);
use_specular_map = GL_TRUE;
}
} else {
glUniform1f(r->specular_strength, 0.0);
glUniform1f(r->specular_shininess, 0.0);
}
glUniform1i(r->use_specular_map, use_specular_map);
glActiveTexture(GL_TEXTURE0);
glUniform1f(r->rim_exponent, material->rim_exponent);
glUniform3fv(r->rim_color, 1, material->rim_color);
glActiveTexture(GL_TEXTURE0 + COLOR_TEXTURE_UNIT);
glBindTexture(GL_TEXTURE_2D, material->color_map);
glUniform1i(r->shader.texture, 0);
glUniform1i(r->shader.texture, COLOR_TEXTURE_UNIT);
glBindVertexArray(mesh->vao);
glDrawArrays(GL_TRIANGLES, 0, mesh->nr_vertices);
@@ -336,6 +356,8 @@ 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);
glUniform1i(r->use_specular_map, GL_FALSE);
glUniform1f(r->rim_exponent, 0.0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, bt->texture);