mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-10-03 20:38:13 +03:00
Merge pull request #62 from kichikuou/lighting
ReignEngine: Implement rim lighting and specular mapping
This commit is contained in:
+13
-1
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user