移动端的HSR技术

overdraw问题:

overdraw顾名思义就是过度绘制,就是在渲染过程中**绘制一帧FBO(或者RenderTarget)**超过一次相同像素的现象!这个是CG的问题!特别在是用来大量的透明混合的情况下会产生的,当然客户端andriod、IOS 前端都会有类似的问题,这是一个普遍的问题,毕竟是图形底层的问题。也是性能通常绕不开的问题。
overdraw产生的主要场景

  1. 大量的透明度和半透明效果:当有多个半透明物体重叠时,每个物体都需要被渲染,即使它们中的一些可能被其他物体遮挡;除此之外透明的渲染为了正确是用来OIT将会产生大量的overdraw,比如Depth
    Peeling就至少需要N/2+1 个 pass层 Order Independent Transparency with Dual Depth Peeling DualDepthPeeling.pdf (utah.edu)!
  2. 复杂的场景:在一个复杂的场景中,可能有很多层的几何体互相遮挡,但如果没有使用有效的遮挡剔除技术,所有这些层都会被渲染。
  3. Ui的数量、层级过多等问题,还有各种UI的透明叠加也会产成

HSR技术:

HSR(Hidden Surface Removal),也称为遮挡剔除或隐藏表面消除,是图形渲染中提高图形渲染效率的技术,完美解决不透明的ovardarw问题,通过剔除那些在最终渲染的视图中不可见的几何面来降低处理和渲染的开销。
本质上算是一种剔除算法在游戏引擎或者3D引擎中,在一个3D场景中由于物体相互遮挡的关系,不是所有的物体或物体的部分都是用户可见的。例如,在一个场景里,一个远处的物体可能完全被前面的一个物体遮挡。如果渲染系统仍然处理这些最终不会被看到(对屏幕的没有贡献),会导致不必要的计算负担,浪费资源和时间。大致思路:沿一条射线从第一个不透明片元向后剔除被遮挡的片元。HSR影响的是整个pass的多个模型,若HSR失效,则推荐模型从前往后渲染更高效(遮挡,还有深度测试)
HSR技术可以在渲染流程的不同阶段被应用:

  1. Object级别:在空间变换和光栅化之前,可以决定整个物体是否可见。比如,使用视锥体剔除(Frustum Culling)或者 游戏中的剔除技术(一)遮挡剔除/Occlusion Culling可以移除完全在相机视野之外的物体。
  2. 背面剔除(Back-Face Culling):是根据mesh的法向量和观察方向判断该多边形是否面向观察者。如果一块面背对着观察者(即法线与观察方向相反),那么它很可能不可见,可以被剔除。
  3. 像素级别:使用深度测试(Z-buffering)或者early-z等技术在像素级别决定哪些像素应该在屏幕上绘制。每个像素点都有一个深度值,渲染时通过比较深度值来确定是否将当前片元的颜色写入到帧缓冲区。

HSR减少了图形管线下游阶段(如光栅化、纹理映射、着色等)的工作量,因此大大提高了渲染效率,这对于实时图形应用,如视频游戏和增强现实/虚拟现实(AR/VR),尤其重要。除了提升性能外,HSR还有助于降低能耗,对于运行在移动设备和低功耗平台上的应用来说尤为关键,所以本文重点介绍在移动端的HSR技术。

Early-Z:

先简单聊一下Early-Z:它是现代图形gpu硬件优化技术,用于减少不必要的像素着色计算,可部分解决overdraw的问题!它在传统渲染管线流程中加入了一个阶段,在执行昂贵的片元着色操作之前再进行深度测试。如果深度测试失败,意味着该像素会被场景中其他对象遮挡,因此可以提前丢弃这个像素,避免执行后续的着色计算。但是一旦开启Early-Z就有的渲染技术无法使用!
在这里插入图片描述

