Skip to content

Commit 45a68a6

Browse files
Update spherical_triangle.hlsl
always move the scalar multiplication of a vector in a dot product outside the dot product
1 parent 4045921 commit 45a68a6

1 file changed

Lines changed: 5 additions & 6 deletions

File tree

include/nbl/builtin/hlsl/shapes/spherical_triangle.hlsl

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ struct SphericalTriangle
7474
// degenerate triangle: any side has near-zero sin, so csc blows up
7575
if (hlsl::any<vector<bool, 3> >(retval.csc_sides >= hlsl::promote<vector3_type>(numeric_limits<scalar_type>::max)))
7676
{
77+
// TODO: can't do this, still need to be able to sample thin triangle like a line light, so need to know all the angles which are still valid
7778
retval.cos_vertices = hlsl::promote<vector3_type>(0.0);
7879
retval.sin_vertices = hlsl::promote<vector3_type>(0.0);
7980
retval.solid_angle = 0;
@@ -106,22 +107,20 @@ struct SphericalTriangle
106107
if (solid_angle <= numeric_limits<scalar_type>::epsilon)
107108
return 0;
108109

109-
matrix<scalar_type, 3, 3> awayFromEdgePlane;
110110
// `cross(A,B)*acos(dot(A,B))/sin(1-dot^2)` can be done with `cross(A,B)*acos_csc_approx(dot(A,B))`
111111
#define ACOS_CSC(I) acos_csc_approx(cos_sides[I])
112112
//#define ACOS_CSC(I) hlsl::acos(cos_sides[I])*csc_sides[I]
113-
awayFromEdgePlane[0] = hlsl::cross(vertices[1], vertices[2]) * ACOS_CSC(0);
114-
awayFromEdgePlane[1] = hlsl::cross(vertices[2], vertices[0]) * ACOS_CSC(1);
115-
awayFromEdgePlane[2] = hlsl::cross(vertices[0], vertices[1]) * ACOS_CSC(2);
113+
scalar_type externalProductsWeightedByPyramidAngles = hlsl::dot(hlsl::cross(vertices[1], vertices[2]),receiverNormal) * ACOS_CSC(0);
114+
externalProductsWeightedByPyramidAngles += hlsl::dot(hlsl::cross(vertices[2], vertices[0]),receiverNormal) * ACOS_CSC(1);
115+
externalProductsWeightedByPyramidAngles += hlsl::dot(hlsl::cross(vertices[0], vertices[1]),receiverNormal) * ACOS_CSC(2);
116116
#undef ACOS_CSC
117-
const vector3_type externalProductsWeightedByPyramidAngles = hlsl::mul(/* transposed already */awayFromEdgePlane, receiverNormal);
118117

119118
// The ABS makes it so that the computation is correct for an `abs(cos(theta))` factor which is the projected solid angle used for a BSDF.
120119
// It also makes the computation insensitive to the CW or CCW winding of the vertices in the triangle.
121120
// Proof: Kelvin-Stokes theorem, if you split the set into two along the horizon with constant CCW winding, the `cross` along the shared edge
122121
// goes in different directions and cancels out, while `acos` of the clipped great arcs corresponding to polygon edges add up to the original sides again.
123122
// The 0.5 is so that triangle covering almost whole hemisphere sums to PI
124-
return hlsl::abs(externalProductsWeightedByPyramidAngles[0]+externalProductsWeightedByPyramidAngles[1]+externalProductsWeightedByPyramidAngles[2]) * scalar_type(0.5);
123+
return externalProductsWeightedByPyramidAngles * scalar_type(0.5);
125124
}
126125

127126
vector3_type vertices[3];

0 commit comments

Comments
 (0)