games101 homework2 详解过程

games101 homework2 详解过程

未使用MSAA来抗锯齿:

1.根据三角形顶点position首先获得三角形像素边界

2.遍历所有像素点,进行判断是否在三角形内部

3.计算重心computeBarycentric2D(),返回重心坐标alpha,beta,gamma,三者之和为1;(这个先要听完渲染和材质那几节)

4.根据重心坐标计算z-buffer值

5.比较当前像素的重心坐标和已存储的z-buffer,替换成z值更大的(depth更小的),如果改变了zbuffer值还需要着色一遍。

使用MSAA:

1.将一个像素虚拟成四个小的bounding box

2.计算4个bounding box 中心的重心坐标,并计算zbuffer 的depth值。

3.以4个bounding box中最小的depth 值进行更新。

void rst::rasterizer::rasterize_triangle(const Triangle& t) {
    auto v = t.toVector4();

	// bounding box
	float min_x = std::min(v[0][0], std::min(v[1][0], v[2][0]));
    float max_x = std::max(v[0][0], std::max(v[1][0], v[2][0]));
	float min_y = std::min(v[0][1], std::min(v[1][1], v[2][1]));
	float max_y = std::max(v[0][1], std::max(v[1][1], v[2][1]));

	min_x = (int)std::floor(min_x);
	max_x = (int)std::ceil(max_x);
	min_y = (int)std::floor(min_y);
	max_y = (int)std::ceil(max_y);

	bool MSAA = false;
	//MSAA 4X
	if (MSAA) {
		
		std::vector<Eigen::Vector2f> pos
		{
			{0.25,0.25},
			{0.75,0.25},
			{0.25,0.75},
			{0.75,0.75},
		};
		for (int x = min_x; x <= max_x; x++) {
			for (int y = min_y; y <= max_y; y++) {
				
				float minDepth = FLT_MAX;
			
				int count = 0;
				
				for (int i = 0; i < 4; i++) {
					
					if (insideTriangle((float)x + pos[i][0], (float)y + pos[i][1], t.v)) {
						
						auto tup = computeBarycentric2D((float)x + pos[i][0], (float)y + pos[i][1], t.v);
						float alpha;
						float beta;
						float gamma;
						std::tie(alpha, beta, gamma) = tup;
						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;
						minDepth = std::min(minDepth, z_interpolated);
						count++;
					}
				}
				if (count != 0) {
					if (depth_buf[get_index(x, y)] > minDepth) {
						Vector3f color = t.getColor() * count / 4.0;
						Vector3f point(3);
						point << (float)x, (float)y, minDepth;
					
						depth_buf[get_index(x, y)] = minDepth;
						
						set_pixel(point, color);
					}
				}
			}
		}
	}
	else {
		for (int x = min_x; x <= max_x; x++) {
			for (int y = min_y; y <= max_y; y++) {
				if (insideTriangle((float)x + 0.5, (float)y + 0.5, t.v)) {
					auto tup = computeBarycentric2D((float)x + 0.5, (float)y + 0.5, t.v);
					float alpha;
					float beta;
					float gamma;
					std::tie(alpha, beta, gamma) = tup;
					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(x, y)] > z_interpolated) {
						Vector3f color = t.getColor();
						Vector3f point(3);
						point << (float)x, (float)y, z_interpolated;
						depth_buf[get_index(x, y)] = z_interpolated;
						set_pixel(point, color);
					}
				}
			}
		}
	}
}
posted @ 2022-02-20 12:04  秋月桐  阅读(81)  评论(0编辑  收藏  举报