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
| //屏幕空间光栅化 //view_pos:顶点在屏幕空间的坐标 void rst::rasterizer::rasterize_triangle(const Triangle& t, const std::array<Eigen::Vector3f, 3>& view_pos) { auto v = t.toVector4(); float x_max = std::max(std::max(v[0].x(), v[1].x()), v[2].x()); float x_min = std::min(std::min(v[0].x(), v[1].x()), v[2].x()); float y_min = std::min(std::min(v[0].y(), v[1].y()), v[2].y()); float y_max = std::max(std::max(v[0].y(), v[1].y()), v[2].y()); for (int i = x_min; i < x_max+1; i++) { for (int j = y_min; j < y_max+1; j++) { if (insideTriangle(i, j, t.v)) { //计算当前像素在三角形内的重心坐标 auto [alpha, beta, gamma] = computeBarycentric2D(i, j, t.v);
//通过重心插值得到深度值z_interpolated //w_reciprocal为透视修正系数 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-Buffer if (depth_buf[get_index(i, j)] > z_interpolated) { //利用重心坐标插值颜色、法线、纹理、shadingcoords(像素位置) 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); 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); // 初始化 payload,用于传递给片段着色器 fragment_shader_payload payload(interpolated_color, interpolated_normal.normalized(), interpolated_texcoords, texture ? &*texture : nullptr); payload.view_pos = interpolated_shadingcoords;
// 更新深度缓存 depth_buf[get_index(i, j)] = z_interpolated;
// 设置像素颜色,调用片段着色器 Vector2i temp(i, j); set_pixel(temp, fragment_shader(payload)); } } } } }
|