fatcg2

这篇博客详细介绍了作者在图形学作业中的实践,包括实现Bresenham直线光栅化算法、简单齐次空间裁剪、三角形的背向面剔除、基于Edge-function的三角形填充算法和深度测试。通过这些任务,作者提升了计算几何和图形学理解,并探讨了遇到的问题和体会。
摘要由CSDN通过智能技术生成

Assignment 2: Rasterization & Z-buffering

19322093吴景图

作业概述

光栅化是将向量图形格式表示的图像转换成位图以用于显示器或者打印机输出的过程。目前我们的电子计算机采用栅格点阵的方式来显示图像、图形等数据,对于输入的连续信号(例如三角形),计算机会对该信号进行离散地采样。对应到三角形的光栅化过程,就是确定哪些栅格点(亦或者说像素点)被三角形覆盖了,我们会对被三角形覆盖了的像素点进行着色,从而最终在屏幕上显示出输入的三角形的形状和颜色。
构建好项目后,会有如下输出(见0.gif)
在这里插入图片描述

Task 1、实现Bresenham直线光栅化算法

实现TRShaderPipeline::rasterize_wire_aux函数。
该函数在 rasterize_wire 中被调用,对三角形的每一条边都进行直线光栅化:

void TRShaderPipeline::rasterize_wire(
 const VertexData &v0,
 const VertexData &v1,
 const VertexData &v2,
 const unsigned int &screen_width,
 const unsigned int &screene_height,
 std::vector<VertexData> &rasterized_points)
{
   
 //Draw each line step by step
 rasterize_wire_aux(v0, v1, screen_width, screene_height, rasterized_points);
 rasterize_wire_aux(v1, v2, screen_width, screene_height, rasterized_points);
 rasterize_wire_aux(v0, v2, screen_width, screene_height, rasterized_points);
}

先研究VertexData

class VertexData
		{
   
		public:
			glm::vec4 pos;  //World space position
			glm::vec3 col;  //World space color
			glm::vec3 nor;  //World space normal
			glm::vec2 tex;	//World space texture coordinate
			glm::vec4 cpos; //Clip space position
			glm::ivec2 spos;//Screen space position

它定义了几个坐标,及颜色等信息,要用的应该是屏幕坐标,即spos。

再看VertexData TRShaderPipeline::VertexData::lerp它的作用是线性插值,在两点之间,按照权值插值,得到一个新点。在这里的应用中,只需要对颜色插值,而位置计算出来的。

Bresenham 算法流程如下
在这里插入图片描述
考虑了dx,dy的正负,dx,dy的绝对值大小,写出了以下不太优美的代码

	void TRShaderPipeline::rasterize_wire_aux(
		const VertexData &from,
		const VertexData &to,
		const unsigned int &screen_width,
		const unsigned int &screen_height,
		std::vector<VertexData> &rasterized_points)
	{
   
		int x0 = from.spos.x;
		int y0 = from.spos.y;
		int x1 = to.spos.x;
		int y1 = to.spos.y;

		int dx = abs(x1 - x0);
		int dy = abs(y1 - y0);

		if ( abs( dx) > abs( dy) )
		{
   
			if (x0 > x1)
				swap(x0, x1), swap(y0, y1);
			int yy = y0;
			int  p = dy * 2 - dx;
			auto tmp = VertexData::lerp(from, to, fabs(float(x0 - from.spos.x) / dx));
			tmp.spos.x = x0;
			tmp.spos.y = yy;
			if (tmp.spos.x >= 0 && tmp.spos.x < screen_width && tmp.spos.y >= 0 && tmp.spos.y < screen_height)
				rasterized_points.push_back(tmp);
			for (int i = x0; i < x1; i++)
			{
   
				tmp = VertexData::lerp(from, to, fabs( float(i + 1 - from.spos.x ) / dx) );
				tmp.spos.x = i + 1;
				if (p <= 0)
				p += abs( dy + dy) ;
				else
				{
   
					yy += ((y1>y0 ) ? 1 : -1);
					p += dy + dy - ( dx + dx);
				}
				tmp.spos.y = yy;
				if (tmp.spos.x >= 0 && tmp.spos.x < screen_width && tmp.spos.y >= 0 && tmp.spos.y < screen_height)
				rasterized_points.push_back(tmp);
			}
		}
		else
		{
   
			if(y0 > y1)
				swap(x0, x1), swap(y0, y1) ;
			int xx = x0;
			int  p = dx + dx - dy;
			auto tmp = VertexData::lerp(from, to, fabs(float(y0 - from.spos.y) / dy));
			tmp.spos.x = xx;
			tmp.spos.y = y0;
			if (tmp.spos.x >= 0 && tmp.spos.x < screen_width && tmp.spos.y >= 0 && tmp.spos.y < screen_height)
				rasterized_points.push_back(tmp);

			for (int i = y0; i < y1; i++)
			{
   
				tmp = VertexData::lerp(from, to, fabs(float(i + 1 - from.spos.y) / dy));
				tmp.spos.y = i + 1;
				if (p <= 0)
				p += abs(dx + dx);
				else
				{
   
					xx += ((x1> x0) ? 1 : -1);
					p += dx + dx - dy - dy;
				}
				tmp.spos.x = xx;
				if (tmp.spos.x >= 0 && tmp.spos.x < screen_width && tmp.spos.y >= 0 && tmp.spos
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值