Skip to content

Commit

Permalink
fix a few lighting bugs
Browse files Browse the repository at this point in the history
There was confusion in the lighting code between light indexes and sun indexes.  These are usually the same, but not always.  This makes several changes to fix light/sun handling.

1. Clarify the distinction between lights and suns and add a `sun_index` field
2. Add a flags field and assign the `dual_cone` boolean to it, as well as a new glare flag
3. Determine light glare by checking the light flag, not the sun (which never worked in the first place as the `stars_sun_has_glare` function checked bitmaps rather than suns)
  • Loading branch information
Goober5000 committed Feb 28, 2024
1 parent f8203e9 commit 1aee240
Show file tree
Hide file tree
Showing 9 changed files with 77 additions and 36 deletions.
2 changes: 1 addition & 1 deletion code/graphics/opengl/gropengldeferred.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ void gr_opengl_deferred_lighting_finish()
auto light_data = prepare_light_uniforms(l, light_uniform_aligner);

if (l.type == Light_Type::Cone) {
light_data->dualCone = l.dual_cone ? 1.0f : 0.0f;
light_data->dualCone = (l.flags & LF_DUAL_CONE) ? 1.0f : 0.0f;
light_data->coneAngle = l.cone_angle;
light_data->coneInnerAngle = l.cone_inner_angle;
light_data->coneDir = l.vec2;
Expand Down
3 changes: 1 addition & 2 deletions code/graphics/opengl/gropenglpostprocessing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,6 @@ extern GLuint Cockpit_depth_texture;
extern GLuint Scene_position_texture;
extern GLuint Scene_normal_texture;
extern GLuint Scene_specular_texture;
extern bool stars_sun_has_glare(int index);
extern float Sun_spot;
void opengl_post_lightshafts()
{
Expand All @@ -452,7 +451,7 @@ void opengl_post_lightshafts()
light_get_global_dir(&light_dir, idx);
vm_vec_rotate(&local_light_dir, &light_dir, &Eye_matrix);

if ( !stars_sun_has_glare(idx) ) {
if ( !light_has_glare(idx) ) {
continue;
}

Expand Down
52 changes: 43 additions & 9 deletions code/lighting/lighting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,13 @@ static void light_rotate(light * l)
}
}

void light_add_directional(const vec3d* dir, const hdr_color* new_color, const float source_radius)
void light_add_directional(const vec3d* dir, int sun_index, bool no_glare, const hdr_color* new_color, const float source_radius)
{
Assert(new_color!= nullptr);
light_add_directional(dir, new_color->i(), new_color->r(), new_color->g(), new_color->b(), source_radius);
light_add_directional(dir, sun_index, no_glare, new_color->i(), new_color->r(), new_color->g(), new_color->b(), source_radius);
}
namespace ltp=lighting_profiles;
void light_add_directional(const vec3d *dir, float intensity, float r, float g, float b, const float source_radius)
void light_add_directional(const vec3d *dir, int sun_index, bool no_glare, float intensity, float r, float g, float b, const float source_radius)
{
if (Lighting_off) return;

Expand All @@ -191,6 +191,8 @@ void light_add_directional(const vec3d *dir, float intensity, float r, float g,
light l;

l.type = Light_Type::Directional;
l.flags = no_glare ? (LF_DEFAULT | LF_NO_GLARE) : LF_DEFAULT;
l.sun_index = sun_index;

vm_vec_copy_scale( &l.vec, dir, -1.0f );

Expand Down Expand Up @@ -233,6 +235,8 @@ void light_add_point(const vec3d *pos, float r1, float r2, float intensity, floa

Num_lights++;
l.type = Light_Type::Point;
l.flags = LF_DEFAULT;
l.sun_index = -1;
l.vec = *pos;
l.r = r;
l.g = g;
Expand Down Expand Up @@ -272,6 +276,8 @@ void light_add_tube(const vec3d *p0, const vec3d *p1, float r1, float r2, float
Num_lights++;

l.type = Light_Type::Tube;
l.flags = LF_DEFAULT;
l.sun_index = -1;
l.vec = *p0;
l.vec2 = *p1;
l.r = r;
Expand Down Expand Up @@ -317,19 +323,46 @@ int light_get_global_count()
* @param pos Position
* @param n Light source
*
* Returns 0 if there is no global light.
* Returns false if there is no global light.
*/
int light_get_global_dir(vec3d *pos, int n)
bool light_get_global_dir(vec3d *pos, int n)
{
if ( (n < 0) || (n >= (int)Static_light.size()) ) {
return 0;
if (!SCP_vector_inbounds(Static_light, n)) {
return false;
}

if (pos) {
*pos = Static_light[n].vec;
vm_vec_scale( pos, -1.0f );
}
return 1;
return true;
}

bool light_has_glare(int n)
{
if (!SCP_vector_inbounds(Static_light, n)) {
return false;
}

return (Static_light[n].flags & LF_NO_GLARE) == 0;
}

int light_get_sun_index(int n)
{
if (!SCP_vector_inbounds(Static_light, n)) {
return -1;
}

return Static_light[n].sun_index;
}

int light_find_for_sun(int sun_index)
{
for (size_t n = 0; n < Static_light.size(); ++n)
if (Static_light[n].sun_index == sun_index)
return static_cast<int>(n);

return -1;
}

void light_apply_rgb( ubyte *param_r, ubyte *param_g, ubyte *param_b, const vec3d *pos, const vec3d *norm, float static_light_level )
Expand Down Expand Up @@ -478,11 +511,12 @@ void light_add_cone(const vec3d *pos, const vec3d *dir, float angle, float inner
Num_lights++;

l.type = Light_Type::Cone;
l.flags = dual_cone ? (LF_DEFAULT | LF_DUAL_CONE) : LF_DEFAULT;
l.sun_index = -1;
l.vec = *pos;
l.vec2= *dir;
l.cone_angle = angle;
l.cone_inner_angle = inner_angle;
l.dual_cone = dual_cone;
l.r = r;
l.g = g;
l.b = b;
Expand Down
20 changes: 15 additions & 5 deletions code/lighting/lighting.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,16 @@ typedef struct light {
float r,g,b; // The color components of the light
float cone_angle; // angle for cone lights
float cone_inner_angle; // the inner angle for calculating falloff
bool dual_cone; // should the cone be shining in both directions?
int flags; // see below
int sun_index; // if this light corresponds to a sun
float source_radius; // The actual size of the object or volume emitting the light
int instance;
} light;

#define LF_DUAL_CONE (1<<0) // should the cone be shining in both directions?
#define LF_NO_GLARE (1<<1) // for example, a sun with $NoGlare
#define LF_DEFAULT 0 // no flags by default

extern SCP_vector<light> Static_light;

struct light_indexing_info
Expand Down Expand Up @@ -91,8 +96,8 @@ extern void light_reset();

//Intensity in lighting inputs multiplies the base colors.

extern void light_add_directional(const vec3d *dir, const hdr_color *new_color, const float source_radius = 0.0f );
extern void light_add_directional(const vec3d *dir, float intensity, float r, float g, float b, const float source_radius = 0.0f);
extern void light_add_directional(const vec3d *dir, int sun_index, bool no_glare, const hdr_color *new_color, const float source_radius = 0.0f );
extern void light_add_directional(const vec3d *dir, int sun_index, bool no_glare, float intensity, float r, float g, float b, const float source_radius = 0.0f);
extern void light_add_point(const vec3d * pos, float r1, float r2, const hdr_color *new_color, const float source_radius = 0.0f);
extern void light_add_point(const vec3d * pos, float r1, float r2, float intensity, float r, float g, float b, const float source_radius = 0.0f);
extern void light_add_tube(const vec3d *p0, const vec3d *p1, float r1, float r2, const hdr_color *new_color, const float source_radius = 0.0f);
Expand All @@ -110,8 +115,13 @@ void light_apply_rgb( ubyte *param_r, ubyte *param_g, ubyte *param_b, const vec3
extern int light_get_global_count();

// Fills direction of global light source N in pos.
// Returns 0 if there is no global light.
extern int light_get_global_dir(vec3d *pos, int n);
// Returns false if there is no global light.
extern bool light_get_global_dir(vec3d *pos, int n);

extern bool light_has_glare(int n);

extern int light_get_sun_index(int n);
extern int light_find_for_sun(int sun_index);

bool light_compare_by_type(const light &a, const light &b);

Expand Down
6 changes: 3 additions & 3 deletions code/missionui/missionscreencommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1960,13 +1960,13 @@ void common_setup_room_lights()
light_reset();
auto tempv = vm_vec_new(-1.0f,0.3f,-1.0f);
auto tempc = hdr_color(1.0f,0.95f,0.9f, 0.0f, 1.5f);
light_add_directional(&tempv,&tempc);
light_add_directional(&tempv,-1,false,&tempc);
tempv.xyz={-0.4f,0.4f,1.1f};
tempc = hdr_color(0.788f,0.886f,1.0f,0.0f,1.5f);
light_add_directional(&tempv,&tempc);
light_add_directional(&tempv,-1,false,&tempc);
tempv.xyz={0.4f,0.1f,0.4f};
tempc = hdr_color(1.0f,1.0f,1.0f,0.0f,0.4f);
light_add_directional(&tempv,&tempc);
light_add_directional(&tempv,-1,false,&tempc);
gr_set_ambient_light(53, 53, 53);
light_rotate_all();
}
Expand Down
4 changes: 2 additions & 2 deletions code/ship/shipfx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,7 @@ void shipfx_warpout_frame( object *objp, float frametime )
/**
* Given world point see if it is in a shadow.
*/
bool shipfx_eye_in_shadow( vec3d *eye_pos, object * src_obj, int sun_n )
bool shipfx_eye_in_shadow( vec3d *eye_pos, object * src_obj, int light_n )
{
object *objp;
ship_obj *so;
Expand All @@ -802,7 +802,7 @@ bool shipfx_eye_in_shadow( vec3d *eye_pos, object * src_obj, int sun_n )
rp0 = *eye_pos;

// get the light dir
if(!light_get_global_dir(&light_dir, sun_n)){
if(!light_get_global_dir(&light_dir, light_n)){
return false;
}

Expand Down
2 changes: 1 addition & 1 deletion code/ship/shipfx.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ extern float shipfx_calculate_arrival_warp_distance(object *objp);
// =================================================

// Given world point see if it is in a shadow.
bool shipfx_eye_in_shadow( vec3d *eye_pos, object *src_obj, int sun_n);
bool shipfx_eye_in_shadow( vec3d *eye_pos, object *src_obj, int light_n);


// =================================================
Expand Down
8 changes: 1 addition & 7 deletions code/starfield/starfield.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1317,7 +1317,7 @@ void stars_draw_sun(int show_sun)

// add the light source corresponding to the sun, except when rendering to an envmap
if ( !Rendering_to_env )
light_add_directional(&sun_dir, bm->i, bm->r, bm->g, bm->b);
light_add_directional(&sun_dir, idx, !bm->glare, bm->i, bm->r, bm->g, bm->b);

// if supernova
if ( supernova_active() && (idx == 0) )
Expand Down Expand Up @@ -2697,12 +2697,6 @@ starfield_bitmap *stars_get_bitmap_entry(int index, bool is_a_sun)
return NULL;
}

bool stars_sun_has_glare(int index)
{
starfield_bitmap *sb = stars_get_bitmap_entry(index, true);
return (sb && sb->glare);
}

// set an instace to not render
void stars_mark_instance_unused(int index, bool is_a_sun)
{
Expand Down
16 changes: 10 additions & 6 deletions freespace2/freespace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -661,13 +661,17 @@ DCF(sn_glare, "Sets the sun glare scale (Default is 1.7)")
}

float Supernova_last_glare = 0.0f;
bool stars_sun_has_glare(int index);

void game_sunspot_process(float frametime)
{
TRACE_SCOPE(tracing::SunspotProcess);
int n_lights, idx;
float Sun_spot_goal = 0.0f;

int sun_idx = 0;
int light_idx = light_find_for_sun(sun_idx);
Assertion(light_idx >= 0, "Could not find sun for light index %d!", sun_idx);

// supernova
auto sn_stage = supernova_stage();
if (sn_stage != SUPERNOVA_STAGE::NONE) {
Expand All @@ -685,7 +689,7 @@ void game_sunspot_process(float frametime)
pct = supernova_sunspot_pct();

vec3d light_dir;
light_get_global_dir(&light_dir, 0);
light_get_global_dir(&light_dir, light_idx);
float dot;
dot = vm_vec_dot( &light_dir, &Eye_matrix.vec.fvec );

Expand All @@ -698,9 +702,9 @@ void game_sunspot_process(float frametime)
}

// draw the sun glow
if ( !shipfx_eye_in_shadow( &Eye_position, Viewer_obj, 0 ) ) {
if ( !shipfx_eye_in_shadow( &Eye_position, Viewer_obj, light_idx ) ) {
// draw the glow for this sun
stars_draw_sun_glow(0);
stars_draw_sun_glow(sun_idx);
}

Supernova_last_glare = Sun_spot_goal;
Expand Down Expand Up @@ -747,8 +751,8 @@ void game_sunspot_process(float frametime)
vec3d light_dir;
light_get_global_dir(&light_dir, idx);

//only do sunglare stuff if this sun has one
if (stars_sun_has_glare(idx)) {
//only do sunglare stuff if this light source has one
if (light_has_glare(idx)) {
float dot = vm_vec_dot( &light_dir, &Eye_matrix.vec.fvec )*0.5f+0.5f;
Sun_spot_goal += (float)pow(dot,85.0f);
}
Expand Down

0 comments on commit 1aee240

Please sign in to comment.