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

news2025/1/23 12:07:43

在这里插入图片描述
本系列为作者学习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.coloradmin.cn/o/1718914.html

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

相关文章

报表工具DataEase技术方案(一)

一、使用场景&#xff1a; 企业内部系统想要快速接入报表功能&#xff0c;但是局限于人力资源不足&#xff0c;不想沿用传统的前端后端开发模式&#xff0c;可以尝试使用开源报表工具 DataEase。 二、架构设计&#xff1a; 使用最简便的报表集成方式&#xff0c;通过DataEase…

越洗越黑”的Pandas数据清洗

引言 先来一个脑筋急转弯活跃一下枯燥工作日常&#xff0c;问&#xff1a;“什么东西越洗越黑&#xff1f;” 有没有猜到的&#xff1f;猜不到我告诉你吧&#xff01; 答案是“煤球”。那么这个脑机急转弯跟我们要讨论的话题有没有关系呢&#xff1f; 嗯是的&#xff0c;还是沾…

2024年大屏幕互动源码+动态背景图和配乐素材+搭建教程

2024年大屏幕互动源码动态背景图和配乐素材搭建教程 php宝塔搭建部署活动现场大屏幕互动系统php源码 运行环境&#xff1a;PHPMYSQL 下载源码地址&#xff1a;极速云

Leetcode刷题笔记7

69. x 的平方根 69. x 的平方根 - 力扣&#xff08;LeetCode&#xff09; 假设求17的平方根 解法一&#xff1a;暴力解法 从1开始依次尝试 比如1的平方是1&#xff0c;2的平方是4...直到5的平方&#xff0c;25>17&#xff0c;所以一定是4点几的平方&#xff0c;所以等于4…

打家劫舍I 打家劫舍II (leetcode)

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 打家劫舍Ihttps://leetcode.cn/problems/Gu0c2T/打家劫舍IIhttps://leetcode.cn/problems/PzWKhm/ 状态转移方程就是这样的&#xff1a; i位置选择偷f[i]&#xff1a;f[i] g[i-1] nums[i];i位置选择不偷g[i]&#xff1a;g…

C语言 指针——指针变量做函数参数:典型实例

目录 一个典型实例——两数互换 一个典型实例——两数互换 Errors

拓展虚拟世界边界,云手机可以做到吗

虚拟世界&#xff0c;AI&#xff0c;VR等词汇是21世纪最为流行的词汇&#xff0c;在科技背后&#xff0c;这些词汇的影响变得越来越大&#xff0c;已经走进了人们的世界&#xff0c;比如之前APPLE发布的vision pro&#xff0c;使人们能够更加身临其境的体验到原生os系统&#x…

存储 Bean 对象更加简单的方式

前置操作 如果是在 spring-config 中添加 bean 标签来注册内容&#xff0c;每个类都要弄一次就显得麻烦和臃肿了&#xff0c;对于 new 操作而言就没有什么优势了。因此 spring 就引入了注解操作来实现对 Bean 对象的存储。 配置扫描路径 想要将对象成功的存储到 Spring 中&…

【Linux系列】深入解析 `kill` 命令:Linux 下的进程管理利器

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

【每日力扣】32. 最长有效括号 416. 分割等和子集

&#x1f525; 个人主页: 黑洞晓威 &#x1f600;你不必等到非常厉害&#xff0c;才敢开始&#xff0c;你需要开始&#xff0c;才会变的非常厉害 32. 最长有效括号 给你一个只包含 ( 和 ) 的字符串&#xff0c;找出最长有效&#xff08;格式正确且连续&#xff09;括号 子串 …

民国漫画杂志《时代漫画》第34期.PDF

时代漫画34.PDF: https://url03.ctfile.com/f/1779803-1248636026-7e46c5?p9586 (访问密码: 9586) 《时代漫画》的杂志在1934年诞生了&#xff0c;截止1937年6月战争来临被迫停刊共发行了39期。 ps: 资源来源网络!

