美文网首页
浅谈OpenGL图像渲染中的深度缓冲区

浅谈OpenGL图像渲染中的深度缓冲区

作者: 我是卖报的小行家 | 来源:发表于2020-07-10 12:02 被阅读0次

一.About深度
*什么是深度?
深度其实就是该像素点在3D世界中距离摄像机的距离,Z值
*什么是深度缓冲区?
深度缓存区,就是⼀块内存区域,专⻔存储着每个像素点(绘制在屏幕上的)深度值.深度值(Z值)越⼤,
则离摄像机就越远。
*为什么需要深度缓冲区?
在不使⽤深度测试的时候,如果我们先绘制⼀个距离⽐较近的物理,再绘制距离较远的物理,则距离
远的位图因为后绘制,会把距离近的物体覆盖掉. 有了深度缓冲区后,绘制物体的顺序就不那么重
要的. 实际上,只要存在深度缓冲区,OpenGL 都会把像素的深度值写⼊到缓冲区中. 除⾮调⽤
glDepthMask(GL_FALSE).来禁⽌写⼊。


截屏2020-07-10 下午12.01.17.png

深度值计算
深度值⼀般由16位,24位或者32位值表示,通常是24位。位数越⾼的话,深度的精确度越
好。深度值的范围在[0,1]之间,值越⼩表示越靠近观察者,值越⼤表示远离观察者。
• 深度缓冲主要是通过计算深度值来⽐较⼤⼩,在深度缓冲区中包含深度值介于0.0和1.0之间,
从观察者看到其内容与场景中的所有对象的 z 值进⾏了⽐较。这些视图空间中的 z 值可以在投
影平头截体的近平⾯和远平⾯之间的任何值。我们因此需要⼀些⽅法来转换这些视图空间 z 值 到 [0,1] 的范围内,下⾯的 (线性) ⽅程把 z 值转换为 0.0 和 1.0 之间的值 :
far和near是提供到投影矩阵设置可⻅视图截锥的远近值


far和near是提供到投影矩阵设置可见视图截锥的远近值

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

非线性深度缓存
⽅程带内锥截体的深度值 z,并将其转换到 [0,1] 范围。在下⾯的图给出 z 值和其相应的深度值的关系:



在实践中是可以减少使⽤这样的线性深度缓冲区。正确的投影特性的⾮线性深度⽅程是和1/z成正⽐的 ,由于⾮线性函数是和 1/z 成正⽐,例如1.0 和 2.0 之间的 z 值,将变为 1.0 到 0.5之间, 这样在z⾮常⼩的时候给了我们很⾼的精度。⽅程如下所示



要记住的᯿要⼀点是在深度缓冲区的值不是线性的屏幕空间 (它们在视图空间投影矩阵应⽤之前是线性)。值为 0.5 在深度缓冲区并不意味着该对象的 z 值是投影平头截体的中间;顶点的 z 值是实际上相当接近近平⾯!你可以看到 z 值和产⽣深度缓冲区的值在下列图中的⾮线性关系。

屏幕空间的深度值是⾮线性如他们在z很⼩的时候有很⾼的精度,较⼤的 z 值有较低的精度。该⽚段的深度值会迅速增加,所以⼏乎所有顶点的深度值接近 1.0。如果我们⼩⼼的靠近物体,你最终可能会看到的⾊彩越来越暗,意味着它们的 z 值越来越⼩,这清楚地表明深度值的⾮线性特性。近的物体相对远的物体对的深度值⽐对象较⼤的影响。只移动⼏英⼨就能让暗⾊完全变亮。
但是我们可以让深度值变换回线性。要实现这⼀⽬标我们需要让点应⽤投影变换逆的逆变换,成为单独的深度值的过程。这意味着我们必须⾸先重新变换范围 [0,1] 中的深度值为单位化的设备坐标(normalized device coordinates)范围内 [-1,1] (裁剪空间(clip space))。然后,我们想要反转⾮线性⽅程 :


⾮线性还原线性[0,1]

//⽚元着⾊器
out vec4 color;
float LinearizeDepth(float depth)
{
 float near = 0.1;
 float far = 100.0;
 float z = depth * 2.0 - 1.0; // Back to NDC
 return (2.0 * near) / (far + near - z * (far - near));
}
void main()
{
 float depth = LinearizeDepth(gl_FragCoord.z);
 color = vec4(vec3(depth), 1.0f); 

使用深度测试

• 深度缓冲区,⼀般由窗⼝管理系统,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)之间. 值越⼩表示越靠近观察者,值越⼤表示越远离观察者。

指定深度测试判断式

void glDepthFunc(GLEnum mode);

打开/阻断 深度缓存区写⼊

void glDepthMask(GLBool value); 
value : GL_TURE 开启深度缓冲区写⼊; GL_FALSE 关闭深度缓冲区写⼊

相关文章

  • OpenGL 基础渲染(颜色混合)

    OpenGL 混合 OpenGL渲染时会把颜色值存在颜色缓存区中,每个片段的深度值也是放在深度缓冲区。当深度缓冲区...

  • 浅谈OpenGL图像渲染中的深度缓冲区

    一.About深度*什么是深度?深度其实就是该像素点在3D世界中距离摄像机的距离,Z值*什么是深度缓冲区?深度缓存...

  • 四.OpenGL 颜色混合

    我们把OpenGL 渲染时会把颜⾊值存在颜色缓存区中,每个片段的深度值也是放在深度缓冲区。当深度 缓冲区被关闭时,...

  • OpenGL颜色混合

    OpenGL 渲染时会把颜⾊值存在颜⾊缓存区中,每个⽚元的深度值也是放在深度缓冲区。当深度缓冲区被关闭时,新的颜⾊...

  • 3.5 颜色混合

    我们把OpenGL渲染时会把颜⾊色值存在颜⾊缓存区中,每个片段的深度值也是放在深度缓冲区。当深度 缓冲区被关闭时,...

  • OpenGL 颜色混合

    我们把OpenGL 渲染时会把颜⾊值存在颜⾊缓存区中,每个⽚段的深度值也是放在深度缓冲区。当深度缓冲区被关闭时,新...

  • OpenGL-颜色混合

    在一般情况下,OpenGL在渲染时把颜色值存放在颜色缓冲区中,把每个片段(像素)的深度值存放在深度缓冲区中。当深度...

  • OpenGL的绘制

    OpenGL渲染图像 OpenGL渲染图像需要执行的操作从OpenGL的几何图元中设置数据,用于构建形状。使用不同...

  • OpenGL图形图像渲染中的深度缓冲区

    什么是深度? 深度其实就是该像素点在3D世界中距离摄像机的距离,即Z值。 什么是深度缓冲区? 深度缓存区,就是一块...

  • OpenGL图形图像渲染中的深度缓冲区

    什么是深度?深度其实就是该像素点在3D世界中距离摄像机的距离,即Z值。 什么是深度缓冲区?深度缓存区,就是一块内存...

网友评论

      本文标题:浅谈OpenGL图像渲染中的深度缓冲区

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