[Bf-blender-cvs] [8a0ff32abda] gsoc-2018-many-light-sampling: Cycles: Updated cone aggregation and measure

Erik Englesson noreply at git.blender.org
Fri Jul 13 13:57:48 CEST 2018


Commit: 8a0ff32abda6171c10b5f4d8f37f6ef82ec4376a
Author: Erik Englesson
Date:   Wed Jul 11 10:12:07 2018 +0200
Branches: gsoc-2018-many-light-sampling
https://developer.blender.org/rB8a0ff32abda6171c10b5f4d8f37f6ef82ec4376a

Cycles: Updated cone aggregation and measure

The paper provided a way to merge two bounding
cones and an updated version of the cone
measure.

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

M	intern/cycles/render/light_tree.cpp
M	intern/cycles/render/light_tree.h

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

diff --git a/intern/cycles/render/light_tree.cpp b/intern/cycles/render/light_tree.cpp
index 3a10877bdf1..14a6f9e15c6 100644
--- a/intern/cycles/render/light_tree.cpp
+++ b/intern/cycles/render/light_tree.cpp
@@ -273,51 +273,56 @@ float LightTree::get_energy(const Primitive &prim){
 Orientation LightTree::aggregate_bounding_cones(
         const vector<Orientation> &bcones) {
 
-	if(bcones.size() == 1){
+	if(bcones.size() == 0){
+		return Orientation();
+	} else if(bcones.size() == 1){
 		return bcones[0];
 	}
 
-	/* use average of all axes as axis for now */
-	Orientation bcone;
-	for(unsigned int i = 0; i < bcones.size(); ++i){
-		bcone.axis += bcones[i].axis;
+	Orientation cone = bcones[0];
+	for(int i = 1; i < bcones.size(); ++i){
+		cone = cone_union(cone, bcones[i]);
 	}
 
-	const float length = len(bcone.axis);
-	if (length == 0){
-		bcone.axis = make_float3(0.0f, 0.0f, 0.0f); // NOTE: 0.0, 0.0, 0.0 here for now
-	} else {
-		bcone.axis /= length;
+	return cone;
+}
+
+/* Algorithm 1 */
+Orientation LightTree::cone_union(const Orientation& cone1, const Orientation& cone2){
+	const Orientation * a = &cone1;
+	const Orientation * b = &cone2;
+	if (b->theta_o > a->theta_o){
+		a = &cone2;
+		b = &cone1;
 	}
 
-	float max_theta_o = 0.0f;
-	float max_theta_e = 0.0f;
-	for(unsigned int i = 0; i < bcones.size(); ++i){
-		float theta = acosf(dot(bcone.axis, bcones[i].axis));
-		float theta_o = min(theta + bcones[i].theta_o, M_PI_F);
-		float theta_e_full = theta_o + bcones[i].theta_e;
-		if (theta_o > max_theta_o) {
-			max_theta_o = theta_o;
-		}
-		if (theta_e_full > max_theta_e) {
-			max_theta_e = theta_e_full;
-		}
+
+	float theta_d = safe_acosf(dot(a->axis, b->axis));
+
+	float theta_e = fmaxf(a->theta_e, b->theta_e);
+	if (fminf(theta_d + b->theta_o, M_PI_F) <= a->theta_o){
+		return Orientation(a->axis, a->theta_o, theta_e);
 	}
 
-	max_theta_e -= max_theta_o;
-	bcone.theta_o = max_theta_o;
-	bcone.theta_e = max_theta_e;
+	float theta_o = (a->theta_o + theta_d + b->theta_o) * 0.5f;
+	if (M_PI_F <= theta_o){
+		return Orientation(a->axis, M_PI_F, theta_e);
+	}
 
-	return bcone;
+	float theta_r = theta_o - a->theta_o;
+	float3 axis = rotate_around_axis(a->axis, cross(a->axis, b->axis), theta_r);
+	axis = normalize(axis);
+	return Orientation(axis, theta_o, theta_e);
 }
 
-float LightTree::calculate_cone_measure(const Orientation &bcone) {
-	// http://www.wolframalpha.com/input/?i=integrate+cos(w-x)sin(w)dw+from+x+to+x%2By
 
+float LightTree::calculate_cone_measure(const Orientation &bcone) {
+	/* eq. 1 */
+	float theta_w = fminf(bcone.theta_o + bcone.theta_e, M_PI_F);
 	return M_2PI_F * (1.0f-cosf(bcone.theta_o) +
-	                  0.5f * bcone.theta_e * sinf(bcone.theta_o) +
+	                  0.5f * (theta_w-bcone.theta_o) * sinf(bcone.theta_o) +
 	                  0.25f * cosf(bcone.theta_o) -
-	                  0.25f * cosf(bcone.theta_o + 2.0f*bcone.theta_e ));
+	                  0.25f * cosf(bcone.theta_o - 2.0f*theta_w ));
 }
 
 void LightTree::split_saoh(const BoundBox &centroidBbox,
@@ -410,7 +415,6 @@ void LightTree::split_saoh(const BoundBox &centroidBbox,
 			cost[i] = (energy_L*M_Omega_L*bbox_L.area() +
 			           energy_R*M_Omega_R*bbox_R.area()) /
 			        (node_energy*node_M_Omega*node_bbox.area());
-
 		}
 
 		/* update minimum cost, dim and bucket */
diff --git a/intern/cycles/render/light_tree.h b/intern/cycles/render/light_tree.h
index 759a04dfd73..2f1ef002438 100644
--- a/intern/cycles/render/light_tree.h
+++ b/intern/cycles/render/light_tree.h
@@ -34,6 +34,8 @@ struct Orientation{ // Orientation bounds
 		theta_e = 0;
 	}
 
+	Orientation(const float3& a, float o, float e): axis(a), theta_o(o), theta_e(e) {}
+
 	float3 axis;
 	float theta_o;
 	float theta_e;
@@ -191,6 +193,7 @@ private:
 	Orientation get_bcone(const Primitive& prim);
 	float get_energy(const Primitive &prim);
 	Orientation aggregate_bounding_cones(const vector<Orientation> &bcones);
+	Orientation cone_union(const Orientation& a, const Orientation& b);
 	float calculate_cone_measure(const Orientation &bcone);
 	int flattenBVHTree(const BVHBuildNode &node, int &offset);
 	void split_saoh(const BoundBox &centroidBbox,



More information about the Bf-blender-cvs mailing list