Unity -- 遮挡剔除

很多童鞋的Unity作品完成后,发现场景卡的要死,尽管在模型阶段采用了很多优化建模方法,但还是卡顿。电脑端都这么卡,发布到移动端就更不用说了。遇到这种情况,很多童鞋急得团团转,不知如何是好。此时,就必须对场景进行深度优化,当然了,Unity深度优化的方法很多,本文将和大家一起探讨Unity3d最重要也是最有效的场景优化方法-遮挡剔除(Occlusion culling),希望对遇到场景卡顿的童鞋有所帮助。当然,对于机器配置高的童鞋,虽然暂时没遇到卡顿,可别忘了,你的作品最终不是在你自己的机器上运行,而是要在配置不高的用户机或移动端运行的,所以,场景的深度优化是每个人绕不过的一道坎。

那么什么是“遮挡剔除Occlusion culling”呢?通俗地讲,就是将距离相机当前位置最近的一组非透明物体完全遮挡(看不到)的物体,动态地禁用渲染(禁用渲染一些物体,游戏视图的渲染负担就会减轻,作品跑起来就会流畅一些),这就是“遮挡剔除”。简单地说,就是把被遮挡住的物体剔除掉。都被挡住看不见了,还不剔掉,留着这些物体,除了因增加系统渲染负担而导致场景卡顿外,没有任何意义。这只是对遮挡剔除的文字描述,为了让童鞋们直观地理解,下面我们用图解诠释。

在认识“遮挡剔除”之前,得先了解什么是“视锥剔除( Frustum Culling)”。大家都知道,摄相机视野的空间形态是一个四棱锥,Unity称之为“视锥(Frustum)”,默认情况下,Unity会和人的眼睛一样,自动将视锥以外的物体动态地禁止渲染,也就是只渲染视锥以内的物体,这就是“视锥剔除”。一般情况下我们是看不到“视锥剔除”现象的,但“视锥剔除”在运行时会自动启用。

下图左上角几条线封围的部分就是相机的视锥(俯视),因为未使用遮挡剔除,所以场景中的所有物体均可见。
在这里插入图片描述
下图为添加遮挡剔除并使用其可视化预览功能的情况。在右下角弹出的可视化预览面板中,激活“Camera Volumes(相机体积)”,取消“Occlusion Culling(遮挡剔除)”复选框的勾选,目的是先禁用遮挡剔除,只预览“视锥剔除”效果。说到这里,有些童鞋肯定有些晕,不是说添加了遮挡剔除,怎么又禁用了呢?因为是想先给大家直观地展示一下视锥剔除的效果,可一般情况下大家是看不到的,而遮挡剔除使用后,视锥剔除和遮挡剔除的效果都可以用可视化预览,并且取消预览面板中的“Occlusion Culling”复选,所预览到的就只是视锥剔除的效果了,这下明白了吧?由下图可见,视锥剔除后,只有视锥以内的物体可见,视锥以外的物体都被剔除掉了。对比上一张图和下图右下角游戏视图的预览,我们发现视锥剔除后,游戏视图中所看到的内容没有任何变化,这也就是说,视锥剔除不会改变游戏视图的视觉内容,但是由于剔除了视锥以外的内容,游戏视图相机的渲染量被大幅降低,如果不剔除,运行时游戏视图的相机会因渲染负担沉重而卡顿。视锥剔除是Unity3d的特性,无需特别设定,运行时会自动启用。说到这里,一定有童鞋说,既然这是Unity3d特性,那你费什么话,啰里啰嗦说半天视锥剔除?因为搞清楚了视锥剔除的原理,对于理解遮挡剔除是非常有帮助的。
在这里插入图片描述
好了,接下来我们就来讨论遮挡剔除。前面我们取消了预览面板中的“Occlusion Culling”复选,现在我们勾选这一项(如下图所示),也就是在Scene视图中除了预览视锥剔除的效果,也预览遮挡剔除的效果。勾选后,由下图可见,刚才视锥内保留的好多物体又消失了,这是因为相机处于室内,室内墙不透明,视锥内的室外物体都被室内墙挡住看不见,使用遮挡剔除后,那些物体也被剔除掉了,所以不可见了,但是对比下图右下角游戏视图的内容和前面没有任何剔除以及视锥剔除后游戏视图的内容,完全一样,也就是说,遮挡剔除后,也不会改变游戏视图的内容,但是在视锥剔除的基础上,又进一步大幅度降低了相机的渲染量,运行时作品会更加流畅,因为被剔除物体的几何、材质、光照贴图、粒子系统等都不再被渲染了。
在这里插入图片描述
通过上面的静帧图解,大家对视锥剔除和遮挡剔除有了形象的理解,但是运行时,相机的位置和方位角是动态变化的,所以被剔除和被保留的物体也是动态变化的。前面为了简化问题,我用了俯视视角图解了视锥剔除和遮挡剔除,下面我们用动态GIF图像来看看实际遮挡剔除和视锥剔除,由于这里对图像大小有限制,所以GIF只能截取很短的片段,能说明问题就好。

