图形学笔记(四)变换——三维变换(三维旋转与欧拉角)、MVP变换、视图变换、投影变换(正交投影与透视投影)
图形学笔记(六)光栅化2 —— Artifacts、时域与频域、滤波、卷积定理、超采样、MSAA
在上一节中我们通过MVP变换将所有物体都映射到了经典立方体中( [ − 1 , 1 ] 3 [-1,1]^3 [−1,1]3)。
接下来,我们又要如何把立方体画到屏幕上呢?
文章目录
1 基本概念
1.1 什么是屏幕(Screen)
- 屏幕是像素的二维数组(pixel),数组的大小被称为分辨率(resolution)
- 屏幕是一个典型的光栅(raster)成像设备
1.2 光栅化(Raster)
- 光栅(Raster)就是德语中的屏幕。
- 光栅化(Rasterize)就是把东西画在屏幕上的过程。
1.3 像素(Pixel)
- 像素是图片单元(picture element)的简写。
- 暂时把像素当作一个只带有一种颜色的小方块(颜色是rgb(红绿蓝0-255)的混合)。
1.4 屏幕空间(Screen-Space)
屏幕空间就是在屏幕上建立一个坐标系(左下角是原点)。
有以下一些约定:
- 像素的坐标写成(x,y)的形式。
- 像素坐标的范围是从(0,0)到(width-1,height-1)的。
- 像素(x,y)的中心是(x+0.5,y+0.5)。
- 屏幕的覆盖范围是从(0,0)到(width,height)的。
2 视口变换
想把立方体的内容在屏幕上绘制出来,首先我们要把经典立方体映射到屏幕,即进行以下的过程:
- 忽略z
- 把xy平面上的 [ − 1 , 1 ] 2 [-1,1]^2 [−1,1]2转化(进行缩放和平移)成[0,width] X [1,height](这个过程也称为视口变换)
视口变换矩阵:
经过上面的步骤,我们就确定了屏幕上一些边界点的坐标,接下来我们就要把轮廓内的东西画到屏幕上来进行显示。
接下来介绍将三角形光栅化为像素的过程。
3 三角形 - 基础图元
3.1 为什么是三角形是基础图元?
因为三角形有很多优势:
- 三角形是最基础的多边形
- 可以把其他多边形打碎成三角形
- 具有独特的属性
- 三角行肯定是个平面(planar)(不想四边形一弯折顶点就可以在不同的平面中了)
- 内部容易区分(通过叉积可以快速判断点是否在三角形内,判断方法可以回顾第二节的内容)
如图所示, A B ⃗ × A P ⃗ > 0 \vec {AB} \times \vec {AP} > 0 AB×AP>0,说明P在AB的左边, B C ⃗ × B P ⃗ > 0 \vec {BC} \times \vec {BP} > 0 BC×BP>0,说明P在BC的左边 , C A ⃗ × C P ⃗ > 0 \vec {CA} \times \vec {CP} > 0 CA×CP>0 ,说明P在CA的左边。如果进行三个叉积运算的结果都为正或都为负,表明点都在三角形边的左边或者都在右边,故说明P在三角形内部。
否则说明点在三角形外面。
- 方便不同的属性进行插值(从一个顶点到另一个顶点内部属性的变化)
3.2 使用像素来表示一个三角形
经过MVP变换和视口变换就可以得到三角形三个顶点的坐标,接下来要将这个坐标转化为像素的集合。
这个过程的输入是三角形顶点投影到屏幕上的位置,输出是像素值的集合,如下图所示。
根据上图我们很容易得到,三角形内部的点一定是要染色的,可是三角形边缘的点怎么办呢?
我们可以通过采样等方式来判断像素(中心点)与三角形的位置关系(在内还是在外?),进而判断边缘的点是否该被染色。
4 光栅化的方法——采样
4.1 定义与理解
定义:把函数离散化的过程。
如下所示,现在有某连续函数,对于很多离散的点去应用这个函数,并计算相应的输出值。
4.2 采样过程
对屏幕进行采样来判断像素的中心是否在三角形内。
(1)定义函数inside(tri,x,y)(1就是染色,0就是不染色)
i n s i d e ( t , x , y ) = { 1 ( x , y ) 处 在 三 角 形 t 内 0 ( x , y ) 不 在 三 角 形 t 内 inside(t,x,y)=\left\{ \begin{aligned} &1 &(x,y)处在三角形t内\\ &0 &(x,y)不在三角形t内\\ \end{aligned} \right. inside(t,x,y)={
10(x,y)处在三角形t内(x,y)不在三角形t内
(2)对屏幕的所有像素来进行采样,代码如下所示:
(3)边界情况
对于边界情况,可以做处理也可以不做处理。
比如我们可以认为,下面的每种说法都是对的
- 图中的点在三角形1内
- 图中的点在三角形2内
- 图中的点在三角形1和三角形2内
4.3 三角形的包围盒(Bounding Box)
包围盒就是圈定三角形顶点的xy最小值和最大值的范围。
引入包围盒后,我们不用遍历整个屏幕只要判断包围盒内的点即可。
5 光栅化的加速方法
以下是一种遍历的加速方法。
如图所示从顶点开始,对每一行都有左和右的包围盒,不再多考虑别的像素。
适合比较窄的和旋转的三角形。
6 光栅化的问题——锯齿(Jaggie)或走样(Aliasing)
如图所示,直接栅格化后,边界并不像一个三角形。
原因:像素本身有大小
所以要进行抗锯齿和反走样。