【Unity】 场景优化策略

Unity 场景优化策略

GPU instancing

使用GPU Instancing可以将多个网格相同、材质相同、材质属性可以不同的物体合并为一个批次,从而减少Draw Calls的次数。这可以提高性能和渲染效率。

GPU instancing可用于绘制在场景中多次出现的几何体,例如树木或灌木丛。

渲染管线兼容性

特征内置渲染管线通用渲染管线 (URP)高清渲染管线 (HDRP)自定义可编程渲染管线 (SRP)
GPU instancing是的是 (1)是 (1)是 (1)

注意

  1. 仅当着色器与 SRP Batcher 不兼容时。

** 设置GPU instancing**

设置很简单只需一步

在默认的材质球下找到Enable GPU Instancing,勾选就可以。


对比效果

没有勾选时:Batches是230左右,Saved By Batching是0

勾选后:Batches是8,Saved By Batching是222左右

使用下文的shader给材质添加随机色后:Batches是4,Saved By Batching是63(这里没有添加阴影Batch会少)

补充:

MaterialPropertyBlock

批处理一般作用与相同的材质。当需要对shader相同材质属性不同的模型批处理时可以用MaterialPropertyBlock。

MaterialPropertyBlock除了在 Renderer.SetPropertyBlock 被使用,还可以在 Graphics.DrawMesh使用。

    void Start(){MaterialPropertyBlock material = new MaterialPropertyBlock();material.SetColor("_Color", new Color(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f)));GetComponent<MeshRenderer>().SetPropertyBlock(material);}

这里可以发现,虽然颜色不一样,但是材质球指向的是同一个

** 创建支持 GPU instancing的着色器**

渲染管线兼容性

特征内置渲染管线通用渲染管线 (URP)高清渲染管线 (HDRP)自定义可编程渲染管线 (SRP)
自定义 GPU instancing着色器是的

顶点和片元着色器示例

Shader "Custom/SimplestInstancedShader"
{Properties{_Color ("Color", Color) = (1, 1, 1, 1)}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag//生成实例化变体。它是可选的。#pragma multi_compile_instancing#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;//在顶点着色器输入/输出结构中定义INSTANCE_ID。UNITY_VERTEX_INPUT_INSTANCE_ID};struct v2f{float4 vertex : SV_POSITION;//使INSTANCE_ID访问片元着色器中的实例化属性。UNITY_VERTEX_INPUT_INSTANCE_ID };//声明名为 的每个实例常量缓冲区的开始UNITY_INSTANCING_BUFFER_START(Props)UNITY_DEFINE_INSTANCED_PROP(float4, _Color)//声明名为 的每个实例常量缓冲区的结尾     UNITY_INSTANCING_BUFFER_END(Props)v2f vert(appdata v){v2f o;//允许顶点着色器函数访问INSTANCE_IDUNITY_SETUP_INSTANCE_ID(v);//将INSTANCE_ID从输入结构复制到顶点着色器中的输出结构。UNITY_TRANSFER_INSTANCE_ID(v, o);o.vertex = UnityObjectToClipPos(v.vertex);return o;}fixed4 frag(v2f i) : SV_Target{//允许片元着色器函数访问INSTANCE_IDUNITY_SETUP_INSTANCE_ID(i);//访问实例化常量缓冲区中的每个实例着色器属性return UNITY_ACCESS_INSTANCED_PROP(Props, _Color);}ENDCG}}
}

静态批处理

它通过将多个静态物体合并成一个批次来减少渲染调用,从而减少CPU和GPU的负载,可以显著减少渲染过程中的Draw Call数量,从而提高性能。

静态批处理适用于那些不会在运行时改变位置、旋转或缩放的物体,例如地形、建筑物等。

渲染管线兼容性

特征内置渲染管线通用渲染管线 (URP)高清渲染管线 (HDRP)自定义可编程渲染管线 (SRP)
静态批处理是的是的是的是的

静态批处理的设置

设置也很简单只需两步

  1. 在ProjectSettings→player→OtherSetting→StaticBatching,勾选

  2. 在默认的材质球下找到Enable GPU Instancing,勾选就可以。

静态批处理的限制

  • 游戏对象处于活动状态且禁止(非禁止对象的会强制禁止)。
  • 游戏对象具有MeshFilter组件,并且该组件已启用。
  • MeshFilter 组件引用了Mesh
  • 网格的顶点数大于 0。
  • 该网格尚未与另一个网格合并。
  • 游戏对象具有MeshRenderer组件,并且该组件已启用。
  • 要批处理在一起的网格,使用相同的顶点属性。例如,Unity 可以对使用顶点位置、顶点法线和一个 UV 的网格进行批处理,但不能对使用顶点位置、顶点法线、UV0、UV1 和顶点切线的网格进行批处理。

效果

Batches是8,Saved By Batching是211

静态批处理的控制

使用StaticBatchingUtility类来控制静态批处理。

