You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// Both vertices and angles at the vertices are denoted by the same upper case letters A, B, and C. The angles A, B, C of the triangle are equal to the angles between the planes that intersect the surface of the sphere or, equivalently, the angles between the tangent vectors of the great circle arcs where they meet at the vertices. Angles are in radians. The angles of proper spherical triangles are (by convention) less than PI
248
248
vec3 cos_vertices,sin_vertices;
249
249
// get solid angle, which is also the reciprocal of the probability
constfloat cosB_ = (cos_b_-cosAngleAlongBC_s*cos_c)*csc_a_*csc_c; // only NaN if `csc_a_` (L close to B) is NaN OR if `csc_c` is NaN (which would mean zero solid angle triangle to begin with, so uv can be whatever)
// now all that remains is to obtain the modified C angle, which is the angle at the unknown vertex `C_s`
261
+
constfloat cosC_ = sin_vertices[0]*sinB_*cos_c-cos_vertices[0]*cosB_; // if cosB_ is NaN then cosC_ doesn't matter because the subtriangle has zero Solid Angle (we could pretend its `-cos_vertices[0]`)
257
262
constfloat sinC_ =sqrt(1.0-cosC_*cosC_);
258
-
constfloat u = irr_glsl_getArccosSumofABC_minus_PI(cos_vertices[0],cosB_,cosC_,sin_vertices[0],sqrt(1.0-cosB_*cosB_),sinC_)/rcpPdf;
constfloat v = (1.0-cosAngleAlongBC_s)/(1.0-cosBC_s);
264
+
constfloat subTriSolidAngleRatio = irr_glsl_getArccosSumofABC_minus_PI(cos_vertices[0],cosB_,cosC_,sin_vertices[0],sinB_,sinC_)*pdf; // will only be NaN if either the original triangle has zero solid angle or the subtriangle has zero solid angle (all can be satisfied with u=0)
265
+
constfloat u = subTriSolidAngleRatio>FLT_MIN ? subTriSolidAngleRatio:0.0; // tiny overruns of u>1.0 will not affect the PDF much because a bilinear warp is used and the gradient has a bound (won't be true if LTC will get used)
266
+
267
+
// INF if any angle is 0 degrees, which implies L lays along BA arc, if the angle at A is PI minus the angle at either B_ or C_ while the other of C_ or B_ has a zero angle, we get a NaN (which is also a zero solid angle subtriangle, implying L along AB arc)
// if cosBC_s is really large then we have numerical issues (should be 1.0 which means the arc is really short), if its NaN then either the original or sub-triangle has zero solid angle, in both cases we can consider that the BC_s arc is actually the BA arc and substitute
270
+
constfloat v = (1.0-cosAngleAlongBC_s)/(1.0-(cosBC_s<uintBitsToFloat(0x3f7fffff) ? cosBC_s:cos_c));
// End-of @Crisspl move this to `irr/builtin/glsl/sampling/triangle.glsl`
277
284
278
285
279
286
// the interaction here is the interaction at the illuminator-end of the ray, not the receiver
280
-
vec3 irr_glsl_light_deferred_eval_and_prob(outfloat pdf, invec3 origin, invec3 normalAtOrigin, inbool wasBSDFAtOrigin, infloat intersectionT, in irr_glsl_AnisotropicViewSurfaceInteraction interaction, in Light light)
287
+
vec3 irr_glsl_light_deferred_eval_and_prob(
288
+
outfloat pdf, in Light light, invec3 L,
289
+
#if TRIANGLE_METHOD==0
290
+
infloat intersectionT,
291
+
#else
292
+
invec3 origin,
293
+
#if TRIANGLE_METHOD==2
294
+
invec3 normalAtOrigin, inbool wasBSDFAtOrigin
295
+
#endif
296
+
#endif
297
+
)
281
298
{
282
299
// we don't have to worry about solid angle of the light w.r.t. surface of the light because this function only ever gets called from closestHit routine, so such ray cannot be produced
283
300
pdf = scene_getLightChoicePdf(light);
284
301
285
302
Triangle tri = triangles[Light_getObjectID(light)];
286
303
#if TRIANGLE_METHOD==0
287
-
pdf *= intersectionT*intersectionT/abs(dot(Triangle_getNormalTimesArea(tri),interaction.isotropic.V.dir));
304
+
pdf *= intersectionT*intersectionT/abs(dot(Triangle_getNormalTimesArea(tri),L));
0 commit comments