当前位置:网站首页>GAMES-101-个人总结归纳-Rasterization
GAMES-101-个人总结归纳-Rasterization
2022-06-22 01:20:00 【风之涯角】
(注:此文以个人知识框架为基础拓开,为方便后期回顾,在保留原课程内容框架的基础上,个别概念的介绍可能过于简单,感兴趣读者可到 GAMES 平台深入学习)
目录
Occlusions and Visibility(深度缓冲)
Visibility / occlusion - Z-buffering
Rasterization
Different raster displays(略)
Rasterizing a triangle
(三角形生万物~~)
判断点在三角形内:
做叉积,结果同正或同负,表示点在三条边同侧,即点在三角形内。

注:cross(P0Q,P0p1) -> left;cross(P1Q,P1P2) -> left; cross(P2Q,P2P0) -> right
Antialiasing(反走样)
Sampling theory
- (黑话)artifacts:一切不准确,看起来不太对的结果
- 采样的存在的问题:
Jaggies(锯齿)
Moiré Patterns(摩尔纹):去掉图片的奇数行和奇数列后按照图片原尺寸显示。

wagonWagon Wheel Illusion(转轮错觉):人眼在时间上采样跟不上转速,而产生的转轮反向旋转的错觉。

3.傅里叶变换,过程不赘述,这里主要是为了给处理 aliasing 的两种方案提供理论基础:
(1)提高采样率(采样的本质是对频域上频谱的重复搬移,时域上采样越稀疏,对应频域上频谱上的搬移越密集,频谱混叠的部分越多,于是产生的 aliasing 越明显);

- (2)反走样:先做模糊(对信号做低通滤波,拿掉高频信号),再采样。换句话说,既然你频谱混叠会产生 aliasing 那我就把混丢部分(高频信号)给你拿掉:

Antialiasing in practice
- MSAA(Multi-Sample Anti-Aliasing)/ Supersampling:在一个像素内用更多采样点进行超采样。

- 业内反走样里程碑:
(1)FXAA (Fast Approximate AA);快速近似抗锯齿:在图像层面对锯齿做后期处理。
(2)TAA (Temporal AA):一种基于时间的优化,当前帧复用上一帧像素的值(在 RTRT 也有相关应用)。
Occlusions and Visibility(深度缓冲)
Visibility / occlusion - Z-buffering
- 概念:以由远到近的顺序对场景中的物体的 Z 值 做深度缓冲,同像素,近物覆盖远物。
- 开销:需要一个额外的 buffer,颜色值存 framebuffer;深度值存 depth buffer(z-buffer)。
- other:z-buffer 无法处理透明物体
- Algorithm:complex:O(n)