using UnityEngine;public class StaticBatchingController : MonoBehaviour
{void Start(){StartStaticBatch();}GameObject[] GetGameObjectsToBatch(){// 返回需要静态批处理的游戏对象数组// 例如:可以通过标签、层级或者其他方式来获取需要静态批处理的游戏对象// 这里只是一个简单示例,实际情况可能需要根据具体需求来获取游戏对象return GameObject.FindGameObjectsWithTag("StaticBatchingObject");}void StartStaticBatch(){// 获取所有需要静态批处理的游戏对象GameObject[] gameObjectsToBatch = GetGameObjectsToBatch();// 执行静态批处理StaticBatchingUtility.Combine(gameObjectsToBatch, this.gameObject);}void StopStaticBatch(){// 禁用静态批处理StaticBatchingUtility.Combine(null, this.gameObject);}
}

动态批处理

通过将运行时动态地将多个静态或动态的游戏对象合并成一个批次,减少渲染调用的数量,提高帧率和性能。

渲染管线兼容性

特征内置渲染管线通用渲染管线 (URP)高清渲染管线 (HDRP)自定义可编程渲染管线 (SRP)
动态批处理是的是的是的

静态批处理的设置

设置也很简单只需一步

在ProjectSettings→player→OtherSetting→DynamicBatching,勾选

动态批处理的限制

  • Unity 无法对包含超过 225 个顶点的网格应用动态批处理。这是因为网格的动态批处理每个顶点都有开销。
    使用顶点位置、顶点法线和单个 UV,则 Unity 最多可以批处理 225 个顶点。但是,如果着色器使用顶点位置、顶点法线、UV0、UV1 和顶点正切,则 Unity 只能批处理 180 个顶点。
  • 如果对象使用不同的材质实例,则 Unity 无法将它们批处理在一起,即使它们本质是使用一个shader。唯一的例外是阴影投射器渲染。
  • 带有光照贴图的游戏对象具有额外的渲染器参数。这意味着,如果要对光照映射的游戏对象进行批处理,它们必须指向相同的光照贴图位置。
  • Unity 无法将动态批处理完全应用于使用多个pass的shader对象。
    • 几乎所有 Unity 着色器都支持多个灯光前向渲染为了实现这一点,他们为每个光源处理一个额外的渲染通道。Unity 仅对第一个渲染通道进行批处理。它无法对额外的每像素光源的绘制调用进行批处理。

效果

Batches是8,Saved By Batching是220左右

手动合并网格

手动将多个网格合并为一个网格,在网格靠得很近且彼此不相对移动的情况下,可以很好地替代,静态批处理和动态批处理。

警告:Unity 无法单独剔除您组合的网格。这意味着,如果组合网格的一部分出现在屏幕上,Unity 会绘制整个组合网格。如果网格是静态的,并且希望 Unity 单独剔除它们,使用静态批处理。

合并网格的设置方法

  • 在创作网格时在资源生成工具中。即模型制作阶段将其合并到一起,同时这样处理相同的模型会照成模型体量的变大。
  • 在 Unity 中使用 Mesh.CombineMeshes

CombineMeshes的用法

//强制添加组件
[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(MeshRenderer))]
public class ExampleClass : MonoBehaviour
{void Start(){MeshFilter[] meshFilters = GetComponentsInChildren<MeshFilter>();//  CombineInstance 结构体 用于描述要使用 Mesh.CombineMeshes 组合的网格。CombineInstance[] combine = new CombineInstance[meshFilters.Length];int i = 0;while (i < meshFilters.Length){combine[i].mesh = meshFilters[i].sharedMesh;combine[i].transform = meshFilters[i].transform.localToWorldMatrix;meshFilters[i].gameObject.SetActive(false);i++;}Mesh mesh = new Mesh();mesh.CombineMeshes(combine);transform.GetComponent<MeshFilter>().sharedMesh = mesh;transform.gameObject.SetActive(true);}
}
CombineInstance 字段说明
lightmapScaleOffset应用于网格的烘焙光照贴图UV比例和偏移量。
mesh要组合的网格。
realtimeLightmapScaleOffset应用于网格的实时光照贴图UV比例和偏移。
subMeshIndex网格的子网格索引。
transform在组合之前要变换网格的矩阵。有关示例,请参阅 Mesh.CombineMeshes。

效果

Batches是8,Saved By Batching是0

遮挡剔除

遮挡剔除不说了

频繁使用遮挡剔除可能会导致一些性能问题,特别是在复杂的场景中。因为每次相机移动或场景发生变化时,都需要重新计算遮挡剔除信息,这可能会消耗一定的计算资源。

LOD

Unity中使用LOD(Level of Detail)时,可以根据相机与物体的距离,自动切换不同级别的模型,以提高性能和减少渲染开销。

unityLOD设置方法

  1. 创建多个不同级别的模型,分别代表远、中、近距离的模型。

  2. 将这些模型作为同一个游戏对象的子对象,并添加LOD Group组件。

  3. 在LOD Group组件中设置每个级别的距离和对应的模型。

