OpenGL

五、OpengGL 渲染技巧之深度测试 颜色混合

2020-07-10  本文已影响0人  夏天的枫_

正背面剔除一文中介绍了关于正背面剔除,却也引出了新的bug。这个bug的原因是这个游泳圈在绘制后,当发生旋转时,OpenGL无法分辨其重叠的部分是哪个图层靠近观察者,这就让OpenGL在旋转发生时绘制就错乱了。而这个问题可以通过深度测试来解决。

1.深度测试

在环境中还选择一个参考坐标系来描述摄像机和物体的位置,该坐标系称为世界坐标系。它是在三维坐标系之上建立的。

开启深度测试

glEnable(GL_DEPTH_TEST)
glDisable(GL_DEPTH_TEST)

深度测试的测试规则是可以通过glDepthFunc(FLenum func)来修改的,测试规则主要在于该函数的以下枚举值:

参数 说明
GL_ALWAYS 总是通过测试
GL_NEVER 总是不通过测试
GL_LESS 当前深度值 < 存储的深度值时通过
GL_EQUAL 当前深度值 = 存储的深度值时通过
GL_LEQUAL 当前深度值 <= 存储的深度值时通过
GL_GREATER 当前深度值 > 存储的深度值时通过
GL_NOTEQUAL 当前深度值 != 存储的深度值时通过
2.深度测试的潜在风险之 Z-Fighting(Z冲突or Z闪烁)问题

由于在开启深度测试后,OpenGL不会再去绘制模型被遮挡的部分,以使得实现的显示更加真实;但由于深度缓冲区的精度限制,图层Z值相差在精度之外时,就无法识别多图层or同一图层,显示出来的现象时交错闪烁两个图层。

3.解决Z-Fighting
/** 启用Polygon Offset 方式
* GL_POLYGON_OFFSET_POINT 对应模式:GL_POINT
* GL_POLYGON_OFFSET_LINE 对应模式:GL_LINE
* GL_POLYGON_OFFSET_FILL 对应模式:GL_FILL
*/
glEnable(GL_POLYGON_OFFSET_FILL)

4.预防Z-Fighting闪烁
5.颜色混合

我们把OpenGL 渲染时会把颜色值存在颜色缓存区中,每个片段的深度值也是放在深度缓冲区。当深
度缓冲区被关闭时,新的颜色将简单的覆盖原来颜色缓存区存在的颜色值,当深度缓冲区再次打开时,新
的颜色片段只是当它们比原来的值更接近邻近的裁剪平面才会替换原来的颜色片段.
那么如果开启深度测试后.但是2个重叠的图层中, 有亿个图层是半透明的. 有亿个图层是非半透明的.
那么此时就不能进行单纯的比较深度值,然后进行覆盖. 而是需要将2个图层的颜色进行混合;

// 开启混合
glEnable(GL_BLEND)
// 关闭混合
glDisable(GL_BLEND)

目标颜色:已经存储在颜色缓存区的颜色值
源颜色:作为当前渲染命令结果进入颜色缓存区的颜色值

固定着色器/可编程着色器,打开混合开关的方式使得颜色混合(单纯的2个图层重叠进行混合)
可编程着色器

颜色混合总结: 源颜色混合的alpha值越高,添加的源颜色成分越高,目标颜色所保留的成分就越少。混合函数经常用于实现其他一些不透明的物体前面绘制一个透明物体的效果。

上一篇 下一篇

猜你喜欢

热点阅读