下图左侧是游戏视图,右侧是Scene视图,从Scene视图可见,应用遮挡剔除后,当相机移动时,很多物体被视锥和因遮挡被动态地剔除了,但是游戏视图始终是完整的,根本看不到哪些物体被剔除。这里说明一下,右侧视图当中地面深色的东西是地面的光照贴图,不是物体,剔除后保留的物体只有相机前方很少的一部分,场景的全貌如第一帧所示,大家可以仔细观察右侧视图中保留物体的动态变化。
  在这里插入图片描述
由于上图右侧视图太小,下面我们拉近并手工拖动相机观察一下遮挡剔除和视锥剔除的综合效果(如下图所示)
在这里插入图片描述
到这里,相信大家对什么是遮挡剔除和视锥剔除有了直观的认识和理解,需要说明的是,如果将整个场景合并为一个物体,遮挡剔除和视锥剔除没有任何效果,为什么呢?因为视锥剔除是根据物体的最大外轮廓(或者说是物体的边界框)是否在视锥以内来确定是否被剔除,如果合并成一个物体,相机怎么移动,物体的边界框都在视锥以内。对于遮挡剔除来说,都合并成一个物体了,哪还有被遮挡的物体呢?所以要通过遮挡剔除和视锥剔除优化场景,严禁将所有物体合并为一个物体,除非场景规模非常小。需要说明的是,这只是剔除静态物体的例子,对于动态物体的遮挡剔除,后面再说。

遮挡剔除的过程是使用一个虚拟相机构建潜在可见物体集合的层级结构数据,好让每个摄像机在运行时使用这个数据来识别哪些物体可见,哪些物体不可见。 有了这些数据,Unity的相机将只对可见物体渲染,不仅降低了绘制调用(draw calls)的次数,并可提高游戏的性能。

遮挡剔除的数据由许多单元格(前面GIF图像中Scene视图中的蓝色3d线框)组成,每个单元格是整个场景边界体积的细分,具体地说就是这些单元格构成了一个二叉树结构。遮挡剔除使用了两个树结构,一个用于视图单元(静态物体),另一个用于目标单元(动态物体象)。 所有视图单元映射到定义可见静态物体的索引列表,从而为静态对象提供更准确的剔除效果。

在建模时要记住很重要的一点,即要考虑在物体大小和遮挡剔除的单元格大小之间求得最佳平衡。理想情况下,不应该有比物体小太多的单元格,同样地,也不应该让物体的尺度比单元格大到跨越了许多单元格。可以考虑在建模软件中将大的物体分解成较小的多个物体来改善剔除,但有时也需要考虑将小的物体合并在一起以减少绘制调用(draw calls),并且只要它们都属于同一个单元格,就不会影响遮挡剔除。