Early-Z 不兼容的操作与渲染技术

  1. discard:在像素着色器中改变了深度值修改gl_FragDepth或者discard,在像素着色器中改变深度值时,GPU就不能再提前使用深度测试来剔除片段,因为实际的深度值只有在像素着色器运行后才能知道
  2. 半透明和透明渲染:使用半透明材质时,需要OIT正确排序并混合片元颜色,这通常要求片元被处理而不是在深度测试阶段被剔除。因此,包含半透明物体的场景通常不适合进行 Early-Z 优化。
  3. Alpha Testing: alpha testing(通过比较alpha值来丢弃片元), Early-Z 优化的影响会影响 alpha testing。
  4. 本质是深度测试,不开启深度写入Z-Wirte就无法正确有效的使用Early-Z。

使用深度测试/early-z的要解决透明问题需要预渲染z-buffer 哪就是Z-Prepass技术,实现有两种方式
方法1:双Pass法

  1. 深度预处理Pass(Z-Prepass):在这个阶段,不对物体进行完全渲染,只简单地渲染出各个物体在屏幕上的深度信息,产生z-buffer。这个阶段不需要使用复杂的着色器或进行纹理映射。
  2. 主渲染Pass:有了预先计算好的深度信息,关闭深度写入,并且将深度比较函数设置为相等。(但是这个方法会带来动态批处理的问题,多Pass的Shader不能进行动态批处理,不能进行动态批处理就会带来DC问题,一个Pass通道一个DrawCall)

方法2:提前分离的Pass

  1. 将原先第一个Pass(即Z-Prepass)单独分离出来为单独一个Shader,并先使用这个Shader将整个场景的Opaque的物体渲染一遍。
  2. 原先材质只剩下原先的第二个Pass,仍然关闭深度写入,并且将深度比较函数设置为相等。

early-z技术与HSR 区别:

两者都是像素级别,都是为了解决overdraw的问题, 区别如上提到的early-z只能限制较多因为依赖深度图 所以不写深度就无法做early-z,hsr没有这么多的限制,提高性能~都是需要硬件支持,earlyz主要是pc端,对于移动端的是hsr,同时pc端是IMR移动端是tbdr。
early-z主要是能解决不透明物体的overdraw的问题,对于透明问题就支持并不太好!而且新人的结果可能是错误的比如你有两个三角形A、B交叉在一起,互有遮挡,那你不论怎么排序都会产生先完全绘制一个三角形,再绘制另外一个都是不对的。虽然early-z的改进可以解决这个问题,这个就是Z-PrePass!但是HSR不需要 early-z+Z-PrePass才能彻底的解决场景的既有透明又有不透明等的问题,关键Z-PrePass引入了一个新的pass会有较高的overdraw。

移动端GPU on-chip内存

这里特别强调on-chip是因为它在移动端GPU中重要的作用,看过TBR或者TBDR的同学应该是对on-chip不陌生~虽然on-chip不是直接HSR技术但是确实用到了,tiles或者各种深度texture是临时存储在这里的而且性能还非常高!所以我才在这里重点介绍,
首先现代GPU的内存分布大致是如下图(没找到移动端的先放PC端的顶一下后面有时间再画图或者写GPU内存通信的文章再画)
在这里插入图片描述

on-chip内存是一小块位于GPU核心内部的高速内存,通常也被称作缓存(cache)或本地存储(local storage)。这种内存提供了几个关键的功能,它对移动设备的图形性能和功耗优化至关重要:

  1. 高速数据访问:On-chip内存比外部操作系统的RAM(如DDR内存)具有更低的延迟和更高的带宽,对于tbdr或者TBDR的tiles图形数据,它们相同的数据或者相邻的数据经常被多次读取on-chip可以显著提高这些操作的效率
  2. 降低功耗:距离处理器更近访问速度更快。这在移动设备中功耗、发热、电池寿命是设计的一个关键部分。
  3. 减少GPU和CPU之间的数据移动:数据频繁在GPU和CPU之间传递,会产生大量的总线流量、消耗大量功耗和处理时间。将这些数据保留在GPU的on-chip内存中可以减少这种开销。

移动端的GPU HSR 技术

