openGL深度冲突z-fighting
openGL系列文章目录
文章目录
- openGL系列文章目录
- 前言
- 一、为什么会产生z-fighting
- 二、防止深度冲突
- 1.第一种方法
- 2.第二种方法
- 3.第三种方法
- 参考
前言
针对z-fighting从问题的描述,到为什么会产生z-fighting现象,在继而从投影矩阵的的角度来解释这个问题的发生以及解决,最后稍微介绍一下深度值的非线性与线性的转换所能应用的渲染场景。如有不妥欢迎留言,如果读者觉得我的文章对自己有益,还望推荐给自己的朋友,感激不尽。
开启深度测试后OpenGL就不会再去绘制模型被遮挡的部分,这样实现的显示画面更为真实,但是由于深度缓冲区精度的限制,对于深度相差非常小的情况(例如在同一平面上进行两次绘制),OpenGL就不能正确判定两者的深度值,会导致深度测试的结果不可预测,显示出来的现象时交错闪烁的前后两个画面,这种情况称为z-fighting。
下面我将从这几个方向进行阐述z-fighting的前世今生
1.z-fighting问题的描述
2.为什么会产生z-fighting现象?
3.从透视投影矩阵的角度解释以及如何避免
4.深度值的非线性与线性的转化
一、为什么会产生z-fighting
z-fighting问题的描述
首先来讲一下,我们在进行三维渲染物体的时候,一般都是采用透视投影矩阵这样会产生近大远小的效果,很符合现实中人眼观看世界的情况。但是渲染中经常会遇到场景中离视点较远的物体会有闪烁的现象,而场景中离视点比较近的地方反而很少会长生物体闪烁的现象。
这是为什么那?
而如果我们换用了正交投影矩阵后,闪烁的问题会极大的解决,这又是为什么那?
为什么会产生z-fighting现象?
第一点原因
场景中渲染多个三维物体的时候,几个三维物体的摆放位置有点接近,导致在深度缓冲测试的时候,会产生精度的误差,然后会导致几个物体之间的片段值有的时候a通过,有的时候b通过,导致交替显示这几个物体的颜色值,然后那就会产生闪烁的现象。
第二点原因
采用透视投影矩阵渲染的场景,其深度缓冲区存储的深度值,ndc空间中的深度值。而ndc空间的深度值是经由透视空间转换过来的,ndc空间的深度值与透视空间的深度值转换并非是线性的,而是非线性。大家都知到,透视空间转换到ndc空间会有一步透视除法,是处以z值。这样就会导致,离视点越近的物体的片段深度值是越精确的,离视点距离约远的物体的片段的深度值是约不精确的。这样就会导致z-fighting问题。
而采用正交透视矩阵渲染场景,其变换是线性的,为什么,因为其透视空间转换为ndc空间的时候采用的透视除法是处以1,所以其片段距离视点的深度值是线性的,这样除非你把两个物体设置的位置非常接近,否则是产生不了z-fighting这种现象的。
那么为什么透视投影矩阵渲染场景的时候,在透视空间转换到ndc空间时,透视除法会除以z值那?下面笔者从透视投影矩阵的数学推导层面来回到这个问题。
从透视投影矩阵计算的角度解释以及如何避免
三维空间的物体在经历的图元装配以后,会经历剪裁与淘汰这两步操作。其中在剪裁中经历坐标系的转换的。
坐标系的转换如下所示:
模型坐标系–>世界坐标系—>相机坐标系—>投影坐标系—>标准设备化空间–>视口变换—>光栅化阶段。
在其投影坐标系转换到标准设备化空间的时,需要将xyz坐标转换为-1到1之间,也可以说标准设备化空间(NDC)是一个立方体空间。那么该怎么达到这样的操作那?答案是借助于矩阵,矩阵的一个几何意义就是将一个物体从一个坐标系转换到另外一个坐标系。那么笔者下面将去介绍这个透视投影矩阵是长的什么样子。
注意到蓝色线框里面.有花屏现象
这张图片就没有深度冲突
二、防止深度冲突
1.第一种方法
第一个也是最重要的技巧是永远不要把多个物体摆得太靠近,以至于它们的一些三角形会重叠。通过在两个物体之间设置一个用户无法注意到的偏移值,你可以完全避免这两个物体之间的深度冲突。在箱子和地板的例子中,我们可以将箱子沿着正y轴稍微移动一点。箱子位置的这点微小改变将不太可能被注意到,但它能够完全减少深度冲突的发生。然而,这需要对每个物体都手动调整,并且需要进行彻底的测试来保证场景中没有物体会产生深度冲突。
2.第二种方法
第二个技巧是尽可能将近平面设置远一些。在前面我们提到了精度在靠近近平面时是非常高的,所以如果我们将近平面远离观察者,我们将会对整个平截头体有着更大的精度。然而,将近平面设置太远将会导致近处的物体被裁剪掉,所以这通常需要实验和微调来决定最适合你的场景的近平面距离。
3.第三种方法
另外一个很好的技巧是牺牲一些性能,使用更高精度的深度缓冲。大部分深度缓冲的精度都是24位的,但现在大部分的显卡都支持32位的深度缓冲,这将会极大地提高精度。所以,牺牲掉一些性能,你就能获得更高精度的深度测试,减少深度冲突。
我们上面讨论的三个技术是最普遍也是很容易实现的抗深度冲突技术了。还有一些更复杂的技术,但它们依然不能完全消除深度冲突。深度冲突是一个常见的问题,但如果你组合使用了上面列举出来的技术,你可能不会再需要处理深度冲突了。
参考
牧野
SkySnow
openGL深度冲突z-fighting相关推荐
- webgl中解决深度冲突-多边形偏移
1.webgl中解决深度冲突-多边形偏移 1.什么是深度冲突? 就是当几何图形或者物体的两个表面极为接近时,就会使得表面看上去斑斑点点,这种现象就是 深度冲突. 看看这个缓冲区渲染出的效果 缓冲区数据 ...
- 如何解决深度冲突(Z-fighting),画面闪烁的问题
参考:OpenGL教程:深度测试 深度冲突 一个很常见的视觉错误会在两个平面或者三角形非常紧密地平行排列在一起时会发生,深度缓冲没有足够的精度来决定两个形状哪个在前面.结果就是这两个形状不断地在切换前 ...
- opengl 深度详解_OpenGL中的深度测试
什么是深度测试? 深度是指该像素点在3D世界中距离摄像机位置的Z值.深度测试就是将距离观察者最近(当观察者在Z轴的正面,z值越大越靠近观察者,当观察者在Z轴的负面,z值越小越靠近观察者)的值和其对应的 ...
- opengl 深度详解_一步步学OpenGL(23) -《阴影贴图1》
教程 23 阴影贴图1 原文: http://ogldev.atspace.co.uk/www/tutorial23/tutorial23.html CSDN完整版专栏: https://blog.c ...
- opengl 深度详解_一步步学OpenGL(1) -《打开一个窗口》
注意本教程中需要使用的是freeGLUT(GLUT太老会有潜在危险)窗口库和GLEW扩展库. vs2013配置freeGLUT3.0:vs2013 配置 freeglut3.0(opengl的窗口系统 ...
- 将深度缓冲z值变换到相机坐标系
将Depth Buffer中的Z值转换到Camera坐标系下需要使用投影矩阵 OpenGL: OpenGL的投影矩阵为 设Camera坐标系下点为(Vx,Vy,Vz,1.0) 通过上述投影矩阵变换后的 ...
- opengl深度缓冲获得的深度图精度太低_深度学习行人重识别ReID最新综述与展望...
点击上方"计算机视觉life",选择"星标" 快速获得最新干货 arXiv 新出论文 Deep Learning for Person Re-identific ...
- C++ opengl 深度缓冲区
GL_DEPTH_BUFFER_BIT 每一次清除之前,都要清空深度缓冲区 启动深度测试glEnable(GL_DEPTH_TEST):离视野近的物体会挡住离视野远的物体. 运行截图如下: 源码如下: ...
- 全景视频播放器中OpenGL的相关记录
全景视频播放器中OpenGL的相关记录 一.OpenGL顶点数组 二.坐标系与投影 三.坐标系相关函数 四.纹理坐标 五.纹理过滤 六.深度缓冲区 七.OpenGL的glut库 OpenGL函数功能g ...
最新文章
- NSHelper.showAlertTitle的两种用法 swift
- BBC称中国人加班时间远超欧美:工作效率未必高
- 添加程序以DLL函数
- linux安装 中文乱码怎么解决方法,Linux安装GBK/GB2312程序显示乱码的五种解决方法...
- 腾讯Light·公益创新挑战赛圆满收官,郎朗担任公益传播大使
- cnn神经网络可以用于数据拟合吗_使用Keras搭建卷积神经网络进行手写识别的入门(包含代码解读)...
- 服务器添加管理员隐藏账号,绝招:隐藏管理员账号 三分钟搞定
- 利用vertical-align:middle实现在整个页面居中
- CSDN博客停用公告
- Audition去除音频中的人声保留背景音乐
- 1.3端口扫描:利用Nmap工具进行端口扫描
- 【环境配置】麦克风不够,手机来凑。---用手机当电脑麦克风解决方案
- MAC PHP集成环境安装MAMP
- 如何使用MISRA改进嵌入式编程
- python3GUI--微博图片爬取工具V1.5 By:PyQt5(附源码)
- windows10系统修改c盘Users目录中的中文名称
- 2023内蒙古大学计算机考研信息汇总
- Windows Speech SDK5.1的安装和使用(xp/win7)
- 基于IC5000如何利用iSYSTEM winIDEA烧写+调试程序
- 网络攻防原理及应用 知识梳理