unity Gpu优化

不一样的视角,深度解读unity性能优化。unity性能优化,unity内存优化,cpu优化,gpu优化,资源优化,资源包、资源去重优化,ugui优化。

  • gpu优化
    • 静态批处理
      • 静态批处理原理规则
        • 静态合批的原理
        • 静态合批的必须条件
        • 结论与总结
          • 静态合批原则与优化核心
    • 动态批处理
    • srpBach
    • Gpu实例化
    • 蒙皮实例化

gpu优化

静态批处理

静态批处理原理规则

静态批处理官方文档

静态合批的原理

静态批处理是场景中将同一个材质(属性完全相同的同一个材质,可以是不同网格)的不同变换(位移,旋转,缩放)网格合并成一个大的网格。然后在调用drawcall绑定shader设置shader状态和绑定网格到Gpu,进而一次完成渲染一个大网格实现渲染场景多个相同网格的优化

基础条件

  • GameObject 是活动的。
  • GameObject 具有启用的 Mesh Filter 组件。
  • Mesh Filter 组件引用一个 Mesh。
  • Mesh 启用了读/写。
  • Mesh 的顶点数大于 0。
  • Mesh 没有与其他 Mesh 组合过。
  • GameObject 具有启用的 Mesh Renderer 组件。
  • Mesh Renderer 组件未使用具有 DisableBatching 标签设置为 true 的材质。
  • Camera.main.opaqueSortMode这个对静态合批的影响很大
静态合批的必须条件
  • 网格使用同一个材质,如果通过Instance或者其它方法获取的材质即使属性完全相同,也不是同一个材质。除非所有相同网格都使用这个实例化后的材质,才是同一材质
  • 然后就是shader没有设置DisableBatching 标签设置为 true
  • Mesh 启用了读/写,值得一提的是当你把GameObject的Static Editor Flags 中启用 Batching Static时,运行unity后,unity会自动将网格设置为可读状态

注意:静态批处理对顶点数量有上限。每个静态批次最多可以包含 64000 个顶点。如果超过此数量,Unity 会创建另一个批次。
为了测试静态批处理首先编写一个测试脚本

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Random = UnityEngine.Random;public class GreenCtrl : MonoBehaviour
{[Serializable]public class MeshInfo{public MeshInfo(Mesh mesh){CurMesh = mesh;// Vertex = mesh.vertices.Length;Name = mesh.name;}public string Name;public Mesh CurMesh;public int Vertex;public override int GetHashCode(){return CurMesh.name.GetHashCode();}}[SerializeField] private Transform[] greens;[SerializeField] private Transform greensParent;public int count = 2000;public int size = 100;public float localScale = 10;public GameObject[] instances;public bool isGpuInstance = false;public Mesh[] meshes;// Start is called before the first frame updatevoid Start(){if (isGpuInstance){Gen();InitData();}Camera.main.opaqueSortMode = UnityEngine.Rendering.OpaqueSortMode.Default;MargeMesh();}void MargeMesh(){StaticBatchingUtility.Combine(instances, greensParent.gameObject);}public void CloseSort(){Camera.main.opaqueSortMode = UnityEngine.Rendering.OpaqueSortMode.NoDistanceSort;}public void SetMesh(){HashSet<Mesh> meshHash = new HashSet<Mesh>();meshes = Array.ConvertAll(instances, obj => obj.GetComponentInChildren<MeshFilter>().sharedMesh);HashSet<string> names = new HashSet<string>();for (int i = 0; i < instances.Length; i++){Mesh mesh = meshes[i];List<Vector3> v = new List<Vector3>();meshHash.Add(mesh);names.Add(mesh.name);}meshes = meshHash.ToArray();Array.Sort(meshes, (m1, m2) => GetIndex(m1.name).CompareTo(GetIndex(m2.name)));Debug.LogError($"所有网格总数:{meshHash.Count}====={names.Count}");}int GetIndex(string name){int index = 0;int.TryParse(name.Substring("Combined Mesh (root:scene) ".Length), out index);return index;}// Update is called once per framevoid Update(){if (isGpuInstance){ResetDraw();}}public void Gen(){while (greensParent.childCount > 0){DestroyImmediate(greensParent.GetChild(0).gameObject);}instances = new GameObject[count];for (int i = 0; i < count; i++){Vector2 pos = Random.insideUnitCircle; //随机一个圆内的位置出来pos *= size;// float x = Mathf.Abs(pos.x);//把随机出来的位置固定到第一象限// float y = Mathf.Abs(pos.y);int index = (int)Mathf.Lerp(0, greens.Length, Random.value);Transform trans = greens[index];trans = Instantiate(trans, greensParent);trans.localPosition = new Vector3(pos.x, Mathf.Lerp(0, 2, Random.value), pos.y);trans.localScale = Vector3.one * localScale;instances[i] = trans.gameObject;}InitObj();}private MaterialPropertyBlock materialPropertyBlock;void InitObj(){materialPropertyBlock = new MaterialPropertyBlock();MeshRenderer renderer;foreach (GameObject obj in instances){// 为每个实例设置一个随机颜色float r = Random.Range(0f, 1f);float g = Random.Range(0f, 1f);float b = Random.Range(0f, 1f);Color randomColor = new Color(r, g, b);// 设置属性块中的颜色// materialPropertyBlock.SetColor("_Color", randomColor);// 获取渲染器并应用属性块renderer = obj.GetComponent<MeshRenderer>();// renderer.SetPropertyBlock(materialPropertyBlock);}}public void GenGpuInstance(){for (int i = 0; i < count; i++){Vector2 pos = Random.insideUnitCircle; //随机一个圆内的位置出来pos *= size;int index = (int)Mathf.Lerp(0, greens.Length, Random.value);Transform trans = greens[index];trans = Instantiate(trans, greensParent);trans.localPosition = new Vector3(pos.x, Mathf.Lerp(0, 2, Random.value), pos.y);trans.localScale = Vector3.one * localScale * Random.value;instances[i] = trans.gameObject;}InitObj();}private GraphicsDraw CurGraphicsDraw = new GraphicsDraw();public void InitData(){CurGraphicsDraw.InitDrawData(instances);}public void ResetDraw(){//CurGraphicsDraw.DrawGrass();CurGraphicsDraw.DrawGrassGpuInstance();}
}

编写此类的编辑器脚本,放在Editor文件夹下

using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(GreenCtrl))]
public class GreenCtrlEditor : Editor
{public override void OnInspectorGUI(){base.OnInspectorGUI();if (GUILayout.Button("生成植被")){((GreenCtrl)target).Gen();}if (GUILayout.Button("动态合批")){((GreenCtrl)target).SetMesh();}if (GUILayout.Button("设置网格")){((GreenCtrl)target).SetMesh();}if (GUILayout.Button("关闭渲染顺序")){((GreenCtrl)target).CloseSort();}}
}

