图形学 光栅化详解(Rasterization)

计算机的屏幕是二维的平面坐标,以左上角为原点,x轴向右增加,y轴向下增加。

1920×1080屏幕

在3D图形学中,物体是3维的,拥有X, Y, Z三个坐标,并且拥有R, G, B三种颜色,alpha透明度,U, V贴图坐标,N法线。
三维物体在二维屏幕上的显示,大致分为以下几步:

  1. 坐标变换(transform)
    将场景中的三维坐标转换为二维坐标,这个请参考我的文章坐标系空间变换
  2. 颜色计算(shade)
    计算每个顶点的颜色,通过UV贴图的颜色,结合光照,透明度等,计算出模型每个顶点的具体颜色(R, G, B)。这个在后面也会讲,本期不做介绍。
  3. 光栅化(rasterization)
    假定屏幕分辨率为1920×1080,在二维屏幕渲染(光栅化)时,内存中frame buffer只保存着1920×1080个屏幕点的颜色,然后一个一个的画到屏幕上。(它的实现方式是以一个1920×1080长的一维数组储存每个顶点的RGB颜色,然后遍历数组画出来)
    什么X, Y, Z,什么alpha之类的frame buffer都没有的,在frame buffer里只有3个值:R, G, B。
    X, Y, Z, alpha等等属性要在另外的地方存储。
    光栅化,就是计算出1920×1080这么长的RGB数组中,每一个RGB的值。

在第二步中,我们计算出了3D模型每个顶点的颜色,这个是基于3维坐标的,顶点的三维坐标可以是小数
但在屏幕渲染时,屏幕是只有X,Y二维的,并且其像素点坐标都是整数。1920×1080的屏幕只有1920×1080=2073600个像素点。所以光栅化的连点描边是一个近似过程。

PR线段的屏幕近似

PS:
目前主流的面片分割是三角形分割,所以大家在3DS MAX或者MAYA里看3D模型的网格,基本都是三角形网格,但也有以四边形为最小分割的算法,这里不涉及,我们认为3D模型的面片单元都是三角形。
那么一个三角形的颜色怎么规定呢?
(1)三个顶点颜色取平均值
(2)取某一个顶点的颜色
(3)三个顶点颜色的渐变
这三种方法都可以,根据实际情况自行斟酌。

光栅化主要有以下几步:

  1. 读取模型的顶点,3个3个的读,因为要画三角形。
  2. 将3个顶点两两连成线,形成三角形。
  3. 计算屏幕像素点在三角形内还是三角形外。在三角形内部的,就上色(颜色是之前算出来的),在三角形外部的,就不上色。
    注意:如果一个三角形挡在另一个三角形前面,我们应该只画前面的三角形。所以这里还需要比较一下正准备上色的这个像素点是不是已经上过色了。如果这个像素点已经上过色了,并且它是被Z=1的顶点上的色,而我们正准备上色的这个顶点的Z=2(说明这个顶点被挡在了后面),那么这个顶点就不应该上色,因为它是被挡住的点。)
  4. 不断的循环,直到画完3D模型的所有三角形,这样一个模型就出来了!

那么,假设我们已经得到了3个顶点的坐标,并且已知这个三角形是红色。
v1 (-1.5, 1.5, 1.5)
v2 (1.5, 1.5, 1.5)
v3 (0.2, 0.2, 0.2)
如何判断屏幕的哪些像素点在该三角形内部?
主流的算法有两种:
1.LEE(Linear Expression Evaluation)
2.Scan Line
本期只讲LEE,因为Scan Line我没有亲自搞过。
LEE大致原理如下:

  1. 首先因为屏幕只有二维,所以判断点和边的位置关系的时候可以先不管Z,Z只是用来判断前后遮挡的。
  2. 按照顺时针(或者逆时针)的顺序,连接v1v2, v2v3, v3v1,这样就得到了三条边。
  3. 假定边的头是(X+dX, Y+dY),尾是(X, Y)
    计算这3条边的方程:E(x,y) = dY(x-X)-dX(y-Y)
    展开之后是dY*x + (-dX)*y + (dX*Y-dY*X) = 0
    即Ax + By + C =0
    其中A = dY, B = -dX, C = dX*Y-dY*X
    我们把v1v2, v2v3, v3v1三条边的A, B, C都求出来,就得到了3条边的方程E1, E2, E3。
  4. 将屏幕像素点的x,y带入方程,A1x + B1y + C1 = E1,如果点在边上,则E1=0,如果点不在边上,则E1!=0。
  5. 最神奇的地方来了。
    如果点(x,y)带入3个方程的结果E1, E2, E3同时大于0或者同时小于0,即同号,则该点在三角形内,如果异号,则在三角形外。
  6. 每次获得3个点之后,取出其中的min_x, max_x, min_y, max_y构成的四边形,将屏幕像素点(x,y)中,在该范围内的点取出,带入LEE公式比较结果。
    如果该点在三角形内,并且没有被遮挡(需要对Z进行判断),则上色,否则不上色。不断迭代,直到所有的三角形都被处理完成,3D模型也画到了屏幕上。

