18 lines
32 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="zh" dir="ltr" class="docs-wrapper docs-doc-page docs-version-current plugin-docs plugin-id-default docs-doc-id-start-guide/batcher-guide">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="generator" content="Docusaurus v2.0.0-beta.20">
<link rel="alternate" type="application/rss+xml" href="/cocos-service-pack/blog/rss.xml" title="Cocos Service Pack RSS Feed">
<link rel="alternate" type="application/atom+xml" href="/cocos-service-pack/blog/atom.xml" title="Cocos Service Pack Atom Feed"><title data-rh="true">新 UI 渲染批次合并指南 | Cocos Service Pack</title><meta data-rh="true" name="twitter:card" content="summary_large_image"><meta data-rh="true" property="og:url" content="https://smallmain.github.io/cocos-service-pack/docs/start-guide/batcher-guide"><meta data-rh="true" name="docusaurus_locale" content="zh"><meta data-rh="true" name="docsearch:language" content="zh"><meta data-rh="true" name="docusaurus_version" content="current"><meta data-rh="true" name="docusaurus_tag" content="docs-default-current"><meta data-rh="true" name="docsearch:version" content="current"><meta data-rh="true" name="docsearch:docusaurus_tag" content="docs-default-current"><meta data-rh="true" property="og:title" content="新 UI 渲染批次合并指南 | Cocos Service Pack"><meta data-rh="true" name="description" content="在游戏开发中享受不用关注 Draw Call 的快乐。"><meta data-rh="true" property="og:description" content="在游戏开发中享受不用关注 Draw Call 的快乐。"><link data-rh="true" rel="icon" href="/cocos-service-pack/img/favicon.ico"><link data-rh="true" rel="canonical" href="https://smallmain.github.io/cocos-service-pack/docs/start-guide/batcher-guide"><link data-rh="true" rel="alternate" href="https://smallmain.github.io/cocos-service-pack/docs/start-guide/batcher-guide" hreflang="zh"><link data-rh="true" rel="alternate" href="https://smallmain.github.io/cocos-service-pack/docs/start-guide/batcher-guide" hreflang="x-default"><link rel="stylesheet" href="/cocos-service-pack/assets/css/styles.5581f124.css">
<link rel="preload" href="/cocos-service-pack/assets/js/runtime~main.f365d728.js" as="script">
<link rel="preload" href="/cocos-service-pack/assets/js/main.76c48d58.js" as="script">
</head>
<body class="navigation-with-keyboard">
<script>!function(){function t(t){document.documentElement.setAttribute("data-theme",t)}var e=function(){var t=null;try{t=localStorage.getItem("theme")}catch(t){}return t}();t(null!==e?e:"light")}()</script><div id="__docusaurus">
<div role="region"><a href="#" class="skipToContent_ZgBM">跳到主要内容</a></div><nav class="navbar navbar--fixed-top"><div class="navbar__inner"><div class="navbar__items"><button aria-label="Navigation bar toggle" class="navbar__toggle clean-btn" type="button" tabindex="0"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><a class="navbar__brand" href="/cocos-service-pack/"><div class="navbar__logo"><img src="/cocos-service-pack/img/logo.png" alt="Cocos Service Pack" class="themedImage_W2Cr themedImage--light_TfLj"><img src="/cocos-service-pack/img/logo.png" alt="Cocos Service Pack" class="themedImage_W2Cr themedImage--dark_oUvU"></div><b class="navbar__title text--truncate">Cocos Service Pack</b></a></div><div class="navbar__items navbar__items--right"><a class="navbar__item navbar__link" href="/cocos-service-pack/">首页</a><a class="navbar__item navbar__link navbar__link--active" href="/cocos-service-pack/docs/intro">文档</a><a href="https://smallmain.github.io/cocos-service-pack/demo/web-desktop/index.html" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">演示</a><a href="https://github.com/smallmain/cocos-service-pack" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link header-github-link">加星鼓励</a><div class="searchBox_dLyj"><div class="navbar__search searchBarContainer_NW3z"><input placeholder="搜索" aria-label="Search" class="navbar__search-input"><div class="loadingRing_RJI3 searchBarLoadingRing_YnHq"><div></div><div></div><div></div><div></div></div><div class="searchHintContainer_Pkmr"><kbd class="searchHint_iIMx">ctrl</kbd><kbd class="searchHint_iIMx">K</kbd></div></div></div><div class="toggle_S7eR colorModeToggle_vKtC"><button class="clean-btn toggleButton_rCf9 toggleButtonDisabled_Pu9x" type="button" disabled="" title="切换浅色/暗黑模式(当前为浅色模式)" aria-label="切换浅色/暗黑模式(当前为浅色模式)"><svg viewBox="0 0 24 24" width="24" height="24" class="lightToggleIcon_v35p"><path fill="currentColor" d="M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" class="darkToggleIcon_nQuB"><path fill="currentColor" d="M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"></path></svg></button></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div class="main-wrapper docsWrapper_mKqt"><button aria-label="回到顶部" class="clean-btn theme-back-to-top-button backToTopButton_RiI4" type="button"></button><div class="docPage_ualW"><aside class="theme-doc-sidebar-container docSidebarContainer_UQUJ"><div class="sidebar_RiAD"><nav class="menu thin-scrollbar menu_izAj"><ul class="theme-doc-sidebar-menu menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/cocos-service-pack/docs/intro">介绍</a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist" aria-expanded="true" href="/cocos-service-pack/docs/installation-guide/installation-intro">安装指南</a><button aria-label="打开/收起侧边栏菜单「安装指南」" type="button" class="clean-btn menu__caret"></button></div><ul style="display:block;overflow:visible;height:auto" class="menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/cocos-service-pack/docs/installation-guide/installation-engine-plugin">使用引擎扩展安装</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/cocos-service-pack/docs/installation-guide/installation-manual">手动安装</a></li></ul></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--active" aria-expanded="true" href="/cocos-service-pack/docs/start-guide/start-guide-intro">入门教程</a><button aria-label="打开/收起侧边栏菜单「入门教程」" type="button" class="clean-btn menu__caret"></button></div><ul style="display:block;overflow:visible;height:auto" class="menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link menu__link--active" aria-current="page" tabindex="0" href="/cocos-service-pack/docs/start-guide/batcher-guide">新 UI 渲染批次合并指南</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/cocos-service-pack/docs/start-guide/advance-batcher-guide">进阶合批指南</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/cocos-service-pack/docs/start-guide/new-features">上手其它新特性</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/cocos-service-pack/docs/start-guide/breaking-change">破坏性变更</a></li></ul></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist" aria-expanded="true" href="/cocos-service-pack/docs/user-guide/user-guide-intro">使用指南</a><button aria-label="打开/收起侧边栏菜单「使用指南」" type="button" class="clean-btn menu__caret"></button></div><ul style="display:block;overflow:visible;height:auto" class="menu__list"><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-2 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist" aria-expanded="false" tabindex="0" href="/cocos-service-pack/docs/user-guide/multi-render/multi-render-intro">多纹理渲染</a><button aria-label="打开/收起侧边栏菜单「多纹理渲染」" type="button" class="clean-btn menu__caret"></button></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-2 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist" aria-expanded="false" tabindex="0" href="/cocos-service-pack/docs/user-guide/text-render/text-render-intro">文本渲染</a><button aria-label="打开/收起侧边栏菜单「文本渲染」" type="button" class="clean-btn menu__caret"></button></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-2 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist" aria-expanded="false" tabindex="0" href="/cocos-service-pack/docs/user-guide/dynamic-batcher/dynamic-batcher-intro">动态合图</a><button aria-label="打开/收起侧边栏菜单「动态合图」" type="button" class="clean-btn menu__caret"></button></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-2 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist" aria-expanded="false" tabindex="0" href="/cocos-service-pack/docs/user-guide/spine/spine-intro">Spine</a><button aria-label="打开/收起侧边栏菜单「Spine」" type="button" class="clean-btn menu__caret"></button></div></li></ul></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist" aria-expanded="false" href="/cocos-service-pack/docs/theory-guide/theory-guide-intro">原理文档</a><button aria-label="打开/收起侧边栏菜单「原理文档」" type="button" class="clean-btn menu__caret"></button></div></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/cocos-service-pack/docs/uninstall-guide">卸载指南</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/cocos-service-pack/docs/update-log">更新日志</a></li></ul></nav></div></aside><main class="docMainContainer_uL0j"><div class="container padding-top--md padding-bottom--lg"><div class="row"><div class="col docItemCol_DM6M"><div class="docItemContainer_vinB"><article><nav class="theme-doc-breadcrumbs breadcrumbsContainer_Xlws" aria-label="页面路径"><ul class="breadcrumbs" itemscope="" itemtype="https://schema.org/BreadcrumbList"><li class="breadcrumbs__item"><a aria-label="主页面" class="breadcrumbs__link" href="/cocos-service-pack/"><svg viewBox="0 0 24 24" class="breadcrumbHomeIcon_kU5B"><path d="M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z" fill="currentColor"></path></svg></a></li><li itemscope="" itemprop="itemListElement" itemtype="https://schema.org/ListItem" class="breadcrumbs__item"><a class="breadcrumbs__link" itemprop="item" href="/cocos-service-pack/docs/start-guide/start-guide-intro"><span itemprop="name">入门教程</span></a><meta itemprop="position" content="1"></li><li itemscope="" itemprop="itemListElement" itemtype="https://schema.org/ListItem" class="breadcrumbs__item breadcrumbs__item--active"><span class="breadcrumbs__link" itemprop="name">新 UI 渲染批次合并指南</span><meta itemprop="position" content="2"></li></ul></nav><div class="tocCollapsible_bZGK theme-doc-toc-mobile tocMobile_TmEX"><button type="button" class="clean-btn tocCollapsibleButton_l22C">本页总览</button></div><div class="theme-doc-markdown markdown"><h1>新 UI 渲染批次合并指南</h1><p>在官方文档的进阶主题中,有一个 <a href="https://docs.cocos.com/creator/2.4/manual/zh/advanced-topics/ui-auto-batch.html" target="_blank" rel="noopener noreferrer">UI 渲染批次合并指南</a>,在服务包的 <strong>多纹理渲染</strong><strong>重构动态图集</strong> 等新特性的出现后,对如何合并渲染批次需要有全新的理解。</p><p>如果你未阅读过官方的指南,可以先阅读一遍。</p><hr><h2 class="anchor anchorWithStickyNavbar_mojV" id="什么是多纹理渲染">什么是多纹理渲染?<a class="hash-link" href="#什么是多纹理渲染" title="标题的直接链接"></a></h2><p>在以前的认识里我们知道相邻的节点使用不同的纹理Texture会导致不能合并批次。</p><p>其根本原因是纹理是使用 uniform 变量传给着色器的,而需要合并批次的话不允许每次渲染都拥有不同的 uniform 变量值。</p><p>服务包实现的合批方法是先设置好多个 uniform 变量,比如将 8 张纹理写入到 &quot;texture1&quot; &quot;texture2&quot; &quot;texture3&quot;... 的 8 个 uniform 变量中,然后在着色器里再判断应该在渲染时使用哪个 uniform 变量。</p><p>这样的话如果所有渲染都只用这 8 张纹理的话,就都能合并为 1 个批次。</p><p>这种做法要求设备需要支持采样多个纹理,而在现代绝大多数设备中这不是问题,至少都支持采样 8 张纹理。</p><p>当然除了这种方法,还有另外几种进行多纹理合批的方法,例如 &quot;Texture Array&quot;&quot;Bindless&quot;,但都有实用性与兼容性的问题。</p><div class="admonition admonition-info alert alert--info"><div class="admonition-heading"><h5><span class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>提示</h5></div><div class="admonition-content"><p>以这种方式实现的多纹理渲染并不是没有弊端的:</p><p>因为会多传递一个顶点属性,并且需要在着色器中去判断该使用哪个纹理,导致<strong>合并批次并不一定会提升性能</strong></p><p>所以我们建议在多个档次设备中实际测试项目是否使用多纹理渲染的性能差距。</p><p>如果你还有所担心,就像我们在实现这个功能之前一样,可以看看这些:</p><p><strong>PixiJS 引擎在 2016 年发布的 v4 版本就已经正式实装了多纹理渲染机制!</strong><a href="https://medium.com/goodboy-digital/gpu-multi-texture-sprite-batching-21c90ae8f89b" target="_blank" rel="noopener noreferrer">资料出处</a></p><p><strong>Phaser 引擎在 v4 与 v3 版本都实装了多纹理渲染机制2019 - 2020年</strong><a href="https://www.patreon.com/posts/39665256" target="_blank" rel="noopener noreferrer">资料出处</a></p></div></div><hr><h2 class="anchor anchorWithStickyNavbar_mojV" id="为你的项目启用动态合图">为你的项目启用动态合图<a class="hash-link" href="#为你的项目启用动态合图" title="标题的直接链接"></a></h2><p>在项目之前的开发中,我们通常会关闭动态图集,更倾向于靠静态图集或者自动图集达到降低 Draw Call 的目的。</p><p>导致这个情况最重要的问题是不能复用图集的废弃区域随着游戏的运行图集会完全用完引擎只提供了在切换场景Scene后重置所有图集的机制来解决这个问题。</p><p>但对于大部分项目来说,这种治标不治本的机制基本等于没有解决这个问题。</p><p>现在,服务包几乎重构了整个动态合图系统,你可以考虑启用它了。</p><div class="admonition admonition-note alert alert--secondary"><div class="admonition-heading"><h5><span class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>提示</h5></div><div class="admonition-content"><p>开启动态图集常见的反对意见是:</p><p>在部分小游戏平台里,启用动态图集会有保留 Image 对象所占用的内存空间很大的问题。</p><p>我们建议:</p><ul><li>请实际测试是否启用动态图集的内存占用差距。</li><li>有没有一种可能,只是说可能,出现不能接受的内存占用大小是因为你的项目根本就不做任何资源的释放呢?</li></ul></div></div><hr><h2 class="anchor anchorWithStickyNavbar_mojV" id="充分利用动态合图">充分利用动态合图<a class="hash-link" href="#充分利用动态合图" title="标题的直接链接"></a></h2><p>下面几个建议能让你发挥出动态合图的潜力:</p><h3 class="anchor anchorWithStickyNavbar_mojV" id="放宽能参与合图的纹理尺寸限制">放宽能参与合图的纹理尺寸限制<a class="hash-link" href="#放宽能参与合图的纹理尺寸限制" title="标题的直接链接"></a></h3><p><strong>动态图集会自动进行多纹理合批,你可以放心地使用多达 7 张图集而不用担心交叉渲染导致的打断批次!</strong></p><p>有了这个新特性,你可以根据项目的具体情况来放宽能参与合图的纹理尺寸限制。</p><div class="language-js codeBlockContainer_MPoW theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_B9tL"><pre tabindex="0" class="prism-code language-js codeBlock__0OG thin-scrollbar"><code class="codeBlockLines_gEuF"><span class="token-line" style="color:#393A34"><span class="token plain">cc</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">dynamicAtlasManager</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">maxFrameSize</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1024</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 推荐 512、1024 甚至 2048</span><br></span></code></pre><div class="buttonGroup_hRr1"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_W9eQ" aria-hidden="true"><svg class="copyButtonIcon_XEyF" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_i9w9" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><div class="admonition admonition-tip alert alert--success"><div class="admonition-heading"><h5><span class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>tip</h5></div><div class="admonition-content"><p>服务包会自动将图集的最大数量调整至(设备能同时采样纹理数 - Char 缓存模式自动合批图集数),这个值默认为 <code>7</code></p></div></div><h3 class="anchor anchorWithStickyNavbar_mojV" id="无需管理动态图集只需要释放资源">无需管理动态图集,只需要释放资源<a class="hash-link" href="#无需管理动态图集只需要释放资源" title="标题的直接链接"></a></h3><p><strong>动态合图会在纹理被释放的同时释放其在动态图集使用的空间。</strong></p><p>有了这个新特性,你不需要关心动态图集,只需要做好应有的资源释放,就能保持动态图集的长期有效。</p><h3 class="anchor anchorWithStickyNavbar_mojV" id="更加细致地优化图集的使用效率">更加细致地优化图集的使用效率<a class="hash-link" href="#更加细致地优化图集的使用效率" title="标题的直接链接"></a></h3><p>除了通过调整纹理的 <code>packable</code> 属性可以控制纹理是否会参与动态合图之外。</p><p><strong>还可以控制组件是否默认参与动态合图,也可以控制单个组件是否参与动态合图。</strong></p><p>可前往 <a href="/cocos-service-pack/docs/user-guide/dynamic-batcher/dynamic-batcher-intro">动态合图</a> 的文档了解详情。</p><p>在上面我们推荐可以将纹理尺寸限制放宽到 <code>2048</code>,这听起来貌似有点离谱,但只要规划得当确实可行,比如:</p><ul><li>禁止优化程度有限但尺寸巨大的纹理参与动态合图</li><li>分模块存放资源,禁止冷门(如活动界面)的纹理参与动态合图或尽早地释放掉</li><li>在资源已经一团糟的项目中,可通过代码禁止某个界面下所有的渲染组件参与动态合图</li></ul><p>完成上面几点这可能需要一些工作量,但能将动态图集用在刀刃上,发挥更大的作用。</p><hr><h2 class="anchor anchorWithStickyNavbar_mojV" id="label-不再是合批噩梦">Label 不再是合批噩梦<a class="hash-link" href="#label-不再是合批噩梦" title="标题的直接链接"></a></h2><p>在项目之前的开发中,我们可能会使用字体图集、调整节点顺序,甚至修改渲染流程来解决 Label 的性能问题。</p><p>引擎提供的 Bitmap 和 Char 两种缓存模式在稍大一点的项目上就显得力所不及了:</p><ul><li><p>Bitmap 缓存模式:字体纹理会打入动态图集,但动态图集却无法复用,随着游戏的进行,图集用完则直接失去作用。</p></li><li><p>Char 缓存模式的缺点:还是无法复用,并且只有一张图集,图集用完则直接无法渲染,应该没人能接受游戏可能跑着跑着字就全部消失了的情况。</p></li></ul><p>但,<strong>服务包重构了 Char 缓存模式,除了解决不能复用的问题之外,由于支持了多纹理渲染,所以既能与动态图集合批,还有最多 8 张字体图集可以使用!</strong></p><h3 class="anchor anchorWithStickyNavbar_mojV" id="脱胎换骨的-char-缓存模式">脱胎换骨的 Char 缓存模式<a class="hash-link" href="#脱胎换骨的-char-缓存模式" title="标题的直接链接"></a></h3><p><strong>如果你不知道该选择什么缓存模式,那就遇事不决,先选 Char 缓存模式。</strong></p><p>虽然 Char 模式也有一些缺点,但由于它既能与动态图集一起合批,还是是按字符进行复用的,所以相比 Bitmap 模式它有着更高的性能优势。</p><p>不用担心字符图集会被用完,内部会用引用计数自动释放废弃字符所占用的空间。</p><p>但 Char 缓存模式不适合下面的场景:</p><ul><li>无法显示带有像 emoji 的字素簇的字符串,这种字符串现在不能被完美地分割成单个字符,所以 Char 缓存模式也就不能正常显示了。</li><li>接上条,像聊天消息、输入框这类不可控的内容文本都不建议用 Char 缓存模式。</li><li>Char 缓存模式不支持一些字体样式,可以在官方文档中了解详情。</li><li>巨大的字体大小(比如几百的)可能会瞬间占满整张字符图集,字符图集虽然有 8 张但也不能这么霍霍。</li></ul><h3 class="anchor anchorWithStickyNavbar_mojV" id="兜底的-bitmap-缓存模式">兜底的 Bitmap 缓存模式<a class="hash-link" href="#兜底的-bitmap-缓存模式" title="标题的直接链接"></a></h3><p>即使不能选择 Char 缓存模式Bitmap 缓存模式也能成为批次的最后一道防线。</p><p>在解决了动态图集的复用问题后Bitmap 缓存模式的纹理也会使用引用计数自动释放,并且不会有 Char 缓存模式无法显示字素簇的问题。</p><p>但当然Bitmap 缓存模式也不是万能的,如果遇到了下面这种情况,就需要考虑使用调整节点顺序这样的老办法来解决了:</p><ul><li>巨大的字体大小也会瞬间占满整张动态图集,动态图集也不能这么霍霍。</li><li>在大量的 Label 需频繁改变文本的情况下,请使用性能分析工具检查动态图集的性能消耗,避免合批的弊大于利。</li></ul><div class="admonition admonition-caution alert alert--warning"><div class="admonition-heading"><h5><span class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>注意</h5></div><div class="admonition-content"><p>无论使用哪种缓存模式,在做缩放动画时不要对 <code>fontSize</code> 属性进行缓动,这会导致每帧都需要重新生成文字纹理,造成巨大的性能负担,可以使用节点的 <code>scale</code> 来代替。</p></div></div><h3 class="anchor anchorWithStickyNavbar_mojV" id="注意事项">注意事项<a class="hash-link" href="#注意事项" title="标题的直接链接"></a></h3><ul><li><strong>Char 缓存模式所使用的字符图集与动态图集不是一个东西</strong></li></ul><p>有多种因素导致没有让 Char 缓存模式直接使用动态图集来实现,这个原因在 Char 缓存模式的原理文档中有详细解释。</p><ul><li><strong>Char 缓存模式依然不能在图集用完的情况下正常渲染</strong></li></ul><p>原因有以下几点:</p><ul><li>我们认为 8 张数量已经够多了8 张都用完的情况大部分是没有合理搭配使用两种缓存模式</li><li>8 张是多纹理渲染的上限,这意味着如果超过 8 张1 个 Label 有 100 个字,就可能有 100 个 Draw Call</li></ul><hr><h2 class="anchor anchorWithStickyNavbar_mojV" id="总结">总结<a class="hash-link" href="#总结" title="标题的直接链接"></a></h2><p>以上就是新合批指南的全部内容了,稍微总结一下渲染批次合并的几个要点:</p><ul><li>启用动态合图,只需要合理地释放资源即可保持动态合图的一直有效</li><li>优先使用 Char 缓存模式,不适合则使用 Bitmap 缓存模式,都不适合则采用老方法</li><li>不要优先考虑修改节点顺序这种需要维护成本的优化方式</li></ul><p>如果你对批次合并还有着更高的需求,可以阅读 <a href="/cocos-service-pack/docs/start-guide/advance-batcher-guide">进阶合批指南</a></p></div></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="文档分页导航"><a class="pagination-nav__link pagination-nav__link--prev" href="/cocos-service-pack/docs/start-guide/start-guide-intro"><div class="pagination-nav__sublabel">上一页</div><div class="pagination-nav__label">入门指南</div></a><a class="pagination-nav__link pagination-nav__link--next" href="/cocos-service-pack/docs/start-guide/advance-batcher-guide"><div class="pagination-nav__sublabel">下一页</div><div class="pagination-nav__label">进阶合批指南</div></a></nav></div></div><div class="col col--3"><div class="tableOfContents_cNA8 thin-scrollbar theme-doc-toc-desktop"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#什么是多纹理渲染" class="table-of-contents__link toc-highlight">什么是多纹理渲染?</a></li><li><a href="#为你的项目启用动态合图" class="table-of-contents__link toc-highlight">为你的项目启用动态合图</a></li><li><a href="#充分利用动态合图" class="table-of-contents__link toc-highlight">充分利用动态合图</a><ul><li><a href="#放宽能参与合图的纹理尺寸限制" class="table-of-contents__link toc-highlight">放宽能参与合图的纹理尺寸限制</a></li><li><a href="#无需管理动态图集只需要释放资源" class="table-of-contents__link toc-highlight">无需管理动态图集,只需要释放资源</a></li><li><a href="#更加细致地优化图集的使用效率" class="table-of-contents__link toc-highlight">更加细致地优化图集的使用效率</a></li></ul></li><li><a href="#label-不再是合批噩梦" class="table-of-contents__link toc-highlight">Label 不再是合批噩梦</a><ul><li><a href="#脱胎换骨的-char-缓存模式" class="table-of-contents__link toc-highlight">脱胎换骨的 Char 缓存模式</a></li><li><a href="#兜底的-bitmap-缓存模式" class="table-of-contents__link toc-highlight">兜底的 Bitmap 缓存模式</a></li><li><a href="#注意事项" class="table-of-contents__link toc-highlight">注意事项</a></li></ul></li><li><a href="#总结" class="table-of-contents__link toc-highlight">总结</a></li></ul></div></div></div></div></main></div></div><footer class="footer footer--dark"><div class="container container-fluid"><div class="footer__bottom text--center"><div class="footer__copyright">Copyright © 2022 Cocos Service Pack.</div></div></div></footer></div>
<script src="/cocos-service-pack/assets/js/runtime~main.f365d728.js"></script>
<script src="/cocos-service-pack/assets/js/main.76c48d58.js"></script>
</body>
</html>