GAMES101作业解答-作业02-Triangles and Z-buffering


GAMES101作业解答-作业02-Triangles and Z-buffering

1. 题目要求

  • 在屏幕上画出一个实心三角形, 换言之,栅格化一个三角形。上一次作业中,在视口变化之后,我们调用了函数 rasterize_wireframe(const Triangle& t)。但这一次,你需要自己填写并调用 函数 rasterize_triangle(const Triangle& t)。
  • 该函数的内部工作流程如下:
    1. 创建三角形的 2 维 bounding box。
    1. 遍历此 bounding box 内的所有像素(使用其整数索引)。然后,使用像素中 心的屏幕空间坐标来检查中心点是否在三角形内。
    1. 如果在内部,则将其位置处的插值深度值 (interpolated depth value) 与深度 缓冲区 (depth buffer) 中的相应值进行比较。
    1. 如果当前点更靠近相机,请设置像素颜色并更新深度缓冲区 (depth buffer)。
      我们需要修改的函数如下:
      • rasterize_triangle(): 执行三角形栅格化算法
      • static bool insideTriangle(): 测试点是否在三角形内。你可以修改此函 数的定义,这意味着,你可以按照自己的方式更新返回类型或函数参数。
      因为我们只知道三角形三个顶点处的深度值,所以对于三角形内部的像素, 我们需要用插值的方法得到其深度值。我们已经为你处理好了这一部分,因为有 关这方面的内容尚未在课程中涉及。插值的深度值被储存在变量 z_interpolated 中。

2. 作业解答

  • 所需的实验环境前面已经介绍了,这些题目都是基于前面的基础或者框架,为了进一步实现各种复杂功能,我们需要理解作业意图以及看闫老师的pdf文件和视频,同时要完成作业需要去查阅一些网上资料。
  • 本次作业主要目的是实现三角形的光栅化以及实现Z-buffer算法对三角形的遮挡。
  • 关键部分的代码如下所示:
// Screen space rasterization 屏幕空间光栅化
void rst::rasterizer::rasterize_triangle(const Triangle& t) {
    auto v = t.toVector4();
    // 画出三角形所在边界
    // x_l = x_min ; x_r = x_max ; y_b = y_min ; y_t = y_max
    int x_l = std::floor(std::min(v[0][0], std::min(v[1][0], v[2][0])));   //floor向下取整
    int x_r = std::ceil(std::max(v[0][0], std::max(v[1][0], v[2][0])));    //ceil向上取整
    int y_b = std::floor(std::min(v[0][1], std::min(v[1][1], v[2][1])));
    int y_t = std::ceil(std::max(v[0][1], std::max(v[1][1], v[2][1])));

    for (int x = x_l; x <= x_r; x++)
        for (int y = y_b; y <= y_t; y++) {

            if (insideTriangle(x + 0.5, y + 0.5, t.v)) {
                auto[alpha, beta, gamma] = computeBarycentric2D((float) x + 0.5f, (float) y + 0.5f, t.v);  //重心坐标插值
                float w_reciprocal = 1.0f / (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(x, y)] > z_interpolated) {
                    Vector3f color = t.getColor();
                    Vector3f point(3);
                    point << (float) x, (float) y, z_interpolated;
                    depth_buf[get_index(x, y)] = z_interpolated;
                    set_pixel(point, color);
                }
            }
        }
}
]// 利用叉乘以及右手定则判断是否在三角形内部方法
static bool insideTriangle(int x, int y, const Vector3f* _v)
{
    Vector2f point(x, y);

    Vector2f AB = _v[1].head(2) - _v[0].head(2);
    Vector2f BC = _v[2].head(2) - _v[1].head(2);
    Vector2f CA = _v[0].head(2) - _v[2].head(2);

    Vector2f AP = point - _v[0].head(2);
    Vector2f BP = point - _v[1].head(2);
    Vector2f CP = point - _v[2].head(2);

    return    AB[0] * AP[1] - AB[1] * AP[0] > 0
              && BC[0] * BP[1] - BC[1] * BP[0] > 0
              && CA[0] * CP[1] - CA[1] * CP[0] > 0;

}
  • 实验结果

    与实验文档中的图是反的,这个坐标系的选取问题,不影响结果。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM