Merge pull request #44941 from reduz/new-light-attenuation
Change the light attenuation formulas.
This commit is contained in:
commit
c7c03d5fba
5 changed files with 58 additions and 14 deletions
|
@ -249,6 +249,15 @@ float quick_hash(vec2 pos) {
|
||||||
return fract(sin(dot(pos * 19.19, vec2(49.5791, 97.413))) * 49831.189237);
|
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() {
|
void main() {
|
||||||
#ifdef MODE_LIGHT_PROBES
|
#ifdef MODE_LIGHT_PROBES
|
||||||
int probe_index = int(gl_GlobalInvocationID.x);
|
int probe_index = int(gl_GlobalInvocationID.x);
|
||||||
|
@ -300,7 +309,7 @@ void main() {
|
||||||
|
|
||||||
d /= lights.data[i].range;
|
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) {
|
if (lights.data[i].type == LIGHT_TYPE_SPOT) {
|
||||||
vec3 rel = normalize(position - light_pos);
|
vec3 rel = normalize(position - light_pos);
|
||||||
|
|
|
@ -208,6 +208,15 @@ float raymarch(float distance, float distance_adv, vec3 from, vec3 direction) {
|
||||||
return occlusion; //max(0.0,distance);
|
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) {
|
bool compute_light_vector(uint light, vec3 pos, out float attenuation, out vec3 light_pos) {
|
||||||
if (lights.data[light].type == LIGHT_TYPE_DIRECTIONAL) {
|
if (lights.data[light].type == LIGHT_TYPE_DIRECTIONAL) {
|
||||||
light_pos = pos - lights.data[light].direction * length(vec3(params.limits));
|
light_pos = pos - lights.data[light].direction * length(vec3(params.limits));
|
||||||
|
@ -220,7 +229,7 @@ bool compute_light_vector(uint light, vec3 pos, out float attenuation, out vec3
|
||||||
return false;
|
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) {
|
if (lights.data[light].type == LIGHT_TYPE_SPOT) {
|
||||||
vec3 rel = normalize(pos - light_pos);
|
vec3 rel = normalize(pos - light_pos);
|
||||||
|
|
|
@ -891,6 +891,15 @@ float sample_directional_soft_shadow(texture2D shadow, vec3 pssm_coord, vec2 tex
|
||||||
|
|
||||||
#endif //USE_NO_SHADOWS
|
#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,
|
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
|
#ifdef LIGHT_BACKLIGHT_USED
|
||||||
vec3 backlight,
|
vec3 backlight,
|
||||||
|
@ -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) {
|
inout vec3 diffuse_light, inout vec3 specular_light) {
|
||||||
vec3 light_rel_vec = lights.data[idx].position - vertex;
|
vec3 light_rel_vec = lights.data[idx].position - vertex;
|
||||||
float light_length = length(light_rel_vec);
|
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);
|
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;
|
float light_attenuation = omni_attenuation;
|
||||||
vec3 shadow_attenuation = vec3(1.0);
|
vec3 shadow_attenuation = vec3(1.0);
|
||||||
vec4 color_specular = unpackUnorm4x8(lights.data[idx].color_specular);
|
vec4 color_specular = unpackUnorm4x8(lights.data[idx].color_specular);
|
||||||
|
@ -1205,9 +1213,8 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
|
||||||
inout vec3 specular_light) {
|
inout vec3 specular_light) {
|
||||||
vec3 light_rel_vec = lights.data[idx].position - vertex;
|
vec3 light_rel_vec = lights.data[idx].position - vertex;
|
||||||
float light_length = length(light_rel_vec);
|
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);
|
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;
|
vec3 spot_dir = lights.data[idx].direction;
|
||||||
vec2 spot_att_angle = unpackHalf2x16(lights.data[idx].cone_attenuation_angle);
|
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);
|
float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_att_angle.y);
|
||||||
|
|
|
@ -112,6 +112,15 @@ vec2 octahedron_encode(vec3 n) {
|
||||||
return n.xy;
|
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() {
|
void main() {
|
||||||
uint voxel_index = uint(gl_GlobalInvocationID.x);
|
uint voxel_index = uint(gl_GlobalInvocationID.x);
|
||||||
|
|
||||||
|
@ -184,14 +193,15 @@ void main() {
|
||||||
direction = normalize(rel_vec);
|
direction = normalize(rel_vec);
|
||||||
light_distance = length(rel_vec);
|
light_distance = length(rel_vec);
|
||||||
rel_vec.y /= params.y_mult;
|
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;
|
} break;
|
||||||
case LIGHT_TYPE_SPOT: {
|
case LIGHT_TYPE_SPOT: {
|
||||||
vec3 rel_vec = lights.data[i].position - position;
|
vec3 rel_vec = lights.data[i].position - position;
|
||||||
direction = normalize(rel_vec);
|
direction = normalize(rel_vec);
|
||||||
light_distance = length(rel_vec);
|
light_distance = length(rel_vec);
|
||||||
rel_vec.y /= params.y_mult;
|
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));
|
float angle = acos(dot(normalize(rel_vec), -lights.data[i].direction));
|
||||||
if (angle > lights.data[i].spot_angle) {
|
if (angle > lights.data[i].spot_angle) {
|
||||||
|
|
|
@ -169,6 +169,15 @@ vec3 hash3f(uvec3 x) {
|
||||||
return vec3(x & 0xFFFFF) / vec3(float(0xFFFFF));
|
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() {
|
void main() {
|
||||||
vec3 fog_cell_size = 1.0 / vec3(params.fog_volume_size);
|
vec3 fog_cell_size = 1.0 / vec3(params.fog_volume_size);
|
||||||
|
|
||||||
|
@ -270,14 +279,14 @@ void main() {
|
||||||
uint light_index = cluster_data.indices[omni_light_pointer + i];
|
uint light_index = cluster_data.indices[omni_light_pointer + i];
|
||||||
|
|
||||||
vec3 light_pos = lights.data[i].position;
|
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);
|
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);
|
vec2 attenuation_energy = unpackHalf2x16(lights.data[i].attenuation_energy);
|
||||||
vec4 color_specular = unpackUnorm4x8(lights.data[i].color_specular);
|
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;
|
vec3 light = attenuation_energy.y * color_specular.rgb / M_PI;
|
||||||
|
|
||||||
|
@ -326,14 +335,14 @@ void main() {
|
||||||
|
|
||||||
vec3 light_pos = lights.data[i].position;
|
vec3 light_pos = lights.data[i].position;
|
||||||
vec3 light_rel_vec = lights.data[i].position - view_pos;
|
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);
|
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);
|
vec2 attenuation_energy = unpackHalf2x16(lights.data[i].attenuation_energy);
|
||||||
vec4 color_specular = unpackUnorm4x8(lights.data[i].color_specular);
|
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;
|
vec3 spot_dir = lights.data[i].direction;
|
||||||
vec2 spot_att_angle = unpackHalf2x16(lights.data[i].cone_attenuation_angle);
|
vec2 spot_att_angle = unpackHalf2x16(lights.data[i].cone_attenuation_angle);
|
||||||
|
|
Loading…
Reference in a new issue