移动端gpu型号很多Adreno、MaliPowerVR,其中对于HSR技术来说有FPK(Forward Pixel Killing)、TBDR(Tile-Based Deferred Rendering)和LRZ(Local Render Z-buffer)技术。

Adreno它广泛应用于高通的Snapdragon
SoC中。Adreno系列GPU以其高性能和良好的功耗效率而著称使用的是LRZ技术;ARM公司开发了Mali系列GPU,它们被许多不同制造商采用在各种SoC设计中,如三星的Exynos系列和华为的Kirin系列Arm
其中Mail使用的是FPK;

PowerVR是TBDR技术iphne的A11以前都是直接使用的PowerVR,最后自研使用 Tailor Your Apps for Apple GPUs and Tile-Based Deferred Rendering | Apple Developer Documentation。

对于TBDR以前的文章记忆有说过:

TBDR与TBR很大的不同就是TBDR使用了HSR技术来几乎完美的解决overdraw。对于TBDR,无论物体的提交顺序如何(不排序),HSR将完全解决OverDraw问题。它最显著的不同点在于通过了Early-Z测试的像素不会立即执行像素着色器,而是先标记该像素属于哪个图元。当Tile处理完所有图元(场景中的所有物体),再绘制Tile上所有做了标记的像素。TBDR做到了硬件层级的遮挡像素剔除,减少OverDraw,减少带宽和内存访问。

HSR能够做到不依赖顺序绘制的像素级剔除,最主要的做法是图元光栅化后,会先标记该像素属于哪个图元(三角形),并存储于Tag Buffer,待场景所有的图元处理完毕,才进入片元着色器。HSR阶段处于光栅化之后像素着色之前:
在这里插入图片描述

特别强调一下如果 遇到开启AlphaTestAlphaBlend的HSR是怎么处理。当前tile上如果前面的物体会挡住后面的物体就能正常发挥,如果HSR的射线检测layer0 ,1 ,2、3都是透明的开启了混合会打断 Defer流程,就正常draw(因此HSR对于AlphaTest和AlphaBlend物体都是没有作用的)导致渲染性能相对于不透明的HSR降低了点但是愣然是高于旧的IMR 或TBR渲染框架的!到layer4是不透明的遮挡了后续的layer5、6合HSR射线检测到后会设置5、6是失效的

LRZ(Local Render Z-buffer)技术:

LZR是Adreno 5及以上的芯片在TBR执行Early-Z剔除时的优化技术。在正常渲染管线前,先多执行一次渲染,生成低精度的DepthTexture,以提前剔除不可见的triangels。说白了,就是用硬件做occlusion culling,功能类似软光栅遮挡剔除,只是在硬件驱动重做速度更快(感觉跟上面结合Z-Prepass差不多只不过是硬件上做的)。 优点是减少内存访问和带宽,减少渲染图元,不需要应用程序从前到后绘制,提高帧率。缺点是:在像素着色器中写入深度值会失效。

