GAMES101 作业2

目录

第一题

第二题


第一题

题目: 判断给定的点(x, y)是否在三角形内

static bool insideTriangle(int x, int 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]
}

解析:

        这里要注意的一点就是 x 和 y 坐标都需要加 0.5, 这样才能将将坐标偏移到像素中心(关于这点闫老师在课中提过), 不过测试时加不加 0.5 看不出差别。

static bool insideTriangle(int x, int 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]
    x += 0.5;   //像素中心的 x 坐标
    y += 0.5;   //像素中心的 y 坐标
    Eigen::Vector3f pt(x, y, 0);
    std::vector<Vector3f> vertexs;
    for (int i = 0; i < _v->size(); ++i)
    {
        Eigen::Vector3f temp(_v[i].x(), _v[i].y(), _v[i].z());
        vertexs.emplace_back(temp);
    }
    for (int i = 0; i < vertexs.size(); ++i)
    {
        int next = i == (vertexs.size() - 1) ? 0 : i + 1;
        Eigen::Vector3f ans = (pt - vertexs[i]).cross(vertexs[next] - vertexs[i]);
        if (ans.z() > 0)    //如果叉乘后 z 大于0, 则证明点在向量的右侧,此时直接返回 false
        {
            return false;
        }
    }
    return true;
}

第二题 

题目: 找到给定三角形的最大包围盒并遍历其中的点, 如果这个点在三角形内, 则使用重心插值算法计算出该点的深度(在 shading 课程中会提到重心插值计算), 当点的深度小于深度缓存中的值时进行着色。

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

    // 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;

    // TODO : set the current pixel (use the set_pixel function) to the color of the triangle (use getColor function) if it should be painted.
}

解析:

        值得注意的一点就是一定要记得着色后更新深度缓存(depth_buf)中对应的值。

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
    //以下四行计算三角形包围盒点的边界
    float x_max = max(max(v[0].x(), v[1].x()), v[2].x());    
    float y_max = max(max(v[0].y(), v[1].y()), v[2].y());
    float x_min = min(min(v[0].x(), v[1].x()), v[2].x());
    float y_min = min(min(v[0].y(), v[1].y()), v[2].y());
    // 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;

    // TODO : set the current pixel (use the set_pixel function) to the color of the triangle (use getColor function) if it should be painted.
    //开始遍历包围盒中的所有点
    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);
                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;
                if (depth_buf[get_index(i, j)] > z_interpolated)    //获取当前点在深度缓存中的值, 如果大于插值计算出的 z 值, 则上色
                {                   
                    Vector3f temp(i, j, 1);
                    set_pixel(temp, t.getColor());                  //着色
                    depth_buf[get_index(i, j)] = z_interpolated;    //不要忘记更新深度缓存
                }
            }
        }
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值