OpenGL--深度测试、多边形偏移以及颜色混合原理解析

2020-07-12  本文已影响0人  HardCabbage

一、深度测试

1.1 深度测试解决什么问题

1.2 什么是深度

1.3 深度缓存区

1.3.1什么是深度测试

1.4 深度缓存区相关操作流程

glClearColor(0.0f,0.0f,0.0f,1.0f); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glDisable(GL_DEPTH_TEST);
 glDepthFunc(GLEnum mode);
深度测试的判断模式
glDepthMask(GLBool value);
value : GL_TURE 开启深度缓冲区写⼊; 
GL_FALSE 关闭深度缓冲区写⼊

二、多边形偏移

2.1 引起Z-fighting (Z冲突.闪烁)的原因

因为开启深度测试后,OpenGL 就不会再去绘制模型被遮挡的部分,这样实现的显示更加真实;但是由于深度缓冲区精度的限制对于深度相差⾮常⼩的情况下,OpenGL 就可能出现不能正确判断两者的深度值的情况,就会导致深度测试的结果变得不可预测,显示出来的现象变成了交错闪烁的一个现象;如下图所示 Zfighting现象

前⾯2个画⾯会出现交错的现象,同一个位置上出现的图层并且深度值出现精度值很低的情况下,就会引起Z冲突、闪烁的现象。简单点来说就是当表示2个物体靠的⾮常的近的时候,OpenGL⽆法确定谁在前,谁在后的问题,从⽽出现显示歧义的问题。

2.2 如何解决Z-fighting的问题

既然是因为物体靠的太近,⽆法区分图层谁在前谁在后,那么这个时候,我们就可以在2个图层之间加⼊⼀个微妙的间隔,但是在添加间隔的时候如果是⼿动添加,会比较复杂且不精确。此时OpenGL 提供⼀个解决⽅案,多边形偏移来解决这个问题。

2.2.1 如何启用多边形偏移 Polygon Offset
如果两个图层之间本来就有间隔,是不是两个图层间就不会互相影响了呢?我们可以理解为,在执行深度测试功能之前,我们已经对立方体的深度值做了一些细微的增加,这样就可以将两个图层的深度值做到有所区分。
glEnable(GL_POLYGON_OFFSET_FILL);
//参数列表: 
//GL_POLYGON_OFFSET_POINT      对应模式: GL_POINT GL_POLYGON_OFFSET_LINE          对应模式: GL_LINE GL_POLYGON_OFFSET_FILL           对应模式: GL_FILL
glDisable(GL_POLYGON_OFFSET_FILL);
2.2.2 指定偏移量
2.2.3如何使用多边形偏移
glEnable(GL_POLYGON_OFFSET_FILL) 
//参数列表: 
//GL_POLYGON_OFFSET_POINT    对应光栅化模式: GL_POINT 
//GL_POLYGON_OFFSET_LINE       对应光栅化模式: GL_LINE 
//GL_POLYGON_OFFSET_FILL       对应光栅化模式: GL_FILL
glPolygonOffset(Glfloat factor,Glfloat units);
//一般设置factor和units为-1,-1
glDisable(GL_POLYGON_OFFSET_FILL);
2.2.4如何预防Z-fighting闪烁问题

三、颜色混合原理

3.1 为什么需要颜色混合

OpenGL在渲染的时候会把颜色值存储到颜色缓存区中,每个片段的深度值也会被放入深度缓存区中,当深度缓存区被关闭时候,新的颜色值将会覆盖原来的颜色缓存区中存在的颜色值,当深度缓存区再次打开的时候,新的颜色片段只是当他们比原来的值更接近临近的裁剪平面才会替换为原来的颜色片段。

3.2 颜色混合的流程

我们可以简单的将颜色混合流程表述为:

3.3颜色混合代码实现
glEnable(GL_BlEND);

当混合图层被开启的时候源颜⾊和⽬标颜⾊的组合⽅式是混合⽅程式控制的。在默认情况下,混合⽅程式如 下所示:

Cf = (Cs * S) + (Cd * D) 
Cf :最终计算参数的颜⾊ 
Cs : 源颜⾊ 
Cd :⽬标颜⾊ 
S:源混合因⼦  
D:⽬标混合因⼦
glBlendFunc(GLenum S,GLenum D);
S:   源混合因⼦
D:⽬标混合因⼦
 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

如果颜⾊缓存区已经有⼀种颜⾊红⾊(1.0f,0.0f,0.0f,0.0f)这个⽬标颜⾊Cd,如果在这上⾯⽤⼀种 alpha0.6的蓝⾊(0.0f,0.0f,1.0f,0.6f)
Cd (⽬标颜⾊) = (1.0f,0.0f,0.0f,0.0f);
Cs (源颜⾊) = (0.0f,0.0f,1.0f,0.6f);
S = 源alpha值 = 0.6f
D = 1 - 源alpha值= 1-0.6f = 0.4f
⽅程式Cf = (Cs * S) + (Cd * D)
那么这两种颜色混合的结果就等价于(Blue * 0.6f) + (Red * 0.4f)
总结:上面的例子最终颜⾊是以原先的红⾊(⽬标颜⾊)与 后来的蓝⾊(源颜⾊)进⾏组合。 源颜⾊的alpha值越⾼,添加的蓝⾊颜⾊成分越⾼,⽬标颜⾊所保留的成分就会越少。混合函数经常⽤于实现在其他⼀些不透明的物体前⾯绘制⼀个透明物体的效果

3.3修改颜⾊混合⽅程式

我们知道颜色混合默认的方程式为Cf = (Cs * S) + (Cd * D),那么我们有没有可能对这个方程式进行修改呢?答案是肯定可以的,下面就来说说如何修改颜色的混合方程式,OpenGL给我们提供了5个不同的方程式进行选择,并且提供了混合方程式选择的函数glbBlendEquation(GLenum mode);,我们可以根据下面的表格来选择颜色混合的方程式。

可用的混合方程模式
上一篇下一篇

猜你喜欢

热点阅读