GAMES101笔记 光栅化及作业二

光栅化

在对顶点的 MVP 变换以及视图变换之后,我们需要将视图变换后的顶点代表的图元,如三角形、网格等等,映射到屏幕上的像素,这一过程我们称之为光栅化。
在这里插入图片描述

采样

采样是指在连续领域中获取离散样本的过程,涉及将连续信号(比如声音、图像或其他信号)在时间或空间上按照一定间隔采集成离散的数据点。在光栅化中我们同样可以定义采样方法,即采样条件是,当像素在三角形内时我们采样。

在这里插入图片描述

定义一个二值函数,位于三角形内则采样,位于三角形外则不采样。(利用向量叉积的方法判断):
在这里插入图片描述

反走样 (Antialiasing)

利用简单的采样我们得到结果可以发现,得到的图像在边缘有明显的锯齿感 (Jaggies) ,反走样的目的就是消除锯齿。
在这里插入图片描述

反走样方法一:采样前滤波 (Pre-Filtering)

走样的根本原因是,采样频率跟不上信号频率。采样前滤波是通过降低实际的信号频率而达到反走样的目的。
在这里插入图片描述

采样前滤波是指在当顶点代表的图元在采样之前,对其进行模糊处理(频域上进行低通滤波或者是在时域上进行卷积),随后再进行采样。

在这里插入图片描述

反走样方法二:超采样 (MSAA)

与采样前滤波不同,超采样通过提高采样频率来达到反走样的目的。超采样的原理就是在一个像素内的多个位置进行采样,记录这些在像素内部且位于三角形内的点,计算这些点在像素内的占比,占比的结果即为该像素最终的采样结果。
传统的点采样:
在这里插入图片描述
超采样:
在这里插入图片描述
在这里插入图片描述

GAMES101 作业2

作业要求

(1)创建三角形的 2 维 bounding box。
(2)遍历此 bounding box 内的所有像素(使用其整数索引)。然后,使用像素中。
心的屏幕空间坐标来检查中心点是否在三角形内。
(3)如果在内部,则将其位置处的插值深度值 (interpolated depth value) 与深度缓冲区 (depth buffer) 中的相应值进行比较,如果当前点更靠近相机,请设置像素颜色并更新深度缓冲区。

void rst::rasterizer::rasterize_triangle(const Triangle& t) {
    auto v = t.toVector4();
 	//1.寻找三角形的最小包围盒
    float min_x = std::floor(std::min(v[0].x(), std::min(v[1].x(), v[2].x())));
    float max_x = std::ceil(std::max(v[0].x(), std::max(v[1].x(), v[2].x())));
    float min_y = std::floor(std::min(v[0].y(), std::min(v[1].y(), v[2].y())));
    float max_y = std::ceil(std::max(v[0].y(), std::max(v[1].y(), v[2].y())));

    for (int i = min_x; i < max_x; i++)
    {
        for (int j = min_y; j < max_y; j++)
        {
            //2.判断bounding box的像素是否位于三角形内
            if (insideTriangle(i + 0.5, j + 0.5, t.v))
            {
                //3.获取插值深度值
                auto tup = computeBarycentric2D((float)i + 0.5, (float)j + 0.5, t.v);
                float alpha;
                float beta;
                float gamma;
                std::tie(alpha, beta, gamma) = tup;
                //计算差值权重
                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_interpolated与深度缓冲区中的值进行比对,如果小,则填充颜色,并更新深度缓冲区
                if (depth_buf[get_index(i, j)] > z_interpolated)
                {
                    //深度存入缓存
                    depth_buf[get_index(i, j)] = z_interpolated;
                    Vector3f point = { (float)i,(float)j,z_interpolated };
                    Vector3f color = t.getColor();
                    //添加颜色
                    set_pixel(point, color);
                }
            }
        }
    }
}

结果展示

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小卡规划

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值