亚马逊云科技峰会盛大举行 | 光环新网携光环云数据以高性能智算服务助力企业创新发展

2024年5月29日&#xff0c;云计算行业的年度盛典”2024亚马逊云科技中国峰会”在上海世博中心再次盛大启幕。作为全球领先的云计算服务提供商&#xff0c;亚马逊云科技峰会聚焦前沿科技&#xff0c;与来自不同行业、不同科技领域的优秀企业和用户共同探索AI时代的云端创新发展。…

mysql大表的深度分页慢sql案例(跳页分页)-2

1 背景 有一张大表&#xff0c;内容是费用明细表&#xff0c;数据量约700万级&#xff0c; 普通B树索引KEY idx_fk_fymx_qybh_xfsj (qybh,xfsj)。 1.1 原始深度分页sql select t.* from fk_fymx t where t.qybh XXXXXXX limit 100000,100; 深度分页会导致加载数据行过多1000001…

协方差矩阵如何能看出多元随机变量的分布情况

协方差矩阵可以通过以下几个方面帮助我们理解多元随机变量的分布情况&#xff1a; 变量的方差&#xff08;对角线元素&#xff09;&#xff1a; 协方差矩阵的对角线元素表示各个变量的方差。方差反映了每个变量本身的离散程度。方差越大&#xff0c;表示该变量在其均值周围的波…

【计算机视觉(6)】

基于Python的OpenCV基础入门——图像的几何变换&#xff08;2&#xff09; 仿射变换透视变换仿射变化和透视变换的代码实现&#xff1a; 仿射变换 仿射变换是一种仅在二维平面中发生的几何变形&#xff0c;通俗的理解原来的直线变换之后还是直线&#xff0c;平行线变换之后还是…

[ubuntu18.04]搭建mptcp测试环境说明

MPTCP介绍 Multipath TCP — Multipath TCP -- documentation 2022 documentation 安装ubuntu18.04&#xff0c;可以使用虚拟机安装 点击安装VMware Tool 桌面会出现如下图标 双击打开VMware Tools&#xff0c;复制如下图所示的文件到Home目录 打开终端&#xff0c;切换到管…

100道面试必会算法-27-美团2024面试第一题-前缀和矩阵

100道面试必会算法-27-美团2024面试第一题-前缀和矩阵 问题解读 给定一个 n x n 的二进制矩阵&#xff0c;每个元素是 0 或 1。我们的任务是计算矩阵中所有边长为 k 的子矩阵中&#xff0c;包含特定数量 1 的情况。例如&#xff0c;我们希望找到所有边长为 k 的子矩阵中包含 k…

【面试八股总结】MySQL事务:事务特性、事务并行、事务的隔离级别

参考资料&#xff1a;小林coding 一、事务的特性ACID 原子性&#xff08;Atomicity&#xff09; 一个事务是一个不可分割的工作单位&#xff0c;事务中的所有操作&#xff0c;要么全部完成&#xff0c;要么全部不完成&#xff0c;不会结束在中间某个环节。原子性是通过 undo …

Apache Druid 代码执行(CVE-2021-25646)漏洞复现

Druid简介与漏洞成因 Apache Druid是一个高性能的实时分析型数据库&#xff0c;旨在对大型数据集进行快速查询分析。Druid最常被当做数据库来用以支持实时摄取、高性能查询和高稳定运行的应用场景&#xff0c;同时&#xff0c;Druid也通常被用来助力分析型应用的图形化界面&am…

【方法】如何取消PPT“以只读方式打开“?

以“只读方式”打开的PPT&#xff0c;可能会受到不同的限制&#xff0c;比如无法编辑修改内容&#xff0c;无法保存原文件等。那如何取消PPT的“只读方式”呢&#xff1f;不同形式的“只读方式”&#xff0c;取消方法不同&#xff0c;下面一起来看看吧&#xff01; “只读方式”…