GAMES101作业2

news2024/11/24 11:54:43

文章目录

  • 作业内容
  • Step 1. 创建三角形的2维bounding box
  • Step 2. 判断bBox中的像素中心点是否在三角形内
  • Step 3. 比较插值深度和Depth Buffer
  • MSAA

作业内容

在屏幕上画出一个实心三角形,
换言之,栅格化一个三角形。上一次作业中,在视口变化之后,我们调用了函数
rasterize_wireframe(const Triangle& t)。但这一次,你需要自己填写并调用
函数 rasterize_triangle(const Triangle& t)。
该函数的内部工作流程如下:

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

Step 1. 创建三角形的2维bounding box

GAMES101_Lecture_05.pdf 43页

  • Checking All Pixels on the Screen?
    Bounding Box
    已知三角形的三个顶点,如何得出蓝色矩形的width 和 height。 或者说左下角点和右上角的坐标

假设三角形的三个顶点经过t.toVector4( )输出的坐标如下:

===== P0 ======
108.579
350
-0.714285
1
===== p1 ======
350
108.579
-0.714285
1 
===== p2 ======
591.421
350
-0.714285
1

那么bounding box 左下角和右上角的坐标为
在这里插入图片描述
B_1_x = min(P0_x, P1_x, P2_x)
B_1_y = min(P0_y, P1_y, P2_y)

B_2_x = max(P0_x, P1_x, P2_x)
B_2_y = max(P0_y, P1_y, P2_y)

bounding_box_width = B_2_x - B_1_x;
bounding_box_height = B_2_y - B_1_y;

    unsigned int bBox_leftbottom_x;
    unsigned int bBox_leftbottom_y;
    unsigned int bBox_topright_x;
    unsigned int bBox_topright_y;
    unsigned int width, height;

    bBox_leftbottom_x = floor(MIN(MIN(v[0].x(), v[1].x()), v[2].x())); //向下取整
    bBox_leftbottom_y = floor(MIN(MIN(v[0].y(), v[1].y()), v[2].y()));
    bBox_topright_x   = ceil(MAX(MAX(v[0].x(), v[1].x()), v[2].x()));  //向上取整
    bBox_topright_y   = ceil(MAX(MAX(v[0].y(), v[1].y()), v[2].y()));
    std::cout << "bBox :leftbottom:(" << bBox_leftbottom_x <<
              ","<<bBox_leftbottom_y <<") "<<
              "topright:("<<bBox_topright_x <<
              ","<< bBox_topright_y <<")" << std::endl;
    width = bBox_topright_x - bBox_leftbottom_x;
    height = bBox_topright_y - bBox_topright_y;
x: 108.579 y: 350 z: -0.714285
x: 350 y: 108.579 z: -0.714285
x: 591.421 y: 350 z: -0.714285
bBox :leftbottom:(108,108) topright:(592,350)
bBox_width:484
bBox_height:242

Step 2. 判断bBox中的像素中心点是否在三角形内

遍历此 bounding box 内的所有像素(使用其整数索引)。然后,使用像素中心的屏幕空间坐标来检查中心点是否在三角形内。

在这里插入图片描述

在Lecture 2中,判断一个点是否在三角形内,可以通过某个顶点到该点的向量与边的叉乘是否都满足z坐标的一致性,比如上图中判断(按逆时针方向)

  • P 0 P 1 → \overrightarrow {P_0P_1} P0P1 x P 0 P Q → \overrightarrow {P_0P_Q} P0PQ
  • P 1 P 2 → \overrightarrow {P_1P_2} P1P2 x P 1 P Q → \overrightarrow {P_1P_Q} P1PQ
  • P 2 P 0 → \overrightarrow {P_2P_0} P2P0 x P 2 P Q → \overrightarrow {P_2P_Q} P2PQ

借助Egien提供的向量叉乘的接口

