Visibility
绘画算法:从远到近将物体画在屏幕上,近处的物体覆盖远处的对应的图层;
将模型三角光栅化,考虑对三角形按照距离屏幕的深度排序,复杂度为,但是可能存在相互覆盖的环;
引入Z-Buffer(深度缓存):
- 为每一个像素保存当前的最小深度;
- 同时维护两个缓存:帧缓存保存颜色值,深度缓存保存深度
算法如下:
1 | Initialize depth buffer to ∞ |
假设每个三角形平均覆盖常数个像素,则该算法复杂度为;也就是该算法并不是基于排序的,假设每个三角不会在同一个像素用相同的深度,那么这个算法其实和三角形深度无关的;
Z-Buffer算法是目前最重要的可见性算法,已经在所有的GPU在硬件上实现;缺点是处理不了透明物体;
Blinn-Phong Reflectance Model
在绘画上,使用平行光线或者色块,引入图像的明暗和色彩;
在图形学上,着色指对物品应用某一种材质的过程;
最简单的着色模型是Blinn-Phong Reflectance Model;
观察下图有如下要素
-
Specular highlights: 高光,一般光线照射到光滑的地方,发生接近于镜面反射的效应;
-
Diffuse reflection: 漫反射,一般光线照射到粗糙的地方,其所有查看方向的表面颜色都相同
-
Ambient lighting:环境照明,物体接收到了间接的环境反射光,一般认为是常量;
建立局部着色模型(Shading in Local)的输入:给定物体表面上一点Shading Point,考察光照照射在该点的输出,不考虑阴影(Shadow)
- Viewer direction: 观察者看到物体的方向
- Surface normal:物体表面切面法线向量
- Light direction:光线方向
- Surface parameters:物体表面属性,比如颜色,亮度
Diffuse Term
物理上来说,在物体单位面积上,考虑接受到光线能量应该正比于;
这是符合直觉的;
- 物体被光照直射,理应接收更多光;
- 物体和光照同向就几乎没有光照射上;
对于一种点光源,光线的能量在某一个时刻集中在一个球壳上(波动性);
考虑能量守恒,光线传播越远,能量衰减(light failoff)越多,用光照强度(intensity)定义能量;
由此建立漫反射模型
- :某方向上的漫反射光diffusely reflected light;
- :扩散系数diffuse soefficient,该点可能吸收一部分光而存在损耗,可以表示成三通道RGB值,就可以定义该点反射出来的颜色;
- :不考虑光线从物体下面穿过,不考虑物体透明和折射
对于漫反射来说,不管从任何方向来看看起来都是一样,上式与无关,这说明此模型的合理性;
Specular Term
对于高光项,如果光线照射在比较光滑的物体,那么高光反射的光线应该类似于镜面反射,可以用其半程向量和法线接近描述;
Blinn-Phong模型定义半程向量
类似定义高光项
- :镜面反射光specularly reflected light
- :亮度系数specular coefficient,相对于漫反射项来说很小
- :为解决余弦项容忍度过高的问题,一般取128,提高幂次以符合经验:偏离高光光线一点点就基本看不到了;
Ambient Term
大胆假设环境中任意一点接收到环境光基本为常量,环境光着色不依赖于任何其他事物,真实世界可能未必这样;
添加常量颜色以考虑忽略的照明并填充黑色阴影,保证没有地方是完全黑的;
- :反射环境光 reflected ambient light
- :环境光系数 ambient coefficient
模型输出为三项相加
Shading Frequency
对于光栅化的图像,可以按照每个三角形面,顶点,和像素为单位进行着色,它们的着色频率并不相同;
Flat Shading:每一个三角形面对应一个法向量,在光滑面上效果不好;
Gouraud Shading:跨三角形的顶点进行插值着色,每个三角形顶点对应一个法线
Phong Shading:在每个三角形上插值法线向量 ,计算每个像素的完整着色模型
以下是三个方法的对比图
对于光栅化的图形,顶点对应的法线可以用其关联的所有三角形法线平均
Real Time Rendering
Pipline如下
Texture Map
我们希望在物体表面上的不同位置的点定义不同属性,观察到任何三维物体的表面是二维的,反过来我们也可以把一张二维图贴在三维物体的表面,我们把这张二维图称为纹理;
对于纹理图上任意一个点,定义uv坐标系,每一个三角形的顶点对应纹理上的一个坐标;
一个看起来舒服的纹理,应该看起来上下左右无缝衔接,因为纹理可以被物体重复多次,比如tiled texture;
Barycentric Coordinates
在三角形内部进行插值的工具是重心坐标,重心坐标可以表示三角形内部的一个顶点,从而在三角形内部实现平滑过渡,常常用于纹理坐标,颜色,法向量的计算;
对于三角形, 在三角形内部的任意一点,可以表示为三个顶点坐标的线性组合
若点在三角形内,还需满足三个系数非负;若无限制条件,表示点在三角形所在平面内;
进一步,定义有向面积,定义三角形面积
用叉乘可以如下展开
特别的,三角形的重心坐标为;
基于任意一点,可以利用重心坐标,根据顶点的属性值,插值成三角形内部的属性值
但是在投影变换下,重心坐标不保证发生变化,应该在投影之前计算三维空间下的重心坐标,插值之后再做投影变换;
Texture Mapping
基本思路为:对每个光栅化屏幕的采样点(通常为像素的中心),计算对应的纹理的坐标,在纹理上采样,设置样本点的纹理颜色;
像素在纹理上的采样对应的称为纹理元素(texel);
在实际应用时,针对不同场景,往往还要作如下优化:
Bilinear Interpolation
假设像素对应的纹理坐标对应红点,我们考虑周围四个像素进行插值;
定义一维上的线段上的插值
考虑水平偏移和垂直偏移,可以在水平方向和垂直方向各做插值
若取16个纹理格子的方法称作Bicubic,对比如下,解决纹理分辨率过低的问题;
Mipmap
对于纹理分辨率过大的情况,可能出现锯齿和摩尔纹的问题;
假设像素对应灰色的四边形,其中心为蓝点,在分辨率相对过大的情况下,可能像素覆盖了许多纹素,仅靠中心点的纹素难以描述整个像素的纹理信息,需要解决在纹理走样上的问题;
抛弃采样的思路,我们尝试解决一类范围查询问题:给定平面上的一块像素区域,获得覆盖纹素的平均值;
引入Mipmap,快速地解决正方形的近似范围查询;
预处理纹理图像,生成的卷积图像作为下一层,直到得到单个纹素,带来的额外空间开销为原来的;
利用Mipmap我们只需要关注像素对应的区域在Mipmap的哪一层即可,对于任意一个像素块,可以映射到纹理上的某一区域;
考虑像素中心和其邻居中心的距离为一个像素块长度,那么这个区域也近似为一个映射长度的正方形;
映射长度计算如下:
这个近似正方形的纹理平均值所在层数为
在这一层像素对应的区域就近似于该层的一个纹素;
这样的计算代价可能是纹理映射变化不连续,我们考虑下层和上一层,进一步作三线性插值(Trilinear Interpolation);
Anisotropic Filtering
使用Mipmap可能会在远处出现过度模糊的问题,可能是近似成正方形区域带来细节丢失严重的问题;
通过各向异性过滤可以缓解Mipmap的问题;
预计算Ripmaps 和总面积表,可以查找轴对齐的矩形区域 ,但是对角线足迹仍然是一个问题,而且带来的开销是原来的3倍;
EWA filtering
通过多次查询,将不规则区域分成若干圆形;
- 计算加权平均;
- 仍然维护Mipmap 层次结构;
- 可以处理不规则的足迹;
Application
在现代GPU中,纹理可以看作一块内存+内存上的范围查询,可以将数据引入片段计算,这实际上是一些物理模型应用的上层抽象;
- 环境光Environment lighting
- 存储微观几何体Store microgeometry
- 程序纹理Procedural textures
- 实体建模Solid modeling
- 体积渲染Volume rendering
Environment Lighting
我们需要将纹理描述环境光时,会生成一种环境贴图的特殊纹理,用于描述不同方向的光照信息;
一般认为环境光线来自无穷远处,也就是说,用环境光描述的环境贴图没有深度意义;
我们可以将环境贴图记录在一个球面上,再将球面展开(类似于地球仪和世界地图),称作Spherical Map;
但是Spherical Map潜在问题是靠近极点的位置可能发生扭曲;
一个改进是利用Cube Map,将光照信息存储在一个立方体上,将立方体展开得到6个图片;
对应关系如下:
Store Height/normal
可以用纹理描述物体表面上的凹凸高度变化,生成凹凸/法线贴图(Bump/Normal mapping),用于虚拟物体的表面几何性质(Fake the detailed geometry);
将设没有贴图时物体表面为黑线,黄色的曲线为凹凸贴图记录的高度信息,我们需要根据两个信息重新计算切线和梯度;
通过旋转坐标系的办法,我们假设没有贴图表面上一点的法向量为;
对于贴图上切线,用某个因子衡量贴图对表面的影响程度,对梯度用如下差分作出近似;
经过贴图修正过后的法线应该是
一个更加现代的方法是位移贴图Displacement mapping,实际改变光栅三角形的顶点位置,对比如下,可以看到在边缘处凹凸贴图的Fake之处,它没有改变几何体的形状;
效果更好带来如下代价:模型需要足够细致,使得光栅采样的频率高于纹理变换的频率;
3D Procedural Noise + Solid Modeling + Volumn Rendering
纹理也可以记录一些三维信息,用噪声描述;