[Bf-blender-cvs] [49f7bee879d] soc-2022-many-lights-sampling: Cleanup: group a few types and functions in the light tree to avoid computing some quantities twice

Weizhen Huang noreply at git.blender.org
Tue Nov 15 20:34:16 CET 2022


Commit: 49f7bee879d8bf5fe64983a3fa2f3ce133c650d9
Author: Weizhen Huang
Date:   Tue Nov 15 20:28:28 2022 +0100
Branches: soc-2022-many-lights-sampling
https://developer.blender.org/rB49f7bee879d8bf5fe64983a3fa2f3ce133c650d9

Cleanup: group a few types and functions in the light tree to avoid
computing some quantities twice

===================================================================

M	intern/cycles/kernel/light/tree.h
M	intern/cycles/kernel/types.h
M	intern/cycles/scene/light.cpp
M	intern/cycles/scene/light_tree.cpp
M	intern/cycles/scene/light_tree.h

===================================================================

diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h
index 60e991723f5..0f3069af41b 100644
--- a/intern/cycles/kernel/light/tree.h
+++ b/intern/cycles/kernel/light/tree.h
@@ -223,15 +223,15 @@ ccl_device void light_tree_emitter_importance(KernelGlobals kg,
   float min_distance, distance;
   float max_distance = 0.0f;
   float cos_theta_u = 1.0f;
-  float3 centroid, point_to_centroid;
+  float3 centroid = make_float3(
+      kemitter->centroid[0], kemitter->centroid[1], kemitter->centroid[2]);
+  float3 point_to_centroid = safe_normalize_len(centroid - P, &distance);
   bool bbox_is_visible = has_transmission;
 
   const int prim = kemitter->prim_id;
   if (prim < 0) {
     const int lamp = -prim - 1;
     const ccl_global KernelLight *klight = &kernel_data_fetch(lights, lamp);
-    centroid = make_float3(klight->co[0], klight->co[1], klight->co[2]);
-    point_to_centroid = safe_normalize_len(centroid - P, &distance);
 
     if (klight->type == LIGHT_SPOT || klight->type == LIGHT_POINT) {
       const float radius = klight->spot.radius;
@@ -268,9 +268,6 @@ ccl_device void light_tree_emitter_importance(KernelGlobals kg,
     const int object = kemitter->mesh_light.object_id;
     float3 V[3];
     triangle_world_space_vertices(kg, object, prim, -1.0f, V);
-    /* TODO: store in KernelLightTreeEmitter */
-    centroid = (V[0] + V[1] + V[2]) / 3.f;
-    point_to_centroid = safe_normalize_len(centroid - P, &distance);
     for (int i = 0; i < 3; i++) {
       const float3 corner = V[i];
       float distance_point_to_corner;
@@ -739,7 +736,7 @@ ccl_device float light_tree_distant_light_importance(KernelGlobals kg,
 
   const float3 light_axis = make_float3(
       kdistant->direction[0], kdistant->direction[1], kdistant->direction[2]);
-  float theta_i = fast_acosf(dot(N, light_axis));
+  float theta_i = fast_acosf(dot(N, -light_axis));
 
   /* If the light is guaranteed to be behind the surface we're sampling, and the surface is
    * opaque, then we can give the light an importance of 0 as it contributes nothing to the
diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h
index 01628cd97fe..2d0fba1074c 100644
--- a/intern/cycles/kernel/types.h
+++ b/intern/cycles/kernel/types.h
@@ -1366,9 +1366,7 @@ typedef struct KernelLightTreeNode {
 static_assert_align(KernelLightTreeNode, 16);
 
 typedef struct KernelLightTreeEmitter {
-  /* Bounding box. */
-  float bounding_box_min[3];
-  float bounding_box_max[3];
+  float centroid[3];
 
   /* Bounding cone. */
   float bounding_cone_axis[3];
@@ -1386,18 +1384,21 @@ typedef struct KernelLightTreeEmitter {
       int object_id;
     } mesh_light;
     struct {
-      float pad;
+      float pad1;
       float size;
     } lamp;
   };
 
   /* Parent. */
   int parent_index;
+
+  /* Padding */
+  float pad3[3];
 } KernelLightTreeEmitter;
 static_assert_align(KernelLightTreeEmitter, 16);
 
 typedef struct KernelLightTreeDistantEmitter {
-  /* Direction from world to light. */
+  /* Direction from light to world. */
   float direction[3];
 
   /* Size of light (in radians). */
diff --git a/intern/cycles/scene/light.cpp b/intern/cycles/scene/light.cpp
index f5e68e479c6..af6623811a5 100644
--- a/intern/cycles/scene/light.cpp
+++ b/intern/cycles/scene/light.cpp
@@ -294,9 +294,8 @@ void LightManager::device_update_distribution(Device *device,
   foreach (Light *light, scene->lights) {
     if (light->is_enabled) {
       if (light_tree_enabled) {
-        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;
+        /* -prim_id - 1 is a light source index. */
+        LightTreePrimitive light_prim(scene, ~device_light_index, scene_light_index);
 
         /* Distant lights get added to a separate vector. */
         if (light->light_type == LIGHT_DISTANT || light->light_type == LIGHT_BACKGROUND) {
@@ -345,12 +344,8 @@ void LightManager::device_update_distribution(Device *device,
                            scene->default_surface;
 
       if (shader->get_use_mis() && shader->has_surface_emission) {
-        /* to-do: for the light tree implementation, we eventually want to include emissive
-         * triangles. Right now, point lights are the main concern. */
         if (light_tree_enabled) {
-          LightTreePrimitive light_prim;
-          light_prim.prim_id = i;
-          light_prim.object_id = object_id;
+          LightTreePrimitive light_prim(scene, i, object_id);
           light_prims.push_back(light_prim);
         }
 
@@ -409,21 +404,17 @@ void LightManager::device_update_distribution(Device *device,
         for (int i = 0; i < node.num_lights; i++) {
           int emitter_index = i + node.first_prim_index;
           LightTreePrimitive &prim = light_prims[emitter_index];
-          BoundBox bbox = prim.calculate_bbox(scene);
-          OrientationBounds bcone = prim.calculate_bcone(scene);
-          float energy = prim.calculate_energy(scene);
 
-          light_tree_emitters[emitter_index].energy = energy;
+          light_tree_emitters[emitter_index].energy = prim.energy;
 
           for (int i = 0; i < 3; i++) {
-            light_tree_emitters[emitter_index].bounding_box_min[i] = bbox.min[i];
-            light_tree_emitters[emitter_index].bounding_box_max[i] = bbox.max[i];
-            light_tree_emitters[emitter_index].bounding_cone_axis[i] = bcone.axis[i];
+            light_tree_emitters[emitter_index].centroid[i] = prim.centroid[i];
+            light_tree_emitters[emitter_index].bounding_cone_axis[i] = prim.bcone.axis[i];
           }
-          light_tree_emitters[emitter_index].theta_o = bcone.theta_o;
-          light_tree_emitters[emitter_index].theta_e = bcone.theta_e;
+          light_tree_emitters[emitter_index].theta_o = prim.bcone.theta_o;
+          light_tree_emitters[emitter_index].theta_e = prim.bcone.theta_e;
 
-          if (prim.prim_id >= 0) {
+          if (prim.is_triangle()) {
             light_tree_emitters[emitter_index].mesh_light.object_id = prim.object_id;
 
             int shader_flag = 0;
@@ -453,10 +444,9 @@ void LightManager::device_update_distribution(Device *device,
             triangle_array[prim.prim_id + object_lookup_offsets[prim.object_id]] = emitter_index;
           }
           else {
-            Light *lamp = scene->lights[prim.lamp_id];
+            Light *lamp = scene->lights[prim.object_id];
             light_tree_emitters[emitter_index].prim_id = prim.prim_id;
             light_tree_emitters[emitter_index].lamp.size = lamp->size;
-            light_tree_emitters[emitter_index].lamp.pad = 1.0f;
             light_array[~prim.prim_id] = emitter_index;
           }
 
@@ -478,43 +468,19 @@ void LightManager::device_update_distribution(Device *device,
     light_tree_distant_group[num_distant_lights].energy = 0.f;
     for (int index = 0; index < num_distant_lights; index++) {
       LightTreePrimitive prim = distant_lights[index];
-      Light *light = scene->lights[prim.lamp_id];
-      OrientationBounds light_bounds;
 
       /* Lights in this group are either a background or distant light. */
       light_tree_distant_group[index].prim_id = ~prim.prim_id;
 
-      float energy = 0.0f;
-      if (light->light_type == LIGHT_BACKGROUND) {
-        /* integrate over cosine-weighted hemisphere */
-        energy = light->get_average_radiance() * M_PI_F;
-
-        /* We can set an arbitrary direction for the background light. */
-        light_bounds.axis[0] = 0.0f;
-        light_bounds.axis[1] = 0.0f;
-        light_bounds.axis[2] = 1.0f;
-
-        /* to-do: this may depend on portal lights as well. */
-        light_bounds.theta_o = M_PI_F;
-      }
-      else {
-        energy = prim.calculate_energy(scene);
-
-        for (int i = 0; i < 3; i++) {
-          light_bounds.axis[i] = -light->dir[i];
-        }
-        light_bounds.theta_o = tanf(light->angle * 0.5f);
-      }
-
-      distant_light_bounds = merge(distant_light_bounds, light_bounds);
+      distant_light_bounds = merge(distant_light_bounds, prim.bcone);
       for (int i = 0; i < 3; i++) {
-        light_tree_distant_group[index].direction[i] = light_bounds.axis[i];
+        light_tree_distant_group[index].direction[i] = prim.bcone.axis[i];
       }
-      light_tree_distant_group[index].bounding_radius = light_bounds.theta_o;
-      light_tree_distant_group[index].energy = energy;
+      light_tree_distant_group[index].bounding_radius = prim.bcone.theta_o;
+      light_tree_distant_group[index].energy = prim.energy;
       light_array[~prim.prim_id] = index;
 
-      light_tree_distant_group[num_distant_lights].energy += energy;
+      light_tree_distant_group[num_distant_lights].energy += prim.energy;
     }
 
     /* The net OrientationBounds contain bounding information about all the distant lights. */
diff --git a/intern/cycles/scene/light_tree.cpp b/intern/cycles/scene/light_tree.cpp
index 7fbaf9fb572..c9891fe6544 100644
--- a/intern/cycles/scene/light_tree.cpp
+++ b/intern/cycles/scene/light_tree.cpp
@@ -23,7 +23,7 @@ OrientationBounds merge(const OrientationBounds &cone_a, const OrientationBounds
   if (is_zero(cone_a.axis)) {
     return cone_b;
   }
-  else if (is_zero(cone_b.axis)) {
+  if (is_zero(cone_b.axis)) {
     return cone_a;
   }
 
@@ -43,61 +43,87 @@ OrientationBounds merge(const OrientationBounds &cone_a, const OrientationBounds
   if (a->theta_o >= fminf(M_PI_F, theta_d + b->theta_o)) {
     return OrientationBounds({a->axis, a->theta_o, theta_e});
   }
-  else {
-    /* Compute new theta_o that contains both a and b. */
-    float theta_o = (theta_d + a->theta_o + b->theta_o) * 0.5f;
 
-    if (theta_o >= M_PI_F) {
-      return OrientationBounds({a->axis, M_PI_F, theta_e});
-    }
+  /* Compute new theta_o that contains both a and b. */
+  float theta_o = (theta_d + a->theta_o + b->theta_o) * 0.5f;
+
+  if (theta_o >= M_PI_F) {
+    return OrientationBounds({a->axis, M_PI_F, theta_e});
+  }
+
+  /* Rotate new axis to be between a and b. */
+  float theta_r = theta_o - a->theta_o;
+  float3 new_axis = rotate_around_axis(a->axis, cross(a->axis, b->axis), theta_r);
+  new_axis = 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list