原文:https://outerra.blogspot.com/2012/11/maximizing-depth-buffer-range-and.htmlhttps://outerra.blogspot.com/2012/11/maximizing-depth-buffer-range-and.html

这里都好理解,简单来说,就是透视投影的情况下,z不是线性变化的,那么就无法依靠硬件的线性插值,而1/z是线性变化的,所以,默认都是把1/z传给硬件。但问题在于,深度测试比较也是使用1/z,这样就引出了精度问题。

这里要这么理解,所谓最佳分辨率设置,应该是距离无关的分辨率设置。假设不可分割的单位是1个苹果,它在距离摄像机1米的位置,投射到屏幕上是一个像素。这个时候我们给它一个深度像素的分辨率。然后我们把苹果挪到2米远。因为变远了,这个像素可以容纳的苹果变多了,只考虑深度方向(z方向)的话,那么就是可以放2个苹果(相似三角形),所以我们的深度分辨率应该变成2。也就是说,深度分辨率和同样屏幕尺寸的几何体的分辨率成正比。也就是

needzres = ksize.(size是投射到一个像素所需要的直径),size和z是成反比的。

注意,上述都是简化成一维,实际二维的话needzres = k * size^2   size^2 = 1/z * k

所以needzres = 1/z * k. 根据微积分的思想,需要logz函数。

这个相对难理解一些,我们先看下基础的情况。

 理想情况下,红线才是我们想要的,对于左边0-1的均匀精度,斜率一样,那么对于任何深度范围他的精度都是一样的。但实际我们使用的是1/z,这样精度就不一致了,far很大的一段距离,才占用一个精度格。

浮点数会有所不同,因为浮点数的精度本身就集中在靠近0的部分,所以我们的斜率靠近0的部分反而需要平一些。

如果我们想要一个和在透视投影下精度也均匀,需要一个怎么样的深度映射函数呢?

已知,透视变换的情况下,几何物体的深度占比,是和1/z成正比的。我们假定这个深度相关的函数是y=f(z), 然后从微分的角度来思考这个问题,考虑一个极小的深度,那就相当于y对z的求导,也就是dy/dz = k/z,k是常数。

所以y=alnz + b。所以,虽然我们在做MVP矩阵推导的时候,得到的是1/z这样形式的映射关系,但它只是为了可以进行线性插值。而如果不考虑硬件的线性插值本身,我们直接通过几何深度的占比,是和1/z成正比的这样一个关系,可以得到函数y=alnz + b这样的一个形式,它就是符合这个深度关系的映射函数。

再回头看:

因为对于任意距离,我都要提供一个完美的分辨率来满足你所需要的尺寸。因为你的尺寸大小是

随着z而减小,所以我们要提供一个刚好相反的函数和你进行匹配。

简单的展示一下大概区别,红色下降的更加快,而蓝色下降的更加缓慢。

这里还有一个深度分辨率的算法,这个网站Learning to Love your Z-buffer.

可以填写具体的数值,然后告诉你,一个最小单元可以容纳多少米。不过里面最高支持24位,我们直接看他的源码:

<script LANGUAGE="JavaScript">
function zb (nbits,zFar,zNear,z)
{var a = zFar / ( zFar - zNear ) ;var b = zFar * zNear / ( zNear - zFar ) ;return Math.floor ( (1<<nbits)*(a+b/z) ) ;
}function zprec (nbits,zFar,zNear,z)
{var b = zFar * zNear / ( zNear - zFar ) ;var res = ( b / ( (b/z) - 1.0/(1<<nbits) ) ) - z ;if ( res < 0.0001 )return res ;elsereturn Math.floor ( res * 100000.0 ) / 100000.0 ;
}function dosum()
{document.temps.ZP.value = -zprec (document.temps.ZB.value,document.temps.ZF.value,document.temps.ZN.value,document.temps.Z.value ) ;document.temps.ZV.value = zb (document.temps.ZB.value,document.temps.ZF.value,document.temps.ZN.value,document.temps.Z.value ) ;
}

核心是-zprec这个函数。

我们自己推导下:

上面是DX的投影矩阵公式。我们令b=fn/n-f。所以z'' = b/z + -f/n-f

差一个精度,相当于z''-1/1<<nbits = b/z -f/n-f - 1/1<<nbits

然后反向求出z,也就是b/(b/z-f/n-f - 1/1<<nbits + f/n-f),简化后,就是图里的公式了。

这里要注意,reverse z虽然有利于精度均衡,但是也看实际效果。

假定near = 0.04, far = 12000, 看下图形:

可以看到,实际效果并不好,精度还是集中在1米以内的范围。

