[Bf-blender-cvs] [5bae09c1c74] soc-2022-many-lights-sampling: Cycles: support spot and area lights in light tree
Jeffrey Liu
noreply at git.blender.org
Sun Jun 19 08:10:40 CEST 2022
Commit: 5bae09c1c742c70162781a414ce8eba6b3d97a23
Author: Jeffrey Liu
Date: Sun Jun 19 02:10:01 2022 -0400
Branches: soc-2022-many-lights-sampling
https://developer.blender.org/rB5bae09c1c742c70162781a414ce8eba6b3d97a23
Cycles: support spot and area lights in light tree
===================================================================
M intern/cycles/kernel/light/light_tree.h
M intern/cycles/scene/light.cpp
M intern/cycles/scene/light_tree.cpp
M release/scripts/addons
===================================================================
diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h
index 87c49ebc30c..1c9684e006c 100644
--- a/intern/cycles/kernel/light/light_tree.h
+++ b/intern/cycles/kernel/light/light_tree.h
@@ -84,28 +84,22 @@ ccl_device float light_tree_emitter_importance(KernelGlobals kg,
if (prim >= 0) {
/* to-do: handle case for mesh lights. */
}
- else {
- const int lamp = -prim - 1;
- const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, lamp);
- if (klight->type == LIGHT_POINT) {
- const float radius = klight->spot.radius;
- const float3 bbox_min = make_float3(
- klight->co[0] - radius, klight->co[1] - radius, klight->co[2] - radius);
- const float3 bbox_max = make_float3(
- klight->co[0] + radius, klight->co[1] + radius, klight->co[2] + radius);
- const float3 rgb_strength = make_float3(
- klight->strength[0], klight->strength[1], klight->strength[2]);
-
- /* to-do: only the radius and invarea from the spotlight properties is used for a point light,
- * but we still need to choose an arbitrary direction. Maybe this can be replaced with something else? */
- const float3 bcone_axis = make_float3(
- klight->spot.dir[0], klight->spot.dir[1], klight->spot.dir[2]);
-
- return light_tree_node_importance(
- P, N, bbox_min, bbox_max, bcone_axis, M_PI_F, M_PI_2_F, linear_rgb_to_gray(kg, rgb_strength));
- }
- }
+ /* If we're not at a mesh light, then we should be at a point, spot, or area light. */
+ const int lamp = -prim - 1;
+ const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, lamp);
+ const float radius = klight->spot.radius;
+ const float3 bbox_min = make_float3(
+ klight->co[0] - radius, klight->co[1] - radius, klight->co[2] - radius);
+ const float3 bbox_max = make_float3(
+ klight->co[0] + radius, klight->co[1] + radius, klight->co[2] + radius);
+ const float3 bcone_axis = make_float3(
+ klight->spot.dir[0], klight->spot.dir[1], klight->spot.dir[2]);
+ const float3 rgb_strength = make_float3(
+ klight->strength[0], klight->strength[1], klight->strength[2]);
+
+ return light_tree_node_importance(
+ P, N, bbox_min, bbox_max, bcone_axis, M_PI_F, M_PI_2_F, linear_rgb_to_gray(kg, rgb_strength));
}
ccl_device float light_tree_cluster_importance(KernelGlobals kg,
@@ -208,6 +202,7 @@ ccl_device bool light_tree_sample(KernelGlobals kg,
/* We should never reach this point. */
assert(false);
+ return false;
}
ccl_device bool light_tree_sample_from_position(KernelGlobals kg,
diff --git a/intern/cycles/scene/light.cpp b/intern/cycles/scene/light.cpp
index 84c4f63a2fb..e9407554cbe 100644
--- a/intern/cycles/scene/light.cpp
+++ b/intern/cycles/scene/light.cpp
@@ -288,6 +288,7 @@ void LightManager::device_update_distribution(Device *,
int scene_light_index = 0;
foreach (Light *light, scene->lights) {
if (light->is_enabled) {
+ /* to-do: make sure not to add background lights to the light tree once those scenes are tested. */
LightTreePrimitive light_prim;
light_prim.prim_id = ~device_light_index; /* -prim_id - 1 is a light source index. */
light_prim.lamp_id = scene_light_index;
diff --git a/intern/cycles/scene/light_tree.cpp b/intern/cycles/scene/light_tree.cpp
index d50f257e6c7..22930586d43 100644
--- a/intern/cycles/scene/light_tree.cpp
+++ b/intern/cycles/scene/light_tree.cpp
@@ -60,28 +60,93 @@ OrientationBounds merge(const OrientationBounds& cone_a,
BoundBox LightTreePrimitive::calculate_bbox(Scene *scene) const
{
BoundBox bbox = BoundBox::empty;
- Light *lamp = scene->lights[lamp_id];
- /* A point light can emit light from any point within its radius. */
- bbox.grow(lamp->get_co() - make_float3(lamp->get_size()));
- bbox.grow(lamp->get_co() + make_float3(lamp->get_size()));
+
+ if (prim_id >= 0) {
+ /* to-do: handle mesh lights in the future. */
+ }
+ else {
+ Light *lamp = scene->lights[lamp_id];
+ LightType type = lamp->get_light_type();
+ const float3 center = lamp->get_co();
+ const float size = lamp->get_size();
+
+ if (type == LIGHT_POINT || type == LIGHT_SPOT) {
+ /* Point and spot lights can emit light from any point within its radius. */
+ const float3 radius = make_float3(size);
+ bbox.grow(center - radius);
+ bbox.grow(center + radius);
+ }
+ else if (type == LIGHT_AREA) {
+ /* For an area light, sizeu and sizev determine the 2 dimensions of the area light,
+ * while axisu and axisv determine the orientation of the 2 dimensions.
+ * We want to add all 4 corners to our bounding box. */
+ const float3 half_extentu = 0.5 * lamp->get_sizeu() * lamp->get_axisu() * size;
+ const float3 half_extentv = 0.5 * lamp->get_sizev() * lamp->get_axisv() * size;
+
+ bbox.grow(center + half_extentu + half_extentv);
+ bbox.grow(center + half_extentu - half_extentv);
+ bbox.grow(center - half_extentu + half_extentv);
+ bbox.grow(center - half_extentu - half_extentv);
+ }
+ else {
+ /* This should never be reached during construction. */
+ assert(false);
+ }
+ }
+
return bbox;
}
OrientationBounds LightTreePrimitive::calculate_bcone(Scene *scene) const
{
- OrientationBounds bcone;
- Light *lamp = scene->lights[lamp_id];
- bcone.axis = lamp->get_dir() / len(lamp->get_dir());
- bcone.theta_o = M_PI_F;
- bcone.theta_e = M_PI_2_F;
+ OrientationBounds bcone = OrientationBounds::empty;
+
+ if (prim_id >= 0) {
+ /* to-do: handle mesh lights in the future. */
+ }
+ else {
+ Light *lamp = scene->lights[lamp_id];
+ LightType type = lamp->get_light_type();
+
+ bcone.axis = normalize(lamp->get_dir());
+
+ if (type == LIGHT_POINT) {
+ bcone.theta_o = M_PI_F;
+ bcone.theta_e = M_PI_2_F;
+ }
+ else if (type == LIGHT_SPOT) {
+ bcone.theta_o = 0;
+ bcone.theta_e = lamp->get_spot_angle() * 0.5f;
+ }
+ else if (type == LIGHT_AREA) {
+ bcone.theta_o = 0;
+ bcone.theta_e = M_PI_2_F;
+ }
+ else {
+ /* This should never be reached during construction. */
+ assert(false);
+ }
+ }
+
return bcone;
}
float LightTreePrimitive::calculate_energy(Scene *scene) const
{
- Light *lamp = scene->lights[lamp_id];
- /* Past GSoC work also divides this by pi, but will need to test which is more accurate. */
- return scene->shader_manager->linear_rgb_to_gray(lamp->get_strength());
+ float3 strength = make_float3(0.0f);
+
+ if (prim_id >= 0) {
+ /* to-do: handle mesh lights in the future. */
+ }
+ else {
+ Light *lamp = scene->lights[lamp_id];
+ /* to-do: Past GSoC work also divides this by pi, but will need to test which is more accurate.
+ * It seems like direction should be handled implicitly by the bounding cone,
+ * by testing will provide more conclusive answers. */
+ strength = lamp->get_strength();
+ }
+
+ return scene->shader_manager->linear_rgb_to_gray(strength);
}
void LightTreeBuildNode::init_leaf(
diff --git a/release/scripts/addons b/release/scripts/addons
index bdf75cb276d..5902265f1e5 160000
--- a/release/scripts/addons
+++ b/release/scripts/addons
@@ -1 +1 @@
-Subproject commit bdf75cb276dfd3b5266c909de4c099c00c68a659
+Subproject commit 5902265f1e5aaeca3781ea15f994bdf0b3cb054d
More information about the Bf-blender-cvs
mailing list