[6].开启Opengl的深度测试把

2020-07-10  本文已影响0人  NealDN

跳去目录


(这里需要先完成demo5


深度缓冲(Depth buffer)

深度缓冲,也被叫做Z-缓冲,是用来存储图形所有片段的深度信息,在进行3D图形的绘制时,每当计算一个图形片段,GLEW便会自动生成一个深度作为这个片段的Z值(深度),而当这个片段将要被渲染时,OpenGL会将这个片段的深度与Z-深度进行比较,通过比较,如果这个片段在其他片段的后面,那么这个片段将会被丢弃,不再渲染,也就不会再出现在屏幕上,反之,则渲染在屏幕上。

上述的这个过程称之为深度测试(Depth Testing)

(话说外国人的取名思路真是新奇 0.0)

深度测试(Depth Testing)

​ 在OpenGL中,深度测试是默认关闭的(即在上下文深度测试是关闭的属性),如果想要使用深度测试的功能,需要瘦瘦去打开它

glEnable(GL_DEPTH_TEST);

​ 也正因为开启了深度测试,所以在重新渲染其他图形之前,我们需要清空深度缓冲区中间的数据,不然后续的深度测试会有影响.

glClear(GL_DEPTH_BUFFER_BIT);

深度缓冲区中的每一个缓冲都是有有精度的,通常,深度缓冲的精度以16、24、32位的float形式进行存储,一般情况下,都是以24位的精度进行存储的。在早期的游戏中,是以16位的精度进行存储的,这样会产生一个问题,当画面数据过于庞大时,深度缓冲区中的缓存值会存在相同的数据(数据特别大的时候),这时候OpenGL就不再能分辨正面背面,而产生类似于穿模的状况,这时候提升精度就解决这个问题了。

​ 但是并不是精度越高就越好,精度越高,单个深度缓冲占据的空间就越大,处理起来就越复杂,对配置的要求就越高

深度测试函数

(在深度测试启用时,深度测试函数才会起效果。)

OpenGL在进行深度测试时,会通过特定的深度测试函数来进行数据的运算并更新深度缓冲,我们可以调用glDepthFunc函数来设置比较运算符(或者说深度函数(Depth Function)

//GL_ALWAYS 深度函数
glDepthFunc(GL_ALWAYS);

深度函数可以改为下表中的函数(实际上每个深度函数都是一系列的计函数计算)

深度函数

深度值精度

深度缓冲是由一系列0.0-1.0的深度值所构成的,这个值可以是投影平截头体的近平面(Near)和远平面(Far)之间的任何值,通过片段自身的z坐标与near和far,可以粗略的计算出这个片段的深度值,基于OpenGL,这个值位于0.0-1.0之间,F_{depth} = \frac{z - near}{far - near},这里的near和far是之前设置投影矩阵的时候设置的。

远近平面

但是这个公式是线性的,实际上几乎永远不会使用这样的数学模型,因为我们需要的是,在z离的很近的时候要提供足够的精度以供OpenGL渲染视图,在z离的很远的时候只需要很小的精度用于判断是否需要抹去,也就是需要设置为 \frac{1}{z} 的数学模型,因此,可以考虑将深度值的计算模型替换为 F_{depth} = \frac{1/z - 1/near}{1/far - 1/near} ,这样就能够满足我们的条件了。

深度冲突

深度冲突(Z-fighting)是指两个平面或三角形很紧密的平行排列在一起时(理解为重合吧),深度精度不足以去判断它们的深度,所以深度测试并不能判断哪个应该显示,哪个应该抹去,所表现出来的结果是,两个片段不断的重复交替出现消失(玩CS的小伙伴应该遇到过很多次了),这种现象并不能够完全的避免,就算是提高了精度值,在数据量足够庞大的时候依然有可能会出现这样的问题(就算1080的不够,还有2K,4K,甚至未来的8K,16K的游戏呢 =。=),对于这种情况,有一些技巧可以防止其产生。


跳去目录

上一篇下一篇

猜你喜欢

热点阅读