@@ -1549,16 +1549,16 @@ Mesh<Float, Spectrum>::compute_surface_interaction(const Ray3f &ray,
15491549 }
15501550
15511551 if (has_vertex_normals () && (m_shadow_offset_scale > 0 .f )) {
1552- Vector3f tmp0 = si. p - p0,
1553- tmp1 = si. p - p1,
1554- tmp2 = si.p - p2;
1555- Float dot0 = dr::minimum ( dr::dot (tmp0, n0), 0 . 0f ),
1556- dot1 = dr::minimum (dr::dot (tmp1, n1 ), 0 .0f ),
1557- dot2 = dr::minimum (dr::dot (tmp2, n2 ), 0 .0f );
1558- tmp0 -= dot0 * n0 ;
1559- tmp1 -= dot1 * n1;
1560- tmp2 -= dot2 * n2;
1561- si. shadow_offset = m_shadow_offset_scale * dr::fmadd (tmp0, b0 , dr::fmadd (tmp1, b1, tmp2 * b2 ));
1552+ // Implements "Hacking the shadow terminator" by Johannes Hanika (2021).
1553+ // The code matches the original implementation, but was slightly simplified
1554+ // since b0 * p0 + b1 * p1 + b2 * p2 = si.p, and b0 + b1 + b2 = 1.
1555+ Vector3f tmp0 = p0 - si. p , tmp1 = p1 - si. p , tmp2 = p2 - si. p ;
1556+ Float dot0 = dr::maximum (dr::dot (tmp0, n0 ), 0 .f ),
1557+ dot1 = dr::maximum (dr::dot (tmp1, n1 ), 0 .f ),
1558+ dot2 = dr::maximum ( dr::dot (tmp2, n2), 0 . f ) ;
1559+ si. shadow_offset =
1560+ m_shadow_offset_scale *
1561+ dr::fmadd (b0, dot0 * n0 , dr::fmadd (b1, dot1 * n1, b2 * dot2 * n2 ));
15621562 }
15631563
15641564 if (m_flip_normals) {
0 commit comments