美文网首页
OpenGL 渲染技巧-隐藏⾯消除问题解决

OpenGL 渲染技巧-隐藏⾯消除问题解决

作者: 懿轩加油 | 来源:发表于2019-05-16 17:42 被阅读0次
隐藏⾯消除

其实很直接的解释就是在绘制3D场景的时候,需要决定那部分是观察者能够看到的,那部分是观察者看不到的,对于不可见的部分,应该及时或则及早的丢弃,比如在一个不透明的大物体后面,就不应该被渲染,这种情况就叫做'隐藏面消除'(Hidden surface elimination).

Snip20190516_5.png
隐藏面消除的解决方案有哪些呢

1:油画算法
2:正背面剔除
3:深度测试(Z-buffer⽅法)

油画算法

先绘制场景中的离观察者较远的物体,再绘制较近的物体

Snip20190516_2.png 上面这个幅图的绘制顺序就是先绘制红色部分,再绘制黄色部分,最后再绘制灰色部分,这样就能达到解决隐藏面消除的问题
油画算法的弊端
使⽤用油画算法,只要将场景按照物理理距离观察者的距离远近排序,由远及近的绘制即可.那么会出现 什什么问题? 如果三个三⻆角形是叠加的情况,油画算法将⽆无法处理理
正背面剔除(Face Culling)

首先我们思考一些问题

1:尝试相信⼀个3D图形,你从任何⼀个方向去观察,最多可以看到⼏个⾯?
2:答案是,最多3面. 从一个⽴方体的任意位置和⽅向上看,你用过不可能看到多于3个⾯.
3:那么思考? 我们为何要多余的去绘制那根本看不到的3个⾯面?
4:如果我们能以某种⽅式去丢弃这部分数据,OpenGL 在渲染的性能即可提⾼超过50%.

那么问题又来了

1:如何知道某个面在观察者的视野中不会出现呢?
答: 1:任何平面都有2个⾯,正⾯/背⾯.意味着你⼀个时刻只能看到⼀⾯
2:OpenGL 可以做到检查所有正⾯朝向观察者的⾯,并渲染它们.从⽽丢 弃背⾯朝向的⾯. 这样可以 节约片元着⾊器的性能
2:如何告诉OpenGL你绘制的图形,那个是正面,那个是背面?
答:通过分析顶点数据的顺序

正背面

Snip20190516_10.png
其实正面背面也不是固定的,他其实不光跟定点连接顺序有关,还跟观察者的位置有关,所以正面和背面是由观察者和三角形定义顺序共同决定的
开启表⾯剔除(默认背⾯剔除)
void glEnable(GL_CULL_FACE);
关闭表⾯剔除(默认背⾯剔除)
void glDisable(GL_CULL_FACE);
⽤户选择剔除那个⾯面(正⾯/背⾯)
void glCullFace(GLenum mode);
mode参数为: GL_FRONT,GL_BACK,GL_FRONT_AND_BACK ,默认GL_BACK
用户指定环绕那个为正面
void glFrontFace(GLenum mode);
mode参数为: GL_CW,GL_CCW,默认值:GL_CCW
例如,剔除正⾯实现
glCullFace(GL_BACK); 
glFrontFace(GL_CW);

正背面消除法是解决了隐藏⾯消除问题,但是新的问题又产生了

Snip20190516_12.png 解决这个问题就要先了解深度
深度

1:什么是深度

深度其实就是该像素点在3D世界中距离摄像机的距离,Z值

2:什么是深度缓冲区

深度缓存区,就是⼀块内存区域,专⻔存储着每个像素点(绘制在屏幕上的)深度值.深度值(Z值)越⼤, 则离摄像机就越远

3:为什么需要深度缓冲区?

在不使⽤用深度测试的时候,如果我们先绘制⼀个距离⽐较近的物理,再绘制距离较远的物理,则距离 远的位图因为后绘制,会把距离近的物体覆盖掉. 有了深度缓冲区后,绘制物体的顺序就不那么􏰀 要的. 实际上,只要存在深度缓冲区,OpenGL 都会把像素的深度值写⼊到缓冲区中. 除⾮调⽤用glDepthMask(GL_FALSE).来禁⽌写⼊

Z-buffer⽅方法(深度缓冲区Depth-buffer)

深度测试

深度缓冲区(DepthBuffer)和颜⾊缓存区(ColorBuffer)是对应的.颜色缓存区存储像素的颜⾊信息,⽽深度缓冲区存储像素的深度信息. 在决定是否绘制⼀个物体表⾯时, ⾸先要将表⾯对应的像素的深度值与当前深度缓冲区中的值进行⽐较. 如果⼤于深度缓冲区中的值,则丢弃这部分.否则 利用这个像素对应的深度值和颜⾊值.分别更新深度缓冲区和颜⾊色缓存区. 这个过程称为”深度测试”

深度缓冲区,一般由窗⼝管理系统,GLFW创建.深度值一般由16位,24位,32位值表示. 通常是24位.位
数越高,深度精确度更好.
开启深度测试
glEnable(GL_DEPTH_TEST);
在绘制场景前,清除颜⾊缓存区,深度缓冲 glClearColor(0.0f,0.0f,0.0f,1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
清除深度缓冲区默认值为1.0,表示最⼤大的深度值,深度值的范围为(0,1)之间. 值越⼩小表示越靠近观察者,值越⼤大表示 越远离观察者

相关文章

  • OpenGL 渲染技巧-隐藏⾯消除问题解决

    隐藏⾯消除 其实很直接的解释就是在绘制3D场景的时候,需要决定那部分是观察者能够看到的,那部分是观察者看不到的,对...

  • OpenGL渲染技巧(隐藏面消除)

    首先先看一个图片 在绘制3D场景的时候,我们需要决定哪些部分是对观察者可⻅的,或者哪些部分是对观察者不可⻅的.对于...

  • 六、OpenGL 渲染技巧:深度测试、多边形偏移、 混合

    OpenGL + OpenGL ES +Metal 系列文章汇总 深度测试 在上一篇五、OpenGL 渲染技巧:正...

  • OpenGL 阐述隐藏面消除解决方案

    OpenGL 阐述隐藏面消除解决方案 在OpenGL中如果没有设置隐藏背面,就会出现下面这种情况,正面红色和背面黑...

  • 四、OpenGL渲染技巧之圆环面绘制及隐藏面消除

    绘制游泳圈 前提准备一个OpenGL的工程 1.在OpenGL绘制立体3D图形——Torus主要用的的函数绘制游泳...

  • OpenGL渲染技巧

      在OpenGL渲染中, 我们会碰到各种各样的问题,所以也会对应的产生各种各样的渲染技巧,接下来就介绍我们最经常...

  • OpenGL渲染技巧

    1、渲染过程产⽣的问题 在绘制3D场景的时候,我们需要决定哪些部分是对观察者 可见的,或者哪些部分是对观察者不可⻅...

  • OpenGL渲染技巧

    1、隐藏面消除 在渲染3D场景过程中可能会产生以下问题 我们需要决定哪些部分是对观察者可⻅的,或者哪些部分是对观察...

  • OpenGL渲染技巧

    OpenGL渲染技巧 了解了OpenGL的渲染流程和常用API后,就可以简单的绘制出图形了。但是在绘制中可能会碰到...

  • OpenGL渲染技巧

    首先,我们来绘制一个3D图形“甜甜圈”,示例程序运行效果如下: 咋看,似乎没什么问题。但当我们试着向右旋转它的时候...

网友评论

      本文标题:OpenGL 渲染技巧-隐藏⾯消除问题解决

      本文链接:https://www.haomeiwen.com/subject/vsibaqtx.html