OpenGL3渲染技巧

渲染过程中遇到的问题

在绘制图形时,需要确定哪些部分是对观察者可见,哪些部分是对观察者不可见,对于不可见的部分需要及早舍弃,这种情况叫做隐藏面消除:”Hidden surface elimination“,当视图切换时候会出现一些问题,为了解决这个问题,提出了一种算法叫油画算法,先绘制离观察者远的内容,再绘制离观察者近的内容部分,但是油画算法性能差,还会出现无法确定远近的问题。

正背面剔除(FaceCulling)(策略 > 复杂计算)
绘制3D图像最多看到3个面,看不到的面绘制就显得多余,以某种方式丢弃这部分的数据,提高GPU的性能。

正背面剔除的做法:

1.需要确定某个面在观察者视野中不会出现
2.任何平面都有两个面,一个时刻只能看到一面。
OpenGL 可以做到检查所有正面朝向的观察者的面,并渲染他们,从而丢弃背面朝向的面,这样可以节约片元着色器的性能

OpenGL判断正面,背面的条件

    clockwise 顺时针
    counter_clockwise 逆时针

立体图形的正背面处理

1.开启和关闭表面剔除

void glEanable(GL_CULL_FACE)
void glDisable(GL_CULL_FACE)

2.用户选择剔除哪个面,mode的参数可以是GL_FRONT,GL_BACK,GLFRONT_AND_BACK,默认是GL_BACK背面剔除

void glCullFace(GLEnum mode)

3.用户指定绕序哪个为正面,mode参数为GL_CW,GL_CCW,默认是GL_CWW,默认GL_CWW逆时针为正面

void glFrontFace(GLEnum mode)

4.填充方式设置

glpolygonMode(GL_FRONT_AND_BACK,GL_FILL)
glPostRedisplay()

5.RenderScene中开启正背面剔除

glEnable(GL_CULLFACE)
glCullFace(GL_BACK)
glDisable(GLFullFace)
深度的解释

一个顶点在3D世界中距离观察者的距离z值,深度缓冲区就是一块内存区域,专门存储每个像素点的深度值,深度越大,离观察者越远。
深度缓冲区存在的必要性:在不使用深度测试的时候,如果先绘制一个距离较近的物体,再绘制一个距离较远的的物体,则距离较远的物体因为后绘制,所以会把前面的物体覆盖掉,有了深度缓冲区,绘制顺序就不那么重要了,只要存在深度缓冲区,OpenGL都会吧像素的深度值写入到缓冲区中,除非调用glDepthMask(GL_FALSE)来禁止写入

深度缓冲(DepthBuffer)和颜色缓冲区(ColorBuffer)是对应颜色缓冲区存储像素的颜色信息,深度缓冲区存储像素的深度信息,决定是否绘制一个物体表面时,将表面对应的像素深度值与当前深度缓冲区中的值进行比较,如果深度大于深度缓冲区中的深度,那么舍弃当前的颜色和深度,否则就使用这个像素的深度值和颜色值。分别更新深度缓冲区和颜色缓冲区,这个过程叫做深度测试

使用深度测试:

1.开启深度测试

gleanable(GL_DEPTH_TEST)

2.绘制场景前,清除颜色缓冲区,深度缓冲区

glClearColor(0.0f,0.0f,0.0f,0.0f)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

清除深度缓冲区默认值为1.0,表示最大深度值,深度值范围(0,1)之间,值越小表示越靠近观察者

3.指定深度测试判断模式

void glDepthFunc(GLEnum mode)

参数GL_LEQUAL 当前深度值 <= 存储深度值时通过

zFighting问题

当深度测试时候因为精确度导致深度相同,会造成闪烁问题,叫做zFighting,为了解决zFighting问题,使用了多边形偏移的方案。
Polygon Offset让深度产生间隔。启用流程

1.启用多边形偏移

glEnable(GL_PLOYGON_OFFSET_FILL)
//偏移方案需要对应光栅化的方式
//GL_POYGON_OFFSET_POINT GL_POINT
//GL_POYGON_OFFSET_LINE GL_LINE
//GL_POYGON_OFFSET_FILL GL_ILL

2.指定偏移量
Depth offset = (D2 * factor) + (r * units)
m:多边形的深度斜率的最大值,多边形越与近裁面平行,m值越接近0
r:能产生于窗口坐标系的深度值可分辨的差异最小值,r具体是由OpenGL平台指定7的一个常量,一个大于0的offset会把模型推到离观察者更近的位置
一般将-1.0和-1这样的值赋值给glPoygonOffset基本可以满足需求
应用到片段上总偏移量计算方式

3.关闭Polygon Offset

glDisable(GL_POLYGON_OFFSET_FILL)

预防zFighting的方案:
1.不要将两个物体靠的太近
2.将量将裁减面设置的离观察者远一点
3.使用更高位的深度缓冲区,默认24位,现在有些硬件可达到32位

混合

使用场景:带透明度的视图渲染方案就不能用深度测试了,需要用到颜色混合,还有就是在不透明的物体前面遮挡了一个透明的物体

组合颜色:
1.目标颜色:已经存储在颜色缓冲区的颜色值
2.源颜色:作为当前渲染民营结束进入颜色缓冲区的颜色值

当混合功能被启动时,源颜色和目标颜色的组合方式是混合方程式控制的。
Cf = Cs * S + Cd * D

Cf : 最终计算参数的颜色
Cs: 源颜色
Cd: 目标颜色
S:源演混合因子
D:目标混合因子
设置混合因子需要用到glBlendFun函数

glBlendFunc(GLEnum S,GLEnum D)
//glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)

1.启用混合的方式

gleEnable(GL_BIEND)

2.颜色混合功能不开启,不计算,默认初始化位黑色,可以修改。

glBlendCOlor(GLClampf red, GLClampf  green,GLClamf blue, GLClampf  alpha)
渲染甜甜圈的效果实现
ttq.gif

你可能感兴趣的:(OpenGL3渲染技巧)