需要注意的地方:

  1. 如何判断遮挡,即得到三角形内的点的Z值?
    答:我们知道了v1, v2, v3三个点,可以求三角形平面方程,求出之后,只需要将某个点的(x,y)代入,即可求出z。
    平面方程一般式为:Ax + By + Cz + D = 0
    取E1, E2两个边向量,进行叉乘,得到法向量N(A,B,C)
    没错,你没看错,N的X, Y, Z即是A, B, C。(数学真神奇)
    然后取v1(x, y, z)带入方程,求出D,平面解析式就得到了。
    然后将想求z的点的x,y带入,就可以求出z了。

  2. 屏幕的Z轴是朝里的,所以z越大说明离我们越远,z越小就里我们越近,近处的会遮挡远处的。

  3. LEE的特殊情况
    由于多个三角形的边和边是互相挨着的,所以如果直接按上面的方法画,会有很多边重复画了2遍,为了提高渲染效率,我们需要保证每条边只画一遍
    怎么保证呢?
    答:只画三角形的左边和上边

如何定义左边和上边?
由于重画这个问题只出现在边上,对于三角形内部的像素点,都是只画一次的,所以不用考虑内部点,只考虑三条边上的点。

如图所示:
1)假定三角形v1v2v3是这样的,我们当前要上色的像素点为P1(红色),落到了v1v3这条边上,那么就取不在这条边上的顶点v2,计算过v2的水平线与v1v3的交点R1,如果R1在v2的右侧,即R1.x > v2.x,那么说明P1是落在了右侧的边,所以不画

2)假定我们当前要上色的像素点为P2(绿色),落到了v2v3这条边上,那么就取不在这条边上的顶点v1,计算过v1的水平线与v2v3的交点R2,如果R2在v1的右侧,即R2.x > v1.x,那么说明P2是落在了右侧的边,所以不画

3)假定我们当前要上色的像素点为P3(蓝色),落到了v1v2这条边上,那么就取不在这条边上的顶点v3,计算过v3的水平线与v1v2的交点R3,如果R3在v3的右侧,即R3.x > v3.x,那么说明P3是落在了右侧的边,但图中是R3.x < v3.x,所以P3落在了左侧边,要画

4)如果存在垂直边或者水平边,怎么判断左右?
垂直边和上面是一种情况,不用单独拿出来考虑。
水平边的画,只画上方,即只画左边和上边
还是看上图,假定边v2v3是水平的,那么我们取v1,发现v1的y比较小,即v1在v2v3上方,那么边v2v3就是下边,所以不画,反之则画。

可以参考的论文

  1. Siggraph 1985 - "Fast Spheres, Shadows, Textures, Transparencies, and Image Enhancements in Pixel-Planes," Henry Fuchs,et. al.

  2. 2000 Sig/Euro Workshop on Graphics Hardware - "Tiled Polygon Traversal Using Half-Plane Edge Functions," Joel McCormack, Robert McNamara

  3. Siggraph 1988 - "A Parallel Algorithm for Polygon Rasterization," Juan Pineda

  4. Siggraph 2005 - “Resolution-Independent Curve Rendering Using Programmable Graphics Hardware,” Charles Loop, Jim Blinn

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容