@@ -1847,7 +1847,10 @@ void PhongRay::on_intersection()
18471847 // the normal or the diffuse lighting contribution
18481848 reflected_ = true ;
18491849 result_color_ = plot_.colors_ [hit_id];
1850- Direction to_light = plot_.light_location_ - r ();
1850+ // The ray has been advanced slightly past the boundary. Use an
1851+ // approximation to the actual hit point for stable normal/lighting.
1852+ Position r_hit = r () - TINY_BIT * u ();
1853+ Direction to_light = plot_.light_location_ - r_hit;
18511854 to_light /= to_light.norm ();
18521855
18531856 // TODO
@@ -1868,12 +1871,22 @@ void PhongRay::on_intersection()
18681871 // Get surface pointer
18691872 const auto & surf = model::surfaces.at (surface_index ());
18701873
1871- Direction normal = surf->normal (r_local ());
1874+ // The crossed surface may be on a higher coordinate level than the
1875+ // innermost local coordinates, so we check the surface's coordinate level
1876+ // to find the appropriate coordinate level to use for the normal
1877+ // calculation
1878+ int surf_level = boundary ().coord_level () - 1 ;
1879+ // ensure surface level is within bounds of current coordinate stack
1880+ surf_level = std::max (0 , std::min (surf_level, n_coord () - 1 ));
1881+
1882+ Position r_hit_level =
1883+ coord (surf_level).r () - TINY_BIT * coord (surf_level).u ();
1884+ Direction normal = surf->normal (r_hit_level);
18721885 normal /= normal.norm ();
18731886
1874- // Need to apply translations to find the normal vector in
1887+ // Need to apply rotations to find the normal vector in
18751888 // the base level universe's coordinate system.
1876- for (int lev = n_coord () - 2 ; lev >= 0 ; --lev) {
1889+ for (int lev = surf_level - 1 ; lev >= 0 ; --lev) {
18771890 if (coord (lev + 1 ).rotated ()) {
18781891 const Cell& c {*model::cells[coord (lev).cell ()]};
18791892 normal = normal.inverse_rotate (c.rotation_ );
0 commit comments