Invert spotlight angle attenuation
Inverted the spotlight angle attenuation so a higher value results in a dimmer light, this makes it more consistent with the distance attenuation. Also changed the way spotlighs are computed in SDFGI and GIPorbes and GPU lightmapper, now it matches the falloff used in the scene rendering code.
This commit is contained in:
parent
7bb7a3c4a7
commit
99e1ce0690
9 changed files with 54 additions and 44 deletions
|
@ -93,8 +93,8 @@ void LightmapperRD::add_spot_light(bool p_static, const Vector3 &p_position, con
|
|||
l.direction[2] = p_direction.z;
|
||||
l.range = p_range;
|
||||
l.attenuation = p_attenuation;
|
||||
l.spot_angle = Math::deg2rad(p_spot_angle);
|
||||
l.spot_attenuation = p_spot_attenuation;
|
||||
l.cos_spot_angle = Math::cos(Math::deg2rad(p_spot_angle));
|
||||
l.inv_spot_attenuation = 1.0f / p_spot_attenuation;
|
||||
l.color[0] = p_color.r;
|
||||
l.color[1] = p_color.g;
|
||||
l.color[2] = p_color.b;
|
||||
|
|
|
@ -54,8 +54,8 @@ class LightmapperRD : public Lightmapper {
|
|||
float size;
|
||||
float range;
|
||||
float attenuation;
|
||||
float spot_angle;
|
||||
float spot_attenuation;
|
||||
float cos_spot_angle;
|
||||
float inv_spot_attenuation;
|
||||
uint32_t static_bake;
|
||||
uint32_t pad[3];
|
||||
|
||||
|
|
|
@ -56,8 +56,8 @@ struct Light {
|
|||
|
||||
float range;
|
||||
float attenuation;
|
||||
float spot_angle;
|
||||
float spot_attenuation;
|
||||
float cos_spot_angle;
|
||||
float inv_spot_attenuation;
|
||||
|
||||
bool static_bake;
|
||||
uint pad[3];
|
||||
|
|
|
@ -313,13 +313,16 @@ void main() {
|
|||
|
||||
if (lights.data[i].type == LIGHT_TYPE_SPOT) {
|
||||
vec3 rel = normalize(position - light_pos);
|
||||
float angle = acos(dot(rel, lights.data[i].direction));
|
||||
if (angle > lights.data[i].spot_angle) {
|
||||
float cos_spot_angle = lights.data[i].cos_spot_angle;
|
||||
float cos_angle = dot(rel, lights.data[i].direction);
|
||||
|
||||
if (cos_angle < cos_spot_angle) {
|
||||
continue; //invisible, dont try
|
||||
}
|
||||
|
||||
float d = clamp(angle / lights.data[i].spot_angle, 0, 1);
|
||||
attenuation *= pow(1.0 - d, lights.data[i].spot_attenuation);
|
||||
float scos = max(cos_angle, cos_spot_angle);
|
||||
float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - cos_spot_angle));
|
||||
attenuation *= 1.0 - pow(spot_rim, lights.data[i].inv_spot_attenuation);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1611,8 +1611,8 @@ void RendererSceneRenderRD::_pre_process_gi(RID p_render_buffers, const Transfor
|
|||
lights[idx].has_shadow = storage->light_has_shadow(li->light);
|
||||
lights[idx].attenuation = storage->light_get_param(li->light, RS::LIGHT_PARAM_ATTENUATION);
|
||||
lights[idx].radius = storage->light_get_param(li->light, RS::LIGHT_PARAM_RANGE);
|
||||
lights[idx].spot_angle = Math::deg2rad(storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ANGLE));
|
||||
lights[idx].spot_attenuation = storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
|
||||
lights[idx].cos_spot_angle = Math::cos(Math::deg2rad(storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ANGLE)));
|
||||
lights[idx].inv_spot_attenuation = 1.0f / storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
|
||||
|
||||
idx++;
|
||||
}
|
||||
|
@ -4539,8 +4539,8 @@ void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_ins
|
|||
l.color[1] = color.g;
|
||||
l.color[2] = color.b;
|
||||
|
||||
l.spot_angle_radians = Math::deg2rad(storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE));
|
||||
l.spot_attenuation = storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
|
||||
l.cos_spot_angle = Math::cos(Math::deg2rad(storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE)));
|
||||
l.inv_spot_attenuation = 1.0f / storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
|
||||
|
||||
Transform xform = light_instance_get_base_transform(light_instance);
|
||||
|
||||
|
@ -6491,9 +6491,9 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
|
|||
|
||||
light_data.size = size;
|
||||
|
||||
light_data.cone_attenuation = storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ATTENUATION);
|
||||
light_data.inv_spot_attenuation = 1.0f / storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ATTENUATION);
|
||||
float spot_angle = storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ANGLE);
|
||||
light_data.cone_angle = Math::cos(Math::deg2rad(spot_angle));
|
||||
light_data.cos_spot_angle = Math::cos(Math::deg2rad(spot_angle));
|
||||
|
||||
light_data.mask = storage->light_get_cull_mask(base);
|
||||
|
||||
|
@ -8094,8 +8094,8 @@ void RendererSceneRenderRD::_render_sdfgi_static_lights(RID p_render_buffers, ui
|
|||
lights[idx].has_shadow = storage->light_has_shadow(li->light);
|
||||
lights[idx].attenuation = storage->light_get_param(li->light, RS::LIGHT_PARAM_ATTENUATION);
|
||||
lights[idx].radius = storage->light_get_param(li->light, RS::LIGHT_PARAM_RANGE);
|
||||
lights[idx].spot_angle = Math::deg2rad(storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ANGLE));
|
||||
lights[idx].spot_attenuation = storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
|
||||
lights[idx].cos_spot_angle = Math::cos(Math::deg2rad(storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ANGLE)));
|
||||
lights[idx].inv_spot_attenuation = 1.0f / storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
|
||||
|
||||
idx++;
|
||||
}
|
||||
|
|
|
@ -406,10 +406,10 @@ private:
|
|||
float attenuation;
|
||||
|
||||
float color[3];
|
||||
float spot_angle_radians;
|
||||
float cos_spot_angle;
|
||||
|
||||
float position[3];
|
||||
float spot_attenuation;
|
||||
float inv_spot_attenuation;
|
||||
|
||||
float direction[3];
|
||||
uint32_t has_shadow;
|
||||
|
@ -1146,8 +1146,8 @@ private:
|
|||
float attenuation;
|
||||
|
||||
uint32_t type;
|
||||
float spot_angle;
|
||||
float spot_attenuation;
|
||||
float cos_spot_angle;
|
||||
float inv_spot_attenuation;
|
||||
float radius;
|
||||
|
||||
float shadow_color[4];
|
||||
|
@ -1362,8 +1362,8 @@ private:
|
|||
float color[3];
|
||||
float attenuation;
|
||||
|
||||
float cone_attenuation;
|
||||
float cone_angle;
|
||||
float inv_spot_attenuation;
|
||||
float cos_spot_angle;
|
||||
float specular_amount;
|
||||
uint32_t shadow_enabled;
|
||||
|
||||
|
|
|
@ -51,10 +51,10 @@ struct Light {
|
|||
float attenuation;
|
||||
|
||||
vec3 color;
|
||||
float spot_angle_radians;
|
||||
float cos_spot_angle;
|
||||
|
||||
vec3 position;
|
||||
float spot_attenuation;
|
||||
float inv_spot_attenuation;
|
||||
|
||||
vec3 direction;
|
||||
bool has_shadow;
|
||||
|
@ -233,13 +233,15 @@ bool compute_light_vector(uint light, vec3 pos, out float attenuation, out vec3
|
|||
|
||||
if (lights.data[light].type == LIGHT_TYPE_SPOT) {
|
||||
vec3 rel = normalize(pos - light_pos);
|
||||
float angle = acos(dot(rel, lights.data[light].direction));
|
||||
if (angle > lights.data[light].spot_angle_radians) {
|
||||
float cos_spot_angle = lights.data[light].cos_spot_angle;
|
||||
float cos_angle = dot(rel, lights.data[light].direction);
|
||||
if (cos_angle < cos_spot_angle) {
|
||||
return false;
|
||||
}
|
||||
|
||||
float d = clamp(angle / lights.data[light].spot_angle_radians, 0, 1);
|
||||
attenuation *= pow(1.0 - d, lights.data[light].spot_attenuation);
|
||||
float scos = max(cos_angle, cos_spot_angle);
|
||||
float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - cos_spot_angle));
|
||||
attenuation *= 1.0 - pow(spot_rim, lights.data[light].inv_spot_attenuation);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,10 +43,10 @@ struct Light {
|
|||
float attenuation;
|
||||
|
||||
vec3 color;
|
||||
float spot_angle_radians;
|
||||
float cos_spot_angle;
|
||||
|
||||
vec3 position;
|
||||
float spot_attenuation;
|
||||
float inv_spot_attenuation;
|
||||
|
||||
vec3 direction;
|
||||
bool has_shadow;
|
||||
|
@ -146,13 +146,15 @@ bool compute_light_vector(uint light, uint cell, vec3 pos, out float attenuation
|
|||
|
||||
if (lights.data[light].type == LIGHT_TYPE_SPOT) {
|
||||
vec3 rel = normalize(pos - light_pos);
|
||||
float angle = acos(dot(rel, lights.data[light].direction));
|
||||
if (angle > lights.data[light].spot_angle_radians) {
|
||||
float cos_spot_angle = lights.data[light].cos_spot_angle;
|
||||
float cos_angle = dot(rel, lights.data[light].direction);
|
||||
if (cos_angle < cos_spot_angle) {
|
||||
return false;
|
||||
}
|
||||
|
||||
float d = clamp(angle / lights.data[light].spot_angle_radians, 0, 1);
|
||||
attenuation *= pow(1.0 - d, lights.data[light].spot_attenuation);
|
||||
float scos = max(cos_angle, cos_spot_angle);
|
||||
float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - cos_spot_angle));
|
||||
attenuation *= 1.0 - pow(spot_rim, lights.data[light].inv_spot_attenuation);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -67,8 +67,8 @@ struct Light {
|
|||
float attenuation;
|
||||
|
||||
uint type;
|
||||
float spot_angle;
|
||||
float spot_attenuation;
|
||||
float cos_spot_angle;
|
||||
float inv_spot_attenuation;
|
||||
float radius;
|
||||
|
||||
vec4 shadow_color;
|
||||
|
@ -266,13 +266,16 @@ void main() {
|
|||
rel_vec.y /= params.y_mult;
|
||||
attenuation = get_omni_attenuation(light_distance, 1.0 / lights.data[i].radius, lights.data[i].attenuation);
|
||||
|
||||
float angle = acos(dot(normalize(rel_vec), -lights.data[i].direction));
|
||||
if (angle > lights.data[i].spot_angle) {
|
||||
attenuation = 0.0;
|
||||
} else {
|
||||
float d = clamp(angle / lights.data[i].spot_angle, 0, 1);
|
||||
attenuation *= pow(1.0 - d, lights.data[i].spot_attenuation);
|
||||
float cos_spot_angle = lights.data[i].cos_spot_angle;
|
||||
float cos_angle = dot(-direction, lights.data[i].direction);
|
||||
|
||||
if (cos_angle < cos_spot_angle) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float scos = max(cos_angle, cos_spot_angle);
|
||||
float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - cos_spot_angle));
|
||||
attenuation *= 1.0 - pow(spot_rim, lights.data[i].inv_spot_attenuation);
|
||||
} break;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue