一.正背面剔除
//GLT_SHADER_DEFAULT_LIGHT 默认光源着色器
//模型视图矩阵
//投影矩阵
//基本颜色
shaderManager.UseStockShader(GLT_SHADER_DEFAULT_LIGHT,transformPipeline.GetModelViewMatrix,transformPipeline.GetProjectionMatrix(),vRed);
我们在绘制3D图形时,使用使用默认光源着色器渲染正常情况下看不出任何问题,但是经过我们旋转后会出现图2问题,这是为什么呢?其实这是因为在旋转过程中,我们不应该看到的东西,它被渲染出来了,所以需要让我们告诉它哪块不需要被渲染。这种情况就叫做“隐藏面消除”。
在这之前,我们提到过油画算法,油画算法是什么?
如图三,油画算法通俗来讲就是指,在绘制过程中,使用远小近大的原则一层一层的绘制出图层。
但是类似图4的问题,我们可以通过油画算法来解决么?答案是不能的,所以我们需要使用正背面剔除。
正背面剔除是什么?
在3D图形中,我们如果以一个角度去观察这个3D图形,我们最多只能看到这个图形的三个面,那这样的话我们可以不去绘制背面的面,同时也可以节省片元着色器的性能。
但随之而来的是我们怎么去判定正背面?
在OpenGL中,是由三角形来绘制图形的,那在3D环境中,OpenGL规定:
顺时针旋转绘制顶点的三角形是背面三角形。
逆时针旋转绘制顶点的三角形是正面三角形。
由此我们可以知道,配合上camera 与顺逆三角形就可以判定哪个是正面,哪个是背面。
所以我们开启下面
开启表面剔除(默认背面剔除)
void glEnable(GL_CULL_FACE);
用户选择剔除那个面
mode参数:GL_FRONT,GL_BACK,GL_FRONT_AND_BACK
void glCullFace(GLenum mode);
例如:
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
二.深度测试
在开启正背面剔除后,出现了上述问题,这个问题的出现时因为我们在旋转过程中,重叠部分,OpenGL不清楚是应该显示哪个一块,所以我们引入了深度测试
深度:深度就是在OpenGL坐标系中,像素点Z坐标距离观察者的距离。
如果观察者在Z轴的正方向,Z值越大则靠近观察者;
如果观察者在Z轴的反方向,Z值越大则远离观察者;
所以我们可以根据哪个图层离观察者近,就显示哪个。
//开启深度测试
glEnable(GL_DEPTH_TEST);
但是同时,我们开启深度测试后会出现Z-Fighting闪烁问题,什么是Z-Fighting闪烁?
如上图,在深度测试缓存中,两个图层靠的太近的话,受限于深度的精度问题,可能会默认为两个图层在同一深度,这样的话OpenGL就分不出来谁先谁后,这样就会出现Z-Fighting闪烁。那出现这个问题后我们怎么去解决呢?
在两个图层中增加一个间隔即可解决Z-Fighting闪烁问题,这个方式叫做“多边形偏移”
//启用Polygon Offset
glEnable(GL_POLYGON_OFFSET_FILL);
三.颜色混合
对于两个颜色混合的时候遵循如下方程式:
Cf = (Cs * S) + (Cd * D)
Cf :最终计算的颜色
Cs:源颜色(将要存入的颜色值)离观察者近的颜色
S:源混合因子 (源alpha值 )
Cd:目标颜色(已经存入的颜色值)
D:目标混合因子 (1-源alpha值)
//开启混合
glEnable(BL_BIEND);