可以使用场景视图的“overdraw(绘制重叠)”模式(如下图所示),定性地来查看绘制重叠(之所以发生绘制重叠,是因为物体出现了相互遮挡)的情况,也就是查看场景中物体的相互遮挡情况。
  在这里插入图片描述
我们还是以前面的场景为例,将Scene视图由Shader改为overdraw模式,如下图所示,这是使用未遮挡剔除的场景。overdraw模式用来查看场景中物体的遮挡情况,由下面中间图可见,矩形框所标注的区域亮度很高,说明这个区域物体重叠严重,也就是被遮挡的物体很多。另外,可通过游戏视图的状态信息面板,定量地查看游戏场景的状态,如下面右图右上角所示。从状态信息可见没有遮挡剔除时,批次数量(Batches)为296(这个值越高,越卡顿,2017版之前用Drawcall来表示),三角面约42万,顶点数约62万。
在这里插入图片描述
下图是使用遮挡剔除后的情况。由下面中间图可见,矩形框所标注的区域亮度明显降低,说明这个区域物体重叠已经消除,也就是被遮挡的物体已经被剔除。由下面右图可见,批次数量降至62,三角面降至约15万,顶点数降至约21万。这里说明一下,批次数量(batches)的值是游戏是否运行流畅的重要标志,场景优化的目标就是降低批次数量、三角形数量、顶点数量,这些值越低,作品运行越流畅,否则会很卡顿。
在这里插入图片描述
 由上面的图解再一次说明,遮挡剔除对于优化场景性能非常重要,也非常有效。

遮挡剔除对模型的要求:要使用遮挡剔除,模型必须在建模软件中被分解成合理尺寸的大小,以适应unity中遮挡剔除的单元格细分尺寸。在建模软件中尽可能把模型分解成比较小的几何体,且被比较大的物体(例如墙壁,建筑物等)遮挡的布局对于unity中的遮挡剔除优化是很有帮助的。

遮挡剔除的一般设置:在检视面板中,将要参与遮挡剔除计算的静态物体标记为Occluder Static(静态遮挡物)或Occludee Static(静态被遮挡物),如下图所示。Occluder是遮挡物,也就是遮挡其他物体的物体,Occludee是被遮挡物,也就是被其他物体遮挡的物体。有的物体需要同时勾选Occluder Static和Occludee Static,也就是这个物体既遮挡别的物体,也会被别的物体遮挡。有的物体只需勾选Occluder Static,例如比较大的物体,它是永远不会被其他物体遮挡。而有的物体只需勾选Occludee Static,例如比较小的物体,因为它遮挡其他物体的可能性很小,单独勾选Occluder Static或Occludee Static,可减少遮挡剔除的计算量,即可加快遮挡剔除的烘焙。如果将场景中比较大且不可能被其他物体遮挡的物体设置Occludee Static,或者将比较小且不可能遮挡别的物体的物体设为Occluder Static,除了浪费烘焙时间和增大遮挡剔除数据文件外,毫无意义,所以根据物体的实际情况,合理地对其进行遮挡剔除设置,对加快遮挡剔除烘焙和优化遮挡剔除数据非常重要。另外补充一点,很多人在烘焙场景时,按照官方的要求,将要烘焙的静态物体直接设置为“Static(静态)“,也就是将检视面板右上角的“Static”复选框直接勾选,可当展开“Static”后面的下拉菜单的三角符时,发现后面有一堆这静态那静态的选项,如果直接勾选Static,就等于把这个下拉菜单里的所有选项(除Noting外)都勾选了,我认为,在烘焙场景时,不要直接勾选“Static”,而只需勾选“Lightmap Static”,全部勾上会给烘焙增加多余的计算负担和时间,做什么计算,就勾什么选项,全部勾上,进行遮挡剔除计算时不分青红皂白,会浪费很多时间,原因前面已经说过了,这里再次提醒一下。
在这里插入图片描述
这里特别说明一下,当使用LOD Group优化时,只有LOD0可作为遮挡物。

