三角形光栅化

本次实现基于tinyRender项目,笔者进行了自己的思考,而后和书籍进行验证

三角形的填充

线扫描

线扫描是比较古典的方法了,我们确定三角形的边界,就可以自低向上的进行扫描

那么首先,我们需要对三角形顶点的y轴从小到大进行排序,ymin,ymid和ymax

y = ymid 这条横线把三角形分割成上下两个部分,每个部分的x轴的边界由对应的边构成

那么我们只需要从ymin往ymax一行一行扫描就行,代码如下:

void LineScan(TGAImage& image, Vec2i t[3], TGAColor color = red)
{
	SortPoint_ByYAxis(t);

	float x1 = t[0].x;
	float x2 = t[0].x;
	float reverseK01 = 1.0 * (t[1].x - t[0].x) / (t[1].y - t[0].y);
	float reverseK02 = 1.0 * (t[2].x - t[0].x) / (t[2].y - t[0].y);
	float reverseK12 = 1.0 * (t[2].x - t[1].x) / (t[2].y - t[1].y);

	int error1 = 0, error2 = 0;
	for (int y = t[0].y; y < t[1].y; ++y)
	{
		line(x1 + offset, y, x2 + offset, y, image, color);
		x1 += reverseK01;
		x2 += reverseK02;
	}
	// 这里有一点冗余
	error1 = 0, error2 = 0;
	for (int y = t[1].y; y <= t[2].y; ++y)
	{
		line(int(x1 + offset), y, int(x2 + offset), y, image, color);
		x1 += reverseK12;
		x2 += reverseK02;
	}	
}

笔者本来想从ymin出发和ymid-ymax所在斜线上的点,利用斜线进行三角形填充。但是这样会出现漏洞,因为像素块是一个一个的,这样会导致一部分的像素块没办法被填充

重心计算法

假设三角形ABC,重心为P,三角形的重心计算 : P = (1-u-v)A + uB + vC

进行展开:P = A + u(B-A) + v(C-A) + A ➡️

转换成线性方程组:

转换成矩阵形式:

那么我们对三角形进行BOX裁剪,然后计算其三角形内的所有重心,进行填充即可,代码实现如下:

void GravityCenterAlgorithmn(TGAImage& image, Vec2i* pts, TGAColor color = red)
{
	// 减一 是为了在合理范围内
	Vec2i bboxmin(image.get_width() - 1, image.get_height() - 1);
	Vec2i bboxmax(0, 0);
	Vec2i clamp(image.get_width() - 1, image.get_height() - 1);
	// BOX裁剪 ➡️ 因为三角形可能在边界外
	for (int i = 0; i < 3; ++i)
	{
		// 确保边界大于0,为三角形最小坐标的边界
		bboxmin.x = std::max(0, std::min(pts[i].x, bboxmin.x));
		bboxmin.y = std::max(0, std::min(pts[i].y, bboxmin.y));

		// 确保边界为三角形的边界
		bboxmax.x = std::min(clamp.x, std::max(pts[i].x, bboxmax.x));
		bboxmax.y = std::min(clamp.y, std::max(pts[i].y, bboxmax.y));
	}

	Vec2i P;
	for (P.x = bboxmin.x; P.x <= bboxmax.x; P.x++)
	{
		for (P.y = bboxmin.y; P.y <= bboxmax.y; P.y++)
		{
			Vec3f bc_screen = barycentric(pts, P);
			// 其实就是避免点在三角形之外的情况
			if (bc_screen.x < 0 || bc_screen.y < 0 || bc_screen.z < 0)
				continue;
			image.set(P.x, P.y, color);
		}
	}
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