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
| void rst::rasterizer::rasterize_triangle(const Triangle& t, const std::array<Eigen::Vector3f, 3>& view_pos) { auto v = t.toVector4(); int x_max, x_min, y_max, y_min; x_min = MIN(floor(v[0].x()), MIN(floor(v[1].x()), floor(v[2].x()))); x_max = MAX(ceil(v[0].x()), MAX(ceil(v[1].x()), ceil(v[2].x()))); y_min = MIN(floor(v[0].y()), MIN(floor(v[1].y()), floor(v[2].y()))); y_max = MAX(ceil(v[0].y()), MAX(ceil(v[1].y()), ceil(v[2].y())));
for (int x = x_min; x <= x_max; x++) { for (int y = y_min; y <= y_max; y++)
{ 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;
auto index = get_index(x, y); if (z_interpolated < depth_buf[index] || std::isinf(depth_buf[index])) { depth_buf[index] = z_interpolated;
auto interpolated_color = interpolate(alpha, beta, gamma, t.color[0], t.color[1], t.color[2], 1); auto interpolated_normal = interpolate(alpha, beta, gamma, t.normal[0], t.normal[1], t.normal[2], 1).normalized(); auto interpolated_texcoords = interpolate(alpha, beta, gamma, t.tex_coords[0], t.tex_coords[1], t.tex_coords[2], 1); auto interpolated_shadingcoords = interpolate(alpha, beta, gamma, view_pos[0], view_pos[1], view_pos[2], 1);
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(Eigen::Vector2i(x, y), pixel_color); } } } } }
|