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.direction[2] = p_direction.z;
|
||||||
l.range = p_range;
|
l.range = p_range;
|
||||||
l.attenuation = p_attenuation;
|
l.attenuation = p_attenuation;
|
||||||
l.spot_angle = Math::deg2rad(p_spot_angle);
|
l.cos_spot_angle = Math::cos(Math::deg2rad(p_spot_angle));
|
||||||
l.spot_attenuation = p_spot_attenuation;
|
l.inv_spot_attenuation = 1.0f / p_spot_attenuation;
|
||||||
l.color[0] = p_color.r;
|
l.color[0] = p_color.r;
|
||||||
l.color[1] = p_color.g;
|
l.color[1] = p_color.g;
|
||||||
l.color[2] = p_color.b;
|
l.color[2] = p_color.b;
|
||||||
|
|
|
@ -54,8 +54,8 @@ class LightmapperRD : public Lightmapper {
|
||||||
float size;
|
float size;
|
||||||
float range;
|
float range;
|
||||||
float attenuation;
|
float attenuation;
|
||||||
float spot_angle;
|
float cos_spot_angle;
|
||||||
float spot_attenuation;
|
float inv_spot_attenuation;
|
||||||
uint32_t static_bake;
|
uint32_t static_bake;
|
||||||
uint32_t pad[3];
|
uint32_t pad[3];
|
||||||
|
|
||||||
|
|
|
@ -56,8 +56,8 @@ struct Light {
|
||||||
|
|
||||||
float range;
|
float range;
|
||||||
float attenuation;
|
float attenuation;
|
||||||
float spot_angle;
|
float cos_spot_angle;
|
||||||
float spot_attenuation;
|
float inv_spot_attenuation;
|
||||||
|
|
||||||
bool static_bake;
|
bool static_bake;
|
||||||
uint pad[3];
|
uint pad[3];
|
||||||
|
|
|
@ -313,13 +313,16 @@ void main() {
|
||||||
|
|
||||||
if (lights.data[i].type == LIGHT_TYPE_SPOT) {
|
if (lights.data[i].type == LIGHT_TYPE_SPOT) {
|
||||||
vec3 rel = normalize(position - light_pos);
|
vec3 rel = normalize(position - light_pos);
|
||||||
float angle = acos(dot(rel, lights.data[i].direction));
|
float cos_spot_angle = lights.data[i].cos_spot_angle;
|
||||||
if (angle > lights.data[i].spot_angle) {
|
float cos_angle = dot(rel, lights.data[i].direction);
|
||||||
|
|
||||||
|
if (cos_angle < cos_spot_angle) {
|
||||||
continue; //invisible, dont try
|
continue; //invisible, dont try
|
||||||
}
|
}
|
||||||
|
|
||||||
float d = clamp(angle / lights.data[i].spot_angle, 0, 1);
|
float scos = max(cos_angle, cos_spot_angle);
|
||||||
attenuation *= pow(1.0 - d, lights.data[i].spot_attenuation);
|
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].has_shadow = storage->light_has_shadow(li->light);
|
||||||
lights[idx].attenuation = storage->light_get_param(li->light, RS::LIGHT_PARAM_ATTENUATION);
|
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].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].cos_spot_angle = Math::cos(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].inv_spot_attenuation = 1.0f / storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
|
||||||
|
|
||||||
idx++;
|
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[1] = color.g;
|
||||||
l.color[2] = color.b;
|
l.color[2] = color.b;
|
||||||
|
|
||||||
l.spot_angle_radians = Math::deg2rad(storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE));
|
l.cos_spot_angle = Math::cos(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.inv_spot_attenuation = 1.0f / storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
|
||||||
|
|
||||||
Transform xform = light_instance_get_base_transform(light_instance);
|
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.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);
|
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);
|
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].has_shadow = storage->light_has_shadow(li->light);
|
||||||
lights[idx].attenuation = storage->light_get_param(li->light, RS::LIGHT_PARAM_ATTENUATION);
|
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].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].cos_spot_angle = Math::cos(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].inv_spot_attenuation = 1.0f / storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
|
||||||
|
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -406,10 +406,10 @@ private:
|
||||||
float attenuation;
|
float attenuation;
|
||||||
|
|
||||||
float color[3];
|
float color[3];
|
||||||
float spot_angle_radians;
|
float cos_spot_angle;
|
||||||
|
|
||||||
float position[3];
|
float position[3];
|
||||||
float spot_attenuation;
|
float inv_spot_attenuation;
|
||||||
|
|
||||||
float direction[3];
|
float direction[3];
|
||||||
uint32_t has_shadow;
|
uint32_t has_shadow;
|
||||||
|
@ -1146,8 +1146,8 @@ private:
|
||||||
float attenuation;
|
float attenuation;
|
||||||
|
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
float spot_angle;
|
float cos_spot_angle;
|
||||||
float spot_attenuation;
|
float inv_spot_attenuation;
|
||||||
float radius;
|
float radius;
|
||||||
|
|
||||||
float shadow_color[4];
|
float shadow_color[4];
|
||||||
|
@ -1362,8 +1362,8 @@ private:
|
||||||
float color[3];
|
float color[3];
|
||||||
float attenuation;
|
float attenuation;
|
||||||
|
|
||||||
float cone_attenuation;
|
float inv_spot_attenuation;
|
||||||
float cone_angle;
|
float cos_spot_angle;
|
||||||
float specular_amount;
|
float specular_amount;
|
||||||
uint32_t shadow_enabled;
|
uint32_t shadow_enabled;
|
||||||
|
|
||||||
|
|
|
@ -51,10 +51,10 @@ struct Light {
|
||||||
float attenuation;
|
float attenuation;
|
||||||
|
|
||||||
vec3 color;
|
vec3 color;
|
||||||
float spot_angle_radians;
|
float cos_spot_angle;
|
||||||
|
|
||||||
vec3 position;
|
vec3 position;
|
||||||
float spot_attenuation;
|
float inv_spot_attenuation;
|
||||||
|
|
||||||
vec3 direction;
|
vec3 direction;
|
||||||
bool has_shadow;
|
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) {
|
if (lights.data[light].type == LIGHT_TYPE_SPOT) {
|
||||||
vec3 rel = normalize(pos - light_pos);
|
vec3 rel = normalize(pos - light_pos);
|
||||||
float angle = acos(dot(rel, lights.data[light].direction));
|
float cos_spot_angle = lights.data[light].cos_spot_angle;
|
||||||
if (angle > lights.data[light].spot_angle_radians) {
|
float cos_angle = dot(rel, lights.data[light].direction);
|
||||||
|
if (cos_angle < cos_spot_angle) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
float d = clamp(angle / lights.data[light].spot_angle_radians, 0, 1);
|
float scos = max(cos_angle, cos_spot_angle);
|
||||||
attenuation *= pow(1.0 - d, lights.data[light].spot_attenuation);
|
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;
|
float attenuation;
|
||||||
|
|
||||||
vec3 color;
|
vec3 color;
|
||||||
float spot_angle_radians;
|
float cos_spot_angle;
|
||||||
|
|
||||||
vec3 position;
|
vec3 position;
|
||||||
float spot_attenuation;
|
float inv_spot_attenuation;
|
||||||
|
|
||||||
vec3 direction;
|
vec3 direction;
|
||||||
bool has_shadow;
|
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) {
|
if (lights.data[light].type == LIGHT_TYPE_SPOT) {
|
||||||
vec3 rel = normalize(pos - light_pos);
|
vec3 rel = normalize(pos - light_pos);
|
||||||
float angle = acos(dot(rel, lights.data[light].direction));
|
float cos_spot_angle = lights.data[light].cos_spot_angle;
|
||||||
if (angle > lights.data[light].spot_angle_radians) {
|
float cos_angle = dot(rel, lights.data[light].direction);
|
||||||
|
if (cos_angle < cos_spot_angle) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
float d = clamp(angle / lights.data[light].spot_angle_radians, 0, 1);
|
float scos = max(cos_angle, cos_spot_angle);
|
||||||
attenuation *= pow(1.0 - d, lights.data[light].spot_attenuation);
|
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;
|
float attenuation;
|
||||||
|
|
||||||
uint type;
|
uint type;
|
||||||
float spot_angle;
|
float cos_spot_angle;
|
||||||
float spot_attenuation;
|
float inv_spot_attenuation;
|
||||||
float radius;
|
float radius;
|
||||||
|
|
||||||
vec4 shadow_color;
|
vec4 shadow_color;
|
||||||
|
@ -266,13 +266,16 @@ void main() {
|
||||||
rel_vec.y /= params.y_mult;
|
rel_vec.y /= params.y_mult;
|
||||||
attenuation = get_omni_attenuation(light_distance, 1.0 / lights.data[i].radius, lights.data[i].attenuation);
|
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));
|
float cos_spot_angle = lights.data[i].cos_spot_angle;
|
||||||
if (angle > lights.data[i].spot_angle) {
|
float cos_angle = dot(-direction, lights.data[i].direction);
|
||||||
attenuation = 0.0;
|
|
||||||
} else {
|
if (cos_angle < cos_spot_angle) {
|
||||||
float d = clamp(angle / lights.data[i].spot_angle, 0, 1);
|
continue;
|
||||||
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);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue