OpenGL学习笔记(十四)深度测试

深度测试,就是unity中的层级,就是说定义他的层级,这样才不会出现多余的渲染或不需要的图形。
其实就是根据Z轴上的值,来判断哪些片段被抛弃。
其实前面我们已经使用过深度测试了,就是下面这句代码

	glEnable(GL_DEPTH_TEST);

使用这句代码就能开启深度测试。
我们来复习一下:
这是没有开深度测试的效果图:
在这里插入图片描述
这是开了深度测试的效果图:
在这里插入图片描述
然后还有一句,禁止更新深度缓存区的代码,只是用了这句代码,我的程序就一片背景色,我也没办法得知到底是为啥:

glDepthMask(GL_FALSE);

在这里插入图片描述
接下来就是glDepthFunc()了。
其有一堆的设置:

glDepthFunc(GL_ALWAYS);//总是通过深度测试,就是全部通过,跟没开一样,参考一号图

	glDepthFunc(GL_LESS);//当片段深度小于深度缓冲区中的值时,通过测试,其实就是默认开启时的设置,参考二号图

	glDepthFunc(GL_NEVER);//永远不能通过测试,就是一片背景色呗。一块三角形都没有渲染出来。参考三号图


  	glDepthFunc(GL_EQUAL);//需要片段深度与深度缓冲区中的值相等时通过测试,参考三号图

    glDepthFunc(GL_LEQUAL);//需要片段深度与深度缓冲区中的值小于相等时通过测试,参考二号图

	glDepthFunc(GL_GREATER);//需要片段深度大于深度缓冲区中的值时通过测试,参考三号图

	glDepthFunc(GL_NOTEQUAL);//需要片段深度与深度缓冲区中的值不相等时通过测试,参考一号图

	glDepthFunc(GL_GEQUAL);//需要片段深度大于等于深度缓冲区中的值时通过测试,参考三号图
深度值精度:就是我们将观察空间中Z轴的,通过一种方式转换到0到1之间,所给计算的精度。
当其比较近的时候,他的精度要求也就高,远了要就应该低一些,所以我们不能使用线性的函数,
而应该选用非线性的函数。


重要的是要记住深度缓冲中的值在屏幕空间中不是线性的(在透视矩阵应用之前在观察空间中是线性的)。深度缓冲中0.5的值并不代表着物体的z值是位于平截头体的中间了,这个顶点的z值实际上非常接近近平面!

下面是深度测试的可视化:
先将FragmentSource.frag的最后一句改一下:

    FragColor = vec4(vec3(gl_FragCoord.z), 1.0);

在这里插入图片描述
我们就能够发现所有的正方体都变成了白色,这是因为屏幕空间中的深度值时非线性的,在z值较小时,精度很高,但z值较大时,精度就并不高。所以当距离拉远时,屏幕空间中的深度值,也就全部都是接近于1的。而当你拉近视角时,你就能够看见正方体的白色变暗了,这就是其深度值的变化。
如下图:
在这里插入图片描述
因此我们需要的是从屏幕空间【0,1】转换到我们的裁剪空间【-1,1】,再逆转投影矩阵,得到我们要的线性深度值。
之后将片段着色器改成这样。

#version 330 core
out vec4 FragColor;
float near = 0.1; 
float far  = 100.0; 

float LinearizeDepth(float depth) 
{
    float z = depth * 2.0 - 1.0; // 将屏幕空间的值转到裁剪空间
    return (2.0 * near * far) / (far + near - z * (far - near));    //逆转投影矩阵,具体的推导我不想了解,需要的时候再去了解吧
}

void main()
{             
    float depth = LinearizeDepth(gl_FragCoord.z) / far; // 为了演示除以 far
    FragColor = vec4(vec3(depth), 1.0);
}

我们就得到了下面这个效果图:
在这里插入图片描述
我们可以看到越近的正方体的颜色越深,也代表这他们的值越小。

还有就是当深度测试时,两个贴图靠的太近时,因为其深度值太过接近,所以就有可能出现贴图重叠的情况。
在这里插入图片描述

记录一下,深度测试时的深度冲突的防止方法。
第一个也是最重要的技巧是永远不要把多个物体摆得太靠近,以至于它们的一些三角形会重叠
第二个技巧是尽可能将近平面设置远一些
另外一个很好的技巧是牺牲一些性能,使用更高精度的深度缓冲

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值