[Bf-blender-cvs] [9a97eb549c4] soc-2022-many-lights-sampling: Refactor: move light tree parameters computation to light type header files
Weizhen Huang
noreply at git.blender.org
Tue Nov 29 17:02:39 CET 2022
Commit: 9a97eb549c4c0c8c1064f11d7c9c6d57decef4be
Author: Weizhen Huang
Date: Tue Nov 29 17:01:32 2022 +0100
Branches: soc-2022-many-lights-sampling
https://developer.blender.org/rB9a97eb549c4c0c8c1064f11d7c9c6d57decef4be
Refactor: move light tree parameters computation to light type header files
===================================================================
M intern/cycles/kernel/light/area.h
M intern/cycles/kernel/light/background.h
M intern/cycles/kernel/light/distant.h
M intern/cycles/kernel/light/point.h
M intern/cycles/kernel/light/spot.h
M intern/cycles/kernel/light/tree.h
M intern/cycles/kernel/light/triangle.h
===================================================================
diff --git a/intern/cycles/kernel/light/area.h b/intern/cycles/kernel/light/area.h
index f7c52db1692..8daadebe67d 100644
--- a/intern/cycles/kernel/light/area.h
+++ b/intern/cycles/kernel/light/area.h
@@ -322,31 +322,42 @@ ccl_device_inline bool area_light_sample_from_intersection(
return true;
}
-ccl_device_inline float area_light_tree_weight(const ccl_global KernelLight *klight,
- const float3 P,
- const float3 N)
+template<bool in_volume_segment>
+ccl_device_forceinline bool area_light_tree_parameters(const ccl_global KernelLight *klight,
+ const float3 centroid,
+ const float3 P,
+ const float3 N,
+ const float3 bcone_axis,
+ ccl_private float &cos_theta_u,
+ ccl_private float2 &distance,
+ ccl_private float3 &point_to_centroid)
{
- float3 light_P = klight->co;
-
- float3 extentu = klight->area.extentu;
- float3 extentv = klight->area.extentv;
- float3 Ng = klight->area.dir;
- bool is_round = (klight->area.invarea < 0.0f);
-
- if (dot(light_P - P, Ng) > 0.0f) {
- return 0.0f;
+ if (!in_volume_segment) {
+ /* TODO: a cheap substitute for minimal distance between point and primitive. Does it
+ * worth the overhead to compute the accurate minimal distance? */
+ point_to_centroid = safe_normalize_len(centroid - P, &distance.y);
+ distance.x = distance.y;
}
- if (!is_round) {
- if (klight->area.tan_spread > 0.0f) {
- if (!area_light_spread_clamp_area_light(
- P, Ng, &light_P, &extentu, &extentv, klight->area.tan_spread)) {
- return 0.0f;
- }
+ const float3 extentu = klight->area.extentu;
+ const float3 extentv = klight->area.extentv;
+ for (int i = 0; i < 4; i++) {
+ const float3 corner = ((i & 1) - 0.5f) * extentu + 0.5f * ((i & 2) - 1) * extentv + centroid;
+ float distance_point_to_corner;
+ const float3 point_to_corner = safe_normalize_len(corner - P, &distance_point_to_corner);
+ cos_theta_u = fminf(cos_theta_u, dot(point_to_centroid, point_to_corner));
+ if (!in_volume_segment) {
+ distance.x = fmaxf(distance.x, distance_point_to_corner);
}
}
- return 1.0f;
+ const bool front_facing = dot(bcone_axis, point_to_centroid) < 0;
+ const bool shape_above_surface = dot(N, centroid - P) + fabsf(dot(N, extentu)) +
+ fabsf(dot(N, extentv)) >
+ 0;
+ const bool in_volume = is_zero(N);
+
+ return (front_facing && shape_above_surface) || in_volume;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/light/background.h b/intern/cycles/kernel/light/background.h
index 95bd5d47f9f..b37b4410ed4 100644
--- a/intern/cycles/kernel/light/background.h
+++ b/intern/cycles/kernel/light/background.h
@@ -430,4 +430,18 @@ ccl_device float background_light_pdf(KernelGlobals kg, float3 P, float3 directi
return pdf;
}
+ccl_device_forceinline bool background_light_tree_parameters(const float3 centroid,
+ ccl_private float &cos_theta_u,
+ ccl_private float2 &distance,
+ ccl_private float3 &point_to_centroid)
+{
+ /* Cover the whole sphere */
+ cos_theta_u = -1.0f;
+
+ distance = make_float2(1.0f, 1.0f);
+ point_to_centroid = -centroid;
+
+ return true;
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/light/distant.h b/intern/cycles/kernel/light/distant.h
index c074a6bf097..3b6aa505fd2 100644
--- a/intern/cycles/kernel/light/distant.h
+++ b/intern/cycles/kernel/light/distant.h
@@ -108,4 +108,20 @@ ccl_device bool distant_light_sample_from_intersection(KernelGlobals kg,
return true;
}
+ccl_device_forceinline bool distant_light_tree_parameters(const float3 centroid,
+ const float theta_e,
+ ccl_private float &cos_theta_u,
+ ccl_private float2 &distance,
+ ccl_private float3 &point_to_centroid)
+{
+ /* Treating it as a disk light 1 unit away */
+ cos_theta_u = fast_cosf(theta_e);
+
+ distance = make_float2(1.0f / cos_theta_u, 1.0f);
+
+ point_to_centroid = -centroid;
+
+ return true;
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/light/point.h b/intern/cycles/kernel/light/point.h
index edf4f899aed..7597bc12b84 100644
--- a/intern/cycles/kernel/light/point.h
+++ b/intern/cycles/kernel/light/point.h
@@ -109,4 +109,27 @@ ccl_device_inline bool point_light_sample_from_intersection(
return true;
}
+template<bool in_volume_segment>
+ccl_device_forceinline bool point_light_tree_parameters(const ccl_global KernelLight *klight,
+ const float3 centroid,
+ const float3 P,
+ ccl_private float &cos_theta_u,
+ ccl_private float2 &distance,
+ ccl_private float3 &point_to_centroid)
+{
+ if (in_volume_segment) {
+ cos_theta_u = 1.0f; /* Any value in [-1, 1], irrelevant since theta = 0 */
+ return true;
+ }
+ point_to_centroid = safe_normalize_len(centroid - P, &distance.y);
+
+ const float radius = klight->spot.radius;
+ const float hypotenus = sqrtf(sqr(radius) + sqr(distance.y));
+ cos_theta_u = distance.y / hypotenus;
+
+ distance.x = hypotenus;
+
+ return true;
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/light/spot.h b/intern/cycles/kernel/light/spot.h
index 13fe1f63e74..b1d652f13f9 100644
--- a/intern/cycles/kernel/light/spot.h
+++ b/intern/cycles/kernel/light/spot.h
@@ -151,23 +151,29 @@ ccl_device_inline bool spot_light_sample_from_intersection(
return true;
}
-ccl_device_inline float spot_light_tree_weight(const ccl_global KernelLight *klight,
- const float3 P,
- const float3 N)
+template<bool in_volume_segment>
+ccl_device_forceinline bool spot_light_tree_parameters(const ccl_global KernelLight *klight,
+ const float3 centroid,
+ const float3 P,
+ ccl_private float &cos_theta_u,
+ ccl_private float2 &distance,
+ ccl_private float3 &point_to_centroid)
{
+ float min_distance;
+ const float3 point_to_centroid_ = safe_normalize_len(centroid - P, &min_distance);
+
const float radius = klight->spot.radius;
- const float cos_theta = klight->spot.cos_half_spot_angle;
- const float theta = fast_acosf(cos_theta);
- const float3 light_dir = klight->spot.dir;
+ const float hypotenus = sqrtf(sqr(radius) + sqr(min_distance));
+ cos_theta_u = min_distance / hypotenus;
- const float h1 = radius * fast_sinf(theta);
- const float d1 = radius * cos_theta;
- const float h2 = d1 / fast_tanf(theta);
+ if (in_volume_segment) {
+ return true;
+ }
- const float3 apex = klight->co - (h1 + h2) * light_dir;
- const float3 apex_to_point = normalize(P - apex);
+ distance = make_float2(hypotenus, min_distance);
+ point_to_centroid = point_to_centroid_;
- return (dot(apex_to_point, light_dir) < cos_theta) ? 0.0f : 1.0f;
+ return true;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h
index 2ad37e046c4..7f78d96f3f6 100644
--- a/intern/cycles/kernel/light/tree.h
+++ b/intern/cycles/kernel/light/tree.h
@@ -89,7 +89,7 @@ ccl_device void light_tree_cluster_importance(const float3 N_or_D,
float cos_max_incidence_angle = 1.0f;
/* when sampling the light tree for the second time in `shade_volume.h` and when query the pdf in
* `sample.h` */
- const bool in_volume = (dot(N_or_D, N_or_D) < 5e-4f);
+ const bool in_volume = is_zero(N_or_D);
cos_theta = dot(bcone.axis, -point_to_centroid);
if (!in_volume_segment && !in_volume) {
@@ -98,7 +98,7 @@ ccl_device void light_tree_cluster_importance(const float3 N_or_D,
sin_theta_i = safe_sqrtf(1.0f - sqr(cos_theta_i));
/* cos_min_incidence_angle = cos(max{theta_i - theta_u, 0}) = cos(theta_i') in the paper */
- cos_min_incidence_angle = cos_theta_i > cos_theta_u ?
+ cos_min_incidence_angle = cos_theta_i >= cos_theta_u ?
1.0f :
cos_theta_i * cos_theta_u + sin_theta_i * sin_theta_u;
@@ -171,6 +171,62 @@ ccl_device void light_tree_cluster_importance(const float3 N_or_D,
}
}
+template<bool in_volume_segment>
+ccl_device_inline bool compute_emitter_centroid_and_dir(
+ KernelGlobals kg,
+ ccl_global const KernelLightTreeEmitter *kemitter,
+ const float3 P,
+ ccl_private float3 ¢roid,
+ ccl_private packed_float3 &dir)
+{
+ const int prim_id = kemitter->prim_id;
+ if (prim_id < 0) {
+ const ccl_global KernelLight *klight = &kernel_data_fetch(lights, ~prim_id);
+ centroid = klight->co;
+
+ switch (klight->type) {
+ case LIGHT_SPOT:
+ dir = klight->spot.dir;
+ break;
+ case LIGHT_POINT:
+ /* Disk-oriented normal */
+ dir = safe_normalize(P - centroid);
+ break;
+ case LIGHT_AREA:
+ dir = klight->area.dir;
+ break;
+ case LIGHT_BACKGROUND:
+ /* Aarbitrary centroid and direction */
+ centroid = make_float3(0.0f, 0.0f, 1.0f);
+ dir =
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list