【UnityShader入门精要学习笔记】第十六章 Unity中的渲染优化技术 (下)

在这里插入图片描述
本系列为作者学习UnityShader入门精要而作的笔记,内容将包括:

  • 书本中句子照抄 + 个人批注
  • 项目源码
  • 一堆新手会犯的错误
  • 潜在的太监断更,有始无终

我的GitHub仓库

总之适用于同样开始学习Shader的同学们进行有取舍的参考。


文章目录

  • 减少需要处理的顶点数目
    • 优化几何体
    • 模型的LOD技术
    • 遮挡剔除技术
  • 减少需要处理的片元数目
    • 控制绘制顺序
    • 小心透明物体
    • 减少实时光照和阴影
  • 节省带宽
    • 减少纹理大小
    • 使用分辨率缩放
  • 减少计算复杂度
    • Shader 的LOD技术
    • 代码方面的优化


上一节我们描述了如何通过减少DrawCall来减轻CPU的资源调度压力。本章中我们将从其他方面来优化性能:

减少需要处理的顶点数目

优化几何体

3D游戏制作离不开3D模型。由于渲染时需要逐顶点逐面片渲染,因此优化3D模型是很重要的。

一般的原则是优化模型的网格结构,减少模型中的顶点数量(面数)

有时,Unity中显示的顶点数量会超过模型本身的顶点数量。这是由于在GPU看来,有时为了计算的需要,会将一个顶点拆分为两个顶点,主要目的有两个:一个是为了分离纹理坐标(uv splits),另一个是为了产生平滑的边界(smoothing splits)

它们的本质其实是对于GPU来说的,顶点的每一个属性和顶点之间必须是一对一的关系。例如一个立方体,它的六个面之间有一些相同的顶点,但是这些顶点相对于每个面的纹理坐标就不同了,因此就会拆分为多个不同纹理坐标的顶点,平滑边界也是类似的。因此一个顶点可能会对应多个法线信息和切线信息。

因此我们需要尽可能减少顶点数量,一个建议是——移除不必要的硬边以及纹理衔接,避免边界平滑和纹理分离。


模型的LOD技术

另一个减少顶点数目的方法是使用LOD技术,LOD技术的原理是为模型准备好几套不同细节程度的模型(纹理),然后根据摄像机和物体间的距离选择为模型加载的LOD层级,Unity就会自动使用对应等级的模型。

一般离得越远则细节程度越低,离得越近细节程度越高


遮挡剔除技术

遮挡剔除就是Occlusion Culling,就是剔除那些我们看不到的物体(面),避免计算不必要的资源。

像摄像机自带的Culling效果,对层级手动设置的Culling效果,包括Shader的背面和正面剔除都是出于这一目的的。

注意区分摄像机的遮挡剔除和视锥体剔除(Frustum Culling),视锥体剔除是剔除不在摄像机视锥内的物体,而遮挡剔除是剔除摄像机视锥内看不见的物体,其原理是用一个虚拟摄像机来遍历场景,并识别那些物体是可见的,哪些是不可见的。

LOD技术和遮挡剔除技术可以同时减少CPU和GPU的负荷,CPU可以提交更少的DrawCall,而GPU需要处理的顶点和面数也少了。


减少需要处理的片元数目

另一个造成GPU的性能瓶颈的原因是需要处理过多的片元。除了我们之前说的减少模型网格顶点数减少片元外,这部分的重点更在于减少OverDraw——即同一个像素的重复绘制。

想象一下,有一个B物体挡在了A物体的前面。若我们先渲染A物体,再渲染B物体,那么同一个像素被渲染了两次,显然A物体是没必要渲染的,就造成了OverDraw,这时我们可以用深度测试来避免这一情况

在这里插入图片描述
我们可以再Scene视图下查看overdraw的情况,来判断物体之间的遮挡。

控制绘制顺序

为了避免OverDraw ,一个重要的优化策略就是控制绘制顺序。由于深度测试的存在,如果我们可以保证物体都是从前往后绘制的,就可以最大限度减少OverDraw。这是因为,在后面绘制的物体由于无法通过深度测试因此不会重复渲染。

在Unity中,那些渲染队列数目小于2500的(如BackGround ,Geometry,AlphaTest)的对象都被认为是不透明的(Opaque)的物体,不透明的物体通常是从前往后绘制的。

