最近带薪学习的一些笔记
最近实习给留了一个图形学自学任务,正好借着这个机会把Games101的第一部分给刷了,也就是实时渲染管线这一部分,在这里总结一下,如有不对感谢指正。
搜了一些其他的资料,发现Games101真的只是一个入门orz,任重而道远啊。
实时渲染管线
点处理阶段
将三维空间中的点通过MVP矩阵(model view projection)变换到投影坐标下。
模型变换model transformation
自身坐标->世界坐标
物体的变换(仿射变换):旋转、缩放、平移。其中平移不是线性变换,为了把这几个变换搞到一个矩阵里,引入了齐次坐标,多存储了一个维度的信息,但是计算方便了一些。
物体的变换可以分解,即上述三种变换可以合成一个矩阵,一个变换矩阵也可以拆分成多个变换操作,但注意不满***换律,先线性变换再平移。注意列向量要左乘。
视口/相机变换View/Camera Transformation
定义相机
- position
- look-at direction
- up direction
- 为了方便,规定相机永远会变换到坐标原点,看向-z,向上方向朝向y(闫老师的课用的是右手系)
变换
- 可以把相机变换拆分成平移和旋转两部分:
- 先平移到原点
- 再旋转到相应轴
投影变换Projection Transformation
分为两种,正交投影和透视投影
正交投影Orthographic Projection
- 不严谨说就是将物体的z轴舍掉,将x,y坐标映射到
区间内
- 通常来说将一个方块
变换成一个标准正方体
- 先平移再缩放
透视投影Perspective Projection
- 透视原物体可以视为一个四棱台,先通过“挤压”转换成方块(
),然后再做正交变换
- 上面公式的
用括号括起来了,原因是计算出来的坐标最后是
,与
代表的点是一样的,但最后一维通常为1。
***面和远平面距离与
需要自己定义。
通常相机会有另外两个参数,一个是视角(field of view, fov),一般是垂直视角(fovY),另一个是宽高比(aspect),可以用这两个值对公式中的其他值进行换算。
- 另外由于相机最后会变换到原点处,所以计算的时候有
最后MVP矩阵应为
三角形处理阶段
就是将所有的点按照原来的几何信息变成三角面。
光栅化阶段
将标准正方体投影到屏幕
- 暂时忽略z
- 将
变换为
- 如何知道渲染哪个点(哪些点在三角形中):先找到三角形的包围盒,然后判断包围盒中所有的点是否在三角形中
- 抗锯齿(MSAA等方法)
Z-buffer
想法: - 存储每个像素当前最小的z值
- 需要额外信息存储深度值
- frame buffer存储颜色值
- depth buffer存储深度值
片元处理阶段
主要是讲着色问题。但是着色会发生在点处理和片元处理这两个阶段。
shading point定义
- viewer direction,
- surface normal,
- light direction
- surface parameters(color, shininess, ...)
shading is local(着色仅考虑自己,不会生成阴影)
Diffuse Reflection漫反射
Lambert 余弦定理
每个单位区域的光与
成正比
已知一个点光源,光线传播能量与距离平方成反比
intensity:
Lambertian(Diffuse) Shading
Specular Term(Blinn-Phong)
镜面反射光的强度取决于观测方向
观测方向接近于镜面反射方向 <=> 半程向量(half vector)接近于法向量
半程向量
一般被认为是白色
Ambient Term
环境光是一个常数
Blinn-Phong Reflection Model
Shading Frequncies着色频率
Shade each triangle(flat shading)
- 三角面片是平的,只有一个法向量
Shade each vertex(Gouraud shading)
- 每个顶点有一个法向量
- 每个三角形的颜色通过内部插值的方法计算出来
Shade each pixel(Phong shading)
- 每个像素插值出一个法向量,计算shading
定义每个点的法向量
- 最好的方法是从已有的规则图形获取(比如一个球)
- 否则需要从三角面来进行推断
- 简单的方法:计算该点所在的所有平面的法向量的平均值(还可以跟据面积做加权平均)
- 简单的方法:计算该点所在的所有平面的法向量的平均值(还可以跟据面积做加权平均)
定义逐像素的法向量
使用Barycetric interpolation进行插值求出
Shader
- 对点处理和片元处理阶段编程
- 描述了在一个点/片元上的操作
Texture mapping
- 三维物体的表面其实是二维的(texture)
- 每个三角形顶点有一个纹理坐标(u,v)
- u、v范围都为[0,1]
Barycentric Coordinates(重心坐标)
引入目的:
- 为了求点的特定值
- 为了平滑跨三角形的数值
如果三个值都是非负的,那么该点在三角形内
应用纹理
简单纹理映射:Diffuse Color
对每个光栅化后的屏幕采样(x,y):
- (u,v) = evaluate texture coordinate at (x,y)
- texcolor = texture.sample(u,v);
- set sample's color to texcolor;
Bilinear 双线性插值
Mipmap
允许做范围查询(fast快, approx.近似的, square正方形)
- 存储仅多了1/3
计算 Mipmap层D
用Trilinear插值计算连续的D值
limitations:
- Overblur,过分模糊(Mipmap只能应用于正方形区域)
- 屏幕像素映射到纹理像素后并不一定都是正方形
Solution:
Anisotropic Filtering各向异性过滤
- 可以查询轴向矩形区域
- 存储开销多了3倍
Spherical Environment Map
将环境光记录在球上
缺点:两端会被拉伸
->Cube Map
将环境光记录在六张图上
缺点:需要额外的计算
凹凸贴图 Bump/Normal mapping
- 纹理可以不只表示颜色,可以存储高度
- 这样可以做一些细节几何的效果(fake the detailed geometry)
- 通过凹凸贴图定义切线,然后再计算法线
- 局部坐标系stn,n的方向永远是(0,0,1)
位移贴图 Displacement mapping
- 与凹凸贴图输入相同
- 会真的改变点的位置
- 模型要足够细致
帧缓冲操作
这部分就是将最终的像素信息输出到屏幕上,一些alpha测试、zbuffer的东西在这里执行。
#学习#