4、OpenGL 深度测试、多边形偏移、颜色混合问题

2020-08-11  本文已影响0人  代码之道

一、深度测试 2251862-b36d5f3113c5c678.gif

图中可以看出,在甜甜圈旋转过程中,前后两部分重叠时,出现了缺口,原因是OpenGL并不能清楚的区分两个图层哪个显示在前,哪个显示在后面,由此导致了甜甜圈缺口问题。

那么如何解决这个问题呢 ?

先来了解几个概念

1. 深度
深度是指OpenGL坐标系中,像素点的 Z 坐标距离观察者的距离。

深度与图形像素点的Z坐标的关系:

2. 深度缓冲区
深度缓冲区是一块专门的内存区域,存储在显存中,储存屏幕上所绘制图形的每个像素点的深度值。将深度值与屏幕上每个像素点进行一一对应,然后将深度值存储在深度缓冲区。深度缓冲区的范围是[0,1],默认值是1.0,表示深度值得最大值。在深度缓冲区中每个像素只会记录一个深度值。

3. 深度测试
一个物体在绘制时,像素点的深度值需要与深度缓存中已经存在的深度值作比较,如果新值 > 旧值,则丢弃这部分不绘制,反之将新的深度值更新至深度缓冲区,由于深度缓冲区与颜色缓冲区是一一对应的,同时也需要更新该像素点的颜色值到颜色缓冲区,这个过程就是深度测试。

我们利用深度测试可以解决甜甜圈缺口的问题。首先开启 glEnable(GL_DEPTH_TEST),用于新旧深度值的对比,决定像素点是绘制还是丢弃。流程图如下:

2251862-5bf801f5a9296349.png

4. 隐藏面消除方案

二、多边形偏移:也称Z-Fight(Z冲突,闪烁)问题

开启深度测试之后,由于深度缓冲区精度有限制,导致深度值在误差极小时,OpenGl出现无法判断的情况,画面出现交错闪现的现象。

由于图形靠的太近,导致无法区分出图层的先后次序,针对该问题,OpenGL提供了一种多边形偏移(Polygon offset)方案

使用多边形偏移分三步:

  1. 开启多边形偏移 glEnable(GL_POLYGON_OFFSET_FILL)
  2. 指定偏移量 glPolygonOffset(GLfloat factor, GLfloat units)
  3. 关闭多边形偏移 glDisable(GL_POLYGON_OFFSET_FILL)

三、颜色混合

当开启深度测试后,两个重叠的图层中,如果上面图层是半透明的,另一个是非半透明的,此时就不能通过深度值比较来进行颜色值得覆盖,而是需要将两个颜色值进行混合,然后存入颜色缓冲区

颜色混合的两种方式:

  1. 开关方式
    glEnable(GL_BLEND)开启,glDisable(GL_BLEND)关闭

  2. 开关方式+混合方程式
    用于处理类似滤镜效果的场景,简单描述就是将需要处理的图片颜色和图片上覆盖的半透明颜色进行混合,单纯的混合已经不能满足我们的需求,这时借助混合方程式来实现两股颜色的混合

glEnable(GL_BlEND);
//设置混合因子--默认值是 GL_SRC_ALPHA 和 GL_ONE_MINUS_SRC_ALPHA
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
//关闭
glDisable(GL_BlEND);

在glBlendFunc方法中,是通过混合方程式来得到颜色的组合,默认情况下混合方程式如下所示

//Cd:源颜色 -- 当前渲染命令传入的颜色值
//CS:目标颜色 -- 颜色缓冲区中已经存在的颜色值
//S:源混合因子
//D:目标混合因子 
Cf = (Cs * S) + (Cd * D)
上一篇 下一篇

猜你喜欢

热点阅读