  4. Unity会根据相机与物体的距离自动切换不同级别的模型。

效果

可以与静态批处理和动态批处理结合

Batches是11,Saved By Batching是310左右

层剔除 layerCullDistances

用于指定摄像机在渲染不同图层时的剔除距离。通过设置layerCullDistances,可以控制摄像机在渲染不同图层时的剔除距离,从而提高渲染性能。层剔除和lod类似,也是按距离剔除,不同的是层剔除不会替换

float[] distances = new float[32];//设定32个默认图层
distances[11] = 300;//为第11层设定距离
Camera.mian.layerCullDistances = distances;//将剔除层传递给相机

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

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

相关文章

深度强化学习论文中的阴影折线图——总结和分析

前言 作为目前人工智能算法的一个重要领域&#xff0c;强化学习算法的表现非常出色&#xff0c;然而&#xff0c;强化学习算法的结果是出了名的不稳定&#xff1a;超参数的搜索空间往往非常大&#xff0c;算法对不同超参数都较为敏感&#xff0c;且哪怕仅仅只有随机数种子的不…

NSSCTF web刷题记录5

文章目录 [HZNUCTF 2023 preliminary]ezlogin[MoeCTF 2021]地狱通讯[NSSRound#7 Team]0o0[ISITDTU 2019]EasyPHP[极客大挑战 2020]greatphp[安洵杯 2020]Validator[GKCTF 2020]ez三剑客-ezweb[安洵杯 2019]easy_serialize_php [HZNUCTF 2023 preliminary]ezlogin 考点&#xff…

ppt中的字体,如何批量替换?

想要将PPT中的文字全部更换&#xff0c;有什么方便的方法吗&#xff1f;今天分享两个方法&#xff0c;一键修改ppt文件字体。 方法一&#xff1a; 找到功能栏中的编辑选项卡&#xff0c;点击替换 – 替换字体&#xff0c;在里面选择我们想要替换的字体就可以了。 方法二&…

css3 初步了解

1、css3的含义及简介 简而言之&#xff0c;css3 就是 css的最新标准&#xff0c;使用css3都要遵循这个标准&#xff0c;CSS3 已完全向后兼容&#xff0c;所以你就不必改变现有的设计&#xff0c; 2、一些比较重要的css3 模块 选择器 1、标签选择器&#xff0c;也称为元素选择…

Linux 使用随记

Linux 使用随记 shell 命令行模式登录后所取得的程序被成为shell&#xff0c;这是因为这个程序负责最外层的跟用户&#xff08;我们&#xff09;通信工作&#xff0c;所以才被戏称为shell。 命令 1、命令格式 command [-options] parameter1 parameter2 … 1、一行命令中第…

信息安全工程师软考知识点

文章目录 知识点总结2023软考总结选择题问答题 知识点总结 军用不对外公开的信息系统安全等级至少应该>三级 数据中心的耐火等级不应低于二级 政府网站的信息安全等级原则上不应低于二级第一代交换机以集线器为代表&#xff0c;工作在OSI物理层 第二代交换机以太网交换机&a…

【MySQL】事务(中)

文章目录 事务异常与产出结论手动提交 和自动提交 对 回滚的区别 事务隔离性理论如何理解隔离性&#xff1f;MySQL的隔离级别事务隔离级别的查看设置隔离级别 事务异常与产出结论 在没有启动事务之前&#xff0c;account表中存在孙权和刘备的数据 在启动事务后&#xff0c; 向 …

问界「力压」比亚迪,到底什么是RAEB?

作者 | Amy 编辑 | 德新 本周&#xff0c;一辆AITO问界M5智驾版「骑」上比亚迪海豚的视频引发热议。从视频推测&#xff0c;应该是M5在倒车过程中&#xff0c;猛地加速&#xff0c;一下冲到海豚车顶了。 这样富有戏剧性的视频&#xff0c;很快引爆了各大车友群。 不过在吃瓜…

解决 vue3 element 表格和图片预览样式有冲突

查看表格中的预览出现样式问题冲突 <el-image:src"${realSrc}"fit"cover":style"width:${realWidth};height:${realHeight};":preview-src-list"realSrcList":append-to-body"true"><template #error><div c…

Project IDX简介——这是一项改进全栈、多平台应用程序开发的试验

如今&#xff0c;将应用程序从零开发到生产环境&#xff08;尤其是在移动、网络和桌面平台上运行良好的应用程序&#xff09;感觉就像构建一台 Rube Goldberg 机器。您必须在无尽的复杂性海洋中航行&#xff0c;将各种技术堆栈粘合在一起&#xff0c;以引导、编译、测试、部署和…

基于SSM+Vue的健身房管理系统

基于SSMVue的健身房管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringMyBatisSpringMVC工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 课程信息 健身器材 管理员界面 用户界面 摘要 健身房管理系统是一种利用现…

MySQL学习day02

一、SQL通用语法 1&#xff09;SQL语句可以单行或多行书写&#xff0c;以分号结尾 2&#xff09;SQL语句可以使用空格/缩进来增强语句的可读性 3&#xff09;MySQL数据库的SQL语句不区分大小写&#xff0c;关键字建议使用大写 4&#xff09;注释&#xff1a; a)单行注释&#x…