staticboolinsideTriangle(float x, float y, const Vector3f* _v) { // TODO : Implement this function to check if the point (x, y) is inside the triangle represented by _v[0], _v[1], _v[2] Vector3f point(x, y, 0); Vector3f e0 = _v[1] - _v[0]; // vector _v[0] to _v[1] Vector3f e1 = _v[2] - _v[1]; Vector3f e2 = _v[0] - _v[2]; Vector3f p0 = point - _v[0]; // vector _v[0] to point Vector3f p1 = point - _v[1]; Vector3f p2 = point - _v[2];
//Screen space rasterization void rst::rasterizer::rasterize_triangle(const Triangle& t) { auto v = t.toVector4();
// TODO : Find out the bounding box of current triangle. float min_x = width; float max_x = 0; float min_y = height; float max_y = 0; for (constauto& vi : v) { min_x = std::min(min_x, vi.x()); max_x = std::max(max_x, vi.x()); min_y = std::min(min_y, vi.y()); max_y = std::max(max_y, vi.y()); } // iterate through the pixel and find if the current pixel is inside the triangle for (int x = min_x; x <= max_x; x++) { for (int y = min_y; y <= max_y; y++) { // If so, use the following code to get the interpolated z value. if (insideTriangle(x + 0.5, y + 0.5, t.v)) { auto [alpha, beta, gamma] = computeBarycentric2D(x + 0.5, y + 0.5, t.v); float w_reciprocal = 1.0 / (alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w()); float z_interpolated = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w(); z_interpolated *= w_reciprocal; // 得到当前像素的深度值
// z-buffering algorithm if (z_interpolated < depth_buf[get_index(x, y)]) { // TODO : set the current pixel (use the set_pixel function) // to the color of the triangle (use getColor function) // if it should be painted. Vector3f point(x, y, z_interpolated); set_pixel(point, t.getColor()); depth_buf[get_index(x, y)] = z_interpolated; } } } } }
// store centers of four smaller pixel MSAA 4X std::vector<std::pair<float, float>> centers_of_pixel{ { 0.25, 0.25 }, { 0.25, 0.75 }, { 0.75, 0.25 }, { 0.75, 0.75 } };
for (int x = min_x; x <= max_x; x++) { for (int y = min_y; y <= max_y; y++) { int count = 0; for (constauto& offset : centers_of_pixel) { auto& [_x, _y] = offset; if (insideTriangle(x + _x, y + _y, t.v)) count++; }
int rst::rasterizer::get_super_index(int x, int y, int k) { return (height - 1 - y) * width * msaa_times() + (width - 1 - x) * msaa_times() + k; }
get_super_color是用于从子采样点的frame_buf中计算出父采样点的颜色
1 2 3 4 5 6 7 8 9 10
Vector3f rst::rasterizer::get_super_color(int x, int y) { auto index = get_super_index(x, y, 0); Vector3f sum(0.0, 0.0, 0.0); for (int i = 0; i < msaa_times(); i++) { sum += super_frame_buf[index + i]; }
// store centers of four smaller pixel MSAA 4X std::vector<std::pair<float, float>> centers_of_pixel{ { 0.25, 0.25 }, { 0.25, 0.75 }, { 0.75, 0.25 }, { 0.75, 0.75 } };
for (int x = min_x; x <= max_x; x++) { for (int y = min_y; y <= max_y; y++) { // 此处不用count而是改为判断是否通过了深度测试,只要子采样点通过了深度测试就要更新父采样点的像素 bool depth_test = false;
for (int k = 0; k < height_times * width_times; k++) { auto& [dx, dy] = centers_of_pixel[k]; if (!insideTriangle(x + dx, y + dy, t.v)) continue;