做网站公司怎样wordpress get_template_part
做网站公司怎样,wordpress get_template_part,软文广告成功案例,wordpress等级插件渲染杂谈#xff1a;early-z、z-culling、hi-z、z-perpass到底是什么#xff1f;
之前一直被这几个和深度缓存#xff08;z-buffer#xff09;相关的概念搞得神魂颠倒。今天在翻阅《Real-Time Rendering》时碰巧碰巧看到了这部分的讲解。硬着头皮看了看#xff0c;姑且算…渲染杂谈early-z、z-culling、hi-z、z-perpass到底是什么
之前一直被这几个和深度缓存z-buffer相关的概念搞得神魂颠倒。今天在翻阅《Real-Time Rendering》时碰巧碰巧看到了这部分的讲解。硬着头皮看了看姑且算是讲几个概念分清楚了。以我的记性估计下周就全忘了所以打算顺手记下来。
这四种技术本质上都是解决传统渲染管线中的同一个问题——过度绘制(OverDraw) 。一个经典的渲染管线通常会依次经历顶点阶段、光栅化、片元阶段和逐像素处理。其中片元阶段会进行复杂的光照计算是整个管线的性能瓶颈。而在逐像素阶段会对计算出来的片元值进行各种测试以判断这个片元会不会最终显示到屏幕上。这就带来了一个矛盾明明我在片元阶段花费了最大的力气计算出结果但马上的逐像素阶段就可能将这个结果直接舍弃。而事实上逐像素阶段的深度测试z-test会舍弃大量片元对于较为复杂的场景甚至会丢弃80%之多。如果我们能在片元阶段之前进行深度测试提前丢弃掉那些不需要绘制到屏幕上的片元那么就可以减少大量片元计算提升效率。early-z、z-cull、hi-z、z-perpass都是为了解决这个问题而产生的不同技术。
1.early-z
early-z的解决方式非常简单就是直接修改传统渲染管线在光栅化和片元阶段中间加入一个early-z阶段。这个阶段进行的操作和原本逐像素处理阶段的z-test为了与early-z区别这个阶段也会被成为late-z操作完全一样现代的gpu已经都开始包含这样的硬件设计。但是early-z有以下两个主要的缺点
* 一旦进行了手动写入深度值、开启alpha test或者丢弃像素等操作那么gpu就会关闭early-z直到下次clear z-buffer后才会重新开启不过现在的gpu也在逐渐优化使其更智能开关early-z。之所以gpu会选择关闭early-z是因为上述那些操作可能会在片元阶段与late-z阶段之间修改深度缓存中的深度值导致提前的early-z的结果并不正确。我们也可以在fragment shader中使用layout(early_fragment_tests)来强制打开early-z。
* early-z的优化效果并不稳定最理想条件下所有绘制顺序都是由近及远那么early-z可以完全避免过度绘制。但是相反的状态下则会起不到任何效果。所以有些时候为了完全发挥early-z的功效我们会在每帧绘制时对场景的物体按照到摄像机的距离由远及近进行排序。这个操作会在cpu端进行当场景复杂到一定程度频繁的排序将会占用cpu的大量计算资源。 2.z-culling
z-culling和early-z一样都是gpu硬件层面的优化所以之前我一直混淆两者是同一种东西。两者最明显的区别是early-z是以pixel quad为单位既以4个像素为一组因为深度缓存内的数据是按Z字形排列的逐个像素进行比较而z-culling是以tile比如16*16像素为单位进行整体比较。这里又涉及到tile的概念虽然我看到的资料中并没有提到但是我认为这里的tile和tile based renderingTBR中的tile是同一概念。也就是说这种技术应该只应用于使用TBR架构的移动端gpu中。其主要方式取得当前tile所对应的的深度缓冲区中的Zmax和Zmin如果该tile当前深度的最小值Zmax则说明整个tile都不可见将整个tile全部丢弃。如果该tile当前深度的最大值Znim则说明整个tile都处于最前面保留整个tile并因此可以省去该tile对应片元在late-z阶段对深度缓冲区的读取操作直接写入就可以。对于其它情况则交给后续的深度处理进行更细致的判断。由于z-culling通常用于TBR架构gpu所以它也和TPR架构一样保持了对gpu带宽的敏感性。因此不同于early-zz-culling并不会对深度缓存进行写入也不会对深度缓存进行直接读取。它所需要的比对数据Zmax和Zmin都会储存在on-chip缓存中的某个固定区域特点即是容量小但速度快。由于z-culling对深度缓存是只读的因此不会因为手动写入深度值、开启alpha test或者丢弃像素等操作对其有影响这刚好解决了early-z的第一个缺点。总结来说z-culling利用TBR架构进行了非常粗粒度的提前深度测试但不会带来额外的对于深度缓存进行读写消耗因此也比z-early具有刚多的适用范围。
这里有一个疑问为什么early-z不像z-culling一样对深度缓存只读来避免收到手动写入深度值、开启alpha test或者丢弃像素等操作的影响其中一个解释是在z-culling阶段后那些没有被优化的片元在late-z阶段会读取深度缓存进行细粒度的测试完成后再更新写入新的深度缓存。同时也会更新z-culling会访问的on-chip缓存。由于z-culling访问的是on-chip的所以不会带来额外开销所以整体上只有对深度缓存进行一次读一次写。而对于early-z来说如果在early-z阶段只读取深度缓存而不写入的话那么在late-z阶段就需要重新读取然后写入以更新深度缓存。这就相当于两次读一次写带来了额外的开销。不过也看到有人说late-z阶段对深度缓存的读写是无论如何都会进行的所以此处存疑。
还需要说明的是z-culling和early-z都可以不依赖于对方单独存在当然两者也可以共存。当两者共存的时候会先进行z-culling做粗粒度的筛选再进行early-z做细粒度的排除。在有些资料中也会把z-culling成为HiZ没错就是最后要讲的hi-z这要是不弄混就怪了。 3.z-perpass
和上面两种技术不同z-perpass是一种软件技术。它主要是配合early-z使用来减少开始提到的early的第二个缺点——效果不稳定。其做法是将场景做两个pass的绘制。第一个pass仅写入深度不做任何复杂的片元计算不输出任何颜色。第二个pass关闭深度写入并将深度比较函数设为“相等”。我在开篇有提到过度绘制的主要矛盾——经过大量运算的片元很大概率会在之后被丢弃掉。那么对于第一个pass由于只写入深度不在片元做任何计算所以即便之后会被丢弃也并不可惜。也就是说无论场景中的物体以怎样的顺序绘制我们都可以以很小的代价提前绘制好当前场景的深度缓存。那么在第二个pass时early-z就可以用这个深度缓存中的值和当前深度值进行比较只绘制深度相等的片元任何其他的片元都可以直接丢弃因此第二个pass要把深度比较函数设为“相等”。同时当前的深度缓存已经是完全正确的结果了因此第二个pass也不需要对深度缓存做任何更新便可以关闭深度写入。
z-perpass必须配合early-z才能发挥效果如果没有early-z的话第二个pass的深度测试依旧在片元后因此所有片元都会在片元阶段进行复杂计算。z-perpass的思想和延迟渲染管线defered render pipeline下面也会提到有些相似差别在于第一z-perpass的第一个pass只计算深度并且结果直接存储在深度缓存。而延迟渲染会同时计算更多其他的屏幕空间数据并将这些数据存储在额外的framebuffer中需要更大的缓存也就是GBuffer。第二z-perpass的第二个pass依旧需要对全场景的各个物体进行绘制至少顶点阶段是如此而延迟渲染的第二个pass类似于后处理本质上只绘制了一个屏幕大小的矩形。
4.hi-z
hi-z全名Hierarchical Z和z-perpass一样也是一种软件技术据说这项技术最早是在《刺客信条大革命》中使用的。其核心原理是利用上一帧的深度图和摄像机矩阵来对当前帧的场景做剔除对于剔除后的物体进行绘制新的深度图和GBuffer然后再用新的深度图和当前摄像机矩阵再对当前帧的场景做剔除对剔除后的物体进行绘制更新刚刚的深度图和GBuffer。之所这种看起来十分复杂的方法能提高效率是因为每一帧的绘制都已上一帧的绘制结果为基础。我们假设相邻两针差距不会特别大那么以上一帧的深度图作为结果来对当前帧可见的物体进行筛选可以得到绝大部分。而对于少量两针不一样的物体进行第二次深度绘制由于第二次绘制的少量不一样的物体所带来的的计算量很小因此可以带来性能上的提升。这种基于前一帧的迭代式的对场景物体进行剔除便可以在一定程度上减少过度绘制。不过由于我也没有实现过这种算法所以对这种算法实际带来的效果存疑。
值得注意的是这里提到了Gbuffer那么说明hi-z技术是基于延迟渲染管线。而延迟渲染管线本身也是在减少各种由其他原因包括但不限于深度测试这个原因导致的过渡绘制。其目的就是希望无论拥有多少模型多少光源整个场景渲染的复杂度都O(1)。延迟渲染管线本身也是个庞大的话题可能以后会结合Unity刚刚正式更新的Scriptable Render Pipeline也写点东西。 终于把这四种技术讲完了除了这四种在名字容易让人混淆的技术外其实还有一些东西没有提到。对于TBR或者TBDR架构的gpu因为其提供了提前优化的潜能所以各家硬件厂商也会有自己独特的针对于过度绘制的优化比如PowerVR的HSRHidden Surface Removal和Arm的APKForward Pixel Kill。这些技术可以配合early-z等技术来更高效的避免过度绘制。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/90291.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!