v1_tmp = vector_3f_p0p1.cross(vector_3f_p0pq);
v2_tmp = vector_3f_p1p2.cross(vector_3f_p1pq);
v3_tmp = vector_3f_p2p1.cross(vector_3f_p2pq);
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]

    Vector3f q = Vector3f(x, y, 1.0);                    // Homogeneous
    Vector3f p0_pq = q - _v[0];
    Vector3f p1_pq = q - _v[1];
    Vector3f p2_pq = q - _v[2];

    Vector3f v1_tmp = (_v[1] - _v[0]).cross(p0_pq);       //p0_p1 x p0_pq
    Vector3f v2_tmp = (_v[2] - _v[1]).cross(p1_pq);       //p1_p2 x p1_pq
    Vector3f v3_tmp = (_v[0] - _v[2]).cross(p2_pq);       //p2_p0 x p2_pq

    if ((v1_tmp.z() > 0 && v2_tmp.z() > 0 && v3_tmp.z() > 0) ||
        (v1_tmp.z() < 0 && v2_tmp.z() < 0 && v3_tmp.z() < 0) ||
        (v1_tmp.z() < 1e-6 && v2_tmp.z() < 1e-6 && v3_tmp.z() < 1e-6))
    {
        return true;
    }
    else
    {
        return false;
    }
}   

Step 3. 比较插值深度和Depth Buffer

  1. 如果在内部,则将其位置处的插值深度值 (interpolated depth value) 与深度
    缓冲区 (depth buffer) 中的相应值进行比较。
  2. 如果当前点更靠近相机,请设置像素颜色并更新深度缓冲区 (depth buffer)。

注意,需要将工程的属性修改成兼容C++17, 否则下面语句报错

