Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change the light attenuation formulas. #44941

Merged
merged 1 commit into from
Jan 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion modules/lightmapper_rd/lm_compute.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,15 @@ float quick_hash(vec2 pos) {
return fract(sin(dot(pos * 19.19, vec2(49.5791, 97.413))) * 49831.189237);
}

float get_omni_attenuation(float distance, float inv_range, float decay) {
float nd = distance * inv_range;
nd *= nd;
nd *= nd; // nd^4
nd = max(1.0 - nd, 0.0);
nd *= nd; // nd^2
return nd * pow(max(distance, 0.0001), -decay);
}

void main() {
#ifdef MODE_LIGHT_PROBES
int probe_index = int(gl_GlobalInvocationID.x);
Expand Down Expand Up @@ -300,7 +309,7 @@ void main() {

d /= lights.data[i].range;

attenuation = pow(max(1.0 - d, 0.0), lights.data[i].attenuation);
attenuation = get_omni_attenuation(d, 1.0 / lights.data[i].range, lights.data[i].attenuation);

if (lights.data[i].type == LIGHT_TYPE_SPOT) {
vec3 rel = normalize(position - light_pos);
Expand Down
11 changes: 10 additions & 1 deletion servers/rendering/renderer_rd/shaders/giprobe.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,15 @@ float raymarch(float distance, float distance_adv, vec3 from, vec3 direction) {
return occlusion; //max(0.0,distance);
}

float get_omni_attenuation(float distance, float inv_range, float decay) {
float nd = distance * inv_range;
nd *= nd;
nd *= nd; // nd^4
nd = max(1.0 - nd, 0.0);
nd *= nd; // nd^2
return nd * pow(max(distance, 0.0001), -decay);
}

bool compute_light_vector(uint light, vec3 pos, out float attenuation, out vec3 light_pos) {
if (lights.data[light].type == LIGHT_TYPE_DIRECTIONAL) {
light_pos = pos - lights.data[light].direction * length(vec3(params.limits));
Expand All @@ -220,7 +229,7 @@ bool compute_light_vector(uint light, vec3 pos, out float attenuation, out vec3
return false;
}

attenuation = pow(clamp(1.0 - distance / lights.data[light].radius, 0.0001, 1.0), lights.data[light].attenuation);
attenuation = get_omni_attenuation(distance, 1.0 / lights.data[light].radius, lights.data[light].attenuation);

if (lights.data[light].type == LIGHT_TYPE_SPOT) {
vec3 rel = normalize(pos - light_pos);
Expand Down
15 changes: 11 additions & 4 deletions servers/rendering/renderer_rd/shaders/scene_forward.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,15 @@ float sample_directional_soft_shadow(texture2D shadow, vec3 pssm_coord, vec2 tex

#endif //USE_NO_SHADOWS

float get_omni_attenuation(float distance, float inv_range, float decay) {
float nd = distance * inv_range;
nd *= nd;
nd *= nd; // nd^4
nd = max(1.0 - nd, 0.0);
nd *= nd; // nd^2
return nd * pow(max(distance, 0.0001), -decay);
}

void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 vertex_ddx, vec3 vertex_ddy, vec3 albedo, float roughness, float metallic, float specular, float p_blob_intensity,
#ifdef LIGHT_BACKLIGHT_USED
vec3 backlight,
Expand All @@ -916,9 +925,8 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
inout vec3 diffuse_light, inout vec3 specular_light) {
vec3 light_rel_vec = lights.data[idx].position - vertex;
float light_length = length(light_rel_vec);
float normalized_distance = light_length * lights.data[idx].inv_radius;
vec2 attenuation_energy = unpackHalf2x16(lights.data[idx].attenuation_energy);
float omni_attenuation = pow(max(1.0 - normalized_distance, 0.0), attenuation_energy.x);
float omni_attenuation = get_omni_attenuation(light_length, lights.data[idx].inv_radius, attenuation_energy.x);
float light_attenuation = omni_attenuation;
vec3 shadow_attenuation = vec3(1.0);
vec4 color_specular = unpackUnorm4x8(lights.data[idx].color_specular);
Expand Down Expand Up @@ -1205,9 +1213,8 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
inout vec3 specular_light) {
vec3 light_rel_vec = lights.data[idx].position - vertex;
float light_length = length(light_rel_vec);
float normalized_distance = light_length * lights.data[idx].inv_radius;
vec2 attenuation_energy = unpackHalf2x16(lights.data[idx].attenuation_energy);
float spot_attenuation = pow(max(1.0 - normalized_distance, 0.001), attenuation_energy.x);
float spot_attenuation = get_omni_attenuation(light_length, lights.data[idx].inv_radius, attenuation_energy.x);
vec3 spot_dir = lights.data[idx].direction;
vec2 spot_att_angle = unpackHalf2x16(lights.data[idx].cone_attenuation_angle);
float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_att_angle.y);
Expand Down
14 changes: 12 additions & 2 deletions servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,15 @@ vec2 octahedron_encode(vec3 n) {
return n.xy;
}

float get_omni_attenuation(float distance, float inv_range, float decay) {
float nd = distance * inv_range;
nd *= nd;
nd *= nd; // nd^4
nd = max(1.0 - nd, 0.0);
nd *= nd; // nd^2
return nd * pow(max(distance, 0.0001), -decay);
}

void main() {
uint voxel_index = uint(gl_GlobalInvocationID.x);

Expand Down Expand Up @@ -184,14 +193,15 @@ void main() {
direction = normalize(rel_vec);
light_distance = length(rel_vec);
rel_vec.y /= params.y_mult;
attenuation = pow(clamp(1.0 - length(rel_vec) / lights.data[i].radius, 0.0, 1.0), lights.data[i].attenuation);
attenuation = get_omni_attenuation(light_distance, 1.0 / lights.data[i].radius, lights.data[i].attenuation);

} break;
case LIGHT_TYPE_SPOT: {
vec3 rel_vec = lights.data[i].position - position;
direction = normalize(rel_vec);
light_distance = length(rel_vec);
rel_vec.y /= params.y_mult;
attenuation = pow(clamp(1.0 - length(rel_vec) / lights.data[i].radius, 0.0, 1.0), 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));
if (angle > lights.data[i].spot_angle) {
Expand Down
21 changes: 15 additions & 6 deletions servers/rendering/renderer_rd/shaders/volumetric_fog.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,15 @@ vec3 hash3f(uvec3 x) {
return vec3(x & 0xFFFFF) / vec3(float(0xFFFFF));
}

float get_omni_attenuation(float distance, float inv_range, float decay) {
float nd = distance * inv_range;
nd *= nd;
nd *= nd; // nd^4
nd = max(1.0 - nd, 0.0);
nd *= nd; // nd^2
return nd * pow(max(distance, 0.0001), -decay);
}

void main() {
vec3 fog_cell_size = 1.0 / vec3(params.fog_volume_size);

Expand Down Expand Up @@ -270,14 +279,14 @@ void main() {
uint light_index = cluster_data.indices[omni_light_pointer + i];

vec3 light_pos = lights.data[i].position;
float d = distance(lights.data[i].position, view_pos) * lights.data[i].inv_radius;
float d = distance(lights.data[i].position, view_pos);
vec3 shadow_attenuation = vec3(1.0);

if (d < 1.0) {
if (d * lights.data[i].inv_radius < 1.0) {
vec2 attenuation_energy = unpackHalf2x16(lights.data[i].attenuation_energy);
vec4 color_specular = unpackUnorm4x8(lights.data[i].color_specular);

float attenuation = pow(max(1.0 - d, 0.0), attenuation_energy.x);
float attenuation = get_omni_attenuation(d, lights.data[i].inv_radius, attenuation_energy.x);

vec3 light = attenuation_energy.y * color_specular.rgb / M_PI;

Expand Down Expand Up @@ -326,14 +335,14 @@ void main() {

vec3 light_pos = lights.data[i].position;
vec3 light_rel_vec = lights.data[i].position - view_pos;
float d = length(light_rel_vec) * lights.data[i].inv_radius;
float d = length(light_rel_vec);
vec3 shadow_attenuation = vec3(1.0);

if (d < 1.0) {
if (d * lights.data[i].inv_radius < 1.0) {
vec2 attenuation_energy = unpackHalf2x16(lights.data[i].attenuation_energy);
vec4 color_specular = unpackUnorm4x8(lights.data[i].color_specular);

float attenuation = pow(max(1.0 - d, 0.0), attenuation_energy.x);
float attenuation = get_omni_attenuation(d, lights.data[i].inv_radius, attenuation_energy.x);

vec3 spot_dir = lights.data[i].direction;
vec2 spot_att_angle = unpackHalf2x16(lights.data[i].cone_attenuation_angle);
Expand Down