fix 2d triangle inner loop behaviour when applying fill rule

we can't just do a `continue` as we need to ensure that we always update
the barycentric coordinates on every single iteration
This commit is contained in:
Gered 2023-04-03 16:19:25 -04:00
parent 39b788c564
commit 725dc12424

View file

@ -36,8 +36,6 @@ pub fn per_pixel_triangle_2d<PixelType: Pixel>(
// https://www.scratchapixel.com/lessons/3d-basic-rendering/rasterization-practical-implementation/rasterization-stage.html // https://www.scratchapixel.com/lessons/3d-basic-rendering/rasterization-practical-implementation/rasterization-stage.html
// https://kitsunegames.com/post/development/2016/07/28/software-3d-rendering-in-javascript-pt2/ // https://kitsunegames.com/post/development/2016/07/28/software-3d-rendering-in-javascript-pt2/
// TODO: implement fill rules, probably using top-left ordering as most 3d APIs do i guess
let mut bounds = Rect::from_coords( let mut bounds = Rect::from_coords(
a.x.min(b.x).min(c.x).floor() as i32, a.x.min(b.x).min(c.x).floor() as i32,
a.y.min(b.y).min(c.y).floor() as i32, a.y.min(b.y).min(c.y).floor() as i32,
@ -77,16 +75,13 @@ pub fn per_pixel_triangle_2d<PixelType: Pixel>(
for pixel in row_pixels.iter_mut() { for pixel in row_pixels.iter_mut() {
// skip bottom-right edge pixels so we only draw pixels inside the triangle as well as those that lie // skip bottom-right edge pixels so we only draw pixels inside the triangle as well as those that lie
// on the top-left edges. this fixes seam issues with triangles drawn with blending that share an edge // on the top-left edges. this fixes seam issues with triangles drawn with blending that share an edge
if (w0.nearly_equal(0.0, f32::EPSILON) && is_cb_bottom_right) let is_on_bottom_right_edge = (w0.nearly_equal(0.0, f32::EPSILON) && is_cb_bottom_right)
|| (w1.nearly_equal(0.0, f32::EPSILON) && is_ac_bottom_right) || (w1.nearly_equal(0.0, f32::EPSILON) && is_ac_bottom_right)
|| (w2.nearly_equal(0.0, f32::EPSILON) && is_ba_bottom_right) || (w2.nearly_equal(0.0, f32::EPSILON) && is_ba_bottom_right);
{
continue;
}
// note that for a counter-clockwise vertex winding order with the direction of Y+ going down instead // note that for a counter-clockwise vertex winding order with the direction of Y+ going down instead
// of up, we need to test for *negative* area when checking if we're inside the triangle // of up, we need to test for *negative* area when checking if we're inside the triangle
if w0 <= 0.0 && w1 <= 0.0 && w2 <= 0.0 { if !is_on_bottom_right_edge && w0 <= 0.0 && w1 <= 0.0 && w2 <= 0.0 {
pixel_fn(pixel, w0, w1, w2); pixel_fn(pixel, w0, w1, w2);
} }