1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| void rst::rasterizer::rasterize_triangle(const Triangle& t, const std::array<Eigen::Vector3f, 3>& view_pos) { auto v = t.toVector4(); int x_min = std::min({ v[0].x(), v[1].x(), v[2].x() }); int x_max = std::max({ v[0].x(), v[1].x(), v[2].x() }); int y_min = std::min({ v[0].y(), v[1].y(), v[2].y() }); int y_max = std::max({ v[0].y(), v[1].y(), v[2].y() });
for (int x = x_min; x <= x_max; x++) { for (int y = y_min; y <= y_max; y++) { if (insideTriangle(x, y, t.v)) { auto [alpha, beta, gamma] = computeBarycentric2D(x, y, t.v); if (alpha >= 0 && beta >= 0 && gamma >= 0) { 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;
int index = get_index(x, y); if (z_interpolated < depth_buf[index]) { depth_buf[index] = z_interpolated; Eigen::Vector2i point(x, y); auto interpolated_color = interpolate(alpha, beta, gamma, t.color[0], t.color[1], t.color[2], 1.0); auto interpolated_normal = interpolate(alpha, beta, gamma, t.normal[0], t.normal[1], t.normal[2], 1.0); auto interpolated_texcoords = interpolate(alpha, beta, gamma, t.tex_coords[0], t.tex_coords[1], t.tex_coords[2], 1.0); auto interpolated_shadingcoords = interpolate(alpha, beta, gamma, view_pos[0], view_pos[1], view_pos[2], 1.0); fragment_shader_payload payload(interpolated_color, interpolated_normal.normalized(), interpolated_texcoords, texture ? &*texture : nullptr); payload.view_pos = interpolated_shadingcoords; auto pixel_color = fragment_shader(payload); set_pixel(point, pixel_color); } } } } } }
|