挂载设置脚本,将对象设置成静态合批Batching Static,以确保生成的对象也是静态批处理,设置父节点,草模型,生成数量Count为100
在这里插入图片描述

注意的是Greens是草模型
在这里插入图片描述
点击生成植被,我设置的生成100个草模型,没有超过64000个顶点
打开FrameDebugger
在这里插入图片描述
可看到植被生成217-2=215个批处理。
点击运行,启动静态批处理
在这里插入图片描述
这是你会发现所有相同材质的网格都合并成一个批次,就是说所有相同材质草模型合并成一个大网格使用同一个材质调用一个drawcall完成了多个模型的渲染。并且静态合批的名称为Static Batch
继续增加草的数量为6000,生成草区域Size调到250,调整一下摄像机的位置
在这里插入图片描述
现在草的静态合批为192-2=190个批次。理论上应该生成1个批次,因为同一个材质会合并为同一批次。为什么会生成这么多个批次呢?
因为静态合批的合并定点数最多64000个顶点,所以超过这个顶点数就会把剩下的网格合并到另一个批次。
那么如何查看合并后的网格信息呢
选中一个草模型对象,在Mesh参数中,当启动游戏后,Mesh就会自动刷新成合批后的网格
未运行前的网格
在这里插入图片描述
运行后的静态合批网格
在这里插入图片描述
你会发现合批后网格都会刷到每一个草模型的Mesh,并且网格名字都是以Combined Mesh (root:Scene)为前缀的网格。
双击网格查看网格信息
在这里插入图片描述
你会发现红色框模型顶点总数接近64000个顶点,但不会超过这个数。
同时绿框为合并网格后的一个个子网格信息
但是我发现所有草合并后的网格只有46个.理论上应该只有46个合批,为什么变成190个合批呢。。。
这一步测试如下
点击“设置网格”
在这里插入图片描述
此功能会把所有不同网格保存起来。会发现确实只有46个合成的大网格。那么为什么多生成这么多合批呢?
这是因为合批还会根据相机的Camera.main.opaqueSortMode渲染顺序模式有关
点击关闭渲染顺序
在这里插入图片描述
点击Disable两次,刷新数据
会发现现在合批会非常接近46了。至于为什么还会多出7个。应该是渲染的其它因素影响。但是到这也差不多把影响合批的原理逻辑基本说明了。
Camera.main.opaqueSortMode这个对静态合批的影响很大。即使正常合并网格,Camera.main.opaqueSortMode也会对静态合批影响很大。
现在将草的模型添加多个,并且这些草使用同一材质,关闭渲染顺序
在这里插入图片描述
你会发下增减了7中同一材质的不同模型,静态合批数量也只增了1倍。