auto [alpha, beta, gamma] = computeBarycentric2D(x, y, t.v); 
for (int x = (int)bBox_leftbottom_x; x <= bBox_topright_x; x++)
{
    for (int y = (int)bBox_leftbottom_y; y <= bBox_topright_y; y++)
    {
        if (insideTriangle(x, y, 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;

            // compare the interpolated depth value with depth buffer value
            if (depth_buf[get_index(x, y)] > z_interpolated)
            {
                depth_buf[get_index(x, y)] = z_interpolated;
                // TODO : set the current pixel (use the set_pixel function) to the color of the triangle (use getColor function) if it should be painted.
                set_pixel(Vector3f(x, y, z_interpolated), t.getColor());
            }
        }
    }
}

MSAA

用 super-sampling 处理 Anti-aliasing : 你可能会注意到,当我们放大图像时,图像边缘会有锯齿感。我们可以用 super-sampling来解决这个问题,即对每个像素进行 2 * 2 采样,并比较前后的结果 (这里并不需要考虑像素与像素间的样本复用)。需要注意的点有,对于像素内的每一个样本都需要维护它自己的深度值,即每一个像素都需要维护一个 samplelist。最后,如果你实现正确的话,你得到的三角形不应该有不正常的黑边

在这里插入图片描述
在这里插入图片描述

for (int x = (int)bBox_leftbottom_x; x <= bBox_topright_x; x++)
 {
     for (int y = (int)bBox_leftbottom_y; y <= bBox_topright_y; y++)
     {
         float depth_tmp = 0.0;      // max value for float in system 
         int count = 0;
         Vector2f sample_point[4] = { Vector2f(0.25, 0.25),Vector2f(0.75, 0.25), Vector2f(0.75,0.75), Vector2f(0.75, 0.25) };
         for (int i=0; i<4; i++)
         {
             if (insideTriangle(x+ sample_point[i].x(), y+sample_point[i].y(), 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;
                 depth_tmp += z_interpolated;
                 count +=1;
             }
         }
         float depth_average = depth_tmp / 4;
         if (count>0&&depth_buf[get_index(x,y)]> depth_average)
         {
             depth_buf[get_index(x, y)] = depth_average;

             set_pixel(Vector3f(x, y, depth_average), t.getColor() * count / 4.0 + frame_buf[get_index(x, y)] * (4 - count) / 4.0);
         }
         
     }
 }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/771015.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

P1403 [AHOI2005] 约数研究

题目描述 科学家们在 Samuel 星球上的探险得到了丰富的能源储备&#xff0c;这使得空间站中大型计算机 Samuel II 的长时间运算成为了可能。由于在去年一年的辛苦工作取得了不错的成绩&#xff0c;小联被允许用 Samuel II 进行数学研究。 小联最近在研究和约数有关的问题&…

Vue+axios 使用CancelToken多次发送请求取消前面所有正在pendding的请求

需求&#xff1a; 项目中 折线图数据是循环调用的&#xff0c;此时勾选一个设备&#xff0c; 会出现多条线。 原因 折线图数据一进来接口循环在调用&#xff0c;勾选设备时&#xff0c;循环调用的接口有的处于pedding状态 &#xff0c;有的还在加载中&#xff0c;这就导致勾…

安泰电子:ATA-ML100水声功率放大器模块技术参数

随着人类对海洋的深度探索和利用的不断加深&#xff0c;水下通信技术日益成为研究的热点。水下通信技术是指在海洋、湖泊等水体中实现信息传递和交流的技术手段。它不仅在海洋资源勘探、海洋环境监测等领域具有广泛应用&#xff0c;还在水下考古、水下工程等领域发挥着重要作用…

018 - STM32学习笔记 - SPI读写FLASH(三)- 写入字符串、小数与整数

018 - STM32学习笔记 - SPI访问Flash&#xff08;三&#xff09;- 写入字符串、小数与整数 上节对Flash的跨页写入数据进行了完善&#xff0c;但是数据写入都是以Byte数组的方式进行写入&#xff0c;这节分别进行字符串的写入和小数整数的写入&#xff0c;本节内容对SPI的函数…

linux之Ubuntu系列(四)用户管理 用户和权限 chmod 超级用户root, R、W、X、T、S 软链接和硬链接

r(Read&#xff0c;读取)&#xff1a;对文件而言&#xff0c;具有读取文件内容的权限&#xff1b;对目录来说&#xff0c;具有浏览目 录的权限。 w(Write,写入)&#xff1a;对文件而言&#xff0c;具有新增、修改文件内容的权限&#xff1b;对目录来说&#xff0c;具有删除、移…

Burp Suite---渗透测试工具

文章目录 Burp SuiteBurp Suite入门设置代理HTTP的代理 Proxy&#xff08;代理&#xff09; Burp Suite 是一款集成化的渗透测试工具&#xff0c;包含了很多功能&#xff0c;可以帮助我们高效地完成对Web应用程序的渗透测试和攻击。 Burp Suite由Java语言编写&#xff0c;基于…

十大网络安全上市公司分析,让我们重点聊聊F5

网络安全上市厂商业务广泛分布于网络安全硬件、软件&#xff0c;网络安全服务等板块&#xff0c;总体来看&#xff0c;十大网络安全上市公司的竞争可谓是如火如荼。今天让我们把目光集中在F5&#xff0c;这个能为我们所有人创造更安全的数字世界的企业&#xff0c;在应用及API交…

PuTTY下载(免安装exe)

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

手写数字识别Minst(CNN)

文章目录 手写数字识别网络结构加载数据集数据集可视化CNN网络结构训练模型保存模型和加载模型测试模型 手写数字识别 网络结构 网上给出的基本网络结构&#xff1a; 然而在本数据集中&#xff0c;输入图不是1*32*32&#xff0c;是1*28*28。所以正确的网络结构应该是 level…

实现关注公众号以后自动推送小程序

准备好小程序的APPID和跳转路径 然后一行代码搞定&#xff1a; <a data-miniprogram-appid"小程序APPID" data-miniprogram-path"跳转路径">点我跳转到小程序</a>

Shuffle简单理解

map的结果本身是无序的&#xff0c;但是map输出的结果有序 mapper和reduce是不同的机器&#xff0c;进行了网络传输&#xff0c;所以存在数据拷贝 第二次排序&#xff0c;是将每个reduce对应的task进行排序&#xff0c;然后再进入reduce maptask运行结束&#xff0c;每个mask块…

被字节拷打了~基础还是太重要了...

今天分享一篇一位同学去字节面试的实习面经&#xff0c;技术栈是java&#xff0c;投了go后端岗位&#xff0c;主要拷打了 redismysql网络系统java算法&#xff0c;面试问题主要集中在 mysql、redis、网络这三部门&#xff0c;因为面试官是搞 go 的&#xff0c;java 只是随便问了…

55 # 实现可写流

先在 LinkedList.js 给链表添加一个移除方法 class Node {constructor(element, next) {this.element element;this.next next;} }class LinkedList {constructor() {this.head null; // 链表的头this.size 0; // 链表长度}// 可以直接在尾部添加内容&#xff0c;或者根据…

数据库小白看这里,这个Oracle数据库知识图谱你值得拥有

2022年前后&#xff0c;墨天轮社区曾陆续推出PostgreSQL知识图谱、MySQL知识图谱&#xff0c;并得到了大家的广泛好评。此后&#xff0c;便有众多朋友对Oracle知识图谱发起不断“催更“。经过近期的内容搜集整合、专家复审与打磨&#xff0c;墨天轮社区正式推出Oracle知识图谱&…

MySQL五种约束类型(普通 /自增主键,外键等) + 进阶查询(聚合查询,内 /外连接查询,自连接查询,子查询,合并查询)

文章目录 前言一、五种约束NOT NULL 约束UNIQUE 约束DEFAULT 约束PRIMARY KEY 主键约束(重点)普通主键自增主键 FOREIGN KEY 外键约束(重点) 二、进阶查询聚合查询聚合函数GROUP BY子句HAVING 联合查询笛卡尔积内连接外连接自连接子查询单行子查询&#xff1a;返回一行记录的子…

AI时代图像安全“黑科技”如何助力人工智能与科技发展?

〇、前言 7月7日下午&#xff0c;2023世界人工智能大会&#xff08;WAIC&#xff09;“聚焦大模型时代AIGC新浪潮—可信AI”论坛在上海世博中心红厅举行。人工智能等技术前沿领域的著名专家与学者、投资人和领军创业者汇聚一堂&#xff0c;共同探索中国科技创新的驱动力量。 在…

搭载下一代人工智能技术,微软推出Power Automate流程挖掘产品

在近日的Microsoft Inspire大会中&#xff0c;微软揭晓了他们即将推出的Power Automate流程挖掘产品&#xff0c;并计划在8月1日正式对外开放。 试用地址&#xff1a;https://powerautomate.microsoft.com/zh-cn/#home-signup 这款产品搭载了下一代人工智能技术&#xff0c;有…

好用的思维导图软件有哪些?这几款简单好用

好用的思维导图软件有哪些&#xff1f;思维导图是一种非常有用的思维工具&#xff0c;可以帮助我们组织和理清复杂的信息。在如今的数字时代&#xff0c;有很多软件可以帮助我们创建和编辑思维导图。下面介绍几款简单好用的思维导图软件。 第一款&#xff1a;迅捷画图 这是一款…

多个信贷范围时客户主数据界面的定制(套头和信用缴纳范围=信贷范围)

客户主数据-销售范围-开票的界面有信贷范围&#xff0c;叫贷方控制范围。 但是默认是看不到的。需要进行配置。 但是SAP的配置里面的名字很奇怪&#xff0c;在客户账户组里面的销售数据中(OVT0)定制 双击后处理的这个界面&#xff0c;和界面的“”开票凭证“”对不上&#x…

云原生微服务应用的平台工程实践

作者&#xff1a;纳海 01 微服务应用云原生化 微服务是一个广泛使用的应用架构&#xff0c;而如何使得微服务应用云原生化却是近些年一直在演进的课题。国内外云厂商对云原生概念的诠释大同小异&#xff0c;基本都会遵循 CNCF 基金会的定义&#xff1a; 云原生技术有利于各组…