ReignEngine: Implement light mapping

This commit is contained in:
kichikuou
2022-07-16 15:26:41 +09:00
parent 84f55a55cd
commit af7127580c
6 changed files with 75 additions and 12 deletions
+6
View File
@@ -24,6 +24,7 @@ struct dir_light {
uniform sampler2D tex;
uniform sampler2D specular_texture;
uniform sampler2D light_texture;
uniform float alpha_mod;
uniform bool use_normal_map;
@@ -36,8 +37,10 @@ uniform float specular_shininess;
uniform bool use_specular_map;
uniform float rim_exponent;
uniform vec3 rim_color;
uniform bool use_light_map;
in vec2 tex_coord;
in vec2 light_tex_coord;
in vec3 frag_pos;
in vec3 eye;
in vec3 normal;
@@ -63,6 +66,9 @@ void main() {
float half_lambert = dot(norm, -light_dir[i]) * 0.5 + 0.5;
diffuse += mix(dir_lights[i].globe_diffuse, dir_lights[i].diffuse, half_lambert);
}
if (use_light_map) {
diffuse *= texture(light_texture, light_tex_coord).rgb;
}
vec4 texel = texture(tex, tex_coord);
frag_rgb += texel.rgb * diffuse;
+3
View File
@@ -41,11 +41,13 @@ uniform vec3 specular_light_dir;
in vec3 vertex_pos;
in vec3 vertex_normal;
in vec2 vertex_uv;
in vec2 vertex_light_uv;
in vec4 vertex_tangent;
in ivec4 vertex_bone_index;
in vec4 vertex_bone_weight;
out vec2 tex_coord;
out vec2 light_tex_coord;
out vec3 frag_pos;
out vec3 eye;
out vec3 normal;
@@ -82,6 +84,7 @@ void main() {
gl_Position = proj_transform * view_transform * world_pos;
tex_coord = vertex_uv;
light_tex_coord = vertex_light_uv;
// These are in tangent-space if use_normal_map is true, in world-space
// otherwise.
+8
View File
@@ -48,6 +48,7 @@ struct mesh {
struct material {
GLuint color_map;
GLuint specular_map;
GLuint light_map;
GLuint normal_map;
float specular_strength;
float specular_shininess;
@@ -98,12 +99,15 @@ struct RE_renderer {
GLint rim_exponent;
GLint rim_color;
GLint view_pos;
GLint use_light_map;
GLint light_texture;
GLint use_normal_map;
GLint normal_texture;
// Attribute variable locations
GLint vertex_normal;
GLint vertex_uv;
GLint vertex_light_uv;
GLint vertex_tangent;
GLint vertex_bone_index;
GLint vertex_bone_weight;
@@ -148,6 +152,7 @@ struct pol {
enum pol_texture_type {
COLOR_MAP = 1,
SPECULAR_MAP = 4,
LIGHT_MAP = 7,
NORMAL_MAP = 8,
MAX_TEXTURE_TYPE
};
@@ -170,6 +175,8 @@ struct pol_mesh {
struct pol_vertex *vertices;
uint32_t nr_uvs;
vec2 *uvs;
uint32_t nr_light_uvs;
vec2 *light_uvs;
uint32_t nr_triangles;
struct pol_triangle *triangles;
};
@@ -188,6 +195,7 @@ struct pol_bone_weight {
struct pol_triangle {
uint32_t vert_index[3];
uint32_t uv_index[3];
uint32_t light_uv_index[3];
vec3 normals[3];
uint32_t material; // index in the material group
};
+25 -4
View File
@@ -35,6 +35,10 @@ struct vertex_common {
GLfloat uv[2];
};
struct vertex_light_uv {
GLfloat uv[2];
};
struct vertex_tangent {
GLfloat tangent[4];
};
@@ -92,12 +96,12 @@ static bool init_material(struct material *material, const struct pol_material *
if (!material->color_map)
return false;
if (m->textures[SPECULAR_MAP]) {
if (m->textures[SPECULAR_MAP])
material->specular_map = load_texture(aar, path, m->textures[SPECULAR_MAP]);
}
if (m->textures[NORMAL_MAP]) {
if (m->textures[LIGHT_MAP])
material->light_map = load_texture(aar, path, m->textures[LIGHT_MAP]);
if (m->textures[NORMAL_MAP])
material->normal_map = load_texture(aar, path, m->textures[NORMAL_MAP]);
}
struct amt_material *amt_m = amt ? amt_find_material(amt, m->name) : NULL;
if (amt_m) {
@@ -120,6 +124,8 @@ static void destroy_material(struct material *material)
glDeleteTextures(1, &material->color_map);
if (material->specular_map)
glDeleteTextures(1, &material->specular_map);
if (material->light_map)
glDeleteTextures(1, &material->light_map);
if (material->normal_map)
glDeleteTextures(1, &material->normal_map);
}
@@ -192,10 +198,13 @@ static void *buf_alloc(uint8_t **ptr, int size)
static void add_mesh(struct model *model, struct pol_mesh *m, int material_index, int material, struct RE_renderer *r)
{
bool has_light_map = m->light_uvs && model->materials[material].light_map;
bool has_normal_map = model->materials[material].normal_map != 0;
bool has_bones = !!model->bone_map;
GLsizei stride = sizeof(struct vertex_common);
if (has_light_map)
stride += sizeof(struct vertex_light_uv);
if (has_normal_map)
stride += sizeof(struct vertex_tangent);
if (has_bones)
@@ -218,6 +227,10 @@ static void add_mesh(struct model *model, struct pol_mesh *m, int material_index
glm_vec3_copy(vert->pos, v_common->pos);
glm_vec3_copy(t->normals[j], v_common->normal);
glm_vec2_copy(m->uvs[t->uv_index[j]], v_common->uv);
if (has_light_map) {
struct vertex_light_uv *v_light_uv = buf_alloc(&ptr, sizeof(struct vertex_light_uv));
glm_vec2_copy(m->light_uvs[t->light_uv_index[j]], v_light_uv->uv);
}
if (has_normal_map) {
struct vertex_tangent *v_tangent = buf_alloc(&ptr, sizeof(struct vertex_tangent));
glm_vec4_ucopy(tangent[j], v_tangent->tangent);
@@ -265,6 +278,14 @@ static void add_mesh(struct model *model, struct pol_mesh *m, int material_index
glEnableVertexAttribArray(r->vertex_uv);
glVertexAttribPointer(r->vertex_uv, 2, GL_FLOAT, GL_FALSE, stride, base + offsetof(struct vertex_common, uv));
base += sizeof(struct vertex_common);
if (has_light_map) {
glEnableVertexAttribArray(r->vertex_light_uv);
glVertexAttribPointer(r->vertex_light_uv, 2, GL_FLOAT, GL_FALSE, stride, base + offsetof(struct vertex_light_uv, uv));
base += sizeof(struct vertex_light_uv);
} else {
glDisableVertexAttribArray(r->vertex_light_uv);
glVertexAttrib2f(r->vertex_light_uv, 0.0, 0.0);
}
if (has_normal_map) {
glEnableVertexAttribArray(r->vertex_tangent);
glVertexAttribPointer(r->vertex_tangent, 4, GL_FLOAT, GL_FALSE, stride, base + offsetof(struct vertex_tangent, tangent));
+17 -8
View File
@@ -125,14 +125,20 @@ static void destroy_vertex(struct pol_vertex *v)
free(v->weights);
}
static void parse_triangle(struct buffer *r, int unknowns_length, struct pol_triangle *t)
static void parse_triangle(struct buffer *r, struct pol_mesh *mesh, int triangle_index, int unknowns_length)
{
struct pol_triangle *t = &mesh->triangles[triangle_index];
t->vert_index[0] = buffer_read_int32(r);
t->vert_index[1] = buffer_read_int32(r);
t->vert_index[2] = buffer_read_int32(r);
t->uv_index[0] = buffer_read_int32(r);
t->uv_index[1] = buffer_read_int32(r);
t->uv_index[2] = buffer_read_int32(r);
if (mesh->light_uvs) {
t->light_uv_index[0] = buffer_read_int32(r) - mesh->nr_uvs;
t->light_uv_index[1] = buffer_read_int32(r) - mesh->nr_uvs;
t->light_uv_index[2] = buffer_read_int32(r) - mesh->nr_uvs;
}
buffer_skip(r, unknowns_length);
@@ -167,14 +173,16 @@ static struct pol_mesh *parse_mesh(struct buffer *r, int pol_version)
mesh->uvs[i][1] = buffer_read_float(r);
}
int triangle_unknowns_length = 12;
int nr_unknown_f64s = buffer_read_int32(r);
if (nr_unknown_f64s) {
buffer_skip(r, nr_unknown_f64s * 8);
triangle_unknowns_length += 12;
mesh->nr_light_uvs = buffer_read_int32(r);
if (mesh->nr_light_uvs > 0) {
mesh->light_uvs = xcalloc(mesh->nr_light_uvs, sizeof(vec2));
for (uint32_t i = 0; i < mesh->nr_light_uvs; i++) {
mesh->light_uvs[i][0] = buffer_read_float(r);
mesh->light_uvs[i][1] = buffer_read_float(r);
}
}
int triangle_unknowns_length = 12;
if (pol_version == 1) {
int nr_unknown_vecs = buffer_read_int32(r);
buffer_skip(r, nr_unknown_vecs * 12);
@@ -191,7 +199,7 @@ static struct pol_mesh *parse_mesh(struct buffer *r, int pol_version)
mesh->nr_triangles = buffer_read_int32(r);
mesh->triangles = xcalloc(mesh->nr_triangles, sizeof(struct pol_triangle));
for (uint32_t i = 0; i < mesh->nr_triangles; i++) {
parse_triangle(r, triangle_unknowns_length, &mesh->triangles[i]);
parse_triangle(r, mesh, i, triangle_unknowns_length);
}
if (pol_version == 1) {
@@ -213,6 +221,7 @@ static void free_mesh(struct pol_mesh *mesh)
destroy_vertex(&mesh->vertices[i]);
free(mesh->vertices);
free(mesh->uvs);
free(mesh->light_uvs);
free(mesh->triangles);
free(mesh);
}
+16
View File
@@ -30,6 +30,7 @@
enum {
COLOR_TEXTURE_UNIT,
SPECULAR_TEXTURE_UNIT,
LIGHT_TEXTURE_UNIT,
NORMAL_TEXTURE_UNIT,
};
@@ -51,6 +52,8 @@ static void init_billboard_mesh(struct RE_renderer *r)
glVertexAttribPointer(r->shader.vertex, 3, GL_FLOAT, GL_FALSE, 20, (const void *)0);
glEnableVertexAttribArray(r->vertex_uv);
glVertexAttribPointer(r->vertex_uv, 2, GL_FLOAT, GL_FALSE, 20, (const void *)12);
glDisableVertexAttribArray(r->vertex_light_uv);
glVertexAttrib2f(r->vertex_light_uv, 0.0, 0.0);
glDisableVertexAttribArray(r->vertex_normal);
glVertexAttrib3f(r->vertex_normal, 0.0, 0.0, 1.0);
glDisableVertexAttribArray(r->vertex_tangent);
@@ -95,10 +98,13 @@ struct RE_renderer *RE_renderer_new(struct texture *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->use_light_map = glGetUniformLocation(r->shader.program, "use_light_map");
r->light_texture = glGetUniformLocation(r->shader.program, "light_texture");
r->use_normal_map = glGetUniformLocation(r->shader.program, "use_normal_map");
r->normal_texture = glGetUniformLocation(r->shader.program, "normal_texture");
r->vertex_normal = glGetAttribLocation(r->shader.program, "vertex_normal");
r->vertex_uv = glGetAttribLocation(r->shader.program, "vertex_uv");
r->vertex_light_uv = glGetAttribLocation(r->shader.program, "vertex_light_uv");
r->vertex_tangent = glGetAttribLocation(r->shader.program, "vertex_tangent");
r->vertex_bone_index = glGetAttribLocation(r->shader.program, "vertex_bone_index");
r->vertex_bone_weight = glGetAttribLocation(r->shader.program, "vertex_bone_weight");
@@ -304,6 +310,15 @@ static void render_model(struct RE_instance *inst, struct RE_renderer *r)
glBindTexture(GL_TEXTURE_2D, material->color_map);
glUniform1i(r->shader.texture, COLOR_TEXTURE_UNIT);
if (material->light_map && inst->plugin->light_map_mode) {
glUniform1i(r->use_light_map, GL_TRUE);
glActiveTexture(GL_TEXTURE0 + LIGHT_TEXTURE_UNIT);
glBindTexture(GL_TEXTURE_2D, material->light_map);
glUniform1i(r->light_texture, LIGHT_TEXTURE_UNIT);
} else {
glUniform1i(r->use_light_map, GL_FALSE);
}
if (material->normal_map && inst->draw_bump && inst->plugin->bump_mode) {
glUniform1i(r->use_normal_map, GL_TRUE);
glActiveTexture(GL_TEXTURE0 + NORMAL_TEXTURE_UNIT);
@@ -373,6 +388,7 @@ static void render_billboard(struct RE_instance *inst, struct RE_renderer *r, ma
glUniform1f(r->specular_shininess, 0.0);
glUniform1i(r->use_specular_map, GL_FALSE);
glUniform1f(r->rim_exponent, 0.0);
glUniform1i(r->use_light_map, GL_FALSE);
glUniform1i(r->use_normal_map, GL_FALSE);
glActiveTexture(GL_TEXTURE0);