结论与总结
静态合批原则与优化核心
  • 将场景模型使用同一个材质,并使用上面同一个图集。保证所有模型使用相同材质
  • 将场景所有不同模型通过工具或者脚本把相对应的纹理合并为一个个对应图集,如所有模型的主纹理合并一个图集,法线纹理合并为一个纹理。也可以让美术去合并。脚本的话可以使用unity 自带的Texture2D.PackTextures()方法区合并图集。但是还要对网格的UV做处理。

动态批处理

srpBach

Gpu实例化

蒙皮实例化

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

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

相关文章

【Sceneform-EQR】(手势优化)通过手势事件实现在AR/VR等三维场景中的控制模型旋转、平移与缩放

在上一篇文档中&#xff0c;我们实现了通过手势控制模型节点的旋转、缩放和平移。现在本文将介绍如何优化上一篇做的手势控制器&#xff0c;从而实现更好的跟手效果。 相关链接&#xff1a;【Sceneform-EQR】&#xff08;手势控制器实现&#xff09;通过手势事件实现在AR/VR等…

网络安全中的RCE命令执行漏洞----入门小白必看

RCE命令执行&代码执行漏洞 RCE命令执行漏洞 RCE漏洞简介 RCE(remote code/command execute) 远程代码/命令执行漏洞 RCE漏洞是两个漏洞&#xff1a; 代码执行漏洞 # 针对后端语言!命令执行漏洞 # 针对系统! 如何产生 在 Web应用中有时候程序员为了考虑灵活性、简洁性…

【SEO】什么是SEO?

什么是SEO&#xff08;搜索引擎优化&#xff09;&#xff1f;为什么SEO对于⼀个⽹站⾄关重要&#xff1f; SEO 全称是搜索引擎优化&#xff08;Search Engine Optimization&#xff09; 因为我们目前开发的网址&#xff0c;需要人看到&#xff0c;除了通过宣传营销的方式展现…

前端布局与响应式设计综合指南(二)

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;Css篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来Css篇专栏内容:前端布局与响应式设计综合指南(二) 目录 23、行内元素和块级元素&#xff1f;img算什么&…

影刀RPA实战:操作Mysql数据库

1.摘要 影刀RPA&#xff08;Robotic Process Automation&#xff09;是一种软件自动化工具&#xff0c;它可以模拟人类用户执行各种重复性任务&#xff0c;其中包括对数据库的操作。 我们可以使用软件自动化指令&#xff0c;通过获取数据库窗口对象来操作数据库&#xff0c;也…

《探秘数据合规官CCRC-DCO人员能力验证》

在当今竞争激烈的商业世界中&#xff0c;“数据合规官CCRC-DCO人员能力验证”这个词逐渐走入人们的视野。但究竟什么是数据合规官CCRC-DCO人员能力验证呢&#xff1f; 首先&#xff0c;咱们来明确一下概念。数据合规官CCRC-DCO人员能力验证&#xff0c;简单来说&#xff0c;就…

数仓范式建模和维度建模有什么不同?

在数据库设计的复杂世界中&#xff0c;还有一类建模方法&#xff0c;为范式建模&#xff0c;是一种旨在优化数据库结构、提高数据一致性和完整性的设计方法。本文将深入探讨范式建模的概念、原理、步骤以及与维度建模的区别。 一、什么是范式建模&#xff1f; 范式建模是一种…

Chromium 中window.DOMParser接口说明c++

一、DOMParser DOMParser 可以将存储在字符串中的 XML 或 HTML 源代码解析为一个 DOM Document。 备注&#xff1a; XMLHttpRequest 支持从 URL 可寻址资源解析 XML 和 HTML&#xff0c;在其response 属性中返回Document。 你可以使用XMLSerializer 接口执行相反的操作 - 将…

接口测试自动化后起之秀-YApi接口管理平台

前言 众多接口管理工具如雨后春笋&#xff0c;让人欣慰的是&#xff0c;有许多优秀作品来自国内&#xff0c;包含Yapi和rap&#xff0c;看着中文的官网&#xff0c;华丽的汉语&#xff0c;不禁让人大快朵颐&#xff0c;暗自称爽。当然这也就带来另一个弊端&#xff0c;使用基数…

