Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2021-03-19 14:52:35 +0300
committerClément Foucault <foucault.clem@gmail.com>2021-03-19 23:11:06 +0300
commit0a0f737f91dcbf280143c826780afe30dae811c9 (patch)
tree29d8a23f8b7e78c1c9b82537341090da432a6bea
parent54f52cac7ccd92c82b9353fd7167f75461618dd7 (diff)
EEVEE: Volumetrics: Add special attenuation volume for lights
This makes volume lights more efficient if they have lower power.
-rw-r--r--source/blender/draw/engines/eevee/eevee_lights.c26
-rw-r--r--source/blender/draw/engines/eevee/shaders/lights_lib.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl13
3 files changed, 28 insertions, 15 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index 146dbc8fc28..63d1cb7adc8 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -41,20 +41,16 @@ void eevee_light_matrix_get(const EEVEE_Light *evli, float r_mat[4][4])
r_mat[3][3] = 1.0f;
}
-static float light_attenuation_radius_get(const Light *la, float light_threshold)
+static float light_attenuation_radius_get(const Light *la,
+ float light_threshold,
+ float light_power)
{
if (la->mode & LA_CUSTOM_ATTENUATION) {
return la->att_dist;
}
-
- /* Compute max light power. */
- float power = max_fff(la->r, la->g, la->b);
- power *= fabsf(la->energy / 100.0f);
- power *= max_fff(la->diff_fac, la->spec_fac, la->volume_fac);
/* Compute the distance (using the inverse square law)
* at which the light power reaches the light_threshold. */
- float distance = sqrtf(max_ff(1e-16, power / max_ff(1e-16, light_threshold)));
- return distance;
+ return sqrtf(max_ff(1e-16, light_power / max_ff(1e-16, light_threshold)));
}
static void light_shape_parameters_set(EEVEE_Light *evli, const Light *la, const float scale[3])
@@ -138,7 +134,7 @@ static float light_shape_power_volume_get(const Light *la, float area_power)
static void eevee_light_setup(Object *ob, EEVEE_Light *evli)
{
const Light *la = (Light *)ob->data;
- float mat[4][4], scale[3], att_radius;
+ float mat[4][4], scale[3];
const DRWContextState *draw_ctx = DRW_context_state_get();
const float light_threshold = draw_ctx->scene->eevee.light_threshold;
@@ -153,10 +149,16 @@ static void eevee_light_setup(Object *ob, EEVEE_Light *evli)
evli->spec = la->spec_fac;
evli->volume = la->volume_fac;
- /* Influence Radius */
- att_radius = light_attenuation_radius_get(la, light_threshold);
+ float max_power = max_fff(la->r, la->g, la->b) * fabsf(la->energy / 100.0f);
+ float surface_max_power = max_ff(evli->diff, evli->spec) * max_power;
+ float volume_max_power = evli->volume * max_power;
+
+ /* Influence Radii. */
+ float att_radius = light_attenuation_radius_get(la, light_threshold, surface_max_power);
+ float att_radius_volume = light_attenuation_radius_get(la, light_threshold, volume_max_power);
/* Take the inverse square of this distance. */
- evli->invsqrdist = 1.0 / max_ff(1e-4f, att_radius * att_radius);
+ evli->invsqrdist = 1.0f / max_ff(1e-4f, square_f(att_radius));
+ evli->invsqrdist_volume = 1.0f / max_ff(1e-4f, square_f(att_radius_volume));
/* Vectors */
normalize_m4_m4_ex(mat, ob->obmat, scale);
diff --git a/source/blender/draw/engines/eevee/shaders/lights_lib.glsl b/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
index d2daa5a1092..0c26c8d1ff1 100644
--- a/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
@@ -251,7 +251,11 @@ float light_attenuation(LightData ld, vec4 l_vector)
vis *= step(0.0, -dot(l_vector.xyz, ld.l_forward));
}
if (ld.l_type != SUN) {
+#ifdef VOLUME_LIGHTING
+ vis *= distance_attenuation(l_vector.w * l_vector.w, ld.l_influence_volume);
+#else
vis *= distance_attenuation(l_vector.w * l_vector.w, ld.l_influence);
+#endif
}
return vis;
}
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl
index f75108babe6..dc755aeab8b 100644
--- a/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl
@@ -40,18 +40,25 @@ void main()
#ifdef VOLUME_LIGHTING /* Lights */
for (int i = 0; i < MAX_LIGHT && i < laNumLight; i++) {
-
LightData ld = lights_data[i];
+ if (ld.l_volume == 0.0) {
+ continue;
+ }
+
vec4 l_vector;
l_vector.xyz = light_volume_light_vector(ld, P);
l_vector.w = length(l_vector.xyz);
- float Vis = light_visibility(ld, P, l_vector);
+ float vis = light_visibility(ld, P, l_vector);
+
+ if (vis < 1e-4) {
+ continue;
+ }
vec3 Li = light_volume(ld, l_vector) * light_volume_shadow(ld, P, l_vector, volumeExtinction);
- outScattering.rgb += Li * Vis * s_scattering *
+ outScattering.rgb += Li * vis * s_scattering *
phase_function(-V, l_vector.xyz / l_vector.w, s_anisotropy);
}
#endif