Skip to content

Commit

Permalink
Changed spotlight emission profile texture from 'cosine of angle' ind…
Browse files Browse the repository at this point in the history
…exing to just 'angle'.

For better angular resolution next to the center of the beam.
  • Loading branch information
res2k committed May 12, 2022
1 parent 7c959dc commit 2ef4f40
Show file tree
Hide file tree
Showing 6 changed files with 11 additions and 8 deletions.
Binary file modified baseq2/pics/flashlight_profile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 4 additions & 2 deletions inc/refresh/refresh.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,16 +122,18 @@ typedef struct dlight_s {
dlight_spot_emission_profile emission_profile;
// Spotlight direction
vec3_t direction;
// Cosine of angle of spotlight cone width (no emission beyond that)
float cos_total_width;
union {
// Options for DLIGHT_SPOT_EMISSION_PROFILE_FALLOFF
struct {
// Cosine of angle of spotlight cone width (no emission beyond that)
float cos_total_width;
// Cosine of angle of start of falloff (full emission below that)
float cos_falloff_start;
};
// Options for DLIGHT_SPOT_EMISSION_PROFILE_AXIS_ANGLE_TEXTURE
struct {
// Angle of spotlight cone width (no emission beyond that), in radians
float total_width;
// Emission profile texture, indexed by 'angle / total_width'
qhandle_t texture;
};
Expand Down
3 changes: 1 addition & 2 deletions scripts/ies_to_texture.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,7 @@ def get_floats(num):
angle_function = scipy.interpolate.interp1d(ies_file.vert_angles, ies_file.light_values[0], kind='cubic')
output_values = numpy.zeros(res)
for x in range(0, res):
cos_angle = x / (res - 1)
angle = math.degrees(math.acos(cos_angle))
angle = (x / (res - 1)) * 90
if angle <= max_angle:
interp = angle_function(angle)
else:
Expand Down
2 changes: 1 addition & 1 deletion src/client/view.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ void V_AddSpotLightTexEmission(vec3_t org, vec3_t dir, float intensity, float r,
return;

dl->spot.emission_profile = DLIGHT_SPOT_EMISSION_PROFILE_AXIS_ANGLE_TEXTURE;
dl->spot.cos_total_width = cosf(DEG2RAD(width_angle));
dl->spot.total_width = DEG2RAD(width_angle);
dl->spot.texture = emission_tex;
}

Expand Down
2 changes: 1 addition & 1 deletion src/refresh/vkpt/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1666,7 +1666,7 @@ static void add_dlight_spot(const dlight_t* light, DynLightData* dynlight_data)
break;
case DLIGHT_SPOT_EMISSION_PROFILE_AXIS_ANGLE_TEXTURE:
dynlight_data->type |= DYNLIGHT_SPOT_EMISSION_PROFILE_AXIS_ANGLE_TEXTURE << 16;
dynlight_data->spot_data = floatToHalf(light->spot.cos_total_width) | (light->spot.texture << 16);
dynlight_data->spot_data = floatToHalf(light->spot.total_width) | (light->spot.texture << 16);
break;
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/refresh/vkpt/shader/light_lists.h
Original file line number Diff line number Diff line change
Expand Up @@ -348,11 +348,13 @@ compute_dynlight_spot(uint light_idx, uint spot_style, vec3 light_center, vec3 p
}
} else if(spot_style == DYNLIGHT_SPOT_EMISSION_PROFILE_AXIS_ANGLE_TEXTURE) {
const uint spot_data = global_ubo.dyn_light_data[light_idx].spot_data;
const float cosTotalWidth = unpackHalf2x16(spot_data).x;
const float theta = acos(cosTheta);
const float totalWidth = unpackHalf2x16(spot_data).x;
const uint texture_num = spot_data >> 16;

if (cosTheta >= 0) {
float tc = clamp((cosTheta - cosTotalWidth) / (1 - cosTotalWidth), 0, 1);
// Use the angle directly as texture coordinate for better angular resolution next to the center of the beam
float tc = clamp(theta / totalWidth, 0, 1);
falloff = global_texture(texture_num, vec2(tc, 0)).r;
} else
falloff = 0;
Expand Down

0 comments on commit 2ef4f40

Please sign in to comment.