精华内容
下载资源
问答
  • 我们都知道CorelDRAW在进行设计广告宣传、名片设计、图形处理、网页发布等方面非常出色的,但您知道吗?它在制作动画方面也同样优秀,今天,我们就用CorelDRAW 11来制作一个正在转动的光盘的动画。  一、设计...

    我们都知道CorelDRAW在进行设计广告宣传、名片设计、图形处理、网页发布等方面是非常出色的,但您知道吗?它在制作动画方面也同样优秀,今天,我们就用CorelDRAW 11来制作一个正在转动的光盘的动画。
        一、设计光盘
        1. 打开CorelDRAW 11中文版,单击菜单栏中的“文件→新建”命令,创建一个新文件,并单击工具栏中的“横向”按钮,使工作区变成横向版式。b2b软件 广告发布软件
        2. 接着单击工具箱中的椭圆工具,按住Ctrl键不放,在工作区中绘制一个正圆形。然后单击工具箱中的标准填充工具,给这个圆填充颜色CMYK(100,0,100,50)(如图1)。

    CorelDRAW制作封面就是这么简单搞可以掂和了 b2b软件 


        3. 选择这个圆形,然后再单击菜单栏中的“位图→转换成位图”命令,在弹出的界面中勾选“平滑处理”和“透明背景”两个复选框。接着再选择“位图→模糊→高斯式模糊”命令 并打开它,设置半径为30像素。

        4. 再次单击工具箱中的椭圆工具,在执行位图转换的圆形上绘制一个圆形,单击工具箱中的渐变填充工具,在渐变填充类型中选择“射线”,在中心位移栏中设置水平为-20%,垂直为-20%。选择颜色调和栏中的自定义选项,在出现的渐变颜色栏中添加两个渐变点,单击“其它”按钮,弹出“选择颜色”对话框,选择RGB模式,对每一个渐变点设置渐变参数:RGB(14,18,14)、RGB(98,210,98)、RGB(140,255,150)、RGB(255,255,255)。单击“确定”按钮,对圆形进行填充(如图2)。
    CorelDRAW制作封面就是这么简单搞可以掂和了 b2b软件 


        5. 选择椭圆工具绘制一个小的圆形放在大圆的中心处。打开渐变填充工具,对这个小圆形进行渐变填充,填充类型为“射线”,选择颜色调和栏中的自定义选项,在出现的渐变颜色栏中添加两个渐变点,渐变参数为RGB(141,100,255)、RGB(141,100,255)、RGB(255,255,255)、RGB(141,100,255),并去掉小圆的边线。 

        6. 下面我们要将圆形的中心抠出个圆心窟窿。用椭圆工具绘制一个小圆,并填充上颜色,可利用放大镜工具进行操作。然后选择这个最小的圆,选择菜单栏中的“排列→造型→修剪”命令,将它的两个选项全去掉,然后单击“修剪”按钮,单击最小的圆外面的小圆即可(如图3)。产品网络推广软件 企业网络推广软件
    CorelDRAW制作封面就是这么简单搞可以掂和了 b2b软件 


        7. 下面我们给这个光盘加上一个封面文字。选中工具箱中的文字工具,在外圆上输入几个字:我的光盘。选中外圆,按住渐变填充工具不放,在弹出的工具中选择底纹填充工具,在弹出的对话框中的底纹库中选择“样本9”,在其下方的底纹列表中选择“钹”,按“确定”按钮,即可给光盘填充上底纹(如图4)。
    CorelDRAW制作封面就是这么简单搞可以掂和了 b2b软件 


        8. 选择“保存”命令,给它起好名称,然后将它保存到您的计算机中,以便日后随时更改。单击“文件→导出”命令,在弹出的对话框中,选择保存类型为Jpg文件,单击“导出”按钮将其导出。

        二、设计光盘的转动动画

        在CorelDRAW 11的各种工具中,最引人注目的就是推出了Corel R.A.V.E 2.0,它是一个综合的一对象为基点的动画设计程序,通过它可以方便地生成SWF、GIF、AVI和MOV等格式的图形动画。

        1. 打开Corel R.A.V.E 2.0,选择菜单栏中的“文件→新建”命令,创建一个新文件,单击“文件→导入”命令,在弹出的对话框中找到我们刚刚制作好的光盘并打开它(如图5)。网站发帖软件 宣传软件
    CorelDRAW制作封面就是这么简单搞可以掂和了 b2b软件 


        2. 选择光盘,然后拖动时间轴上的圆形的黑点一直到第40帧处,在第40帧处单击鼠标右键,在弹出的对话框中选择“插入关键帧”命令,插入一个关键帧。然后单击一下光盘,使其变成旋转模式,将光盘旋转360度。单击“播放”按钮,就可以看到光盘一直不停地转动了。

        3. 至此,整个动画设计完毕,单击“文件→导出”命令,设置好保存的名称,保存的类型(*.gif或*.avi等),将其导出即可观看最终的动画效果了。
    在本教程中飞特上学习CDR的朋友们将学习如何运用CD来设计制作书籍封面,作者通过"茶道人生"实例详细讲解了制作构思与流程,适合CorelDRAW初学者学习制作书籍封面时所需技巧以及熟悉各个常用工具的运用,希望通过学习朋友们能设计制作出更完美的作品~~本文运用CorelDRAW x4来制作"茶道人生"书籍的封面,该封面与封底的创意,使用了简单的配色,突出幽雅的设计理念,呼应图书主题。并且加入了茶叶与茶用器具素材,突出图书中心内容,吸引读者,提高市场的占有率。非常适合初学者学习。
    最终平面效果图
    CorelDRAW制作封面就是这么简单搞可以掂和了 b2b软件 
    最终立体效果图
    CorelDRAW制作封面就是这么简单搞可以掂和了 b2b软件 

    下面是具体的内容介绍:
    一、设计规格
      1. 开本尺寸:16开本
      2. 版心:184cm×260cm
      3. 用纸:封面用纸250g铜版纸,内页用纸60g胶版纸
      4. 页码:270页
      5. 书脊厚度:20mm(书脊厚度计算公式:0.135×克数/100×页数<特别提示:是页数不是码数>)
      6. 装帧:平装
      7. 风格类型:生活艺术类
    二、制作构思与流程
    书籍封面设计,首先新建图像文件,然后根据实际设置好版面尺寸,再使用参考线规划好版面,然后绘制矩形色块以装饰封面,并加入素材作为封面的主体,接着添加阴影与浮雕效果美化(浮雕效果的制作适用于CorelDRAW X4版本)书名标题,再使用文字工具输入封面的作者以及其他相关内容。接下来按照图书的实际尺寸,规划封底和书脊的尺寸,并使用封面类似的风格添加素材,再输入书名和相关出版信息,最后制作一个立体矩形,并将封面元素群组,然后贴到立体矩形上即可。
    三、具体操作步骤
    1、设计书籍封面。打开CorelDRAW x4应用程序,然后选择"文件"/"新建"命令,得到一个A4尺寸的纵向默认页面,再选择"版面"/"页面设置"命令,打开"选项"对话框,参数设置如图01所示:
    CorelDRAW制作封面就是这么简单搞可以掂和了 b2b软件 
    单击"确定"按钮,最后在标准工具栏中设置显示比例为400%,以便更加准确地添加辅助线。
    2、移动鼠标至水平标尺上,往下拖动至垂直标尺的257mm处,添加一条水平辅助线,使用同样的方法,从垂直标尺处往右拖动添加一条垂直辅助线至水平标尺的3mm处,效果如图02所示:
    CorelDRAW制作封面就是这么简单搞可以掂和了 b2b软件 
    3、选择"工具"/"选项"命令,打开其对话框,然后单击辅助线前面的"+"号按钮,在打开的选项中选择"水平"项目,在数值框中输入"3.000",并单击"添加"按钮,添加一条水平数值为"3"mm的辅助线,参数设置如图03A所示:
    CorelDRAW制作封面就是这么简单搞可以掂和了 b2b软件 
    单击"确定"按钮,接着切换至"垂直"选项,添加一条数值为"181.080"的垂直辅助线,最后单击"确定"按钮,效果如图03B所示:
    CorelDRAW制作封面就是这么简单搞可以掂和了 b2b软件 
    将显示比例设置为100%后,添加四条辅助线(即:出血界线)后的结果,效果如图03C所示:
    CorelDRAW制作封面就是这么简单搞可以掂和了 b2b软件 
    提示:印刷时版面四周会有一小部分的区域打印不出来了,所以称之为出血,而建立辅助线可以作为输出印刷时的出血界线,一般为3-5mm。

    这篇教程很简单,也非常详细,它讲述了怎样创建和应用CorelDRAW中的样式。尽管在CorelDRAW 4中就已经出现了样式,但直到现在很多用户还不知道它的存在。使用样式可以使你工作更加轻松,并可以避免有时即使在文件中未包含文本但仍然出现的告诉你缺少字体的消息。如果你是个初学者或是对这一部分不是很明白,那么这篇教程将会对你有所帮助。另外CorelDraw公司还提供了这篇教程所需要的模板和图片,你可以在这里下载,用它来开始学习。这篇教程所用的CorelDRAW版本是11。

      在这个教程里,你将使用样式和模板来创造一张CD的封面和封底,这是最终作品。(图fin1,fin2)



      在这篇教程里,你将学到:
      从模板开始创建一件作品;
      创建和应用图形和文本样式;
      建立和排列多个对象。

      打开模板

      CorelDRAW允许你从模板开始新建一张图,模板是一套预设好的资料,它可以设定页面大小,方位,标尺位置,网格和辅助线信息。
      现在,打开CD封面的设计模板,此模板分为两页,第一页是CD的封面。第二页为封底。(注意:现在的模板还没有网格和辅助线)
      1.点击文件打开;
      2.执行下面的步骤之一:
       Windows--从文件类型中选择CDT-CorelDRAW模板文件,
       Macintosh--从显示菜单中,选择CorelDRAW模板文件;
      3.选择范例文件所在的位置;
      4.双击名为CD_start.cdt的文件;
      5.在随即弹出的对话框中,激活从模板新建(New form template)选项,点击OK。

      设定封面

      你将从CD封面的模板格式开始。
      你还将创建一个图形样式。图形样式是一组用来控制图形显示的属性。在本例中,你将把一个你所创建的图形样式应用于CD封面上的一些图像元素。
      1.点击窗口卷帘窗对象管理器(Windows Dockers Object manager);
      2.在对象管理器卷帘窗中,点击第一页的图层1(Page1 layer1);
      3.打开矩形工具隐藏窗口


    (图Rectangle flyout),从中选择矩形工具

    (图Rectangle tool);
      4.双击矩形工具,这样可以创建一个和页面同样大小的矩形;
      5.在CMYK颜色面板中,选择名为Purple的色标,用右键点击无填充色板(Windows中)或是按住Control,单击无填充色板(Macintosh中)(下同),这样,矩形被填充了紫红色,且没有轮廓线;
      如果屏幕上没有显示CMYK色板,那么从窗口颜色调板默认CMYK调板(Windows}Color palettes}Default CMYK palette)中选择。
      6.右击或按住Control点击这个矩形,在弹出的菜单中选择SytlesSave style properties,存储这个样式;
      7.在名称栏中填入Cover。

      为封面添加图片

      接下来要为封面输入一张图片。
      1.点击文件输入(File Import);
      2.选择范例文件所在的位置;
      3.双击名为saxophon.cdr的文件;
      4.按下空格键,所选图像就会被居中置入页面;
      5.在页面空白处点击一下,取消全部选择。这时的图像应该如下(图import)。




    图import

    [next]

      为封面添加螺旋线

      在这一步,你将用螺旋线装饰封面。

      1.打开对象隐藏窗口


    (图Object flyout),选择螺旋形工具

    (图Spiral tool);

      2.在属性栏中,将旋转圈数设为2


    (图Spiral-revolutions-box);

      3.在属性栏中,点击均匀螺旋线(Symmetrical spiral)按钮


    (图Symmetrical spiral button);

      4.按住Ctrl键(Windows系统中)或是Shift键(Macintosh系统中),在图像上拖出一个高度和宽度相同的螺旋形;

      5.在颜色面板中,右击(或是按住Ctrl点击)白色色板,将轮廓线改为白色;

      6.打开轮廓线窗口(图Outline flyout),选择轮廓线工具


    (图Outline pen);


    图Outline flyout

      7.在宽度对话框中,设置宽度为2.0pt;

      8.从编辑菜单中选择复制来创建螺旋线的副本,把它们拖动到页面的合适位置;

      9.选择选取工具(图Pick tool),在绘图页面的空白处点击一下,取消所有对象的选择;

      10.在任一个螺旋线上点击两次,出现旋转控制手柄;

      11.拖动手柄旋转螺旋线;

      12.重复10步和11步,旋转其它的螺旋;

      13.从编辑菜单中选择选择全部对象(Edit  select all Objects);

      14.从安排菜单中选择组群(Arrange Group),现在,图像应该像下图一样。(图spir
    als)




    图spirals

    [next]

      为封面添加文字
      这里,你将通过创建和摆放文字来为CD封面添加标题。
      创建文字

      1.选择文本工具;(图Text tool)

      2.在萨克斯管下方的图像上点击一下,写上文字Ipsum;

      3.拖动光标选择所有文字,进行下列操作:
       从属性栏的字体列表中选择Staccato222 BT;(图Font list list box)

       在属性栏的字体大小中选择72;(图Font size)

       在颜色面板中点选白色。

      放置文字
      1.点击选择工具;

      2.选择文字Ipsum;

      3.从安排菜单中选择打散(Arrange Break apart);

      4.分别放置每个字母到合适的位置,这样就完成了封面的制作。

      设置封底
      现在你可以将刚才从封面创建的图形样式运用于封底。

      1.在对象管理器窗口中选择第二页的图层1(Page2 Layer1);
      如果不小心关闭了对象管理器窗口,用刚才的方法再次打开。

      2.打开矩形隐藏窗口,选择矩形工具;

      3.双击矩形工具,建立一个和页面大小相同的矩形选框;

      4.右击(在Macintosh中用Ctrl+点击)这个矩形,从右键菜单中选择样式应用Cover(Styles Apply Cover),这个矩形就应用了和封面一样的样式。

      为封底添加螺旋线
      下面,和刚才一样,为封底加上螺旋线作为装饰。

      1至12步和前面完全相同,这里不再赘述。

      13.重复为封面添加螺旋线过程中的4到11步,创建一些螺旋线的副本,这次选择颜色表中的Tropical pink为轮廓颜色;

      14.选择全部对象;

      15.在安排菜单中选择组群,你的图像看起来会像这样。(图back spirals)





    图back spirals

    [next]

      为封底添加封脊
      这张CD封面的第二页模板包括了封底和封脊的位置。在下面的过程中,你将为这张CD创建封脊。

      创建封脊
      1.打开矩形工具隐藏窗口,选择矩形工具;

      2.对角的拖动鼠标,建立一个矩形;

      3.在属性栏的对象宽度中输入11.6(图Object width),在高度栏中输入0.75(图Object height),回车;

      4.右击(Windows)或按住Control+点击(Macintosh)此矩形,然后选择样式应用Cover(Styles Apply Cover),这个矩形就被应用了Cover的样式--purple色的填充和无边框;

      5.选择文本工具;
      6.在矩形的边界上移动鼠标,当指针变成如图形状时(图Text cursor),点击矩形,输入文字LOREM:Ipsum;

      7.选择文字,在属性栏中进行如下操作:

       在字体列表中选择Impact,

       将字体大小设为16,

       点击水平排列按钮(图Horizontal alignment),从下拉菜单中选择居中对齐按钮(图Center);

      8.选择文字LOREM:,在颜色面板中选择Tropical pink;

      9.选择文字Ipsum,在颜色面板中选择白色。

      复制摆放封脊
      1.选择选取工具,点击刚才创建的矩形;

      2.在编辑菜单中选择复制(Edit Duplicate);

      3.在属性栏的旋转角度中输入90,(图Angle of rotation),确定;

      4.在安排菜单下,选择对齐和分布令中的对齐和分布(Arrange Align and distribute Align and distribute;

      5.在对齐和分布对话框中,激活水平中心对齐,左对齐,勾选对齐到页面边缘(Align to Edge of page),应用后关闭对话框;

      6.选择另一个矩形,将之旋转270°;

      7.打开对齐和分布对话框;

      8.在对话框中,激活水平中心对齐,右对齐,勾选对齐到页面边缘,应用后关闭对话框,这时你的图像应该呈现出这个样子(图spine)。




    图spine

    [next]

      为封底添加曲目列表

      这一步,我们要用创建网格建立一个曲目清单,并且加上文字。

      为了确保文字的格式准确无误,你将创建和应用文本样式。文本样式是一套能够控制文本外观的属性。

      建立网格

      1.打开对象隐藏窗口,从中选择网格工具(图Graph paper);

      2.在属性栏中,在网格列数中输入2(图Graph paper columns),网格行数中输入6(图Graph paper rows),点击确认;

      3.拖动鼠标,绘制网格;

      4.选择选取工具;

      5.在属性栏中,设置对象的宽度为2,高度为5;

      6.在颜色调板中选择白色;

      7.打开轮廓工具窗口,选择轮廓对话框工具;

      8.在宽度选项中选择1pt,在样式中选择任何一种虚线;

      9.从安排菜单中选择解组(Arrange Ungroup);

      10.选择选取工具,在绘图页面外的空白处点击一下,取消全部选择;

      11.按住Shift键,选择右边的一列表格中的小矩形,Shift可以让你选择多个对象;

      12.拖动选框右边的手柄,直到属性栏中矩形的宽度达到8厘米,再来看看图像(图track-listing)。




    图track-listing

    [next]

      为表格添加文字

      1.选择文本工具;
      2.移动指针经过表格第一列里的第一个矩形,当鼠标指针变成输入光标时,如图(图Text cursor),输入数字1;

      3.把鼠标移动到第一列的第二个矩形上,当鼠标指针变成输入光标时,输入数字2;

      4.重复第三步,分别在剩下的栏中写上数字3~6;

      5.拖动光标,选择数字1,在属性栏进行下列操作:

       在字体列表中选择Humst521 BT,

       将字体大小设为10,

       选择加粗文本(图Bold),

       在水平对齐方式中,选择居中对齐;

      6.在颜色面板中选择Purple;

      7.选择选取工具,

      8.右击或按住Control点击文本,从弹出菜单Styles Savestyle properties;

      9.在将样式存储为对话框中(Save style as),将样式命名为Nnmber;

      10.选择数字2,右击或是Conrtol+点击文本,然后选择样式应用Nunber(Styles Apply Nember);

      11.重复第10步,为每一个数字都应用样式,这时的图应该像这样:(图text numbers)




    图text numbers

    [next]

      为表格添加曲目标题

      1.选择文本工具;

      2.移动指针经过表格第二列的第一个矩形,当指针变成输入光标时,输入文字Visit autem (2:35);

      3.同样,为第2~6个矩形添加文本,内容分别为

       Irium dolor (3:46)

       Praesant luptatum (4:12)

       Diam nonummy (2:31)

       Magna aliquam (2:57)

       Odio dignissim (3:25)

      4.选择文字Visit autem (2:35),在属性栏中进行下列操作:

       在字体列表中选择Humst521 BT,

       将字体大小设为10,

       在水平对齐方式中选择居中对齐;

      5.存储文本样式,将之命名为Title;

      6.用选取工具选择第二个标题,在右键菜单中选择应用样式,选择Title,如果Title不在菜单中显示,点击更多样式按钮,从中选择;

      7.重复上面的步骤,直到所有的标题都应用相同的样式;

      8.选择选取工具,取消对所有对象的选择;

      9.用Shift键选择表格内的所有矩形;

      10.选择安排组群命令;

      11.在安排菜单下,选择对齐和分布命令,将它们对齐到页面中心,这是现在完成的图(图track titles)。



      放置曲目列表

      1.选择矩形工具;

      2.按对角线拖出一个矩形;

      3.在颜色面板中,选择Banana yellow,然后去掉矩形的轮廓线;

      4.在属性栏中,设置矩形的宽度为9.5,高度为5.5;

      5.在对齐和分布命令中,选择对齐到页面中心;

      6.在安排菜单中,选择排序后一个命令(Arrange Order Back one
    );

      7.用选取工具选择表格;

      8.按住Shift键,再选择黄色矩形;

      9.把它们组群;

      10.用向下的方向键,把曲目列表向下轻移数下,放置到稍低于页面中心的位置。(图position the track-listing)

      为封底添加标题

      现在,我们要为封底添加标题,这一步和为封面添加文字基本相同。

      1.选择文本工具;

      2.在曲目列表上点击,放置光标;

      3.输入Ipsum;

      4.在属性栏中选择Staccato222 BT字体,大小为48,颜色为白色;

      5.在安排菜单中选择和页面中心垂直对齐,这样,我们就得到了一张完整的封底。
      最后,选择存储路径,将你的文件命名为cdcover.cdr,存储即可。
    展开全文
  • creator DrawCall详解

    2020-09-03 16:36:04
    本文将会介绍什么是 DrawCall,为什么要减少 DrawCall 以及在 Cocos Creator 项目中如何减少 DrawCall 来提升游戏性能。 正文 什么是 DrawCall? DrawCall 中文译为“绘制调用”或“绘图指令”。 DrawCall

    前言*

    在游戏开发中,DrawCall 作为一个非常重要的性能指标,直接影响游戏的整体性能表现。
    无论是 Cocos Creator、Unity、Unreal 还是其他游戏引擎,只要说到游戏性能优化,DrawCall 都是绝对少不了的一项。
    本文将会介绍什么是 DrawCall,为什么要减少 DrawCall 以及在 Cocos Creator 项目中如何减少 DrawCall 来提升游戏性能。


    正文

    什么是 DrawCall?

    DrawCall 中文译为“绘制调用”或“绘图指令”。
    DrawCall 是一种行为(指令),即 CPU 调用图形 API,命令 GPU 进行图形绘制。
    DrawCall 一般可以简称为“DC”,当然此“DC”非彼“DC”…


    为什么要减少 DrawCall?

    发生了什么
    当我们在讨论减少 DrawCall 时我们在讨论什么?
    其实我们真正需要减少的并不是 DrawCall 这个行为本身,而是减少每个 DrawCall 前置的一些消耗性能和时间的行为。
    看不懂?其实我也不知道我在说些什么,还是接着看下面的内容吧 :

    举个栗子
    问:尝试在两个硬盘之间传输文件,「传输 1 个 1MB 的文件和传输 1024 个 1KB 的文件」,同样是传输了共 1MB 的文件,「哪个更快?」
    答:「传输 1 个 1MB 的文件要比传输 1024 个 1KB 的文件要快得多得多」。因为在每一个文件传输前,CPU 都需要做许多额外的工作来保证文件能够正确地被传输,而这些额外工作造成了大量额外的性能和时间开销,导致传输速度下降。

    回到渲染
    图形渲染管线的大致流程如下:
    在这里插入图片描述

    上图只是对渲染管线的部分概括,方便大家理解,实际的图形渲染管线比较复杂,不在本文讨论范围内。
    「从图中可以看到在渲染管线中,在每一次 DrawCall 前,CPU 都需要做一系列准备工作,才能让 GPU 正确渲染出图像。」
    「而 CPU 的每一次内存显存读写、数据处理和渲染状态切换都会带来一定的性能和时间消耗。」


    到底是谁的锅?
    一般来说 GPU 渲染图像的速度其实是非常快的,绘制 100 个三角形和绘制 1000 个三角形所消耗的时间没差多少。
    但是 CPU 的内存显存读写、数据处理和渲染状态切换相对于 GPU 渲染来说是「非常非常慢」的。
    实际的瓶颈在于 CPU 这边,大量的 DrawCall 会让 CPU 忙到焦头烂额晕头转向不可开交,而 GPU 大部分时间都在摸鱼,是导致游戏性能下降的主要原因。
    所以 DrawCall 这玩意越少越好~


    如何减少 DrawCall?

    在游戏运行时引擎是按照节点层级顺序从上往下由浅到深进行渲染的,理论上每渲染一张图像(文本最终也是图像)都需要一次 DrawCall。
    既然如此,只要我们想办法将尽可能多的图像在一次 DrawCall 中渲染出来(也就是“渲染合批”),就可以尽量少去调用 CPU,从而减少 DrawCall。
    简单点,就是减少让 CPU 工作的次数,但是每次都多给点活,不就可以省去一些“CPU 准备工具然后工作”和“工作结束叫 GPU 加工”的步骤了嘛,代价就是每次工作的时间会变长~
    明白了这个原理之后,下面让我们看看在实际游戏开发中应该如何操作吧。


    静态合图
    静态合图就是在开发时**「将一系列碎图整合成一张大图」**。
    图集对于 DrawCall 优化来说非常重要,但是并不是说我们把所有图片统统打成图集就万事大吉了,这里面也有它的门道,胡乱打图集的话说不定还会变成负优化。
    最重要的是「尽量将处于同一界面(UI)下的相邻且渲染状态相同的碎图打包成图集」,才能达到减少 DrawCall 的目的。
    还记得游戏渲染时是按顺序渲染的吗,所以“相邻”很关键!要考,做笔记!
    改变渲染状态会打断渲染合批,例如改变纹理状态(预乘、循环模式和过滤模式)或改变 Material(材质)、Blend(混合模式)等等,所以使用自定义 Shader 也会打断合批。

    举个栗子,我这里有一个由 10 张碎图和 1 个文本所组成的弹窗(假设都使用同样的渲染方式):

    1. 在不做任何优化且未开启动态合图的情况下,渲染这个弹窗需要 11 个 DrawCall。
    2. 将所有碎图打成一个图集,文本节点夹在精灵节点之间的情况下需要 3 个 DrawCall,在顶部最外层或者底部最外层的情况下需要 2 个 DrawCall。
    3. 文本使用 BMFont,将所有碎图和 BMFont 打成一个图集的话只需要 1 个 DrawCall,如果碎图不和 BMFont 打成一个图集的情况则参考第 2 项。
    4. 碎图不打包图集,开启动态合图,在理想情况下,文本使用 BMFont 最少只需要 1 个 DrawCall,不使用 BMFont 的情况同样参考第 2 项。
      如果上面的例子你不太能理解的话,那请接着看下面的内容,相信你阅读完本篇文章的全部内容后再来看这个例子将会茅塞顿开哈哈哈~
      动态合图和 BMFont 会在后面说到。
      当然上面这个例子算是比较理想的情况,实际上的情况可能会比例子更为复杂,精灵和文本可能会更多,也不一定能将所有图像资源都打包进一个图集。所以我们只能是尽量合理地去优化,避免出现“捡了芝麻,丢了西瓜”的情况。
      不建议任何图像资源的尺寸超过 2048 * 2048,否则在小游戏和原生平台可能会出现问题;
      而且图像尺寸越大,加载的时间也越长,而且是非线性的那种增长,例如加载一张图像比加载两张图像所消耗的时间还长,得不偿失。

    下面介绍两种打包静态图集的方式:
    自动图集资源(Auto Atlas)
    利用 Cocos Creator 内置的自动图集资源来将碎图打包成图集。
    在项目构建时,编辑器会将所有自动图集资源所在文件夹下的所有符合要求的图像分别根据配置打包成一个或多个图集。
    自动图集资源使用起来很灵活,编辑器在打包图集时会自动递归子目录,若子目录下也有自动图集资源(即 .pac 文件)则会跳过该目录,所以我们可以对同一目录下的不同部分的碎图配置不同的参数。

    创建自动图集配置
    在「资源管理器」中右键,点击 [ 新建 -> 自动图集配置 ] 就会新建一个名为 AutoAtlas.pac 的资源。
    在这里插入图片描述

    配置属性
    在「资源管理器」中点击自动图集资源文件就可以在「属性检查器」面板中看到自动图集资源可配置的属性,点击 Preview 按钮即可预览图集。
    在这里插入图片描述

    关于自动图集的几点建议

    1. 合理控制图集最大尺寸,避免单个图像加载时间过长。
    2. 尺寸太大的图像没有必要打进图集(如背景图)。
    3. 善用九宫格(Sliced)可以节省很多空间(这一点需要美术大佬配合)。
    4. 间距保持默认的 2 并保持勾选扩边选项,避免图像裁剪错误和出现黑边的情况。
    5. 勾选不包含未被引用资源选项,自动排除没有用到的图像以节省空间(该选项预览时无效)。
    6. 开发时预览图集,根据结果进行调整,以达到最好的优化效果。
      关于每个属性具体的作用请参考官方文档。
      自动图集资源官方文档:http://docs.cocos.com/creator/manual/zh/asset-workflow/auto-atlas.html#配置自动图集资源

    TexturePacker
    我们也可以使用第三方软件 TexturePacker 来预先将图像打包成图集再导入项目中。

    TexturePacker 是收费软件,但是一般情况下免费功能就已经够用了。
    另外使用 TexturePacker 打包图集时需要注意配置「形状填充(Shape Padding,对应 Auto Atlas 中的间距)」,避免某张图像出现相邻图像的像素的情况。

    TexturePacker 官网地址:https://www.codeandweb.com/texturepacker


    Auto Atlas 和 TexturePacker 的对比
    Auto Atlas
    o Cocos Creator 内置,方便到家了
    o 功能不多但是该有的都有,免费
    o 项目构建时才生成图集,开发时任意修改无压力
    o 图集尺寸在生成时自适应,节省空间
    o 支持自动纹理压缩
    TexturePacker
    o 第三方软件需自行安装,不够方便
    o 收费功能很多很专业但是用不着,免费功能也够用
    o 先生成图集再使用,更换图像又要重新生成图集
    o 尺寸固定需要自己设置
    o 自己压缩去
    总结:Auto Atlas 真香!


    动态合图(Dynamic Atlas)
    这里引用官方文档中对于动态合图的介绍:
    Cocos Creator 提供了在项目构建时的静态合图方法 —— 「自动合图」(Auto Atlas)。但是当项目日益壮大的时候贴图会变得非常多,很难将贴图打包到一张大贴图中,这时静态合图就比较难以满足降低 DrawCall 的需求。所以 Cocos Creator 在 v2.0 中加入了 「动态合图」(Dynamic Atlas)的功能,它能在项目运行时动态的将贴图合并到一张大贴图中。当渲染一张贴图的时候,动态合图系统会自动检测这张贴图是否已经被合并到了图集(图片集合)中,如果没有,并且此贴图又符合动态合图的条件,就会将此贴图合并到图集中。
    动态合图官方文档:https://docs.cocos.com/creator/manual/zh/advanced-topics/dynamic-atlas.html

    简单来说,开启动态合图之后,引擎会在运行时帮我们对符合条件(即尺寸小于碎图限制的最大尺寸)的精灵进行合图,达到和提前打包图集一样的效果。

    引擎的「动态图集尺寸最大是 2048 * 2048」,可合并的「碎图限制的最大尺寸是 512」,用户可以通过下面的 API 进行修改:
    cc.dynamicAtlasManager.maxFrameSize = 512;
    「启用动态合图会占用额外的内存」,不同平台占用的内存大小不一样。
    小游戏和原生平台上默认会禁用动态合图,但如果你的项目内存空间仍有富余的话建议强制开启:
    cc.macro.CLEANUP_IMAGE_CACHE = false;
    cc.dynamicAtlasManager.enabled = true;
    另外还需要保证纹理的 Premulyiply Alpha(预乘)、Wrap Mode(循环模式) 和 Filter Mode(过滤模式) 等信息与动态图集一致才能够动态合批。

    静态图集也可以参与动态合图
    在动态合图的官方文档中有提到:
    当渲染一张贴图的时候,动态合图系统会自动检测这张贴图是否已经被合并到了图集(图片集合)中,如果没有,并且此贴图又符合动态合图的条件,就会将此贴图合并到图集中。
    但其实「只要静态图集满足动态合图的要求(即尺寸小于碎图限制的最大尺寸),也是可以参与动态合图的」。
    注意:自动图集资源(Auto Atlas)需要在其属性检查器面板中开启 「Texture」 栏下的 「Packable」 选项,该选项默认是禁用的。

    额外补充
    「只有纹理开启了 Packable 选项的精灵才能够参与动态合图」,该选项默认开启。

    纹理参与动态合图后会修改原始贴图的 UV 坐标,所以在 Shader 中的无法正确计算 UV 坐标,导致 Shader 无效。
    「如果需要对精灵使用自定义 Shader,需要禁用其纹理的 Packable 选项。」
    也可以在代码中禁用该选项:
    let sprite = this.node.getComponent(cc.Sprite);
    let texture = sprite.spriteFrame.getTexture();
    texture.packable = false;

    Packable 官方文档:https://docs.cocos.com/creator/manual/zh/asset-workflow/sprite.html?h=packable


    位图字体(BMFont)
    在场景中使用系统字体或 TTF 字体的 Label 会打断渲染合批,特别是 Label 和 Sprite 层叠交错的情况,每一个 Label 都会打断合批增加一个 DrawCall,文本多的场景下轻轻松松 100+。
    对于游戏中的文本,特别是数字、字母和符号,都建议「使用 BMFont 来代替 TTF 或系统字体」,并且「将 BMFont 与 UI 碎图打包到同一图集中」(或「开启动态合图」),可以免除大部分文本导致的 DrawCall。
    举个栗子
    例如一个场景中有 80 张精灵和 80 个文本(系统字体)相互交错,节点层级如下图:

    运行起来之后可以看到左下角的 Profile 显示 DrawCall 已经高达 161 个,也就是说每一个精灵和文本都增加一个 DrawCall,这种情况即使精灵打了图集也一样无济于事。
    不要问明明只有 80 张精灵和 80 个文本不应该是 160 个 DrawCall 吗为什么是 161 个…
    因为左下角的 Profile 也要占一个 : (

    对比栗子
    还是上面的场景,尝试将 Label 的系统字体换成 BMFont 并且与精灵打包到同一个图集之后,同样是 80 个精灵和 80 个文本。
    但是 DrawCall 只有 2 个,同时帧时间降低到了 1ms,帧率提升了 10 FPS,渲染耗时降低到了 0.6ms。
    实际上场景只占了 1 个 DrawCall,另一个 DrawCall 是左下角的 Profile 占的…

    另外,对于汉字可以尝试使用 Label 组件的 「Cache Mode」 来优化。


    文本缓存模式(Cache Mode)
    Cocos Creator 2.0.9 版本在 Label 组件上增加了 「Cache Mode」 选项,来解决系统字体和 TTF 字体带来的性能问题。
    Cache Mode 官方文档:https://docs.cocos.com/creator/manual/zh/components/label.html#文本缓存类型(cache-mode)
    Cache Mode 有以下3 种选择:
    NONE(默认)
    每一个 Label 都会生成为一张单独的位图,且不会参与动态合图,所以每一个 Label 都会打断渲染合批。


    BITMAP
    当 Label 组件开启 BITMAP 模式后,文本同样会生成为一张位图,但是「只要符合动态合图要求就可以参与动态合图,和周围的精灵合并 DrawCall」。
    「一定要注意 BITMAP 模式只适用于不频繁更改的文本,否则内存爆炸了后果自负!」
    举个栗子
    同样是上文提到的「精灵和文本相互交错」的例子,「文本使用 BITMAP 模式,精灵不打包成图集,开启动态合图」。
    结果是所有精灵(包括背景)和文本都成功动态合图,实际 DrawCall 降至 1 个。
    如果精灵打包成了图集则会变成 160 个,因为图集默认不参与动态合图。
    所以当前这种情况(少精灵多文本)不打图集反而是比较好的选择。


    CHAR
    当 Label 组件开启 CHAR 模式后,引擎会将该 Label 中出现的所有字符缓存到一张全局共享的位图中,相当于是生成了一个 BMFont。
    「适用于文本频繁更改的情况,对性能和内存最友好。」
    注意:「该模式只能用于字体样式和字号固定,并且不会频繁出现巨量未使用过的字符的 Label。因为共享位图的最大尺寸为 2048*2048,占满了之后就没办法再渲染新的字符,需要切换场景才会清除共享位图。」
    开启了 CHAR 模式的 Label 无法参与动态合图,但是可以和相邻的同样是 CHAR 模式的 Label 合并 DrawCall(相当于是一张未打包进图集的 BMFont)。
    举个栗子
    还是是上文提到的「精灵和文本相互交错」的例子,为了更好体现 CHAR 模式的优势,我更改了场景节点的结构,将精灵和文本进行「分离」(关于这点可以看下面的 「UI层级调整」)。

    所有 Label 开启 CHAR 模式,并在脚本中每过 0.2 秒就将文本更改成新的随机数。
    在这个例子中,引擎会在运行时生成一张包含数字 0 到 9 的 BMFont 存在内存中,另外由于我将所有 Label 都聚合在一起,所以所有 Label 的渲染合并成了 1 个 DrawCall,「另外请特别关注左下角的帧时间、帧率和渲染耗时」。

    光看上面的图似乎看不出个所以然来,那我们增加一个对照组,「将所有文本的 Cache Mode 选项设为默认的 NONE 模式」。
    此时可以发现「帧时间最高达到了 2 ms,平均帧率下降了大概 6 FPS,渲染耗时更是翻了 4 倍最高达到了 1.8 ms。」

    总结
    结论已经很明显了,对于大量频繁更改的文本,使用 CHAR 模式带来的性能提升是非常明显的。
    同时 CHAR 模式的局限也很明显,一般用于场景中出现大量数字文本,类似于经验值增加、血量减少之类的特效的情况。


    UI 层级调整
    除了以上的优化方案,我们还可以在游戏场景中下功夫,将性能优化做到极致。
    其实上文也有提到,我们可以通过「优化节点层级,分离图像节点和文本节点,文本使用 BMFont 或 Cache Mode 选项,尽量出现避免文本打断渲染合批的情况」。

    特别是对于战斗场景中大量的文本提示(伤害值、血量值和法力值等等)或合成游戏中大量的经验值文本,因为这些文本基本都是数字,使用这种方式即使再多文本也只需要 1 个 DrawCall 就可以全部渲染出来。
    举个栗子
    下面的场景中,文本开启 CHAR 模式,使用脚本每秒生成 50 个左右的随机数字,文本节点统一放在 labelLayer 节点下,让所有文本可以共享 1 个 DrawCall,另外背景和椰子头占 1 个,左下角 Profile 占 1 个。
    可以看到即使场景中瞬间出现这么多文本,整体性能也还是比较可观的。
    在这个例子中,引擎在运行时为我们生成了一份包含数字 0 到 9 的全局共享位图(BMFont)。
    当然如果可以在 Label 中直接使用 BMFont 的话那就更好了。


    补充
    再次提醒

    1. 改变渲染状态会打断渲染合批,例如改变纹理状态(预乘、循环模式和过滤模式)或改变 Material(材质)、Blend(混合模式)等等,所以使用自定义 Shader 也会打断合批。
    2. 图集默认不参与动态合图,手动开启自动图集资源的 Packable 选项后如果最终图集符合动态合图要求也可以参与动态合图。
    3. 纹理开启 Packable 选项参与动态合图后无法使用自定义 Shader,因为动态合图会修改原始贴图的 UV 坐标。
    4. 使用 Cache Mode 的 BITMAP 模式需要注意内存情况,CHAR 模式需要注意文本内容是否多且不重复。
      最后还需要注意
      在 Cocos Creator 2.0.7 之前的版本中,改变节点的颜色或透明度、Sprite 组件使用九宫格(Sliced)都会打断渲染合批。

    转载

    转载自微信公众号 Creator星球游戏开发社区
    https://mp.weixin.qq.com/s/rMhJvRXNhT5vzXn5YCYSzQ

    展开全文
  • Cocos Creator 性能优化:DrawCall

    千次阅读 2020-07-02 21:58:10
    本文将会介绍什么是 DrawCall,为什么要减少 DrawCall 以及在 Cocos Creator 项目中如何减少 DrawCall 来提升游戏性能。 正文 什么是 DrawCall? DrawCall 中文译为“绘制调用”或“绘图指令”。 DrawCall

    前言

    在游戏开发中,DrawCall 作为一个非常重要的性能指标,直接影响游戏的整体性能表现。

    无论是 Cocos Creator、Unity、Unreal 还是其他游戏引擎,只要说到游戏性能优化,DrawCall 都是绝对少不了的一项。

    本文将会介绍什么是 DrawCall,为什么要减少 DrawCall 以及在 Cocos Creator 项目中如何减少 DrawCall 来提升游戏性能。


    正文

    什么是 DrawCall?

    DrawCall 中文译为“绘制调用”或“绘图指令”。

    DrawCall 是一种行为(指令),即 CPU 调用图形 API,命令 GPU 进行图形绘制。

    DrawCall 一般可以简称为“DC”,当然此“DC”非彼“DC”…


    为什么要减少 DrawCall?

    发生了什么

    当我们在讨论减少 DrawCall 时我们在讨论什么?

    其实我们真正需要减少的并不是 DrawCall 这个行为本身,而是减少每个 DrawCall 前置的一些消耗性能和时间的行为。

    看不懂?其实我也不知道我在说些什么,还是接着看下面的内容吧 : p

    举个栗子

    问:尝试在两个硬盘之间传输文件,传输 1 个 1MB 的文件和传输 1024 个 1KB 的文件,同样是传输了共 1MB 的文件,哪个更快?

    答:传输 1 个 1MB 的文件要比传输 1024 个 1KB 的文件要快得多得多。因为在每一个文件传输前,CPU 都需要做许多额外的工作来保证文件能够正确地被传输,而这些额外工作造成了大量额外的性能和时间开销,导致传输速度下降。

    回到渲染

    图形渲染管线的大致流程如下:

    上图只是对渲染管线的部分概括,方便大家理解,实际的图形渲染管线比较复杂,不在本文讨论范围内。

    从图中可以看到在渲染管线中,在每一次 DrawCall 前,CPU 都需要做一系列准备工作,才能让 GPU 正确渲染出图像。

    而 CPU 的每一次内存显存读写、数据处理和渲染状态切换都会带来一定的性能和时间消耗。


    到底是谁的锅?

    一般来说 GPU 渲染图像的速度其实是非常快的,绘制 100 个三角形和绘制 1000 个三角形所消耗的时间没差多少。

    但是 CPU 的内存显存读写、数据处理和渲染状态切换相对于 GPU 渲染来说是非常非常慢的。

    实际的瓶颈在于 CPU 这边,大量的 DrawCall 会让 CPU 忙到焦头烂额晕头转向不可开交,而 GPU 大部分时间都在摸鱼,是导致游戏性能下降的主要原因。

    所以 DrawCall 这玩意越少越好~


    如何减少 DrawCall?

    在游戏运行时引擎是按照节点层级顺序从上往下由浅到深进行渲染的,理论上每渲染一张图像(文本最终也是图像)都需要一次 DrawCall。

    既然如此,只要我们想办法将尽可能多的图像在一次 DrawCall 中渲染出来(也就是“渲染合批”),就可以尽量少去调用 CPU,从而减少 DrawCall。

    简单点,就是减少让 CPU 工作的次数,但是每次都多给点活,不就可以省去一些“CPU 准备工具然后工作”和“工作结束叫 GPU 加工”的步骤了嘛,代价就是每次工作的时间会变长~

    明白了这个原理之后,下面让我们看看在实际游戏开发中应该如何操作吧。


    静态合图

    静态合图就是在开发时将一系列碎图整合成一张大图

    图集对于 DrawCall 优化来说非常重要,但是并不是说我们把所有图片统统打成图集就万事大吉了,这里面也有它的门道,胡乱打图集的话说不定还会变成负优化。

    最重要的是尽量将处于同一界面(UI)下的相邻且渲染状态相同的碎图打包成图集,才能达到减少 DrawCall 的目的。

    还记得游戏渲染时是按顺序渲染的吗,所以“相邻”很关键!要考,做笔记!

    改变渲染状态会打断渲染合批,例如改变纹理状态(预乘、循环模式和过滤模式)或改变 Material(材质)、Blend(混合模式)等等,所以使用自定义 Shader 也会打断合批。

    举个栗子,我这里有一个由 10 张碎图和 1 个文本所组成的弹窗(假设都使用同样的渲染方式):

    1. 在不做任何优化且未开启动态合图的情况下,渲染这个弹窗需要 11 个 DrawCall。
    2. 将所有碎图打成一个图集,文本节点夹在精灵节点之间的情况下需要 3 个 DrawCall,在顶部最外层或者底部最外层的情况下需要 2 个 DrawCall。
    3. 文本使用 BMFont,将所有碎图和 BMFont 打成一个图集的话只需要 1 个 DrawCall,如果碎图不和 BMFont 打成一个图集的情况则参考第 2 项。
    4. 碎图不打包图集,开启动态合图,在理想情况下,文本使用 BMFont 最少只需要 1 个 DrawCall,不使用 BMFont 的情况同样参考第 2 项。

    如果上面的例子你不太能理解的话,那请接着看下面的内容,相信你阅读完本篇文章的全部内容后再来看这个例子将会茅塞顿开哈哈哈~

    动态合图和 BMFont 会在后面说到。

    当然上面这个例子算是比较理想的情况,实际上的情况可能会比例子更为复杂,精灵和文本可能会更多,也不一定能将所有图像资源都打包进一个图集。所以我们只能是尽量合理地去优化,避免出现“捡了芝麻,丢了西瓜”的情况。

    不建议任何图像资源的尺寸超过 2048 * 2048,否则在小游戏和原生平台可能会出现问题;

    而且图像尺寸越大,加载的时间也越长,而且是非线性的那种增长,例如加载一张图像比加载两张图像所消耗的时间还长,得不偿失。


    下面介绍两种打包静态图集的方式:

    自动图集资源(Auto Atlas)

    利用 Cocos Creator 内置的自动图集资源来将碎图打包成图集。

    在项目构建时,编辑器会将所有自动图集资源所在文件夹下的所有符合要求的图像分别根据配置打包成一个或多个图集。

    自动图集资源使用起来很灵活,编辑器在打包图集时会自动递归子目录,若子目录下也有自动图集资源(即 .pac 文件)则会跳过该目录,所以我们可以对同一目录下的不同部分的碎图配置不同的参数。

    创建自动图集配置

    资源管理器中右键,点击 [ 新建 -> 自动图集配置 ] 就会新建一个名为 AutoAtlas.pac 的资源。

    配置属性

    资源管理器中点击自动图集资源文件就可以在属性检查器面板中看到自动图集资源可配置的属性,点击 Preview 按钮即可预览图集。

    关于自动图集的几点建议
    1. 合理控制图集最大尺寸,避免单个图像加载时间过长。
    2. 尺寸太大的图像没有必要打进图集(如背景图)。
    3. 善用九宫格(Sliced)可以节省很多空间(这一点需要美术大佬配合)。
    4. 间距保持默认的 2 并保持勾选扩边选项,避免图像裁剪错误和出现黑边的情况。
    5. 勾选不包含未被引用资源选项,自动排除没有用到的图像以节省空间(该选项预览时无效)。
    6. 开发时预览图集,根据结果进行调整,以达到最好的优化效果。

    关于每个属性具体的作用请参考官方文档。

    自动图集资源官方文档:http://docs.cocos.com/creator/manual/zh/asset-workflow/auto-atlas.html#配置自动图集资源


    TexturePacker

    我们也可以使用第三方软件 TexturePacker 来预先将图像打包成图集再导入项目中。

    TexturePacker 是收费软件,但是一般情况下免费功能就已经够用了。

    另外使用 TexturePacker 打包图集时需要注意配置形状填充(Shape Padding,对应 Auto Atlas 中的间距),避免某张图像出现相邻图像的像素的情况。

    TexturePacker 官网地址:https://www.codeandweb.com/texturepacker


    Auto Atlas 和 TexturePacker 的对比

    Auto Atlas
    • Cocos Creator 内置,方便到家了
    • 功能不多但是该有的都有,免费
    • 项目构建时才生成图集,开发时任意修改无压力
    • 图集尺寸在生成时自适应,节省空间
    • 支持自动纹理压缩
    TexturePacker
    • 第三方软件需自行安装,不够方便
    • 收费功能很多很专业但是用不着,免费功能也够用
    • 先生成图集再使用,更换图像又要重新生成图集
    • 尺寸固定需要自己设置
    • 自己压缩去

    总结:Auto Atlas 真香!


    动态合图(Dynamic Atlas)

    这里引用官方文档中对于动态合图的介绍:

    Cocos Creator 提供了在项目构建时的静态合图方法 —— 自动合图(Auto Atlas)。但是当项目日益壮大的时候贴图会变得非常多,很难将贴图打包到一张大贴图中,这时静态合图就比较难以满足降低 DrawCall 的需求。所以 Cocos Creator 在 v2.0 中加入了 动态合图(Dynamic Atlas)的功能,它能在项目运行时动态的将贴图合并到一张大贴图中。当渲染一张贴图的时候,动态合图系统会自动检测这张贴图是否已经被合并到了图集(图片集合)中,如果没有,并且此贴图又符合动态合图的条件,就会将此贴图合并到图集中。

    动态合图官方文档:https://docs.cocos.com/creator/manual/zh/advanced-topics/dynamic-atlas.html

    简单来说,开启动态合图之后,引擎会在运行时帮我们对符合条件(即尺寸小于碎图限制的最大尺寸)的精灵进行合图,达到和提前打包图集一样的效果。

    引擎的动态图集尺寸最大是 2048 * 2048,可合并的碎图限制的最大尺寸是 512,用户可以通过下面的 API 进行修改:

    cc.dynamicAtlasManager.maxFrameSize = 512;
    

    启用动态合图会占用额外的内存,不同平台占用的内存大小不一样。小游戏和原生平台上默认会禁用动态合图,但如果你的项目内存空间仍有富余的话建议强制开启:

    cc.macro.CLEANUP_IMAGE_CACHE = false;
    cc.dynamicAtlasManager.enabled = true;
    

    另外还需要保证纹理的 Premulyiply Alpha(预乘)、Wrap Mode(循环模式) 和 Filter Mode(过滤模式) 等信息与动态图集一致才能够动态合批。

    静态图集也可以参与动态合图

    在动态合图的官方文档中有提到:

    当渲染一张贴图的时候,动态合图系统会自动检测这张贴图是否已经被合并到了图集(图片集合)中,如果没有,并且此贴图又符合动态合图的条件,就会将此贴图合并到图集中。

    但其实只要静态图集满足动态合图的要求(即尺寸小于碎图限制的最大尺寸),也是可以参与动态合图的

    注意:自动图集资源(Auto Atlas)需要在其属性检查器面板中开启 Texture 栏下的 Packable 选项,该选项默认是禁用的。

    额外补充

    只有纹理开启了 Packable 选项的精灵才能够参与动态合图,该选项默认开启。

    纹理参与动态合图后会修改原始贴图的 UV 坐标,所以在 Shader 中的无法正确计算 UV 坐标,导致 Shader 无效。

    如果需要对精灵使用自定义 Shader,需要禁用其纹理的 Packable 选项。

    也可以在代码中禁用该选项:

    let sprite = this.node.getComponent(cc.Sprite);
    let texture = sprite.spriteFrame.getTexture();
    texture.packable = false;
    

    Packable 官方文档:https://docs.cocos.com/creator/manual/zh/asset-workflow/sprite.html?h=packable


    位图字体(BMFont)

    在场景中使用系统字体或 TTF 字体的 Label 会打断渲染合批,特别是 Label 和 Sprite 层叠交错的情况,每一个 Label 都会打断合批增加一个 DrawCall,文本多的场景下轻轻松松 100+。

    对于游戏中的文本,特别是数字、字母和符号,都建议使用 BMFont 来代替 TTF 或系统字体,并且将 BMFont 与 UI 碎图打包到同一图集中(或开启动态合图),可以免除大部分文本导致的 DrawCall。

    举个栗子

    例如一个场景中有 80 张精灵和 80 个文本(系统字体)相互交错,节点层级如下图:

    运行起来之后可以看到左下角的 Profile 显示 DrawCall 已经高达 161 个,也就是说每一个精灵和文本都增加一个 DrawCall,这种情况即使精灵打了图集也一样无济于事。

    不要问明明只有 80 张精灵和 80 个文本不应该是 160 个 DrawCall 吗为什么是 161 个…

    因为左下角的 Profile 也要占一个 : (

    对比栗子

    还是上面的场景,尝试将 Label 的系统字体换成 BMFont 并且与精灵打包到同一个图集之后,同样是 80 个精灵和 80 个文本。

    但是 DrawCall 只有 2 个,同时帧时间降低到了 1ms,帧率提升了 10 FPS,渲染耗时降低到了 0.6ms。

    实际上场景只占了 1 个 DrawCall,另一个 DrawCall 是左下角的 Profile 占的…

    另外,对于汉字可以尝试使用 Label 组件的 Cache Mode 来优化。


    文本缓存模式(Cache Mode)

    Cocos Creator 2.0.9 版本在 Label 组件上增加了 Cache Mode 选项,来解决系统字体和 TTF 字体带来的性能问题。

    Cache Mode 官方文档:https://docs.cocos.com/creator/manual/zh/components/label.html#文本缓存类型(cache-mode)

    Cache Mode 有以下3 种选择:

    NONE(默认)

    每一个 Label 都会生成为一张单独的位图,且不会参与动态合图,所以每一个 Label 都会打断渲染合批。


    BITMAP

    当 Label 组件开启 BITMAP 模式后,文本同样会生成为一张位图,但是只要符合动态合图要求就可以参与动态合图,和周围的精灵合并 DrawCall

    一定要注意 BITMAP 模式只适用于不频繁更改的文本,否则内存爆炸了后果自负!

    举个栗子

    同样是上文提到的精灵和文本相互交错的例子,文本使用 BITMAP 模式,精灵不打包成图集,开启动态合图

    结果是所有精灵(包括背景)和文本都成功动态合图,实际 DrawCall 降至 1 个。

    如果精灵打包成了图集则会变成 160 个,因为图集默认不参与动态合图。

    所以当前这种情况(少精灵多文本)不打图集反而是比较好的选择。


    CHAR

    当 Label 组件开启 CHAR 模式后,引擎会将该 Label 中出现的所有字符缓存到一张全局共享的位图中,相当于是生成了一个 BMFont。

    适用于文本频繁更改的情况,对性能和内存最友好。

    注意:该模式只能用于字体样式和字号固定,并且不会频繁出现巨量未使用过的字符的 Label。因为共享位图的最大尺寸为 2048*2048,占满了之后就没办法再渲染新的字符,需要切换场景才会清除共享位图。

    开启了 CHAR 模式的 Label 无法参与动态合图,但是可以和相邻的同样是 CHAR 模式的 Label 合并 DrawCall(相当于是一张未打包进图集的 BMFont)。

    举个栗子

    还是是上文提到的精灵和文本相互交错的例子,为了更好体现 CHAR 模式的优势,我更改了场景节点的结构,将精灵和文本进行分离(关于这点可以看下面的 UI层级调整)。

    所有 Label 开启 CHAR 模式,并在脚本中每过 0.2 秒就将文本更改成新的随机数。

    在这个例子中,引擎会在运行时生成一张包含数字 0 到 9 的 BMFont 存在内存中,另外由于我将所有 Label 都聚合在一起,所以所有 Label 的渲染合并成了 1 个 DrawCall,另外请特别关注左下角的帧时间、帧率和渲染耗时

    光看上面的图似乎看不出个所以然来,那我们增加一个对照组,将所有文本的 Cache Mode 选项设为默认的 NONE 模式

    此时可以发现帧时间最高达到了 2 ms,平均帧率下降了大概 6 FPS,渲染耗时更是翻了 4 倍最高达到了 1.8 ms。

    总结

    结论已经很明显了,对于大量频繁更改的文本,使用 CHAR 模式带来的性能提升是非常明显的。

    同时 CHAR 模式的局限也很明显,一般用于场景中出现大量数字文本,类似于经验值增加、血量减少之类的特效的情况。


    UI 层级调整

    除了以上的优化方案,我们还可以在游戏场景中下功夫,将性能优化做到极致。

    其实上文也有提到,我们可以通过优化节点层级,分离图像节点和文本节点,文本使用 BMFont 或 Cache Mode 选项,尽量出现避免文本打断渲染合批的情况

    特别是对于战斗场景中大量的文本提示(伤害值、血量值和法力值等等)或合成游戏中大量的经验值文本,因为这些文本基本都是数字,使用这种方式即使再多文本也只需要 1 个 DrawCall 就可以全部渲染出来。

    举个栗子

    下面的场景中,文本开启 CHAR 模式,使用脚本每秒生成 50 个左右的随机数字,文本节点统一放在 labelLayer 节点下,让所有文本可以共享 1 个 DrawCall,另外背景和椰子头占 1 个,左下角 Profile 占 1 个。

    可以看到即使场景中瞬间出现这么多文本,整体性能也还是比较可观的。

    在这个例子中,引擎在运行时为我们生成了一份包含数字 0 到 9 的全局共享位图(BMFont)。

    当然如果可以在 Label 中直接使用 BMFont 的话那就更好了。


    补充

    再次提醒

    1. 改变渲染状态会打断渲染合批,例如改变纹理状态(预乘、循环模式和过滤模式)或改变 Material(材质)、Blend(混合模式)等等,所以使用自定义 Shader 也会打断合批。

    2. 图集默认不参与动态合图,手动开启自动图集资源的 Packable 选项后如果最终图集符合动态合图要求也可以参与动态合图。

    3. 纹理开启 Packable 选项参与动态合图后无法使用自定义 Shader,因为动态合图会修改原始贴图的 UV 坐标。

    4. 使用 Cache Mode 的 BITMAP 模式需要注意内存情况,CHAR 模式需要注意文本内容是否多且不重复。

    最后还需要注意

    在 Cocos Creator 2.0.7 之前的版本中,改变节点的颜色或透明度、Sprite 组件使用九宫格(Sliced)都会打断渲染合批。

    蒜我球球你了快更新吧 : (


    相关资料

    Cocos Creator 用户手册
    https://docs.cocos.com/creator/manual/zh/


    传送门

    微信推文版本

    个人博客:菜鸟小栈

    开源主页:陈皮皮

    Eazax-CCC 游戏开发脚手架


    更多分享

    为什么选择使用 TypeScript ?

    高斯模糊 Shader

    一文看懂 YAML


    公众号

    菜鸟小栈

    我是陈皮皮,这是我的个人公众号,专注但不仅限于游戏开发、前端和后端技术记录与分享。

    每一篇原创都非常用心,你的关注就是我原创的动力!

    Input and output.

    展开全文
  • 本文将会介绍什么是 DrawCall,为什么要减少 DrawCall 以及在 Cocos Creator 项目中如何减少 DrawCall 来提升游戏性能。 正文 什么是 DrawCall? DrawCall 中文译为“绘制调用”或“绘图指令”。 DrawC

    前言

    在游戏开发中,DrawCall 作为一个非常重要的性能指标,直接影响游戏的整体性能表现。

    无论是 Cocos Creator、Unity、Unreal 还是其他游戏引擎,只要说到游戏性能优化,DrawCall 都是绝对少不了的一项。

    本文将会介绍什么是 DrawCall,为什么要减少 DrawCall 以及在 Cocos Creator 项目中如何减少 DrawCall 来提升游戏性能。


    正文

    什么是 DrawCall?

    DrawCall 中文译为“绘制调用”或“绘图指令”。

    DrawCall 是一种行为(指令),即 CPU 调用图形 API,命令 GPU 进行图形绘制。

    DrawCall 一般可以简称为“DC”,当然此“DC”非彼“DC”...


    为什么要减少 DrawCall?

    发生了什么

    当我们在讨论减少 DrawCall 时,我们指的是什么?

    其实我们真正需要减少的,并不是 DrawCall 这个行为本身,而是减少每个 DrawCall 前置的一些消耗性能和时间的行为。

    看不懂?没关系,接着看下面的内容吧 : p

    举个栗子

    问:尝试在两个硬盘之间传输文件,「传输 1 个 1MB 的文件和传输 1024 个 1KB 的文件」,同样是传输了共 1MB 的文件,「哪个更快?」

    答:「传输 1 个 1MB 的文件要比传输 1024 个 1KB 的文件要快得多得多」。因为在每一个文件传输前,CPU 都需要做许多额外的工作来保证文件能够正确地被传输,而这些额外工作造成了大量额外的性能和时间开销,导致传输速度下降。

    回到渲染

    图形渲染管线的大致流程如下:

    上图只是对渲染管线的部分概括,方便大家理解,实际的图形渲染管线比较复杂,不在本文讨论范围内。

    「从图中可以看到在渲染管线中,每一次 DrawCall 前,CPU 都需要做一系列准备工作,才能让 GPU 正确渲染出图像。」

    「而 CPU 的每一次内存显存读写、数据处理和渲染状态切换都会带来一定的性能和时间消耗。」


    到底是谁的锅?

    一般来说 GPU 渲染图像的速度其实是非常快的,绘制 100 个三角形和绘制 1000 个三角形所消耗的时间没差多少。

    但是 CPU 的内存显存读写、数据处理和渲染状态切换相对于 GPU 渲染来说是「非常非常慢」的。

    实际的瓶颈在于 CPU 这边,大量的 DrawCall 会让 CPU 忙得焦头烂额晕头转向不可开交,而 GPU 大部分时间都在摸鱼,是导致游戏性能下降的主要原因。

    所以 DrawCall 这玩意越少越好~


    如何减少 DrawCall?

    在游戏运行时引擎是按照节点层级顺序,从上往下由浅到深进行渲染的,理论上每渲染一张图像(文本最终也是图像)都需要一次 DrawCall。

    既然如此,只要我们想办法将尽可能多的图像在一次 DrawCall 中渲染出来(也就是“渲染合批”),就可以尽量少去调用 CPU,从而减少 DrawCall。

    简单点,就是减少让 CPU 工作的次数,但是每次都多给点活,不就可以省去一些“CPU 准备工具然后工作”和“工作结束叫 GPU 加工”的步骤了嘛,代价就是每次工作的时间会变长~

    明白了这个原理之后,下面让我们看看在实际游戏开发中应该如何操作吧。


    静态合图

    静态合图就是在开发时「将一系列碎图整合成一张大图」

    图集对于 DrawCall 优化来说非常重要,但是并不是说我们把所有图片统统打成图集就万事大吉了,这里面也有它的门道,胡乱打图集的话说不定还会变成负优化。

    最重要的是「尽量将处于同一界面(UI)下的相邻且渲染状态相同的碎图,打包成图集」,才能达到减少 DrawCall 的目的。

    还记得游戏渲染时是按顺序渲染的吗,所以“相邻”很关键!要考,做笔记!

    改变渲染状态会打断渲染合批,例如改变纹理状态(预乘、循环模式和过滤模式)或改变 Material(材质)、Blend(混合模式)等等,所以使用自定义 Shader 也会打断合批。

    举个栗子,我这里有一个由 10 张碎图和 1 个文本所组成的弹窗(假设都使用同样的渲染方式):

    1. 在不做任何优化且未开启动态合图的情况下,渲染这个弹窗需要 11 个 DrawCall。

    2. 将所有碎图打成一个图集,文本节点夹在精灵节点之间的情况下,需要 3 个 DrawCall。在顶部最外层或者底部最外层的情况下,需要 2 个 DrawCall。

    3. 文本使用 BMFont,将所有碎图和 BMFont 打成一个图集的话只需要 1 个 DrawCall,如果碎图不和 BMFont 打成一个图集的情况,则参考第 2 项。

    4. 碎图不打包图集,开启动态合图,在理想情况下,文本使用 BMFont 最少只需要 1 个 DrawCall,不使用 BMFont 的情况同样参考第 2 项。

    如果上面的例子你不太能理解的话,那请接着看下面的内容,相信你阅读完本篇文章的全部内容后再来看这个例子将会茅塞顿开哈哈哈~

    动态合图和 BMFont 会在后面说到。

    当然上面这个例子算是比较理想的情况,实际上的情况可能会比例子更为复杂,精灵和文本可能会更多,也不一定能将所有图像资源都打包进一个图集。

    所以我们只能是尽量合理地去优化,避免出现“捡了芝麻,丢了西瓜”的情况。

    不建议任何图像资源的尺寸超过 2048 * 2048,否则在小游戏和原生平台可能会出现问题;

    而且图像尺寸越大,加载的时间也越长,而且是非线性的那种增长,例如加载一张图像比加载两张图像所消耗的时间还长,得不偿失。


    下面介绍两种打包静态图集的方式:

    自动图集资源(Auto Atlas)

    利用 Cocos Creator 内置的自动图集资源来将碎图打包成图集。

    在项目构建时,编辑器会将所有自动图集资源所在文件夹下的所有符合要求的图像分别根据配置打包成一个或多个图集。

    自动图集资源使用起来很灵活,编辑器在打包图集时会自动递归子目录,若子目录下也有自动图集资源(即 .pac 文件)则会跳过该目录,所以我们可以对同一目录下的不同部分的碎图配置不同的参数。

    创建自动图集配置

    「资源管理器」中右键,点击 [ 新建 -> 自动图集配置 ] 就会新建一个名为 AutoAtlas.pac 的资源。

    配置属性

    「资源管理器」中点击自动图集资源文件,就可以在「属性检查器」面板中看到自动图集资源可配置的属性,点击 Preview 按钮即可预览图集。

    关于自动图集的几点建议

    1. 合理控制图集最大尺寸,避免单个图像加载时间过长。

    2. 尺寸太大的图像没有必要打进图集(如背景图)。

    3. 善用九宫格(Sliced)可以节省很多空间(这一点需要美术大佬配合)。

    4. 间距保持默认的 2 并保持勾选扩边选项,避免图像裁剪错误和出现黑边的情况。

    5. 勾选不包含未被引用资源选项,自动排除没有用到的图像以节省空间(该选项预览时无效)。

    6. 开发时预览图集,根据结果进行调整,以达到最好的优化效果。

    关于每个属性具体的作用请参考官方文档。

    自动图集资源官方文档:http://docs.cocos.com/creator/manual/zh/asset-workflow/auto-atlas.html#配置自动图集资源


    TexturePacker

    我们也可以使用第三方软件 TexturePacker 来预先将图像打包成图集再导入项目中。

    TexturePacker 是收费软件,但是一般情况下免费功能就已经够用了。

    另外使用 TexturePacker 打包图集时需要注意配置「形状填充(Shape Padding,对应 Auto Atlas 中的间距)」,避免某张图像出现相邻图像的像素的情况。

    TexturePacker 官网地址:https://www.codeandweb.com/texturepacker


    Auto Atlas 和 TexturePacker 的对比

    Auto Atlas

    • Cocos Creator 内置,方便到家了

    • 功能不多但是该有的都有,免费

    • 项目构建时才生成图集,开发时任意修改无压力

    • 图集尺寸在生成时自适应,节省空间

    • 支持自动纹理压缩

    TexturePacker

    • 第三方软件需自行安装,不够方便

    • 收费功能很多很专业,但是用不着,免费功能也够用

    • 先生成图集再使用,更换图像又要重新生成图集

    • 尺寸固定需要自己设置

    • 自己压缩去

    总结:Auto Atlas 真香!


    动态合图(Dynamic Atlas)

    这里引用官方文档中对于动态合图的介绍:

    Cocos Creator 提供了在项目构建时的静态合图方法 —— 「自动合图」(Auto Atlas)。但是当项目日益壮大的时候贴图会变得非常多,很难将贴图打包到一张大贴图中,这时静态合图就比较难以满足降低 DrawCall 的需求。

    所以 Cocos Creator 在 v2.0 中加入了 「动态合图」(Dynamic Atlas)的功能,它能在项目运行时动态的将贴图合并到一张大贴图中。

    当渲染一张贴图的时候,动态合图系统会自动检测这张贴图是否已经被合并到了图集(图片集合)中,如果没有,并且此贴图又符合动态合图的条件,就会将此贴图合并到图集中。

    动态合图官方文档:https://docs.cocos.com/creator/manual/zh/advanced-topics/dynamic-atlas.html

    简单来说,开启动态合图之后,引擎会在运行时帮我们对符合条件(即尺寸小于碎图限制的最大尺寸)的精灵进行合图,达到和提前打包图集一样的效果。

    引擎的「动态图集尺寸最大是 2048 * 2048」,可合并的「碎图限制的最大尺寸是 512」,用户可以通过下面的 API 进行修改:

    cc.dynamicAtlasManager.maxFrameSize = 512;
    

    「启用动态合图会占用额外的内存」,不同平台占用的内存大小不一样。

    小游戏和原生平台上默认会禁用动态合图,但如果你的项目内存空间仍有富余的话建议强制开启:

    cc.macro.CLEANUP_IMAGE_CACHE = false;
    cc.dynamicAtlasManager.enabled = true;
    

    另外还需要保证纹理的 Premulyiply Alpha(预乘)、Wrap Mode(循环模式) 和 Filter Mode(过滤模式) 等信息与动态图集一致才能够动态合批。

    静态图集也可以参与动态合图

    在动态合图的官方文档中有提到:

    当渲染一张贴图的时候,动态合图系统会自动检测这张贴图是否已经被合并到了图集(图片集合)中。

    如果没有,并且此贴图又符合动态合图的条件,就会将此贴图合并到图集中。

    但其实「只要静态图集满足动态合图的要求(即尺寸小于碎图限制的最大尺寸),也是可以参与动态合图的」

    注意:自动图集资源(Auto Atlas)需要在其属性检查器面板中开启 「Texture」 栏下的 「Packable」 选项,该选项默认是禁用的。

    额外补充

    「只有纹理开启了 Packable 选项的精灵才能够参与动态合图」,该选项默认开启。

    纹理参与动态合图后会修改原始贴图的 UV 坐标,所以在 Shader 中的无法正确计算 UV 坐标,导致 Shader 无效。

    「如果需要对精灵使用自定义 Shader,需要禁用其纹理的 Packable 选项。」

    也可以在代码中禁用该选项:

    let sprite = this.node.getComponent(cc.Sprite);
    let texture = sprite.spriteFrame.getTexture();
    texture.packable = false;
    

    Packable 官方文档:https://docs.cocos.com/creator/manual/zh/asset-workflow/sprite.html?h=packable


    位图字体(BMFont)

    在场景中使用系统字体或 TTF 字体的 Label 会打断渲染合批,特别是 Label 和 Sprite 层叠交错的情况,每一个 Label 都会打断合批增加一个 DrawCall,文本多的场景下轻轻松松 100+。

    对于游戏中的文本,特别是数字、字母和符号,都建议「使用 BMFont 来代替 TTF 或系统字体」,并且「将 BMFont 与 UI 碎图打包到同一图集中」(或「开启动态合图」),可以免除大部分文本导致的 DrawCall。

    举个栗子

    例如一个场景中有 80 张精灵和 80 个文本(系统字体)相互交错,节点层级如下图:

    运行起来之后可以看到左下角的 Profile 显示 DrawCall 已经高达 161 个,也就是说每一个精灵和文本都增加一个 DrawCall,这种情况即使精灵打了图集也一样无济于事。

    不要问明明只有 80 张精灵和 80 个文本不应该是 160 个 DrawCall 吗为什么是 161 个...

    因为左下角的 Profile 也要占一个 : (

    对比栗子

    还是上面的场景,尝试将 Label 的系统字体换成 BMFont 并且与精灵打包到同一个图集之后,同样是 80 个精灵和 80 个文本。

    但是 DrawCall 只有 2 个,同时帧时间降低到了 1ms,帧率提升了 10 FPS,渲染耗时降低到了 0.6ms。

    实际上场景只占了 1 个 DrawCall,另一个 DrawCall 是左下角的 Profile 占的......

    另外,对于汉字可以尝试使用 Label 组件的 「Cache Mode」 来优化。


    文本缓存模式(Cache Mode)

    Cocos Creator 2.0.9 版本在 Label 组件上增加了 「Cache Mode」 选项,来解决系统字体和 TTF 字体带来的性能问题。

    Cache Mode 官方文档:https://docs.cocos.com/creator/manual/zh/components/label.html#文本缓存类型(cache-mode)

    Cache Mode 有以下3 种选择:

    NONE(默认)

    每一个 Label 都会生成为一张单独的位图,且不会参与动态合图,所以每一个 Label 都会打断渲染合批。


    BITMAP

    当 Label 组件开启 BITMAP 模式后,文本同样会生成为一张位图,但是「只要符合动态合图要求就可以参与动态合图,和周围的精灵合并 DrawCall」

    「一定要注意 BITMAP 模式只适用于不频繁更改的文本,否则内存爆炸了后果自负!」

    举个栗子

    同样是上文提到的「精灵和文本相互交错」的例子,「文本使用 BITMAP 模式,精灵不打包成图集,开启动态合图」

    结果是所有精灵(包括背景)和文本都成功动态合图,实际 DrawCall 降至 1 个。

    如果精灵打包成了图集则会变成 160 个,因为图集默认不参与动态合图。

    所以当前这种情况(少精灵多文本)不打图集反而是比较好的选择。


    CHAR

    当 Label 组件开启 CHAR 模式后,引擎会将该 Label 中出现的所有字符缓存到一张全局共享的位图中,相当于是生成了一个 BMFont。

    「适用于文本频繁更改的情况,对性能和内存最友好。」

    注意:「该模式只能用于字体样式和字号固定,并且不会频繁出现巨量未使用过的字符的 Label。因为共享位图的最大尺寸为 2048*2048,占满了之后就没办法再渲染新的字符,需要切换场景才会清除共享位图。」

    开启了 CHAR 模式的 Label 无法参与动态合图,但是可以和相邻的同样是 CHAR 模式的 Label 合并 DrawCall(相当于是一张未打包进图集的 BMFont)。

    举个栗子

    还是上文提到的「精灵和文本相互交错」的例子,为了更好体现 CHAR 模式的优势,我更改了场景节点的结构,将精灵和文本进行「分离」(关于这点可以看下面的 「UI层级调整」)。

    所有 Label 开启 CHAR 模式,并在脚本中每过 0.2 秒,就将文本更改成新的随机数。

    在这个例子中,引擎会在运行时生成一张包含数字 0 到 9 的 BMFont 存在内存中,另外由于我将所有 Label 都聚合在一起,所以所有 Label 的渲染合并成了 1 个 DrawCall,「另外请特别关注左下角的帧时间、帧率和渲染耗时」

    光看上面的图似乎看不出个所以然来,那我们增加一个对照组,「将所有文本的 Cache Mode 选项设为默认的 NONE 模式」

    此时可以发现「帧时间最高达到了 2 ms,平均帧率下降了大概 6 FPS,渲染耗时更是翻了 4 倍最高达到了 1.8 ms。」

    总结

    结论已经很明显了,对于大量频繁更改的文本,使用 CHAR 模式带来的性能提升是非常明显的。

    同时 CHAR 模式的局限也很明显,一般用于场景中出现大量数字文本,类似于经验值增加、血量减少之类的特效的情况。


    UI 层级调整

    除了以上的优化方案,我们还可以在游戏场景中下功夫,将性能优化做到极致。

    其实上文也有提到,我们可以通过「优化节点层级,分离图像节点和文本节点,文本使用 BMFont 或 Cache Mode 选项,尽量出现避免文本打断渲染合批的情况」

    特别是对于战斗场景中大量的文本提示(伤害值、血量值和法力值等等)或合成游戏中大量的经验值文本,因为这些文本基本都是数字,使用这种方式即使再多文本也只需要 1 个 DrawCall 就可以全部渲染出来。

    举个栗子

    下面的场景中,文本开启 CHAR 模式,使用脚本每秒生成 50 个左右的随机数字,文本节点统一放在 labelLayer 节点下,让所有文本可以共享 1 个 DrawCall,另外背景和椰子头占 1 个,左下角 Profile 占 1 个。

    可以看到即使场景中瞬间出现这么多文本,整体性能也还是比较可观的。

    在这个例子中,引擎在运行时为我们生成了一份包含数字 0 到 9 的全局共享位图(BMFont)。

    当然如果可以在 Label 中直接使用 BMFont 的话那就更好了。


    补充

    再次提醒

    1. 改变渲染状态会打断渲染合批,例如改变纹理状态(预乘、循环模式和过滤模式)或改变 Material(材质)、Blend(混合模式)等等,所以使用自定义 Shader 也会打断合批。

    2. 图集默认不参与动态合图,手动开启自动图集资源的 Packable 选项后如果最终图集符合动态合图要求也可以参与动态合图。

    3. 纹理开启 Packable 选项参与动态合图后无法使用自定义 Shader,因为动态合图会修改原始贴图的 UV 坐标。

    4. 使用 Cache Mode 的 BITMAP 模式需要注意内存情况,CHAR 模式需要注意文本内容是否多且不重复。

    5. Mask会打断合批。

    最后还需要注意

    在 Cocos Creator 2.0.7 之前的版本中,改变节点的颜色或透明度、Sprite 组件使用九宫格(Sliced)都会打断渲染合批。

    蒜我球球你了快更新吧 : (


    相关资料

    「Cocos Creator 用户手册」

    https://docs.cocos.com/creator/manual/zh/

     

    如有侵权,请告知。必定删除。

    展开全文
  • draw9patch详解

    2015-12-02 16:31:32
    draw9patch.bat这个工具在android的sdk目录中的tools里,首先来看一下运行它后的界面:一、名字介绍为什么叫9patch呢?Patch的中文意思"片,块"的意思,那这里按中文的意思来说就是9片或9块.因此可想而知这个图片...
  • 初步看了一下这篇文章,基本没有什么大用,只是对于初学时,有点点的指导作用.要真正掌握DirectDraw还是系统去学习一下DirectDraw,有本DirectDraw中文手册,可以看一下. 以下为转: 这并非哗众取宠,
  • 作者:太阳下的泪 ... 初步看了一下这篇文章,基本没有什么大用,...要真正掌握DirectDraw还是系统去学习一下DirectDraw,有本DirectDraw中文手册,可以看一下.   以下为转:   这并非哗众取宠, 通常学习一
  • 本文转自:draw9patch详解 ...Patch的中文意思”片,块”的意思,那这里按中文的意思来说就是9片或9块.因此可想而知这个图片会被分为9片,如下图片所示 二、打开源图片 如果要制作一张9...
  • 知道了是什么原因,大家自己都知道解决办法了:换个正版序列号就行了。还有个最简单的办法就是把你系统的时间倒退一点,比如换成2009年,只要不超过2010.06.01就都能正常运行,不过这自然是治标不治本的办法。想要...
  • DirectX中文手册

    千次阅读 2015-06-19 14:08:26
    DirectX中文手册 目 录 第一章 DirectX基础(初级篇) 第一节 什么是DirectX 一、什么是DirectX ? 二、DirectX的组成部分 三、关于DirectDraw 四、为什么要使用DirectDraw? 五、DirectX5.0的新特性? ...
  • 因为网上讲这个框架的文章不是很多,而且它本身对中文支持不是很好,手册什么的都英文的,虽然不是很多,但考虑到一些新手可能没有时间和精力来阅读参考手册,为了让更多的朋友了解它,所以工作之余就大概的翻译了...
  • DirectX中文手册.rar

    2008-07-29 14:40:19
    目前,手册中只有DirectDraw部分,它的内容都从DirectX 5.0 SDK 中翻译过来的,有些地方加入了我自己的理解。如果你觉得有不合适的地方,请告诉老王(waa@126.com),愿意与你一起修改。 因为这些文档有...
  • 核心没什么太难的内容,卡在Emgucv的draw字符身上了。 当然后来发现opencv下看别人用pil搞定了,python下也有自己的中文字库很容易就替换了。 但Emgucv的资料太少了,最后想了一个很扯淡的招,自己画两张新图,...
  • ZendFramework中文文档

    2011-03-22 10:11:12
    14.1.1. 什么是过滤器(filter)? 14.1.2. 过滤器的基本用法 14.1.3. 使用静态 get() 方法 14.2. 标准过滤器类 14.2.1. Alnum 14.2.2. Alpha 14.2.3. BaseName 14.2.4. Digits 14.2.5. Dir 14.2.6. ...
  • 本书经过内容识别处理,所以好处就是书上的案例源码可以直接粘贴复制到编辑器中,当然有个别括号什么的可能需要自己纠正一下。 ................本书高清 ...............本书和代码结合在一起讲解的,其中也讲到...
  • 排除了中文符号的可能(用英文字符逐个修改的); 然后也取消过缩进让后面的参数在一排还是会提示错误; 重启过电脑; 将此段代码重新编写过; 为什么会出现语法错误呢?请求大佬指教! 以下整个文件的代码 ...
  • Android 9patch图片详解

    2014-11-26 08:53:18
    draw9patch.bat这个工具在android的sdk目录中的tools里,首先来看一下运行它后的界面: 一、名字介绍 为什么叫9patch呢?Patch的中文意思"片,块"的意思,那这里按中文的意思来说就是9片或9块.因此可想而知这个...
  • Batch(合批)全面讲解(一)

    千次阅读 2019-04-26 17:06:38
    什么是Batch Batch翻译成中文一般我们称之为“批次”。我们经常用引擎每帧提交的批次数量来作为衡量渲染压力的指标。 调用一次渲染API的绘制接口(如:Direct3D的DrawPrimitive/DrawIndexedPr...
  • 1.2 什么是Eclipse 1.3 SWT/JFace技术 1.4 插件技术和OSGi 1.5 RCP技术 1.6 EMF技术 1.7 GEF技术 1.8 本章小结 第2章 SWT/JFace概述 第3章 SWT编程基础 第4章 使用基本控件与对话框 第5章 容器与布局管理器 第6章 ...
  • 但是要记住学习算法最关键的还是解题思路和方法,用什么语言实现其次的,如果你时间比较多我建议你用 Java 语言再实现一遍。 《labuladong的算法小抄》 非常推荐!这一本很新的书,写书前作者在 Github 开源...
  • 二分法解决问题的关键点是什么,相关问题有哪些? 如何用栈的特点来简化操作, 涉及到的题目有哪些? 双指针问题的思路以及相关题目有哪些? 滑动窗口问题的思路以及相关题目有哪些? 回溯法解题的思路以及相关题目有...
  • 什么是Servlet以及Servlet的优越性 实体对象的抽象以及一种基于数据库的实现 使用 Java 连接处于proxy(or 防火墙)之外的HTTP服务器 使用 XML 小服务程序配置文件配置小服务程序 使用Java Applet访问数据库 使用...

空空如也

空空如也

1 2
收藏数 35
精华内容 14
关键字:

draw是什么中文