设置物体的Occluder Static和Occludee Static,也可以在遮挡剔除面板中完成,即单击打开菜单Window > Rendering > Occlusion Culling,在弹出的面板(如下图所示)中选择“Object”,并且在场景中选择“网格渲染器(也就是场景中的物体)”,遮挡剔除面板下方即会出现Occluder Static和Occludee Static两个复选框,在这里勾选,和前面设置物体的Occluder Static和Occludee Static属性异曲同工。遮挡剔除面板各按钮的功能见下图。

在这里插入图片描述
注意一点,只有相机在遮挡区域里面才会生效

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

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

相关文章

【No.21】蓝桥杯组合数学|数位排序|加法计数原理|乘法计数原理|排列数|组合数|抽屉原理|小蓝吃糖果|二项式定理|杨辉三角|归并排序(C++)

组合数学 数位排序 【问题描述】 小蓝对一个数的数位之和很感兴趣,今天他要按照数位之和给数排序。当两个数各个数位之和不同时,将数位和较小的排在前面,当数位之和相等时,将数值小的排在前面。 例如,2022 排在 409 前面, 因为 2022 的数位之和是 6,小于 409 的数位 之和 13。…

(完结)Java项目实战笔记--基于SpringBoot3.0开发仿12306高并发售票系统--(三)项目优化

本文参考自 Springboot3微服务实战12306高性能售票系统 - 慕课网 (imooc.com) 本文是仿12306项目实战第(三)章——项目优化,本篇将讲解该项目最后的优化部分以及一些压测知识点 本章目录 一、压力测试-高并发优化前后的性能对比1.压力测试相关…

Linux部署Sonarqube+Gogs+Jenkins(一)

Linux部署SonarqubeGogsJenkins 一、1.Linux安装JDK11环境1. 本地进行上传2. 进入到/usr/java目录,并且进行解压3. 配置文件/etc/profile,配置环境变量4.让对应的配置文件生效5. 验证 二、Linux安装Python环境三、Linux安装Jenkins环境1、/usr目录下创建…

【送书福利第六期】:《AI绘画教程:Midjourney使用方法与技巧从入门到精通》

文章目录 一、《AI绘画教程:Midjourney使用方法与技巧从入门到精通》二、内容介绍三、作者介绍🌤️粉丝福利 一、《AI绘画教程:Midjourney使用方法与技巧从入门到精通》 一本书读懂Midjourney绘画,让创意更简单,让设计…

Mysql连接报错:1130-host ... is not allowed to connect to this MySql server如何处理

我用navicat连接我的阿里云服务器的mysql服务器的时候,出现了1130的报错。(mysql Server version: 5.7.42-0ubuntu0.18.04.1 (Ubuntu)) 我来记录一下这个原因,以及修改过程! 1.首先进入mysql -u root -p, mysql客户端…

车辆充电桩管理系统的设计与实现|Springboot+ Mysql+Java+ B/S结构(可运行源码+数据库+设计文档)

本项目包含可运行源码数据库LW,文末可获取本项目的所有资料。 推荐阅读100套最新项目持续更新中..... 2024年计算机毕业论文(设计)学生选题参考合集推荐收藏(包含Springboot、jsp、ssmvue等技术项目合集) 1. 前台功能…

命名空间【C++】(超详细)

文章目录 命名空间的概念命名空间的定义命名空间定义的位置作用域每一个命名空间都是一个独立的域作用域符:: 编译器找一个变量/函数等的定义,寻找域的顺序为什么要有命名空间?1.解决库与程序员定义的同名的重定义问题2.解决程序员…

变分信息瓶颈

变分信息瓶颈和互信息的定义 1 变分信息瓶颈 定义:变分信息瓶颈(Variational Information Bottleneck)是一种用于学习数据表示的方法,它旨在通过最小化输入和表示之间的互信息来实现数据的压缩和表示学习。这种方法通常用于无监…

pnpm、monorepo分包管理、多包管理、npm、vite、前端工程化、保姆级教程

