【GAMES101学习笔记】05 - 三角形的光栅化

1. 投影变换(Perspective Projection)

视锥中的概念:

screenShot.png

  • 宽高比(Aspect ratio) :宽和高的比值;
  • 垂直可视角 fovY(Vertical Field-of-View) :可见角度的范围,屏幕上下边中点与 Camera 点的两条连线的夹角。

screenShot.png

  • tan ⁡ f o v Y 2 = t ∣ n ∣ \tan{\cfrac{fovY}{2}} = \cfrac{t}{\vert{n}\vert} tan2fovY=nt
  • a s p e c t = r t aspect = \cfrac{r}{t} aspect=tr

在经过投影变换之后,所有 Object 均投影到 正则立方体(“canonical” cube) [ − 1 , 1 ] 3 [-1,1]^3 [1,1]3

2. 屏幕(Sceen)

2.1 相关概念

  • 像素的二维数组;
  • 分辨率(Resolution) :屏幕的大小;
  • 一种典型的光栅成像设备;
  • 光栅化(Rasterize) :将 Object 绘制在屏幕上;
  • 像素(Pixel) :是 “图片元素”(picture element) 的缩写;
    • 像素是一个颜色均匀的正方形
    • 颜色是(red, green, blue)的混合

2.2 屏幕的定义

screenShot.png

  • 像素的坐标都可以表示成 ( x , y ) (x,y) (x,y) ,其中 x x x y y y 都是整数;
  • 设原点为 ( 0 , 0 ) (0,0) (0,0) ,那么所有像素都可以表示成 ( 0 , 0 ) → ( w i d t h − 1 , h e i g h t − 1 ) (0,0) \to (width-1,height-1) (0,0)(width1,height1)
  • 像素 ( x , y ) (x,y) (x,y) 的中心为 ( x + 0.5 , y + 0.5 ) (x+0.5,y+0.5) (x+0.5,y+0.5)
  • 屏幕覆盖的范围: ( 0 , 0 ) → ( w i d t h , h e i g h t ) (0,0) \to (width,height) (0,0)(width,height)

2.3 正则立方体到屏幕

  • z z z 轴分量无关;
  • 仅在 x O y xOy xOy 平面上进行变换: [ − 1 , 1 ] 2 ↦ [ 0 , w i d t h ] × [ 0 , h e i g h t ] [-1,1]^2 \mapsto [0,width] \times [0,height] [1,1]2[0,width]×[0,height]

视口变换矩阵(Viewport transform matrix)
M v i e w p o r t = ( w i d t h 2 0 0 w i d t h 2 0 h e i g h t 2 0 h e i g h t 2 0 0 1 0 0 0 0 1 ) M_{viewport} = \begin{pmatrix} \frac{width}{2} & 0 & 0 & \frac{width}{2} \\[1.5ex] 0 & \frac{height}{2} & 0 & \frac{height}{2} \\[1.5ex] 0 & 0 & 1 & 0 \\[1.5ex] 0 & 0 & 0 & 1 \end{pmatrix} Mviewport=2width00002height0000102width2height01

  • 将正则立方体的宽度和高度缩放至 w i d t h width width h e i g h t height height
  • 将正则立方体的中心位移至屏幕的中心点 ( w i d t h 2 , h e i g h t 2 ) (\frac{width}{2},\frac{height}{2}) (2width,2height)
  • z z z 方向上不发生变化。

3. 光栅化

绘制到光栅成像设备:

  • 多边形网格(Polygon Meshes)
  • 三角形网格(Triangle Meshes)

3.1 使用三角形的原因

  • 三角形是最基础的多边形;
  • 任何多边形都能被剖分成若干个三角形;
  • 保证是平面的,而四边形有可能 4 个点不在同一个平面上;
  • 轮廓定义明确,不存在凹凸的性质,可以用叉积判断某点与三角形的碰撞情况;
  • 三角形上的顶点的插值方法定义明确(重心插值)。

3.2 将三角形像素化

判断像素的中心点与三角形的位置关系

3.2.1 采样法

  • 通过若干个点上计算一个函数就是 采样(sampling)
  • 采样(sampling) 就是将函数 离散化(discretize)
for (int x = 0; x < xmax; ++x)
    output[x] = f(x);

这里我们利用 “像素的中心” 对屏幕空间进行采样,将屏幕离散化;

screenShot.png

定义一个函数,判断像素的中心是否在三角形内:

inside(tri, x, y);

i n s i d e ( t , x , y ) = { 1     P o i n t ( x , y )   i n   t r i a n g l e   t 0     o t h e r w i s e inside(t, x, y) = \begin{cases} 1 \space\space\space Point(x, y) \space in \space triangle \space t \\[1.5ex] 0 \space\space\space otherwise \end{cases} inside(t,x,y)=1   Point(x,y) in triangle t0   otherwise

在二维空间用指示器函数进行采样:

for (int x = 0; x < xmax; ++x)
    for (int y = 0; y < ymax; ++y)
        image[x][y] = inside(tri, x + 0.5, y + 0.5);

screenShot.png

判断点是否在三角形内

边界处理

  • 上边和左边:算在三角形上;
  • 下边和右边:不算在三角形上。

screenShot.png

三角形的轴向包围盒 AABB

screenShot.png

特殊的加速方法

  • 每一行找最左和最右的像素

screenShot.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值