OpenGL 浅析隐藏面消除

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情


今天我们,简单聊一聊关于在绘制3D场景的时候,可能会产生的渲染问题,以及在解决渲染问题时所使用的隐藏面消失的内容。

问题如下图所示:

在绘制好的3D图形中,我们做旋转操作后,会有部分黑色的情况:

未命名.png

因为我们在使用OpenGL渲染时,都是通过三角形拼接显示出来的, 默认会将观察者能看到的和不能看到的角度,全部绘制出来;然而,观察者不能看到的部分应该及早的丢弃掉,而实际上,那些不应该被我们看到的背面,也渲染并被我们看到,就会导致部分内容存在渲染问题。所以,我们应该将不可见的部分丢弃掉,不做渲染,这中情况叫做 “隐藏面消除”(Hidden surface elimination)


油画算法:

  • 先绘制场景中的离观察者较远的物体,再绘制较近的物体.
  • 例例如下⾯面的图例例: 先绘制红⾊色部分,再绘制⻩黄⾊色部分,最后再绘制灰⾊色部分,即可解决隐藏⾯面消除的问题

未命名.png

就是对这些三角形进行排序,并且首先渲染那些比较远的三角形,再在它们上分渲染那么较近的三角形.

油画算法 存在的问题

未命名3.png

这种方法在计算机图形处理中是非常低效的;
1、 我们必须对任何发生几何图形重叠的地方每个像素进行2次写操作,而在存储其中进行写操作会使速度变慢;
2、对独立三角形进行排序的开销过高。
3、油画算法有瓶颈期,比如绘制图像交叠时,没有明确的先后顺序就无从下手绘制了。

正背面剔除(Face Culling)

  • 尝试想想一个3D图形,你从任何一个方向去观察,最多可以看到几个面?
  • 答案是,最多3面.从一个立方体的任意位置和方向上看,你用过不可能看到多于3个面.
  • 那么思考?我们为何要多余的去绘制那根本看不到的3个面?
  • 如果我们能以某种方式去丟弃这部分数据,OpenGL 在渲染的性能即可提高超过50%。
  • 如何知道某个面在观察者的视野中不会出现?
  • 任何平面都有连个面: 正面/背面, 意味着一个时刻,我们只能看到一个面;
  • OpenGL 可以做到检查所有正面朝向观察者的面,并渲染它们-从而丢弃背面朝向的面.这样可以节约片元着色器的性能;
  • 通过分析顶点数据的顺序 我们可以知道绘制的图形中,哪个面时正面,哪个面时反面。

分析顶点顺序.001.png

OpenGL语法

//1.开启正背面剔除
glEnable(GL_CULL_FACE);
//2.关闭正背面剔除
glDisable(GL_CULL_FACE);
//3. 指定剔除面:mode GL_FRONT  GL_BACK GL_FRONT_AND_BACK 
void glCullFace(GLenum mode);
复制代码

猜你喜欢

转载自juejin.im/post/7104286169180930055