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:
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;