// Copyright 2024 Bytedance Inc. All Rights Reserved. // Author: tianlei.richard@qq.com (tianlei.richard) #include #include "rasterizer.h" #include "spdlog/spdlog.h" Rasterizer::Rasterizer(const int width, const int height) : width_(width), height_(height), pixels_(std::vector>( height, std::vector( width, PixelProperty{ 0., 0., 0., -std::numeric_limits::infinity()}))) {} std::vector> Rasterizer::rasterize(const std::vector &primitives) { for (const auto &t : primitives) { const auto &triangle_points = t.get_points<3>(); const auto &aabb = t.axis_align_bbox(); const int x_min = std::min(std::max(0, aabb.x), width_); const int x_max = std::min(std::max(0, aabb.x + aabb.width), width_); const int y_min = std::min(std::max(0, aabb.y), height_); const int y_max = std::min(std::max(0, aabb.y + aabb.height), height_); spdlog::info("Triangle range, ({},{},{},{})", x_min, x_max, y_min, y_max); for (int i = y_min; i < y_max; ++i) { for (int j = x_min; j < x_max; ++j) { auto &property = pixels_[i][j]; const auto &[is_inside, z_screen] = inside(Point2d{j + 0.5, i + 0.5}, t); if (is_inside && z_screen > property[3]) { property[0] = 0; property[1] = 1; property[2] = 0; property[3] = z_screen; } } } } return pixels_; } std::pair Rasterizer::inside(const Point2d &p_screen, const Triangle &t) { const auto points = t.get_points<3>(); const auto plane_normal = t.normal_vector(); const auto plane_point = points[0]; const auto z_screen = plane_point.z() - (plane_normal.x() * (p_screen.x() - plane_point.x()) + plane_normal.y() * (p_screen.y() - plane_point.y())) / plane_normal.z(); const Point3d p{p_screen.x(), p_screen.y(), z_screen}; const auto v1 = points[1] - points[0]; const auto v2 = points[2] - points[1]; const auto v3 = points[0] - points[2]; const auto c1 = v1.cross(p - points[0]).normalized(); const auto c2 = v2.cross(p - points[1]).normalized(); const auto c3 = v3.cross(p - points[2]).normalized(); const auto r1 = c1.dot(c2); const auto r2 = c1.dot(c3); const auto r3 = c2.dot(c3); return {r1 > 0 && r2 > 0 && r3 > 0, z_screen}; }