一步步学习计算机视觉in IOS(三)OpenGL渲染-3D遮盖问题处理

image.png

在绘制3D场景时,为了尽可能的逼真需要有近大远小的效果,而且可能会出现互相遮盖的情况。

image.png

对于OpenGL中渲染的多边形而言,遮盖的问题同样存在,一个物体在光照下是有两面的:阳面(光照覆盖的面)和阴面(背光的面),上图中黄色部分就是我们理解的阳面,黑色即为阴面,但是上图的甜甜圈
看起来特别奇怪,本该显示阳面的部分确显示了阴面。OpenGL需要判断当前需要展示的渲染数据。

如果我们不进行判断,那么OpenGL不知道该显示哪些界面,只根据绘制的先后顺序决定显示结果,就会导致本来是观察者不应该看到且该丢弃部分,不仅看到了,而且没有将隐藏部分丢弃。

不进行判断的后果

下面让我们使用lines图元来看下为何会黑化。


image.png
image.png

在渲染系统中,各种复杂的图像都是由普通的三角形组成的。因为我们没有处理覆盖问题,OpenGL不知道1和2两个图元的渲染顺序,导致图元2中的黑色元素替换了1中的元素,出现黑色。

正背面剔除

那么,如果OpenGL可以做到检查所有正面朝向观察者的面,可以轻松地获取渲染顺序。此外,背后朝向的面则不再渲染,也可以节约片元着色器的性能。

OpenGL是通过分析顶点顺序来区分正背面的,默认情况下是按照逆时针顶点连接顺序的三⻆形⾯为正面,按照顺时针顶点连接顺序的三角形⾯为背面。

image.png

那么,我们只要渲染正面图元1,不渲染反面图元2,就可以得到正确的渲染数据。

但是,有没有可能相互覆盖的图元都是正面的呢?这也是有可能的。

1
2

如上图所示,图1中的两块图元区域都是正面的,如果旋转到这两块区域重叠,那么正背面剔除法是无法解决的。

image.png

深度混合

就上图的情况,如何渲染是依赖于观察者的。对观察者而言,离观察者更近的区域应该渲染。那么如何定义渲染物体与观察者的距离呢?为了解决这个问题,就需要引入深度以及深度缓冲区的概念:

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

深度与图形中像素点的Z坐标有如下关系:
如果观察者在Z轴的正方向,Z值越大则越靠近观察者
如果观察者在Z轴的负方向,Z值越小则越靠近观察者

  • 深度缓冲区是用来存储绘制到屏幕上每一个像素点的深度信息的—块内存缓冲区。它为每个像素存储一个深度值(z值),深度缓冲区的大小和颜色缓冲区(Frame Buffer)的大小一致。

在代码中,我们此次刷新时都要清空的数据中,就有深度缓冲区:

 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

深度测试

一个物体在绘制时,像素点新的深度值需要与深度缓存中已经存在的深度值作比较,如果 新值 > 旧值,说明该像素点离观察者较远,丢弃新像素不绘制,反之,将新的深度值更新至深度缓存区,绘制新像素

Z-Fighting(Z冲突,闪烁)问题

深度测试中比对了像素的Z值,那么如果Z值相等,或者说差值极小呢?这就会带来Z-Fighting问题。

image.png

其问题产生的主要原因是由于图形靠的太近,导致无法区分出图层先后次序,针对该问题,OpenGL提供了一种多边形偏移(Polygon Offset)方案,让深度值之间产生间隔,避免干涉。

//开启Polygon Offset
glEnable(GL_POLYGON_OFFSET_FILL)
//指定偏移量
//参数一般填 -1 和 -1
glPolygonOffset (GLfloat factor, GLfloat units);
// 关闭Polygon Offset
glDisable(GL_POLYGON_OFFSET_FILL);

混合

在深度测试中,我们直接用深度较浅的图元的渲染数据替换了之前的渲染数据,但是如果我们想让遮盖的新图元透明,那么就需要进行颜色混合了。

OpenGL渲染时会把颜色值存在颜⾊缓存区中,每个⽚段的深度值也是放在深度缓冲区。

  • 当深度缓冲区被关闭时,新的颜色将简单地覆盖原来颜色缓存区存在的颜色值。
  • 当深度缓冲区再次打开时,新的颜⾊片段只是当它们比原来的值更接近邻近的裁剪平⾯才会替换原来的颜⾊片段。
//开启混合
gl_Enable(GL_BIEND);
  • ⽬标颜色:已经存储在颜色缓存区的颜色值 (已经存在的颜色,旧颜色)
  • 源颜色:作为当前渲染命令结果进入颜色缓存区的颜⾊值 (新进来的颜色 ,新颜色)
    混合后的颜色有颜色方程式决定:
//Cf: 最终计算参数的颜⾊
//Cs: 源颜⾊
//Cd: 目标颜⾊
//S: 源混合因⼦,源Alpha混合因子
//D: ⽬标混合因⼦,⽬标Alpha混合因子
Cf = (Cs * S) + (Cd * D);
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352