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 19:28:37 +0300
committerClément Foucault <foucault.clem@gmail.com>2021-03-19 23:11:06 +0300
commit355f884b2f0932e0e1d50e9506d4c0e3bf6e2289 (patch)
tree797e94ce821fadad21de1ada18e779e3c889d9e5 /source/blender/draw/engines/eevee/eevee_lights.c
parent0a0f737f91dcbf280143c826780afe30dae811c9 (diff)
EEVEE: Volumetrics: Add Area light shape support
Previously area lights were just considered as point lights. We now use a "most representative point" technique that make the light shape appearant and gives more homogenous result. This technique is quite cheap but it is not physically correct. So I came up with a power function to have almost the same intensity output as cycles in the general case.
Diffstat (limited to 'source/blender/draw/engines/eevee/eevee_lights.c')
-rw-r--r--source/blender/draw/engines/eevee/eevee_lights.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index 63d1cb7adc8..dff69bcdd52 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -72,7 +72,7 @@ static void light_shape_parameters_set(EEVEE_Light *evli, const Light *la, const
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));
+ evli->radius = max_ff(0.001f, hypotf(evli->sizex, evli->sizey) * 0.5f);
}
else if (la->type == LA_SUN) {
evli->radius = max_ff(0.001f, tanf(min_ff(la->sun_angle, DEG2RADF(179.9f)) / 2.0f));
@@ -111,14 +111,22 @@ 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)
+static float light_shape_power_volume_get(const Light *la,
+ const EEVEE_Light *evli,
+ 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;
+ /* This corrects for area light most representative point trick. The fit was found by
+ * reducing the average error compared to cycles. */
+ float area = evli->sizex * evli->sizey;
+ float tmp = M_PI_2 / (M_PI_2 + sqrtf(area));
+ /* Lerp between 1.0 and the limit (1 / pi). */
+ power *= tmp + (1.0f - tmp) * M_1_PI;
}
else if (ELEM(la->type, LA_SPOT, LA_LOCAL)) {
/* Match cycles. Empirical fit... must correspond to some constant. */
@@ -191,7 +199,7 @@ static void eevee_light_setup(Object *ob, EEVEE_Light *evli)
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);
+ evli->volume *= light_shape_power_volume_get(la, evli, shape_power);
/* No shadow by default */
evli->shadow_id = -1.0f;