101作业2

任务

  1. 判断二维空间中,点是否在三角形内
  2. 深度缓冲的z-buffer算法
  3. 超采样

任务1

课件中给出了一个算法用来判断点是否在三角形内,即判断点p始终在逆时针存储的三角形ABC的AB、BC、CA的有向边的左手边。这里计算的时候由于不知道三角形是顺时针存储还是逆时针存储,只要p始终在有向边的一边,我就判断p在三角形内部。
另外,这里用三维的叉乘也可以,不过最终都回到判断z方向的正负号的问题上来,所以二维三维都可以。

float cross_2d(Eigen::Vector2f v, Eigen::Vector2f w){
    return v.x()*w.y()-v.y()*w.x();
}
static bool insideTriangle(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]
    float x_p = x;
    float y_p = y;
    Eigen::Vector2f AB(_v[1].x() - _v[0].x(),_v[1].y()-_v[0].y());
    Eigen::Vector2f BC(_v[2].x() - _v[1].x(),_v[2].y()-_v[1].y());
    Eigen::Vector2f CA(_v[0].x() - _v[2].x(),_v[0].y()-_v[2].y());
    Eigen::Vector2f AP(x_p - _v[0].x(),y_p-_v[0].y());
    Eigen::Vector2f BP(x_p - _v[1].x(),y_p-_v[1].y());
    Eigen::Vector2f CP(x_p - _v[2].x(),y_p-_v[2].y());
    if(cross_2d(AB,AP)*cross_2d(BC,BP)>=0&&cross_2d(AB,AP)*cross_2d(CA,CP)>=0)return true;
    else return false;
}

任务2

由于中心插值已经写好了,所以只写了一个画家算法,非常简单的判断。

void rst::rasterizer::rasterize_triangle(const Triangle& t) {
    auto v = t.toVector4();
    
    // TODO : Find out the bounding box of current triangle.
    // iterate through the pixel and find if the current pixel is inside the triangle
    int max_x = std::max(std::max(v[0].x(),v[1].x()),v[2].x());
    int min_x = std::min(std::min(v[0].x(),v[1].x()),v[2].x());
    int max_y = std::max(std::max(v[0].y(),v[1].y()),v[2].y());
    int min_y = std::min(std::min(v[0].y(),v[1].y()),v[2].y());

    for(int x = min_x;x<=max_x;x++){
        for(int y = min_y;y<=max_y;y++){
            // std::cout << x << " " << y << std::endl;
            if(insideTriangle(x + 0.5,y + 0.5,t.v)){
                // If so, use the following code to get the interpolated z value.
                auto[alpha, beta, gamma] = computeBarycentric2D(x, y, 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;
                // std::cout << z_interpolated << std::endl;
                if(z_interpolated < depth_buf[get_index(x,y)]){
                    depth_buf[get_index(x,y)] = z_interpolated;
                    set_pixel(Vector3f(x,y,0),t.getColor());
                    // TODO : set the current pixel (use the set_pixel function) to the color of the triangle (use getColor function) if it should be painted.
                
                }
            }
        }
    }
}

任务3

MSAA超采样,额外存储了一个4倍的深度缓冲,在深度测试时有四倍的计算量。但在算shader的时候没有增加计算量?

void rst::rasterizer::rasterize_triangle_MSAA(const Triangle& t) {
    auto v = t.toVector4();
    
    // TODO : Find out the bounding box of current triangle.
    // iterate through the pixel and find if the current pixel is inside the triangle
    int max_x = std::max(std::max(v[0].x(),v[1].x()),v[2].x());
    int min_x = std::min(std::min(v[0].x(),v[1].x()),v[2].x());
    int max_y = std::max(std::max(v[0].y(),v[1].y()),v[2].y());
    int min_y = std::min(std::min(v[0].y(),v[1].y()),v[2].y());

    std::vector<float> x_offset = {0.25,0.25,0.75,0.75};
    std::vector<float> y_offset = {0.25,0.75,0.25,0.75};
    for(int x = min_x;x<=max_x;x++){
        for(int y = min_y;y<=max_y;y++){
            // std::cout << x << " " << y << std::endl;
            for(int i = 0;i<4;i++){
                float x_f = x + x_offset[i];
                float y_f = y + y_offset[i];
                int ind = get_index(x,y);
                if(insideTriangle(x_f,y_f,t.v)){
                    // If so, use the following code to get the interpolated z value.
                    auto[alpha, beta, gamma] = computeBarycentric2D(x_f, y_f, 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;
                    // std::cout << z_interpolated << std::endl;
                    if(z_interpolated < depth_buf_MSAA[ind][i]){
                        depth_buf_MSAA[ind][i] = z_interpolated;
                        frame_buf[ind] += 0.25 * t.getColor();
                    }
                }
            }
        }
    }
}

结果对比如下图:
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值