1.1 光照计算发生在图形流水线的Vertex Operations中,只计算每个顶点的颜色,而三角形内部的点的颜色在Fragment Operations阶段通计算,这样效率高,因为像素的数量远远大于顶点的数量。
1.2 计算三角形内每个像素的颜色的过程,称为shading,也称明暗处理、着色。几种常见处理方法有:
- 常数明暗处理;
- Gouraud 明暗处理;
- Phong 明暗处理;
1.3 常数明暗处理
每个面片内所有像素都取同样的颜色,颜色来源于某个顶点的颜色。即对每个多边形只计算一个光照强度,然后用此值作为整个多边形平面的明暗值赋给多边形的每个像素,使多边形的每个点都具有相同的明暗度。
1.4 Gouraud 明暗处理
采用双线性插值的方式计算面片内像素的颜色,具体为:
- 计算出多边形各个顶点的法向(对周围面片法向进行平均求得此顶点的法向);
- 采用光照公式计算出各顶点的光亮度值;
- 然后再对多边形顶点的光亮度进行“双线性插值”计算出多边形内任意片元的光亮度。
双线性插值发生在光栅化阶段,会对多边形进行扫描转换,此时正好就可以再扫描过程中对每个片元进行双线性插值。
顶点层次处理的对象是顶点,Fragment operations阶段处理的是片元(像素)。
1.5 在OpenGL中,主要分为Flat Shading和Smooth Shading。
1.6 Gouraud 明暗处理问题
- 曲面分割过粗可能产生错误效果;
- 高光的丢失,如下图高光部分不规则,主要是由于插值不均匀导致的;
- 马赫带效应(即高亮度变化率不连续的边界处呈现亮带或黑带);
1.7 Phong 明暗处理
主要思想是不插值光亮度颜色,而是插值法向量,因此也称为“法向量插值明暗处理”。对多边形顶点处法向量做双线性插值,将插值计算得到得多边形内各片元得法向量带入光亮度计算公式,得到各片元得光亮度。
- 计算出多边形各顶点得法向;
- 对多边形中得某个片元,双线性插值计算其法向;
- 计算出多边形内片元得光亮度。
1.8 各明暗处理方法效果
- Phong Shading模拟得高光效果更逼真,但由于模型本身精细度不高,轮廓并不光滑。
- Phong明暗处理得缺点是计算量大;一般采用shader来实现;
- Gouraud明暗处理:直接插值得到光亮度;
- Phong 明暗处理:先插值得到法向量,再带入光照模型计算得到光亮度颜色;
- Phong shading处理过程中,计算顶点在CPU中,双线性插值计算其法向发生在光栅化阶段;
- 在Fragment operation阶段计算片元得光亮度;
- 前两者是顶点级得光照计算,而Phong shading则是像素级别得光照计算;
1.9 其他明暗处理方法
- 可以通过凹凸纹理来指定每个像素的法向或者高度值;如下中间的凹凸纹理,作用于一个面片的效果,可以产生凹凸不平的效果;
1.20 OpenGL中只支持常数明暗处理和Gouraud 明暗处理,Phong Shading需要shader编程实现。
- GL_FLAT:常数明暗处理;
- GL_SMOOTH:采用Gouraud明暗处理;
glShadeModel(GLenum mode);