浅尝pnpm monorepo 多包管理方案 💡tips: 创建pnpm monorope多包管理框架流程 初始化 mkdir taurus & cd taurus pnpm init创建基础文件 创建文件pnpm-workspace.yaml packages:- packages/**创建文件夹packages/ -packages/ -package.json -pnpm-workspace…

Java类与对象:从概念到实践的全景解析!

​ 个人主页:秋风起,再归来~ 文章专栏:javaSE的修炼之路 个人格言:悟已往之不谏,知来者犹可追 克心守己,律己则安! 1、类的定义格式 在java中定义类时需要用到…

DSVPN实验报告

一、分析要求 1. 配置R5为ISP,只能进行IP地址配置,所有地址均配为公有IP地址。 - 在R5上,将接口配置为公有IP地址,并确保只进行了IP地址配置。 2. R1和R5之间使用PPP的PAP认证,R5为主认证方;R2于R5之间…

【MySQL】DQL-基础查询-语句&演示(查询多个字段 / 所有字段/并设置别名/去重)

前言 大家好吖,欢迎来到 YY 滴MySQL系列 ,热烈欢迎! 本章主要内容面向接触过C Linux的老铁 主要内容含: 欢迎订阅 YY滴C专栏!更多干货持续更新!以下是传送门! YY的《C》专栏YY的《C11》专栏YY的…

一分钟了解三极管到底放大了什么?

目录 三极管放大原理 三极管的工作状态 截止区 放大区 饱和区 三极管的放大作用 电流放大 电压放大 功率放大 在电子学中,三极管通常用于实现信号放大、开关控制等多种功能,三极管主要功能是放大电流信号。下面,将详细解释三极管放大的原理和…

海格里斯助推实体制造业转型升级 “算法定义硬件”解题AIoT市场

随着自动化的发展,电子商务和智能制造推动了自动化立体仓库的快速发展与创新,产生了“密集仓储”的概念。对于一个实体企业来讲,其数智物流转型正在趋向于“去伪存真”,企业追求高ROI与真实经济价值,具有降本增效的业务…

java(1)之环境部署

1、下载安装包 直接百度java 点击这个就可以,进去之后下载,根据自身情况,window就下Windows版本的记得下那个jdk别下别的(用不了),然后下一个编译器可以是idea可以是eclipse都可以 2、环境搭建 分为两步…

使用pdf表单域填充pdf内容

需要引用如下包 <dependency><groupId>com.itextpdf</groupId><artifactId>itext-core</artifactId><version>8.0.3</version><type>pom</type></dependency>1、预先准备一个pdf模板&#xff0c;并在指定位置添加…

IDEA的Scala环境搭建

目录 前言 Scala的概述 Scala环境的搭建 一、配置Windows的JAVA环境 二、配置Windows的Scala环境 编写一个Scala程序 前言 学习Scala最好先掌握Java基础及高级部分知识&#xff0c;文章正文中会提到Scala与Java的联系&#xff0c;简单来讲Scala好比是Java的加强版&#x…

云原生(六)、CICD - Jenkins快速入门

Jenkuns快速入门 一、CICD概述 CICD是持续集成&#xff08;Continuous Integration&#xff09;和持续部署&#xff08;Continuous Deployment&#xff09;的缩写。它是软件开发中的一种流程和方法论&#xff0c;旨在通过自动化的方式频繁地将代码集成到共享存储库中&#xf…

Jira 软件缺陷管理 (软件测试)

内容来源&#xff1a;总结黑马课程 1.软件缺陷信息 2.创建缺陷问题 2.1 缺陷模板 2.2 创建缺陷问题模板

vite+vue3使用模块化批量发布Mockjs接口

在Vue3项目中使用Mock.js可以模拟后端接口数据&#xff0c;方便前端开发和调试。下面是使用vitevue3使用模块化批量发布Mockjs接口的步骤&#xff1a; 1. 安装Mock.js 在Vue3项目的根目录下&#xff0c;使用以下命令安装Mock.js&#xff1a; npm install mockjs --save-dev …