【Unity】 场景优化策略

news2024/12/24 2:42:04

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 100

        Pass
        {
            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_ID
                UNITY_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_ID
                UNITY_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.coloradmin.cn/o/1205026.html

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

相关文章

【分享】Excel“只读方式”的两种模式

查阅Excel表格的时候&#xff0c;担心不小心修改了内容&#xff0c;可以给Excel设置以“只读方式”打开&#xff0c;这样就算修改了内容也不能直接保存表格。Excel表格可以设置两种“只读方式”&#xff0c;一起来看看吧&#xff01; “只读方式” 1&#xff1a; 打开Excel表…

CCF ChinaSoft 2023 论坛巡礼 | 顶会顶刊论坛

2023年CCF中国软件大会&#xff08;CCF ChinaSoft 2023&#xff09;由CCF主办&#xff0c;CCF系统软件专委会、形式化方法专委会、软件工程专委会以及复旦大学联合承办&#xff0c;将于2023年12月1-3日在上海国际会议中心举行。 本次大会主题是“智能化软件创新推动数字经济与社…

Netty入门指南之Reactor模型

作者简介&#xff1a;☕️大家好&#xff0c;我是Aomsir&#xff0c;一个爱折腾的开发者&#xff01; 个人主页&#xff1a;Aomsir_Spring5应用专栏,Netty应用专栏,RPC应用专栏-CSDN博客 当前专栏&#xff1a;Netty应用专栏_Aomsir的博客-CSDN博客 文章目录 参考文献前言单线程…

网银转账虚拟生成器在线制作,工商农业邮政建设招商,标签+对话框+画板+快照实现

标签对话框画板快照实现就实现了一个虚拟截图生成器&#xff0c;当然我加了水印了&#xff0c;这个图片你根本盗用不了&#xff0c;图片模版的话网上真的太多了&#xff0c;我这个也是网上找的&#xff0c;自己百度图库搜一下&#xff0c;然后标签记得一定用黑月的透明标签&…

c语言-数据结构-链表分割

链表分割实际上是给定一个值&#xff0c;遍历链表把链表中小于该值的节点与大于该值的节点分开&#xff0c;一般是将小于该值的节点放到链表的前面部分&#xff0c;大于该值的节点放在链表的后面部分。 链表分割示意图如下&#xff1a; 思路&#xff1a; 首先创建两条带哨兵位节…

Topk问题!(面试高频常考)

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; 剑指offer &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言&#x1f324;️什么是Top-k问题&#xff1f;&#x1f324;️常见的Top-K问题类型☁️寻找…

Global_Mapper_Pro_25.0安装教程大全

一. 下载&#xff1a; http://dt1.8tupian.net/2/29913a55b1000.pg3二. 介绍&#xff1a; Global Mapper Pro 25是领先的GIS数据处理解决方案&#xff01;提供了一整套符合标准的功能来提升您的操作和技能&#xff0c;您可以最合理的利用您的工具集来完成以前复杂的工作任务&a…

深度学习AIR-PolSAR-Seg图像数据预处理

文章目录 深度学习sar图像数据预处理一.图片预处理操作1.log(1x)处理2.sqrt平方化处理 二.原网络训练效果展示原始数据训练效果展示&#xff1a; 三.对比实验1.采用原始数据2.采用取log(1x)后的数据3.采用取平方后归一化处理&#xff1a; 四.总结&#xff1a;五.思考 深度学习s…

揭秘 DCNN——AlexNet

来源 — gifs.com 一、说明 还记得 2012 年的 ImageNet 视觉识别挑战赛吗&#xff1f;当然&#xff0c;你知道&#xff01;经过大量的反复试验和实验&#xff0c;研究员 Alex Krizhevsky 及其合著者 Ilya Sutskever 和 Geoffrey E. Hinton&#xff08;他真正理解了深度学习中…

Windows没有USB启动选项很常见,但解决方法更常见

当试图在计算机上重新安装Windows 11/10操作系统,或从安装介质启动时,一些用户看到错误–系统没有任何USB启动选项,请在启动管理器菜单中选择其他启动选项。此错误出现在不同OEM的多个设备,原因包括启用了安全引导、禁用了Legacy/CSM支持、联想服务引擎、未正确制作可引导U…

万宾科技智能传感器EN100-C2有什么作用?

在日常生活中井盖是一种常见的城市设施&#xff0c;但井盖出现问题可能会对人们的生活造成什么影响呢&#xff1f;移位或老化的井盖可能会威胁人们的安全&#xff0c;同时也会影响城市生命线的正常运行。然而智能井盖的出现为解决这些问题提供了有效的应对方案。 WITBEE万宾智能…

Day44 力扣动态规划 : 300.最长递增子序列|674. 最长连续递增序列 | 718. 最长重复子数组

Day44 力扣动态规划 : 300.最长递增子序列&#xff5c;674. 最长连续递增序列 &#xff5c; 718. 最长重复子数组 300.最长递增子序列第一印象看完题解的思路dp递推公式遍历顺序初始化 实现中的困难感悟代码 674. 最长连续递增序列第一印象dp状态转移公式遍历顺序初始化 看完题…

能够定时发送朋友圈的软件

此款软件提供便捷的网页端登录方式&#xff0c;让您轻松管理多个账号&#xff0c;实现多账号聚合管理&#xff0c;只需一个界面即可解决所有问题。 朋友圈内容编辑功能强大&#xff0c;让您在输入框内输入文本内容&#xff0c;点击表情图标选择表情&#xff0c;还能通过“”图标…

Go利用反射实现一个ini文件的解析器程序

package mainimport ("bufio" // 逐行读取配置文件"fmt""log""os""reflect""strconv""strings" )type Config struct { // 定义配置结构体Section1 Section1 ini:"section1" // 嵌套结构体1…

洗地机哪个牌子最好用?洗地机怎么选?2023洗地机选购推荐

家里有小孩或者是养有宠物的都有一个深刻的体验&#xff0c;那就是房子每天都很乱&#xff0c;隔三岔五就得做一次卫生清理、地板杀菌等。如果是房屋面积太大的话&#xff0c;只靠自己手动清洁是非常的耗时间并且还很劳累。洗地机的出现可谓是造福人类&#xff0c;解脱了家庭劳…

EM@一次双绝对值不等式

文章目录 一次双绝对值不等式求解步骤去绝对值情况分析&#x1f47a;例例代数法几何方法比较 例 一次双绝对值不等式求解步骤 设 f ∣ f 1 ∣ ∣ f 2 ∣ f|f_1||f_2| f∣f1​∣∣f2​∣, f 1 , f 2 f_1,f_2 f1​,f2​都是一次多项式,则原不等式 f ⩾ a f\geqslant{a} f⩾a或 …

跨越编程界限:C++到JavaSE的平滑过渡

JDK安装 安装JDK 配置环境变量&#xff1a; Path 内添加 C:\Program Files\Java\jdk1.8.0_201\bin 添加 JAVA_HOME C:\Program Files\Java\jdk1.8.0_201 添加 CLASSPATH .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar 第一个Java程序 HelloWorld.java public class…

记录--让我们来深入了解一下前端“三清”是什么

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 前端“三清” 在前端开发中&#xff0c;我们经常听到关于“三清”的说法&#xff0c;即 window、document、Object。这三者分别代表了 BOM(浏览器对象模型)、DOM(文档对象模型)以及 JS 的顶层对象。在…

Git精讲(一)

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、Git初识1、提出问题2、如何解决--版本控制器3、注意事项 二、Git 安装1、Linux-centos2、…

世微 升压恒压IC dc-dc转换器 充电器手持设备便携式产品 AP8660

AP8660是一款升压dc-dc转换器&#xff0c;内置MOS调节器&#xff0c;内部补偿&#xff0c;还可以最小6个外部组件&#xff0c;内部的软识启动功能可以降压涌入电流 AP8660 SOT23-6封装&#xff0c;可以为PCB提供节省空间 特点 可调输出&#xff0c;最高达到24W 内部固定PWM频…