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:07:23 +0300
committerClément Foucault <foucault.clem@gmail.com>2021-03-19 23:11:06 +0300
commit884f934a853f7043a7e5a6ea380d560c858a78b7 (patch)
tree14c4441579169bcc50de145d24dbff5ab206200a /source/blender/draw/engines/eevee/eevee_lights.c
parentfb3e5b7f986e7215c6488c2b93db8559e84cfb98 (diff)
EEVEE: Lights: Add Volume and diffuse light power slider
This adds 2 new sliders for light objects that modulates the diffuse light and the volume light intensities. This also changes the way volume light is computed using point lamp representation. We use "Point Light Attenuation Without Singularity" from Cem Yuksel instead of the usual inverse square law.
Diffstat (limited to 'source/blender/draw/engines/eevee/eevee_lights.c')
-rw-r--r--source/blender/draw/engines/eevee/eevee_lights.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index b773049f6f7..146dbc8fc28 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -50,7 +50,7 @@ static float light_attenuation_radius_get(const Light *la, float light_threshold
/* Compute max light power. */
float power = max_fff(la->r, la->g, la->b);
power *= fabsf(la->energy / 100.0f);
- power *= max_ff(1.0f, la->spec_fac);
+ 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)));
@@ -75,6 +75,8 @@ static void light_shape_parameters_set(EEVEE_Light *evli, const Light *la, const
else {
evli->sizey = max_ff(0.003f, la->area_size * scale[1] * 0.5f);
}
+ /* For volume point lighting. */
+ evli->radius = max_ff(0.001f, hypotf(evli->sizex, evli->sizey));
}
else if (la->type == LA_SUN) {
evli->radius = max_ff(0.001f, tanf(min_ff(la->sun_angle, DEG2RADF(179.9f)) / 2.0f));
@@ -103,8 +105,8 @@ static float light_shape_power_get(const Light *la, const EEVEE_Light *evli)
/* for point lights (a.k.a radius == 0.0) */
// power = M_PI * M_PI * 0.78; /* XXX : Empirical, Fit cycles power */
}
- else {
- power = 1.0f / (evli->radius * evli->radius * M_PI); /* 1/(r²*Pi) */
+ else { /* LA_SUN */
+ power = 1.0f / (evli->radius * evli->radius * M_PI);
/* Make illumination power closer to cycles for bigger radii. Cycles uses a cos^3 term that we
* cannot reproduce so we account for that by scaling the light power. This function is the
* result of a rough manual fitting. */
@@ -113,11 +115,30 @@ static float light_shape_power_get(const Light *la, const EEVEE_Light *evli)
return power;
}
+static float light_shape_power_volume_get(const Light *la, float area_power)
+{
+ /* Volume light is evaluated as point lights. Remove the shape power. */
+ float power = 1.0f / area_power;
+ /* Make illumination power constant */
+ if (la->type == LA_AREA) {
+ /* Match cycles. Empirical fit... must correspond to some constant. */
+ power *= 0.0792f * M_PI;
+ }
+ else if (ELEM(la->type, LA_SPOT, LA_LOCAL)) {
+ /* Match cycles. Empirical fit... must correspond to some constant. */
+ power *= 0.0792f;
+ }
+ else { /* LA_SUN */
+ /* Nothing to do. */
+ }
+ return power;
+}
+
/* Update buffer with light data */
static void eevee_light_setup(Object *ob, EEVEE_Light *evli)
{
- Light *la = (Light *)ob->data;
- float mat[4][4], scale[3], power, att_radius;
+ const Light *la = (Light *)ob->data;
+ float mat[4][4], scale[3], att_radius;
const DRWContextState *draw_ctx = DRW_context_state_get();
const float light_threshold = draw_ctx->scene->eevee.light_threshold;
@@ -128,7 +149,9 @@ static void eevee_light_setup(Object *ob, EEVEE_Light *evli)
/* Color */
copy_v3_v3(evli->color, &la->r);
+ evli->diff = la->diff_fac;
evli->spec = la->spec_fac;
+ evli->volume = la->volume_fac;
/* Influence Radius */
att_radius = light_attenuation_radius_get(la, light_threshold);
@@ -163,8 +186,10 @@ static void eevee_light_setup(Object *ob, EEVEE_Light *evli)
evli->light_type = LAMPTYPE_AREA_ELLIPSE;
}
- power = light_shape_power_get(la, evli);
- mul_v3_fl(evli->color, power * la->energy);
+ float shape_power = light_shape_power_get(la, evli);
+ mul_v3_fl(evli->color, shape_power * la->energy);
+
+ evli->volume *= light_shape_power_volume_get(la, shape_power);
/* No shadow by default */
evli->shadow_id = -1.0f;