微信扫一扫 分享朋友圈

已有 1046 人浏览分享

开启左侧

GAMES101_02

[复制链接]
1046 1
回帖奖励 1 艺术分      回复本帖可获得 1 艺术分奖励! 每人限 1 次
购买主题 已有 1 人购买  本主题需向作者支付 1 创新分 才能浏览

评论 1

Z君好困  妖精巫师  发表于 2023-4-12 11:40:11 | 显示全部楼层

本帖最后由 Z君好困 于 2023-4-12 11:45 编辑

本帖最后由 Z君好困 于 2023-4-12 11:44 编辑

MSAA多重采样抗锯齿处理: 在rasterizer.hpp中添加变量方法:

std::vector[Eigen::Vector3f](Eigen::Vector3f) frame_buf;
std::vector[Eigen::Vector3f](Eigen::Vector3f) msaa_frame_buf;
std::vector<float> depth_buf;
std::vector<float> msaa_depth_buf;
int get_index(int x, int y);
int get_msaa_index(int x, int y);

在cpp中修改相应函数:

void rst::rasterizer::clear(rst::Buffers buff)
{
    if ((buff & rst::Buffers::Color) == rst::Buffers::Color)
    {
        std::fill(frame_buf.begin(), frame_buf.end(), Eigen::Vector3f{ 0, 0, 0 });
        std::fill(msaa_frame_buf.begin(), msaa_frame_buf.end(), Eigen::Vector3f{ 0, 0, 0 });
    }
    if ((buff & rst::Buffers::Depth) == rst::Buffers::Depth)
    {
        std::fill(depth_buf.begin(), depth_buf.end(), std::numeric_limits<float>::infinity());
        std::fill(msaa_depth_buf.begin(), msaa_depth_buf.end(), std::numeric_limits<float>::infinity());
    }
}
rst::rasterizer::rasterizer(int w, int h) : width(w), height(h)
{
    frame_buf.resize(w * h);
    depth_buf.resize(w * h);
    msaa_frame_buf.resize(w * h * 4);
    msaa_depth_buf.resize(w * h * 4);
}
int rst::rasterizer::get_msaa_index(int x, int y)
{
    return (height*2 - 1 - y) * width*2 + x;
}

最后修改光栅化函数:

确定一个2*2的四格采样点,分别对每个像素内的四个采样点做深度和颜色值的记录,最后通过深度测试的进行颜色加和。

void rst::rasterizer::rasterize_triangle(const Triangle& t) {
    auto v = t.toVector4();
    std::vector<Eigen::Vector2f> Multiple_sampler_step
    {
        {0.25,0.25},
        {0.25,0.75},
        {0.75,0.25},
        {0.75,0.75},
    };
    // 画出三角形所在边界
    // 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++) {
            bool pass = false;//判断深度测试是否通过
            for (int i = 0; i < 4; i++)
            {
                if (insideTriangle(x + Multiple_sampler_step[i][0], y + Multiple_sampler_step[i][1], t.v)) {
                    auto tup = computeBarycentric2D(x + Multiple_sampler_step[i][0], y + Multiple_sampler_step[i][1], t.v);  //重心坐标插值
                    float alpha, beta, gamma;
                    std::tie(alpha, beta, gamma) = tup;
                    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 (msaa_depth_buf[get_msaa_index(x*2+i/2,y*2+i%2)] > z_interpolated) {
                        pass = true;
                        //将深度值和颜色值存入相应缓冲
                        msaa_depth_buf[get_msaa_index(x * 2 + i / 2, y * 2 + i % 2)] = z_interpolated;
                        msaa_frame_buf[get_msaa_index(x * 2 + i / 2, y * 2 + i % 2)] = t.getColor();
                    }
                }
            }
            if (pass)
            {
                Vector3f point{ (float)x,(float)y,0 };
                Vector3f color = (msaa_frame_buf[get_msaa_index(x * 2, y * 2)] + msaa_frame_buf[get_msaa_index(x * 2, y * 2 + 1)] +
                    msaa_frame_buf[get_msaa_index(x * 2 + 1, y * 2)] + msaa_frame_buf[get_msaa_index(x * 2 + 1, y * 2 + 1)]) / 4;
                set_pixel(point, color);
            }
        }
}
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

0

关注

1

粉丝

11

主题
精彩推荐
热门资讯
网友晒图
图文推荐
  • iOS App

  • 安卓App

Archiver|手机版|小黑屋|技你太美101

GMT+8, 2024-7-1 14:10 , Processed in 0.107045 second(s), 40 queries .

Powered by 技你太美101

© 2024 JNTM101 Team