unity 实现千人同屏

文章介绍了开发团队为解决大量角色导致的性能问题,提出并实现了一种名为动画实例化的技术。该技术通过将动画制作成纹理,减少CPU上的动画计算,从而提高CPU性能,支持更多的角色实例。在移动平台上,尤其是在GPU支持OpenGLES3.0及更高版本的情况下,此技术能显著降低CPU成本,增加角色数量而不影响帧率。虽然目前不支持所有动画特性,但已证明对类似敌人群体的有效性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作为开发人员,我们总是关注性能,包括CPU和GPU。随着场景变得越来越大越来越复杂,保持良好的性能变得越来越有挑战性,尤其是当我们添加越来越多的角色时。我和我在上海的同事在帮助客户时经常遇到这个问题,所以我们决定花几周时间致力于一个旨在提高角色实例化性能的项目。我们把产生的技术称为动画实例化。

我们经常用来实现户外场景GPU实例化,如草和树。要不是SkinnedMeshRenderer(比如人物),我们不能用实例化,因为蒙皮是在CPU上计算的,一个一个提交给GPU。一般来说,我们不能通过一次提交就画出所有的角色。当场景中有大量SkinnedMeshRenderers时,这会导致大量绘制调用和动画计算。

我们已经找到了一种方法来降低CPU成本,并用动画实例化来补充Unity中的GPU实例化。你可以在GitHub上获取我们的代码。请注意,这是定制的实验性解决方案,直到最近,我们才与少数企业支持客户分享它。现在,我们准备好接受更多反馈,请让我们知道您的想法直接在项目注释中!

目标

我们这个实验项目的最初目标是:

  • 实例化SkinnedMeshRenderer

  • 实现尽可能多的动画特性

  • 《牛津小词典》

  • 支持移动平台

  • 选择

由于时间限制,我们的目标并没有全部实现。支持的动画功能有:根运动、附件、动画事件(尚不支持的功能:过渡、动画层)。此外,请记住,这仅适用于使用OpenGL ES 3.0和更新版本的移动平台。

然而,我们认为实验成功地证明了这种方法可以产生有趣的结果。让我们深入了解一些细节。

动画生成

在为角色使用实例化之前,我们需要生成动画。我们把一个角色的动画制作成纹理。这些纹理被称为动画纹理。纹理用于GPU上的蒙皮。

发展

这个生成器从附属于游戏对象的Animator组件中收集动画。它还收集动画事件。从Mecanim系统转移到动画实例化很方便。如果要在角色上附加某些东西,需要在“附件设置”中指定可以附加某些东西的骨骼。

当我们完成生成动画纹理时,动画实例脚本将在运行时加载动画信息。请注意,动画信息不是动画剪辑文件。

举例说明

应用动画实例很简单。让我们将动画实例脚本添加到我们生成的游戏对象中。每顶点骨骼参数控制每顶点计算的骨骼数量。这里需要注意的重要一点是,拥有更少的骨骼可以提高性能,但会降低准确性。

发展

接下来,我们需要修改着色器以支持实例化。基本上,你需要的是将这些线添加到你的着色器中。它不会影响您的着色,但会向蒙皮添加顶点着色器。

#include “AnimationInstancingBase.cginc”

#pragma vertex vert

技术性能分析

我们使用了稍微修改过的版本的演示场景机械动画场景示例并在iPhone 6上测试了它的性能。让我们仔细看看原始和实例化示例的分析器视图。

中央处理器

最初的项目产生了300个字符,我们的FPS大约是15。为了达到至少30 FPS,我们必须将字符数限制在150左右。在动画实例版本中,我们可以生成900个角色,同时保持30 FPS。

发展

发展

如你所见,CPU上的计算降低了项目的速度。

使用实例化项目,我们减少了动画计算(骨骼和皮肤等)。)很多在CPU上。那样的话,我们就可以产生五到六倍的角色了!

发展

发展

在测试场景中,绘制环境需要大约80次绘制调用。这个角色有三个素材。所以我们有三个绘制调用来渲染一个角色。

如果没有实例化,生成250个字符需要大约1100次绘制调用(3 *250个字符+它们的阴影)。

使用动画实例化时,在生成800个角色后,绘制调用仅增加到大约50个。可以看到,实例化列中有4800个批处理绘制调用,48个批处理(3 * 8字符+ 3 * 8阴影)。这是因为我们每批提交100个字符。

发展

发展

国家政治保卫局。参见OGPU

这项技术增加了一点GPU成本,因为我们在GPU上放置了皮肤。如果角色有阴影,我们必须在阴影通道中再次为角色蒙皮。但是,它提高了整体帧速率,因为它降低了CPU成本。通常CPU成本是游戏中人群模拟的最大问题。

