说明

该作业主要想实现两个三角形的绘制

绘制结果走样

按照课上所讲的方法,对包围盒里面的所有像素进行判断是否在三角形内,然后着色,这样的结果由于采样频率的问题将导致边缘走样现象的发生

if(!insideTriangle(P.x(),P.y(),t.v)) continue;
int cur_index = get_index(P.x(),P.y());
//重心坐标
auto[alpha, beta, gamma] = computeBarycentric2D(P.x(), P.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 -- zbuffer
z_interpolated *= w_reciprocal;
if(z_interpolated < depth_buf[cur_index])
{
depth_buf[cur_index] = z_interpolated;
P.z() = z_interpolated;
set_pixel(P,t.getColor());
}

使用MSAA处理结果 -- 有黑边的情况

采用4xMSAA来进行卷积模糊,即将一个像素块分成4个采样区域。然后分别计算这个4个采样区域能否被三角形覆盖,最后最终的像素颜色就是这4块区域的平均值。

float basec = 4.0f;
float dir[4][2] = {0.25,0.25,0.25,0.75,0.75,0.25,0.75,0.75};
for(P.x()=minx;P.x()<=maxx;P.x()++)
{
for(P.y() = miny;P.y() <= maxy;P.y()++)
{
float count = 0.0;
for(float x = 0.25;x<1.0;x+=0.5)
{
for(float y = 0.25;y<1.0;y+=0.5)
{
//统计有多少个采样点在三角形内
if(insideTriangle(P.x()+x,P.y()+y,t.v))
{
count += 1.0;
}
}
}
if(insideTriangle(P.x()+0.5,P.y()+0.5,t.v))
{
auto[alpha, beta, gamma] = computeBarycentric2D(P.x()+0.5, P.y()+0.5, 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(z_interpolated < depth_buf[get_index(P.x(),P.y())])
{
depth_buf[get_index(P.x(),P.y())] = z_interpolated;
P.z() = 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(P,t.getColor());
//最终颜色为平均值
Eigen::Vector3f color = t.getColor() * (count/basec);
//black edge -- the edge color is averge by green and blue but last code not do this
set_pixel(P,color);
}
}
}

黑边出现的原因

对于边缘重叠部分,由于绿色三角形的z值小,所以体现出绘制颜色为绿色,而当考虑4个采样点的情况,当只有一个采样点在绿色三角形内,其余三个在蓝色三角形内。实际最终颜色应该为1/4 green + 3/4 blue。

而上述代码只考虑覆盖,所以导致最终颜色为1/4 green 出现黑边

MSAA -- 解决黑边

在作业中说到需要为每个像素点存储颜色和深度。

最终一个像素的颜色应当是存储的这四个颜色的平均值。

//the start loc of this 2*2 area
int loc_start = get_index(P.x(),P.y())*4;
//this pixel real dep
float mindep = FLT_MAX;
//4xMSAA
float count = 0.0;
for(int k = 0;k<4;k++)
{
float curx = P.x()+dir[k][0];
float cury = P.y()+dir[k][1];
if(insideTriangle(curx,cury,t.v))
{
//calculate every sample color and dep save in sample_dep and sample_color
auto[alpha, beta, gamma] = computeBarycentric2D(curx, cury, 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;
//one sample
if(z_interpolated < sample_dep[loc_start+k])
{
sample_dep[loc_start+k] = z_interpolated;
sample_color[loc_start+k] = t.getColor()/4;
}
//this pixel dep == min(4 sample dep)
mindep = std::min(mindep,sample_dep[loc_start+k]);
}
}
//set color for this pixel
Eigen::Vector3f color = sample_color[loc_start]+sample_color[loc_start+1]+sample_color[loc_start+2]+sample_color[loc_start+3];
//get dep of this pixel
depth_buf[get_index(P.x(),P.y())] = std::min(mindep,depth_buf[get_index(P.x(),P.y())]);
P.z() = depth_buf[get_index(P.x(),P.y())];
set_pixel(P,color);

Games101--作业2的更多相关文章

  1. GAMES101作业2

    作业任务: 填写并调用函数 rasterize_triangle(const Triangle& t). 即实现光栅化 该函数的内部工作流程如下: 创建三角形的 2 维 bounding bo ...

  2. 【UE4】GAMES101 图形学作业2:光栅化和深度缓存

    总览 在上次作业中,虽然我们在屏幕上画出一个线框三角形,但这看起来并不是那么的有趣.所以这一次我们继续推进一步--在屏幕上画出一个实心三角形,换言之,栅格化一个三角形.上一次作业中,在视口变化之后,我 ...

  3. 【UE4】GAMES101 图形学作业5:光线与物体相交(球、三角面)

    总览 在这部分的课程中,我们将专注于使用光线追踪来渲染图像.在光线追踪中最重要的操作之一就是找到光线与物体的交点.一旦找到光线与物体的交点,就可以执行着色并返回像素颜色. 在这次作业中,我们要实现两个 ...

  4. 【UE4】GAMES101 图形学作业4:贝塞尔曲线

    总览 Bézier 曲线是一种用于计算机图形学的参数曲线. 在本次作业中,你需要实现de Casteljau 算法来绘制由4 个控制点表示的Bézier 曲线(当你正确实现该算法时,你可以支持绘制由更 ...

  5. 【UE4】GAMES101 图形学作业3:Blinn-Phong 模型与着色

    总览 在这次编程任务中,我们会进一步模拟现代图形技术.我们在代码中添加了Object Loader(用于加载三维模型), Vertex Shader 与Fragment Shader,并且支持了纹理映 ...

  6. 【UE4】GAMES101 图形学作业1:mvp 模型、视图、投影变换

    总览 到目前为止,我们已经学习了如何使用矩阵变换来排列二维或三维空间中的对象.所以现在是时候通过实现一些简单的变换矩阵来获得一些实际经验了.在接下来的三次作业中,我们将要求你去模拟一个基于CPU 的光 ...

  7. 【UE4】GAMES101 图形学作业0:矩阵初识

    作业描述 给定一个点P=(2,1), 将该点绕原点先逆时针旋转45◦,再平移(1,2), 计算出变换后点的坐标(要求用齐次坐标进行计算). UE4 知识点 主要矩阵 FMatrix FBasisVec ...

  8. python10作业思路及源码:类Fabric主机管理程序开发(仅供参考)

    类Fabric主机管理程序开发 一,作业要求 1, 运行程序列出主机组或者主机列表(已完成) 2,选择指定主机或主机组(已完成) 3,选择主机或主机组传送文件(上传/下载)(已完成) 4,充分使用多线 ...

  9. SQLServer2005创建定时作业任务

    SQLServer定时作业任务:即数据库自动按照定时执行的作业任务,具有周期性不需要人工干预的特点 创建步骤:(使用最高权限的账户登录--sa) 一.启动SQL Server代理(SQL Server ...

  10. 使用T-SQL找出执行时间过长的作业

        有些时候,有些作业遇到问题执行时间过长,因此我写了一个脚本可以根据历史记录,找出执行时间过长的作业,在监控中就可以及时发现这些作业并尽早解决,代码如下:   SELECT sj.name , ...

随机推荐

  1. Java操作EasyExcel实现导入导出入门

    介绍 EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单.节省内存著称.EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从 ...

  2. OCP试题解析之053-16 MEMORY_TARGET

    16.Setting which of the following initialization parameters enables Automatic Memory Management? A. ...

  3. 【Android 逆向】【攻防世界】android2.0

    这是一道纯算法还原题 1. apk安装到手机,提示输入flag,看来输入就是flag 2. jadx 打开apk查看 this.button.setOnClickListener(new View.O ...

  4. 学习go语言编程之标准库

    标准库包分类 Golang标准库可以大致按其中库的功能进行以下分类: 分类 对应包 描述 输入输出 bufio,fmt,io,log,flag 这个分类包括二进制以及文本格式在屏幕.键盘.文件以及其他 ...

  5. 单表查询,多表查询,子查询---day37

    1.单表查询 # ### part1 单表查询 # sql 查询语句的完整语法 '''select..from..where..group by..having..order by..limit..' ...

  6. java+文件读写实现的图书管理系统

    一功能 管理员具有的功能 1.增加图书.删除图书.修改图书信息.查询图书.图书列表 2.借阅者管理,通过借阅的书号查询图书信息 3.个人信息修改 读者功能 1.图书借阅 2.图书归还 3.图书查询 4 ...

  7. Flutter学习

    常用网址 免费下载 !<AliFlutter 体系化建设和实践> Flutter 开发文档 Flutter实战 Dart 编程语言概览 pub仓库 main函数使用了(=>)符号, ...

  8. 开源软件CVE_Search的配置与使用(详细)

    目录 项目介绍 环境配置 初始化cve_search 使用cve_search 简介 CVE: https://baike.baidu.com/item/CVE/9483464?fr=aladdin ...

  9. 【算法day6】哈希表、有序表、链表(反转单链表)

    哈希表的简单介绍 1)哈希表在使用层面上可以理解为一种集合结构 2)如果只有key,没有伴随数据value,可以使用HashSet结构(C++中叫UnOrderedSet) 3)如果既有key,又有伴 ...

  10. 【Azure 应用服务】 在App Service中无法上传证书[Private Key Certificates (.pfx)],导入Azure Key Vault中的证书也无法成功

    问题描述 在App Service的TLS/SSL settings页面,切换到Private Key Certificates (.pfx),通过Import Key Vault Certifica ...