FPK(Forward Pixel Killing技术:

TBR框架下Early-Z结合使用,管线位置位于Early-Z之后,是一个先进先出FIFO的队列。队列中有4个Quad(可以理解为2×2像素的平面),每个Quad有屏幕上位置的数据和Z数据Z越大代表离摄像机越远。流程大致如下:

  1. 预光栅化:在正式渲染之前,系统会执行一个轻量级的光栅化过程,以确定哪些图元可能影响当前Tile。
  2. 早期Z测试:对预光栅化结果进行深度测试,以确定这些图元是否有可能被其他图元遮挡。
  3. killed:这是关键部分,根据屏幕上相同位置(pos)的不同z,对不透明的像素进行替换(有近的就不渲染远的,渲染的线程直接停掉),这个过程叫作killed,因为这些像素将不会进入后续的着色阶段。
  4. 正式光栅化与着色:一旦完成了早期像素剔除,剩下的是那些确实需要被渲染的像素。这些像素将通过正规的光栅化和着色管线进行处理。
    FPK的特点:
  • FPK剔除粒度是Quad(2x2像素块)。
  • FPK只对不透明物体有效透明物体无效。
  • FPK必须开启深度测试才能起作用。

参考资料:

EarlyZ和TBDR中的HSR有什么本质区别么?
Tailor Your Apps for Apple GPUs and Tile-Based Deferred Rendering | Apple Developer Documentation
Optimizing the draw call render order
《Arm Mali GPU Best Practices》
隐藏面消除法—Forward Pixel Kill
移动设备GPU架构知识汇总
【技术美术百人计划】图形 2.7.2 GPU硬件架构概述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/733315.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

艾多美用“艾”为生命加油,献血活动回顾

用艾为生命加油 6月10日~16日,艾多美中国开启献血周活动,已经陆续收到来自烟台总部、山东、广东、河南、四川、重庆、贵阳,乌鲁木齐,吉林,等地区的艾多美员工、会员、经销商发来的爱心助力,截止到目前&…

KIVY BLOG Kivy tutorial 007: Introducing kv language

Kivy tutorial 007: Introducing kv language – Kivy Blog DECEMBER 18, 2019 BY ALEXANDER TAYLOR Kivy tutorial 007: Introducing kv language Kivy 导师课007: 介绍kv语言 Central themes: kv language, building a gui, integration with Python 中心主题:…

【React】富文本编辑器react-quill

安装 react-quill 富文本编辑器 npm i react-quill2.0.0-beta.2报错解决: npm i react-quill2.0.0-beta.2 --legacy-peer-deps导入编辑器组件和配套样式文件 import ReactQuill from react-quill // 1 import react-quill/dist/quill.snow.css // 2const Publi…

JR-8000系列机架式多路4K超高清光端机

集中式 4K超高清光传输设备 1 产品特性 ⚫ 支持高达 8 通道 SMPTE 全格式 SDI 信号输入 ⚫ 发送端带有 LOOPOUT 环出端口,具备消抖动功能,可作为信号调理或级联信号源使用 ⚫ 接收端支持双输出端口 ⚫ 支持传输速率:143Mbps-11.88Gbps ⚫…

Redis源码学习:ziplist的数据结构和连锁更新问题

ziplist ziplist 是 Redis 中一种紧凑型的列表结构&#xff0c;专门用来存储元素数量少且每个元素较小的数据。它是一个双端链表&#xff0c; 可以在任意一端进行压入/弹出操作&#xff0c;并且该操作的时间复杂度为O(1)。 ziplist数据结构 <zlbytes><zltail>&l…

CS162 Operating System-lecture2

A tread is suspended or no longer executing when its state’s not loaded in registers the point states is pointed at some other thread .so the thread that’s suspended is actually siting in memory and not yet executing or not executing at all with some thi…

Antd Table 表格 拖拽列宽

antd 的表格组件的列宽&#xff0c;是通过width属性去初始化的&#xff0c;有时候渲染的内容不固定&#xff0c;这个宽做不到通用所以研究怎么实现表格列宽拖动&#xff0c;主要的实现步骤如下&#xff1a; 使用table的components API修改表格头部为 react-resizable提供的组件…

实验13 BGP路径选择

实验13 BGP路径选择 一、 原理描述二、 实验目的三、 实验内容四、 实验配置五、 实验步骤 一、 原理描述 与域内路由不同&#xff0c;域间路由更加注重策略&#xff0c;而不是技术。在域内进行选路&#xff0c;可以使用路由算法计算出到达目的子网的最短路径&#xff1b;而在…

cocos 如何使用九宫格图片,以及在微信小程序上失效。

1.在图片下方&#xff0c;点击edit。 2.拖动线条&#xff0c;使四角不被拉伸。 3.使用。 其他 在微信小程序上失效&#xff0c;需要将packable合图功能取消掉。

[保姆级教程]uniapp实现底部导航栏

文章目录 前置准备工作安装HBuilder-X新建uniapp项目教程使用HBuilder-X启动uniapp项目教程 实现底部导航栏package.json中配置导航栏详细配置内容 前置准备工作 安装HBuilder-X 详细步骤可看上文》》 新建uniapp项目教程 详细步骤可看上文》》 使用HBuilder-X启动uniapp项…

帆软使用总结-新建填报报表

1.界面设计 选择菜单[文件>新建普通报表] 2.分别把B3、C3设置为文本控件 3.选中D3&#xff0c;并设置为下拉控件 4.选择菜单[模板>报表填报属性] 5.选择菜单[模板>模板web属性] 2.效果演示

Day5(和为s的两个数字)双指针

输入一个递增排序的数组和一个数字s&#xff0c;在数组中查找两个数&#xff0c;使得它们的和正好是s。如果有多对数字的和等于s&#xff0c;则输出任意一对即可。 二、思路 1.首先&#xff0c;将不符合要求的值给排除&#xff0c;有以下三种&#xff1a; 数组元素个数不足两个…

基于JSP的交通事故档案管理系统

开头语&#xff1a;你好&#xff0c;我是计算机学长猫哥&#xff0c;如果你对系统有更多的期待或建议&#xff0c;欢迎随时联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;JSPJava 工具&#xff1a;ECLIPSE、Tomcat 系统展示 首页 管理员界…

深入理解计算机系统 CSAPP 家庭作业6.46

理解题意:G是有向图g的邻接矩阵 G[j*dim i] G[j*dim i] || G[i*dim j]; 通过i和j遍历G中的所有元素,||运算将遍历到的元素对称起来. 下面我们来优化col_convert(int *G, int dim) : void col_convert(int N, int G[N][N], int bsize) {if(bsize < 0 || bsize > N…

堆的实现详解

目录 1. 堆的概念和特点2. 堆的实现2.1 堆向下调整算法2.2堆的创建2.3 建堆时间复杂度2.4 堆的插入2.5 堆的删除2.6 堆的代码实现2.6.1 结构体2.6.2 初始化2.6.3 销毁2.6.4 插入2.6.5 删除2.6.6 获取堆顶2.6.7 判空2.6.8 个数2.6.9 向上调整2.6.10 向下调整3. 堆的实现测试测试…

191.回溯算法:组合总和|||(力扣)

代码解决 class Solution { public:vector<vector<int>> result; // 存储所有符合条件的组合vector<int> res; // 当前组合// 回溯函数void backtracing(int k, int n, int index, int sum) {// 如果当前组合的长度等于k&#xff0c;且总和等于nif (res.si…

编写水文专业串口通讯软件的开发经历

编写水文专业串口通讯软件的开发经历 一、关于开发 YAC9900 水位雨量 RTU 通讯软件二、软件开发遇到的问题和困难1、开发架构的适应2、开发语言的学习3、.net core 8 架构中串口构建的难点4、YAC9900 水位雨量 RTU 通讯软件开发中的 UI 冻结 三、发现问题解决问题的具体办法1、…

已解决java.rmi.activation.ActivationException异常的正确解决方法,亲测有效!!!

已解决java.rmi.activation.ActivationException异常的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 问题分析 java.rmi.activation.ActivationException 是与Java RMI&#xff08;远程方法调用&#xff09;的激活机制相关的一种已检查异常。这个异…

港湾周评|高盛眼中的618增长

《港湾商业观察》李镭 年中最重要的购物节618终于尘埃落定了。2024年的618各大电商平台竞技情况如何&#xff1f;又有哪些新的亮点&#xff1f;都成为外界观察消费行为的参考指标。 根据京东618数据显示&#xff1a;累计成交额过10亿的品牌83个&#xff0c;超15万个中小商家销…

Ubuntu22.04开机后发现IP地址变成127.0.0.1

开机就是这个样子 解决办法 ip地址可能被释放&#xff0c;需要重新设置成自动分配 sudo dhclient -v可能网卡未加托管 查看方式: nmcli n若是enable就是已被托管,若是disabled&#xff0c;说明网卡未被托管 解决办法: nmcli n on搞定