记忆

额外的内存用于存储动画纹理。纹理保持皮肤矩阵。我们使用RGBAHalf格式纹理。我们假设一个角色有N块骨头,每块骨头四个像素(一个矩阵);我们生成一个M个关键帧的动画。所以一个动画花费N * 4 * M * 2 = 8NM字节。如果一个角色有50块骨骼,我们生成30个关键帧,那么一个动画就有50 * 4 * 30 = 6000个像素。所以一个1024*1024的纹理最多可以存储174个动画。

结论

我们发现,如果你有很多SkinnedMeshRenderers,动画实例化可以显著降低CPU成本。它适合类似的敌人,如僵尸等人群。

我们希望这个实验项目提供一些洞察力,可以照亮你自己的项目的性能挑战,并让你有能力建立更复杂的场景。当然,未来的工作有很多途径,比如支持过渡、动画层等等。

<think>好的,我现在需要回答用户关于DOTS技术栈的概念和组成的问题。首先,我需要回顾用户提供的引用内容,从中提取相关信息,并按照系统级指令来组织回答。 首先,用户提供的引用中有四个引用,其中引用[2]明确提到DOTS由C# Job System、ECS和Burst组成,并简要介绍了每个部分的作用。引用[3]提到了Job System的特点,而引用[4]则讨论了优化策略。引用[1]更多是讨论DOTS的应用现状和挑战。 接下来,我需要根据这些信息,用中文组织一个结构清晰的回答。按照用户的要求,回答需要分点说明DOTS的组成部分,每个部分详细解释,并正确引用对应的引用编号。时,要确保行内数学表达式用$...$格式,独立公式用$$...$$,但在这个问题中可能涉及较少数学内容,不过需要注意技术术语的正确格式。 然后,生成相关问题,问题要围绕DOTS的概念、组成部分、优势、应用场景等方面展开,确保相关问题有针对性且有助于用户进一步了解。 需要注意的是,用户提到的系统级指令中要求生成相关问题,并在回答中自然添加引用标识,例如[^1]。因此,在回答的每个相关部分末尾,需要检查是否有对应的引用来源,并正确标注。 现在,我需要确认各部分的信息是否准确,比如ECS是否确实是实体组件系统,Burst编译器的作用是否如引用所述。此外,要确保语言流畅,符合中文表达习惯,避免技术术语使用错误。 最后,检查LaTeX语法是否正确,但在这个问题中可能用不到太多数学公式,所以可能不需要使用。不过如果有变量或代码块,要正确格式化。例如,代码块需要用```python等格式,但根据引用内容,可能不需要插入代码,但需要引用用户提供的引用中的相关信息。 总结步骤: 1. 介绍DOTS技术栈的定义和目的。 2. 分点介绍三个核心组成部分:C# Job System、ECS、Burst Compiler。 3. 引用对应的引用资料,如引用[2]说明组成,引用[3]和引用[4]补充Job System和优化策略。 4. 生成相关问题,涵盖概念、优势、应用、挑战等方面。</think>### DOTS技术栈的概念与组成 **Data-Oriented Technology Stack (DOTS)** 是Unity引擎推出的一套高性能编程技术栈,旨在通过数据导向的设计理念优化游戏性能,尤其在多核处理器和复杂计算场景下提升并发性与效率[^2]。其核心由以下三个模块组成: 1. **C# Job System** 基于多线程的任务调度系统,允许开发者将计算密集型任务分配到多个CPU核心并行执行,避免传统单线程的瓶颈。例如,物理模拟或动画计算可通过Job System分解为多个子任务[^3]。 2. **Entity Component System (ECS)** 一种数据导向的架构模式,将游戏对象拆分为: - **实体 (Entity)**:仅作为唯一标识,不包含数据或逻辑。 - **组件 (Component)**:纯数据结构,描述实体的属性(如位置、速度)。 - **系统 (System)**:处理特定组件的逻辑(如移动系统处理所有含位置和速度组件的实体)。 这种设计减少内存碎片,提升CPU缓存命中率。 3. **Burst Compiler** 高性能编译器,将C#代码编译为高度优化的本地机器码,尤其适用于数学计算(如矩阵运算、物理模拟)。通过LLVM后端实现,显著提升运行效率。 ### DOTS的优势与应用场景 - **优势**:通过多线程并行、数据局部性优化和高效编译,DOTS可大幅提升帧率并降低延迟,适用于大规模实体(如千人)或复杂计算(如实时物理模拟)[^4]。 - **现状**:目前DOTS尚未完全成熟,部分模块(如渲染管线)仍需与传统系统结合使用。建议在经典批处理场景(如粒子系统)中逐步尝试,避免全盘替换[^1]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值