剩下的部分看原始文章吧,非常有趣,但确实目前应该很难实践,因为需要修改z来保证插值的正确。但修改z会导致early-z失效,这并不是我们想要的结果

Maximizing Depth Buffer Range and Precision相关推荐

  1. Android OpenGL ES 开发教程(24):Depth Buffer

    OpenGL ES 中Depth Buffer 保存了像素与观测点之间的距离信息,在绘制3D图形时,将只绘制可见的面而不去绘制隐藏的面,这个过程叫"Hidden surface remova ...

  2. OpenGL学习笔记:使用深度缓冲(Depth Buffer)创建一个旋转的立方体

    如果不使用深度缓冲,创建的立方体的某些本应被遮挡住的面被绘制在了这个立方体其他面之上.OpenGL是一个三角形一个三角形地来绘制你的立方体的,所以即便之前那里有东西它也会覆盖之前的像素.因为这个原因, ...

  3. 【OpenGL】透视投影矩阵推导

    项目场景: 系统:ubuntu glad + glfw + opengl3.3 复习games101MVP变换,在使用OpenGL检验推导透视投影矩阵时,发现得出结果的Z坐标与把不符合目标预期.可以看 ...

  4. Common Techniques to Improve Shadow Depth Maps

    Shadow maps, first introduced in 1978, are a common technique for adding shadows to games. Three dec ...

  5. UE_Visibility Buffer Deferred Material

    一.Visibility Buffer 可见性缓冲区(Visibility Buffer)是延迟渲染的进阶处理. 与延迟渲染结合起来更好理解,即:延迟渲染是将材质与光源照明计算进行解耦,基于此种思路将 ...

  6. Unity Shader - ShaderLab: Culling Depth Testing 剔除与深度测试

    目录:Unity Shader - 知识点目录(先占位,后续持续更新) 原文:ShaderLab: Culling & Depth Testing 版本:2019.1 ShaderLab: C ...

  7. 使用Depth Texture

    使用Depth Textures: 可以将depth信息渲染到一张texture,有些效果的制作会需要scene depth信息,此时depth texture就可以派上用场了. Depth Text ...

  8. UE4 custom depth 自定义深度

    用途1: 半透明材质中实现遮挡Mesh自己其他部分的效果. 不遮挡效果如下: 遮挡后效果如下: 实现方法: 深度信息是越远值越大,使用两个Mesh,一个正常渲染,另一个渲染到custom depth ...

  9. Unity Shader: 理解Stencil buffer并将它用于一些实战案例(描边,多边形填充,反射区域限定,阴影体shadow volume阴影渲染)

    本文示例项目Github连接:https://github.com/liu-if-else/UnityStencilBufferUses 最近有两次被人问到stencil buffer的用法,回答的含 ...

最新文章

  1. “电商+金融”融合发展 开辟金融创新新路径
  2. [练习] 用PYTHON来优化网站中的图片
  3. iOS隐藏键盘的几种方式
  4. STL中list用法详解
  5. iOS 开发中的各种证书
  6. Error:java: Annotation processing is not supported for module cycles.异常解决
  7. Linux学习笔记006----Linux命令ps使用详解
  8. 快速配置vs2012+opencv
  9. curl 命令-接口测试
  10. 复盘-对过去的事情做思维演练
  11. 计算机科学概论第12版中文版
  12. 顺丰丰桥接口开发-不限java(LODOP电子面单打印)
  13. echarts柱状堆积图
  14. COJ 0358 xjr考考你数据结构(根号3)线段树区间修改
  15. 现在流行的少儿编程是不是再收大家的智商税?来看看最中肯的回答
  16. Qt示例程序打开失败,出现一个感叹号图标
  17. 网段划分 特殊网段(localhost0.0.0.01.1.1.1127.0.0.1)
  18. Python手把手实现远程控制桌面
  19. 微信开放平台--》网站应用开发 微信登录网站接口(https://open.weixin.qq.com/)
  20. 2021GDOI游记

热门文章

  1. 震惊世界的中国秘方—里面的方子都是一个老中医几十年的心血!很强!!珍惜身体一定要看!!
  2. Android安卓平板设备获取唯一标识
  3. 人工智能工具推荐:图像标注神器——精灵标注
  4. 网络层数据包的结构分析
  5. 谷歌无人汽车新进度:可同时紧盯路面数百目标/facebook
  6. 手把手教你直播平台怎么搭建
  7. 直播平台开发经验分享——直播平台搭建环境配置详解及分析...
  8. 行为金融(七):过度自信
  9. Nginx 部署前端项目dist文件
  10. linux mkfs 分区,linux mkfs命令详解:格式化分区(为分区写入文件系统)