rasterize_triangle 在作业2的基础上对法向量、颜色、纹理颜色与底纹颜色(Shading Colors) 进行插值。翻阅代码发现自带插值函数 interpolate,其余部分依照注释编写即可。
void rst::rasterizer::rasterize_triangle(const Triangle& t, const std::array<Eigen::Vector3f, 3>& view_pos)
{
// TODO: From your HW3, get the triangle rasterization code.
// TODO: Inside your rasterization loop:
// * v[i].w() is the vertex view space depth value z.
// * Z is interpolated view space depth for the current pixel
// * zp is depth between zNear and zFar, used for z-buffer
// float Z = 1.0 / (alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());
// float zp = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();
// zp *= Z;
// TODO: Interpolate the attributes:
auto v = t.toVector4();
float xmin = std::min(t.v[0].x(), std::min(t.v[1].x(), t.v[2].x()));
float xmax = std::max(t.v[0].x(), std::max(t.v[1].x(), t.v[2].x()));
float ymin = std::min(t.v[0].y(), std::min(t.v[1].y(), t.v[2].y()));
float ymax = std::max(t.v[0].y(), std::max(t.v[1].y(), t.v[2].y()));
for(int x = (int)std::ceil(xmin); x <= xmax; x++){
for(int y = (int)std::ceil(ymin); y <= ymax; y++){
if(!insideTriangle(x, y, t.v)) continue;
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;
int id = get_index(x, y);
if(z_interpolated < depth_buf[id]){
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);
fragment_shader_payload payload( interpolated_color, interpolated_normal.normalized(), interpolated_texcoords, texture ? &*texture : nullptr);
payload.view_pos = interpolated_shadingcoords;
// Use:Instead of passing the triangle's color directly to the frame buffer, pass the color to the shaders first to get the final color;
auto pixel_color = fragment_shader(payload);
depth_buf[id] <