而其他队列例如(“Transparent”,“Overlay"等)则是从后往前绘制的,因为这些队列常常是透明度渲染的,这些渲染就比较麻烦,为了正确的渲染效果我们往往还需要手动控制渲染顺序。

在开发中,我们考虑到摄像机下一些人或物在屏幕上的渲染顺序,为它们设置不同的渲染队列,将节省很多渲染时间。


小心透明物体

对于半透明物体来说,由于它们没有开启深度写入,因此如果想要得到正确的渲染结果,必须从后往前渲染,因此为了正确的渲染效果,半透明物体一定会产生overdraw的。

因此,如果屏幕上存在大量半透明物体或者粒子效果,甚至多层半透明效果相互堆叠的情况,就会有大量的OverDraw,这是我们需要避免的。特别是GUI对象的渲染常常要用到半透明效果。

对于上述的情况,我们可以减少视窗中GUI的面积以减少OverDraw的像素。也可以把GUI的绘制和三维场景的绘制交给不同的摄像机,并且三维摄像机的视角范围尽量不要和GUI的相互重叠。


减少实时光照和阴影

实时光照和阴影的计算是很昂贵的,我们之前讲光照的时候说过,实时光照的渲染(特别不属于主光源的部分,例如点光源)会调用每个照射到的物体上的Pass。导致Pass一下子增多了。

例如一个场景如果包含了3个逐像素的光照,而且使用了逐像素的Shader,那么很有可能将DrawCall的数量提高3倍。

并且无论是静态批处理还是动态批处理,额外的逐像素光照pass都会导致中断批处理!

当然游戏是少不了光照的,少用实时光不代表不用光照效果,我们往往会为模型提前烘焙好一张光照纹理和阴影纹理,根据光照方向来进行计算采样来代替实时光照效果。只有某些动态物体才会使用实时光照


节省带宽

大量使用未经压缩的纹理以及使用过大的分辨率都会造成由于带宽引发的性能瓶颈。

减少纹理大小

使用纹理图集atlas可以帮助我们减少DrawCall的数量(因为图集中的所有纹理都可以通过一次DrawCall提交),除此之外纹理大小也是一个需要考虑的问题。所有纹理的长宽比最好是正方形,而且长宽值最好是2的整数幂,这样很多的优化策略才能发挥最大的作用。

除此之外,我们还可以用多级渐远技术和纹理压缩来优化纹理,当勾选了Generate Mip Maps则生成多级渐远纹理,和LOD技术相似,根据远近来选择渲染的纹理。在GUI和2D游戏中使用的纹理等,都应该为纹理生成相应的多级渐远纹理。

纹理压缩同样可以节省带宽,不同的GPU架构可能有不同的纹理压缩格式,除了有时我们需要纹理特别清晰时(例如GUI)我们不希望对纹理进行压缩。


使用分辨率缩放

过大的屏幕分辨率和糟糕的GPU也会造成带宽压力大, 在特定的设备上,我们还需要对程序指定分辨率缩放。


减少计算复杂度

Shader 的LOD技术

Shader的LOD技术和模型的LOD技术类似,其原理是当Shader的LOD值小于当前的LOD值,该shader才会被使用,否则使用了该Shader的物体不渲染。

在未设置LOD值的Shader中,LOD是无限大的,也就是无论如何都使用。在设定了LOD值之后,我们若想要剔除部分复杂计算的Shader就可以通过设置LOD值来剔除,方法是使用Shader.maximumLODShader.globalMaximumLOD来设定允许的最大LOD


代码方面的优化

通常来说,游戏需要计算的数量排序是:游戏对象数量<顶点数量<像素数量。因此我们应当尽可能将操作放在游戏对象上或者顶点上。

例如之前我们采样坐标时放在了顶点着色器上而非片元着色器,就大大提高了计算性能。

(以下说的优化策略在某些设备上不成立,这很正常)

  1. 尽量使用低精度的浮点数进行运算。最高精度的float类型用于存储顶点坐标等变量,但是像颜色值,归一化值这类范围为[0,1]的我们就会使用fixed,half通常使用与一些标量,纹理坐标等变量,计算速度大概是float的两倍。尽量避免不同精度间的值转换。(特别考虑别在片元着色器中使用高精度计算)
  2. 对于大多数的GPU,在数据传递阶段,例如用v2f将数据从顶点着色器传递到片元着色器的时候,我们尽可能使用少的插值变量,例如可以用一个fixed4存储,就不用两个fixed2。(有些平台,例如PowerVR例外)
    3.尽量不使用全屏的屏幕后处理效果,尽量把多个特效合并在一个Pass中
  • 尽量别用if分支语句和for循环语句
  • 尽量避免sin,tan,pow,log等复杂数学运算,我们可以用查找表来代替
  • 尽量不要使用discard

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

德人合科技——天锐绿盾内网安全管理软件 | -文档透明加密模块

天锐绿盾文档加密功能能够为各种模式的电子文档提供高强度加密保护&#xff0c;丰富的权限控制以及灵活的应用管理&#xff0c;帮助企业构建更严密的立体保密体系。 PC地址&#xff1a; https://isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c5dfedee ————…

BioVendor—sHLA-G ELISA试剂盒

人类白细胞抗原-G (HLA-G)与其他MHC类基因的不同之处在于它的低多态性和产生七种HLA-G蛋白的选择性剪接&#xff0c;这些蛋白的组织分布局限于正常的胎儿和成人组织&#xff0c;这些组织对先天和后天免疫细胞都具有耐受性。可溶性HLA-G是一种免疫抑制分子&#xff0c;诱导活化的…

详细解析Barlow Twins:自监督学习中的创新方法

首先先简单了解一下机器学习中&#xff0c;主要有三种学习范式&#xff1a;监督学习、无监督学习和自监督学习&#xff1a; 监督学习&#xff1a;依赖带标签的数据&#xff0c;通过输入输出映射关系进行训练。无监督学习&#xff1a;不依赖标签&#xff0c;关注数据的内在结构…

pikachu靶场(unsafe upfileupload(文件上传)通关教程)

目录 client check 1.在桌面新建一个文本文档 2.保存为.png格式 3.打开网站 4.按照图中操作 5.点击forward 6.访问 MIME type 1.新建一个php文件&#xff0c;里面写上 2.上传文件&#xff0c;就是我们保存的文件 3.打开抓包工具&#xff0c;点击开始上传 4.修改Conen…

ADC数模转换器

一、ADC&#xff08;Analog-Digital Converter&#xff09;模拟-数字转换器 1、ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量&#xff0c;建立模拟电路到数字电路的桥梁 2、12位逐次逼近型ADC&#xff0c;1us转换时间 3、输入电压范围&#xff1a;0~3.3V&a…

【K8s】专题四(2):Kubernetes 控制器之 Deployment

以下内容均来自个人笔记并重新梳理&#xff0c;如有错误欢迎指正&#xff01;如果对您有帮助&#xff0c;烦请点赞、关注、转发&#xff01;欢迎扫码关注个人公众号&#xff01; 目录 一、基本介绍 二、工作原理 三、相关特性 四、资源清单&#xff08;示例&#xff09; 五…

【Linux】多线程——线程概念|进程VS线程|线程控制

> 作者&#xff1a;დ旧言~ > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;理解【Linux】多线程——线程概念|进程VS线程|线程控制 > 毒鸡汤&#xff1a;有些事情&#xff0c;总是不明白&#xff0c;所以我不会坚持。早安! &…

产品上市新闻稿怎么写?纯干货

一个产品的上市&#xff0c;想要达到一个非常好的宣传效果&#xff0c;前期的预热造势是必不可少的&#xff0c;投放产品上市新闻稿到权威专业的媒体&#xff0c;潜移默化去影响用户的心智&#xff0c;产品上市新闻稿怎么写&#xff1f;接下来伯乐网络传媒就来给大家分享一下&a…

重生之 SpringBoot3 入门保姆级学习(10、日志基础与使用)

重生之 SpringBoot3 入门保姆级学习&#xff08;10、日志基础使用&#xff09; 3.1 日志基础3.2 使用日志3.2.1 基础使用3.2.2 调整日志级别3.2.3 带参数的日志 3.1 日志基础 SpringBoot 默认使用 SLF4j&#xff08;Simple Logging Facade for Java&#xff09;和 Logback 实现…

码蹄集部分题目(2024OJ赛17期;二分+差分+ST表+单调队列+单调栈)

1&#x1f40b;&#x1f40b;小码哥处理订单&#xff08;钻石&#xff1b;二分差分&#xff09; 时间限制&#xff1a;1秒 占用内存&#xff1a;128M &#x1f41f;题目描述 &#x1f41f;题目思路 【码蹄集进阶塔全题解07】算法基础&#xff1a;二分 MT2070 – MT2079_哔哩…

Element ui 快速入门(基础知识点)

element ui官网 前言&#xff1a; 在当今时代&#xff0c;我们在编写计算机程序时&#xff0c;不仅仅是写几个增删改查的简单功能&#xff0c;为了满足广大用户对页面美观的需求&#xff0c;为了让程序员们写一些功能更简便&#xff0c;提高团队协作效率&#xff0c;所以eleme…

python操作mongodb底层封装并验证pymongo是否应该关闭连接

一、pymongo简介 github地址&#xff1a;https://github.com/mongodb/mongo-python-driver mymongo安装命令&#xff1a;pip install pymongo4.7.2 mymongo接口文档&#xff1a;PyMongo 4.7.2 Documentation PyMongo发行版包含Python与MongoDB数据库交互的工具。bson包是用…

【Python】解决Python报错:AttributeError: ‘int‘ object has no attribute ‘xxx‘

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

RLC防孤岛保护装置如何工作的?

什么是RLC防孤岛保护装置&#xff1f; 孤岛保护装置是电力系统中一道强大的守护利器&#xff0c;它以敏锐的感知和迅速的反应&#xff0c;守护着电网的平稳运行。当电网遭遇故障或意外脱离主网时&#xff0c;孤岛保护装置如同一位机警的守门人&#xff0c;立刻做出决断&#xf…

Go微服务: 基于Docker搭建Kong网关环境

概述 在当今的微服务架构中&#xff0c;API网关扮演着至关重要的角色&#xff0c;它作为系统的统一入口负责处理所有内外部请求&#xff0c;实现路由转发、负载均衡、安全控制、限流熔断等多种功能Kong&#xff0c;作为一个开源、高性能、可扩展的API网关&#xff0c;凭借其强…

【机器学习】探索未来科技的前沿:人工智能、机器学习与大模型

文章目录 引言一、人工智能&#xff1a;从概念到现实1.1 人工智能的定义1.2 人工智能的发展历史1.3 人工智能的分类1.4 人工智能的应用 二、机器学习&#xff1a;人工智能的核心技术2.1 机器学习的定义2.2 机器学习的分类2.3 机器学习的实现原理2.4 机器学习的应用2.5 机器学习…

在PostGIS中检查孤线(Find isolated lines in PostGIS)

场景 在PostGIS中有一张线要素表,需要检查该表中的孤线,并且进行自动纠正的计算。 其中孤线定义为两端端点都不在任何其他线的顶点上。 本文介绍在PostGIS中的线要素点,通过函数计算指定线要素表中的孤线,并计算最接近的纠偏位置。 In PostGIS, there is a table of line …

GPT-4o(OpenAI最新推出的大模型)

简介&#xff1a;最近&#xff0c;GPT-4o横空出世。对GPT-4o这一人工智能技术进行评价&#xff0c;包括版本间的对比分析、GPT-4o的技术能力以及个人感受等。 方向一&#xff1a;对比分析 GPT-4o&#xff08;OpenAI最新推出的大模型&#xff09;与GPT-4之间的主要区别体现在响应…

268 基于matlab的模拟双滑块连杆机构运动

基于matlab的模拟双滑块连杆机构运动&#xff0c;并绘制运动动画&#xff0c;连杆轨迹可视化输出&#xff0c;并输出杆件质心轨迹、角速度、速度变化曲线。可定义杆长、滑块速度&#xff0c;滑块初始位置等参数。程序已调通&#xff0c;可直接运行。 268 双滑块连杆机构运动 连…

Github单个文件或者单个文件夹下载插件

有时候我们在github上备份了一些资料&#xff0c;比如pdf,ppt&#xff0c;md之类的,需要用到的时候只要某个文件即可&#xff0c;又不要把整个仓库的zip包下载下来&#xff0c;毕竟有时文件太多&#xff0c;下载慢&#xff0c;我们也不需要所有资料&#xff0c;那么就可以使用到…