OpenGL中的正背面剔除、深度测试与颜色混合

一.正背面剔除

圆环正面 图1


旋转后圆环 图2

//GLT_SHADER_DEFAULT_LIGHT 默认光源着色器

//模型视图矩阵

//投影矩阵

//基本颜色

shaderManager.UseStockShader(GLT_SHADER_DEFAULT_LIGHT,transformPipeline.GetModelViewMatrix,transformPipeline.GetProjectionMatrix(),vRed);


我们在绘制3D图形时,使用使用默认光源着色器渲染正常情况下看不出任何问题,但是经过我们旋转后会出现图2问题,这是为什么呢?其实这是因为在旋转过程中,我们不应该看到的东西,它被渲染出来了,所以需要让我们告诉它哪块不需要被渲染。这种情况就叫做“隐藏面消除”

在这之前,我们提到过油画算法,油画算法是什么?


图3

如图三,油画算法通俗来讲就是指,在绘制过程中,使用远小近大的原则一层一层的绘制出图层。


图4


但是类似图4的问题,我们可以通过油画算法来解决么?答案是不能的,所以我们需要使用正背面剔除。

正背面剔除是什么?

在3D图形中,我们如果以一个角度去观察这个3D图形,我们最多只能看到这个图形的三个面,那这样的话我们可以不去绘制背面的面,同时也可以节省片元着色器的性能。

图5

但随之而来的是我们怎么去判定正背面?

 在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);

你可能感兴趣的:(OpenGL中的正背面剔除、深度测试与颜色混合)