SealEngine: Implement hemisphere lighting

This implements the sky/middle/ground hemisphere ambient driven by
light_params[8..19].

SealEngine has no separate specular-light instance; its specular instead
shares the hemisphere light vector.
This commit is contained in:
kichikuou
2026-06-20 11:41:56 +09:00
parent 250bc82818
commit db8279ebc3
3 changed files with 53 additions and 4 deletions
+22 -4
View File
@@ -50,7 +50,7 @@ in vec3 light_dir[NR_DIR_LIGHTS];
uniform vec3 global_ambient;
vec3 dir_lights_diffuse(vec3 norm)
vec3 compute_diffuse(vec3 norm)
{
vec3 diffuse = vec3(0.0);
for (int i = 0; i < NR_DIR_LIGHTS; i++) {
@@ -60,11 +60,29 @@ vec3 dir_lights_diffuse(vec3 norm)
return diffuse;
}
#else // ENGINE == REIGN_ENGINE
#elif ENGINE == SEAL_ENGINE
const vec3 global_ambient = vec3(0.0);
vec3 dir_lights_diffuse(vec3 norm)
// Hemisphere lighting (sky/middle/ground).
uniform vec3 hemi_light_dir;
uniform vec3 hemi_sky_color;
uniform vec3 hemi_mid_color;
uniform vec3 hemi_ground_color;
vec3 compute_diffuse(vec3 norm)
{
float t = 0.5 * dot(norm, hemi_light_dir) + 0.5;
vec3 low_mid = mix(hemi_ground_color, hemi_mid_color, t);
vec3 mid_high = mix(hemi_mid_color, hemi_sky_color, t);
return mix(low_mid, mid_high, t);
}
#else // TAPIR_ENGINE
const vec3 global_ambient = vec3(0.0);
vec3 compute_diffuse(vec3 norm)
{
return vec3(1.0);
}
@@ -138,7 +156,7 @@ void main() {
texel = mix(texel, texture(blend_tex, blend_tex_coord), blend_weight);
}
if (diffuse_type != DIFFUSE_EMISSIVE) {
diffuse = dir_lights_diffuse(norm);
diffuse = compute_diffuse(norm);
if (diffuse_type == DIFFUSE_LIGHT_MAP) {
diffuse *= texture(light_texture, light_tex_coord).rgb;
}
+4
View File
@@ -188,6 +188,10 @@ struct RE_renderer {
GLint ls_light_dir;
GLint ls_light_color;
GLint ls_sun_color;
GLint hemi_light_dir;
GLint hemi_sky_color;
GLint hemi_mid_color;
GLint hemi_ground_color;
GLint alpha_mode;
GLint alpha_texture;
GLint uv_scroll;
+27
View File
@@ -259,6 +259,10 @@ struct RE_renderer *RE_renderer_new(void)
r->ls_light_dir = glGetUniformLocation(r->program, "ls_light_dir");
r->ls_light_color = glGetUniformLocation(r->program, "ls_light_color");
r->ls_sun_color = glGetUniformLocation(r->program, "ls_sun_color");
r->hemi_light_dir = glGetUniformLocation(r->program, "hemi_light_dir");
r->hemi_sky_color = glGetUniformLocation(r->program, "hemi_sky_color");
r->hemi_mid_color = glGetUniformLocation(r->program, "hemi_mid_color");
r->hemi_ground_color = glGetUniformLocation(r->program, "hemi_ground_color");
r->alpha_mode = glGetUniformLocation(r->program, "alpha_mode");
r->alpha_texture = glGetUniformLocation(r->program, "alpha_texture");
r->uv_scroll = glGetUniformLocation(r->program, "uv_scroll");
@@ -1133,6 +1137,26 @@ static void setup_light_scattering(struct RE_plugin *plugin)
}
}
static void setup_hemisphere_light(struct RE_plugin *plugin)
{
struct RE_renderer *r = plugin->renderer;
const float *lp = plugin->light_params;
vec3 hemi_dir = {
-lp[SEAL_LP_HEMI_VEC], -lp[SEAL_LP_HEMI_VEC + 1], lp[SEAL_LP_HEMI_VEC + 2]
};
glm_vec3_normalize(hemi_dir);
glUniform3fv(r->hemi_light_dir, 1, hemi_dir);
glUniform3fv(r->hemi_sky_color, 1, &lp[SEAL_LP_HEMI_SKY_COLOR]);
glUniform3fv(r->hemi_mid_color, 1, &lp[SEAL_LP_HEMI_MID_COLOR]);
glUniform3fv(r->hemi_ground_color, 1, &lp[SEAL_LP_HEMI_GROUND_COLOR]);
// SealEngine's specular uses the hemisphere light vector. hemi_dir points
// toward the light, but the shader's specular formula expects the light
// propagation direction.
vec3 spec_dir;
glm_vec3_negate_to(hemi_dir, spec_dir);
glUniform3fv(r->specular_light_dir, 1, spec_dir);
}
static void setup_lights(struct RE_plugin *plugin)
{
struct RE_renderer *r = plugin->renderer;
@@ -1168,6 +1192,9 @@ static void setup_lights(struct RE_plugin *plugin)
glUniform3fv(r->dir_lights[light_index].diffuse, 1, zero);
glUniform3fv(r->dir_lights[light_index].globe_diffuse, 1, zero);
}
if (re_plugin_version >= RE_SEAL_PLUGIN)
setup_hemisphere_light(plugin);
}
static int cmp_instances_by_z(const void *lhs, const void *rhs)