Merge pull request #41308 from JFonS/fix_spotlight_attenuation
Invert spotlight angle attenuation
This commit is contained in:
commit
ce332859e9
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