nodejs的卸载和nvm安装

由于项目需求&#xff0c;需要多版本控制的nodejs&#xff0c;所以要把原来的nodejs卸载干净&#xff0c;然后再装nvm 常见问题 1.在安装nvm的时候没有卸载node&#xff0c;导致使用nvm安装完之后&#xff0c;node和npm都不可用。 2.在第一次使用nvm安装node后&#xff0c;要…

从零开始使用最新版Paddle【PaddleOCR系列】——第二部分:自建数据集 + 模型微调训练

目录 一、自建数据集 1.官方数据集格式参考 2.自建数据集txt文件编写代码 3.数据集检验 二、模型训练 1.模型配置yaml文件 2.命令行指令训练 在上一篇文章中&#xff0c;构建好了paddleOCR 运行必需的环境&#xff0c;并通过在线下载的方式&#xff0c;使用官方训练好的模型进…

深入理解 JDK 的 Optional 类

深入理解 JDK 的 Optional 类 深入理解 JDK 的 Optional 类1. 什么是 Optional&#xff1f;1.1 主要构造方法示例 2. Optional 的常用方法2.1 判断值是否存在示例2.2 获取值示例2.3 进行操作示例 3. 使用场景3.1 避免 null 值示例3.2 提高代码可读性3.3 与流结合示例 4. 注意事…

中航资本:股市融资50万一天的利息是多少?融资一般多久归还?

融资官方利率是8.35%&#xff0c;实际上大部分券商融资利息在6%~8%左右&#xff0c;详细利率因券商及投资者状况而异。少部分券商可提供低至5%&#xff0c;乃至更低的优惠利率。 该利息按天然日核算&#xff0c;融资利息融资金额融资年利率实际使用资金的天然日天数/360。 假…

基于深度学习的细粒度图像分析综述【翻译】

&#x1f947; 版权: 本文由【墨理学AI】原创首发、各位读者大大、敬请查阅、感谢三连 &#x1f389; 声明: 作为全网 AI 领域 干货最多的博主之一&#xff0c;❤️ 不负光阴不负卿 ❤️ 文章目录 基础信息0 摘要1 INTRODUCTION2 识别与检索 RECOGNITION VS. RETRIEVAL3 问题和…

React01 开发环境搭建

React 开发环境搭建 一、创建 React 项目二、项目精简 一、创建 React 项目 执行下述命令创建 react 项目 blu-react-basis npx create-react-app blu-react-basis项目目录结构如下&#xff1a; 执行下述命令启动项目 npm run start启动效果如下&#xff1a; 二、项目精简 …

Vue.js 错误异常: Component template should contain exactly one root element.

一、错误异常&#xff1a; Errors compiling template: Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead. 二、原因 组件模板应该只包含一个根元素 查看vue代码&#xff0c;发…

OpenCV-人脸检测

文章目录 一、人脸检测流程二、关键方法三、代码示例四、注意事项 OpenCV是一个开源的计算机视觉和机器学习软件库&#xff0c;它提供了多种人脸检测方法&#xff0c;以下是对OpenCV人脸检测的详细介绍&#xff1a; 一、人脸检测流程 人脸检测是识别图像中人脸位置的过程&…

【C语言】数据输出格式控制

数据的输出格式修饰 常用两种&#xff1a; 整型中&#xff0c;输出数据左对齐、右对齐、占m位、不足m位前补0。浮点型中&#xff0c;默认通过四舍五入保留小数点后6位&#xff0c;通过参数设置保留小数点后n位。 #include <stdio.h> #define PI 3.14159 /* 功能&#x…

2024怎么选择网站建设公司?2024靠谱建站公司推荐TOP3

说起怎么挑个靠谱的网站建设公司啊&#xff0c;我觉得有这么几点挺关键的&#xff0c;咱们可以聊聊&#xff1a; 首先啊&#xff0c;你得瞅瞅这公司啥背景&#xff0c;成立了多久了&#xff0c;团队大不大&#xff0c;都服务过哪些客户&#xff0c;有啥拿得出手的成功案例没。…

如何判断通风天窗的优劣

通风天窗是否优质直接决定天窗的通风采光效果&#xff0c;影响厂房的空气质量。判断通风天窗的优劣主要从天窗使用材料、防水密封性能、通风性能、安装与售后服务等多方面出发。‌ ‌通风天窗使用材料是判断通风天窗优劣的重要因素之一。优质的通风天窗应采用耐候性强、坚固耐用…