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:
authorBrecht Van Lommel <brecht@blender.org>2021-03-22 21:27:58 +0300
committerBrecht Van Lommel <brecht@blender.org>2021-04-01 13:31:01 +0300
commit3f24cfb9582e1c826406301d37808df7ca6aa64c (patch)
tree23e816d0ebf5b23d4e68a4a5ec3dbcd75a218110 /intern/cycles/kernel/kernel_light.h
parenta4260ac21977acd5b9cd792f2a68c3aa78dd91cd (diff)
Cycles: light spread importance sampling for rectangular area lights
Compute a subset of the area light that actually affects the shading point and only samples points within that. It's not perfect as the real subset is a circle instead of a rectangle, and the attenuation is not accounted for. However it massively reduces noise for shading points near the area light anyway. Ellipse shaped area lights do not have this importance sampling, but do not have solid angle importance sampling either. Ref D10594
Diffstat (limited to 'intern/cycles/kernel/kernel_light.h')
-rw-r--r--intern/cycles/kernel/kernel_light.h32
1 files changed, 26 insertions, 6 deletions
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index 93b05f0ffce..f288ca3051a 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -119,11 +119,11 @@ ccl_device_inline bool lamp_light_sample(
klight->area.axisu[0], klight->area.axisu[1], klight->area.axisu[2]);
float3 axisv = make_float3(
klight->area.axisv[0], klight->area.axisv[1], klight->area.axisv[2]);
- float3 D = make_float3(klight->area.dir[0], klight->area.dir[1], klight->area.dir[2]);
+ float3 Ng = make_float3(klight->area.dir[0], klight->area.dir[1], klight->area.dir[2]);
float invarea = fabsf(klight->area.invarea);
bool is_round = (klight->area.invarea < 0.0f);
- if (dot(ls->P - P, D) > 0.0f) {
+ if (dot(ls->P - P, Ng) > 0.0f) {
return false;
}
@@ -135,15 +135,25 @@ ccl_device_inline bool lamp_light_sample(
ls->pdf = invarea;
}
else {
+ float3 sample_axisu = axisu;
+ float3 sample_axisv = axisv;
+
+ if (klight->area.tan_spread > 0.0f) {
+ if (!light_spread_clamp_area_light(
+ P, Ng, &ls->P, &sample_axisu, &sample_axisv, klight->area.tan_spread)) {
+ return false;
+ }
+ }
+
inplane = ls->P;
- ls->pdf = rect_light_sample(P, &ls->P, axisu, axisv, randu, randv, true);
+ ls->pdf = rect_light_sample(P, &ls->P, sample_axisu, sample_axisv, randu, randv, true);
inplane = ls->P - inplane;
}
ls->u = dot(inplane, axisu) * (1.0f / dot(axisu, axisu)) + 0.5f;
ls->v = dot(inplane, axisv) * (1.0f / dot(axisv, axisv)) + 0.5f;
- ls->Ng = D;
+ ls->Ng = Ng;
ls->D = normalize_len(ls->P - P, &ls->t);
ls->eval_fac = 0.25f * invarea;
@@ -155,7 +165,7 @@ ccl_device_inline bool lamp_light_sample(
}
if (is_round) {
- ls->pdf *= lamp_light_pdf(kg, D, -ls->D, ls->t);
+ ls->pdf *= lamp_light_pdf(kg, Ng, -ls->D, ls->t);
}
}
}
@@ -290,7 +300,17 @@ ccl_device bool lamp_light_eval(
ls->pdf = invarea * lamp_light_pdf(kg, Ng, -D, ls->t);
}
else {
- ls->pdf = rect_light_sample(P, &light_P, axisu, axisv, 0, 0, false);
+ float3 sample_axisu = axisu;
+ float3 sample_axisv = axisv;
+
+ if (klight->area.tan_spread > 0.0f) {
+ if (!light_spread_clamp_area_light(
+ P, Ng, &light_P, &sample_axisu, &sample_axisv, klight->area.tan_spread)) {
+ return false;
+ }
+ }
+
+ ls->pdf = rect_light_sample(P, &light_P, sample_axisu, sample_axisv, 0, 0, false);
}
ls->eval_fac = 0.25f * invarea;