作业2
题目简单介绍
基于作业1空间转换的基础上,光栅化多个三角形,并对三角形内的像素进行深度插值处理,并对结果 antialiasing.
核心代码
1.判断像素点是否在三角形内:
/// <summary>
/// 判断像素点是否在三角形内
/// </summary>
/// <param name="x">像素点 x</param>
/// <param name="y">像素点 y</param>
/// <param name="_v">三角形三个顶点</param>
/// <returns></returns>
static bool insideTriangle(float x, float 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]
// 利用向量叉积的结果,判断像素点在三边同侧,即表示点在在三角形内
Eigen::Vector3f x1 = _v[0];
Eigen::Vector3f x2 = _v[1];
Eigen::Vector3f x3 = _v[2];
// 三角形三边对应向量
Eigen::Vector3f x1x2;
Eigen::Vector3f x2x3;
Eigen::Vector3f x3x1;
x1x2 = { x2.x() - x1.x(), x2.y() - x1.y(), 0 };
x2x3 = { x3.x() - x2.x(), x3.y() - x2.y(), 0 };
x3x1 = { x1.x() - x3.x(), x1.y() - x3.y(), 0 };
// 像素点与三角形三顶点相连对应向量
Eigen::Vector3f x1p;
Eigen::Vector3f x2p;
Eigen::Vector3f x3p;
x1p ={ x - x1.x(), y - x1.y(), 0};
x2p = { x - x2.x(), y - x2.y(), 0 };
x3p = { x - x3.x(), y - x3.y(), 0 };
// 向量叉乘,取z轴判断正负
float crs1 = x1x2.cross(x1p).z();
float crs2 = x2x3.cross(x2p).z();
float crs3 = x3x1.cross(x3p).z();
return (crs1 > 0 && crs2 > 0 && crs3 > 0) || (crs1 < 0 && crs2 < 0 && crs3 < 0);
}2.对场景内的三角形做 z-buffer 深度缓冲
/// <summary>
/// Screen space rasterization
/// </summary>
/// <param name="t">the triangle need to rasterize</param>
void rst::rasterizer::rasterize_triangle(const Triangle& t) {
auto v = t.toVector4();
// compute the bounding box
int max_x = MAX(v[0].x(), MAX(v[1].x(), v[2].x()));
int max_y = MAX(v[0].y(), MAX(v[1].y(), v[2].y()));
int min_x = MIN(v[0].x(), MIN(v[1].x(), v[2].x()));
int min_y = MIN(v[0].y(), MIN(v[1].y(), v[2].y()));
for (int x1 = min_x; x1 <= max_x; x1++) {
for (int y1 = min_y; y1 <= max_y; y1++) {
if (insideTriangle(x1 + 0.5, y1 + 0.5,t.v)) {
// 计算点在三角形内的中心坐标,关于下面的插值算法可参考:https://zhuanlan.zhihu.com/p/140926917
auto [alpha, beta, gamma] = computeBarycentric2D(x1, y1, 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 (depth_buf[get_index(x1, y1)] > z_interpolated) {
depth_buf[get_index(x1, y1)] = z_interpolated;// 更新 z-buffer 深度值
set_pixel({ (float)x1,(float)y1,1 }, t.getColor()); // 更新 frame-buffer 颜色值
}
}
}
}
}3.MSAA处理:
/// <summary>
/// Screen space rasterization(super sampling)
/// </summary>
/// <param name="t">the triangle need to rasterize</param>
void rst::rasterizer::super_rasterize_triangle(const Triangle& t) {
auto v = t.toVector4();
// compute the bounding box
int max_x = MAX(v[0].x(), MAX(v[1].x(), v[2].x()));
int max_y = MAX(v[0].y(), MAX(v[1].y(), v[2].y()));
int min_x = MIN(v[0].x(), MIN(v[1].x(), v[2].x()));
int min_y = MIN(v[0].y(), MIN(v[1].y(), v[2].y()));
for (int x1 = min_x; x1 <= max_x; x1++) {
for (int y1 = min_y; y1 <= max_y; y1++) {
int inner = 0;
// 一个像素16个点进行超采样
for (int sx = 0; sx < 4; sx++) {
for (int sy = 0; sy < 4; sy++) {
if (insideTriangle(x1 + 0.125 + 0.25 * sx, y1 + 0.125 + 0.25 * sy, t.v)) {
inner++;
}
}
}
if (inner > 0) {
//计算三角形重心坐标
auto [alpha, beta, gamma] = computeBarycentric2D(x1, y1, 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 (depth_buf[get_index(x1, y1)] > z_interpolated) {
depth_buf[get_index(x1, y1)] = z_interpolated;// 更新 z-buffer 深度值
set_pixel({ (float)x1,(float)y1,1 }, t.getColor() * (inner / 16.f));// 更新 frame-buffer 颜色值
}
}
}
}
}效果图
1.正常光栅化

2.MSAA 处理后的效果对比:

边栏推荐
- [bit operation] leetcode1009 Complement of Base 10 Integer
- 对标Copilot,国内首个:自然语言一键生成方法级代码aiXcoder XL来了
- PHP admin deployment - resolve all errors
- Commission contract on BSV (3)
- Apache Doris real-time data analysis nanny level tutorial
- Principle and Countermeasure of anti Association browser
- 【第 07 章 基于主成分分析的人脸二维码识别MATLAB深度学习实战案例】
- Scuba China trip - Suzhou station, online and offline limited time registration channel has been opened!
- NOIP初赛 CSP-J1 CSP-S1 第1轮 初赛 信奥中的数学知识(三)
- The way to build the efficiency platform of didi project
猜你喜欢

Seeking an anti association detection tool, online detection of browser fingerprint

Commission contract on BSV (3)

技术探秘: 360数科夺得ICDAR OCR竞赛世界第一

Recommended by Ali, Tencent and Baidu software testing engineers - waterfall model of software testing model
![[number theory] leetcode1010 Pairs of Songs With Total Durations Divisible by 60](/img/cc/ca70945b1bb2f57093bbae721ca635.png)
[number theory] leetcode1010 Pairs of Songs With Total Durations Divisible by 60

ShardingSphere-proxy-5.0.0分布式哈希取模分片实现(四)

飞桨中国行-苏州站,线上线下限时报名通道已开启!

Heidisql always makes errors when inserting data. What should I do

【第 17 章 基于 Harris 的角点特征检测--Matlab机器学习项目实战】

Scuba China trip - Suzhou station, online and offline limited time registration channel has been opened!
随机推荐
Scuba China trip - Suzhou station, online and offline limited time registration channel has been opened!
LCP 17. Quick calculation robot
内网学习笔记(3)
英伟达笔试面试题整理DIY
第 12 章 基于块匹配的全景图像拼接--Matlab深度学习实战图像处理应用
高分方案纷纷开源,中国“软件杯”遥感赛项第二轮预选赛来了!
NOIP初赛 CSP-J1 CSP-S1 第1轮 初赛 信奥中的数学知识(一)
Commission contract on BSV (2)
出现IOError: No translation files found for default language zh-cn.的解决方法
第 24 章 基于 Simulink 进行图像和视频处理--matlab深度学习实战整理
Intranet learning notes (3)
Curl requests at the server command line
Benchmarking copilot, the first in China: natural language one click generation method level code aixcoder XL is coming
"Good morning, good afternoon, good night" game jam
[AMD Comprehensive Search Experience Sharing 618]
NOIP 提高组 初赛 三、问题求解 习题集NOIP1995-NOIP2018
第 25 章 基于小波变换的数字水印技术
Pytoch neural network [handwritten digit recognition]
Apache Doris real-time data analysis nanny level tutorial
“早安、午安、晚安” Game Jam