unreal4打包后黑边_unreal4 linux打包 - CSDN
  • ue4 设置窗口无边框

    2019-12-20 16:44:00
    不过这种方法有问题一个是时间点问题一开始就调用的话不起作用,目前知道是只能延迟一段时间,然后无边框还残留一截黑边 .build.cs添加"ApplicationCore", "Slate", "SlateCore" 代码 //#if PLATFORM_WINDOWS ...

    第一种方式 简单实用

    就是ProjectSetting中

     

    第二种是通过设置WindowStyle

    不过这种方法有问题 一个是时间点问题 一开始就调用的话 不起作用,目前知道是只能延迟一段时间,然后无边框后 还残留一截黑边

    .build.cs 添加"ApplicationCore", "Slate", "SlateCore"

    代码

    //#if PLATFORM_WINDOWS
    //	if (NoBoarder)
    //	{
    //		TSharedPtr<FGenericWindow> NativeWindow = GEngine->GameViewport->GetWindow()->GetNativeWindow();
    //		auto Window = static_cast<FWindowsWindow*>(NativeWindow.Get());
    //		auto hWnd = Window->GetHWnd();
    //
    //		DWORD WindowExStyle = GetWindowLong(hWnd, GWL_EXSTYLE) & ~(WS_EX_WINDOWEDGE | WS_EX_DLGMODALFRAME);
    //		DWORD WindowStyle = GetWindowLong(hWnd, GWL_STYLE) & ~WS_CAPTION;
    //		SetWindowLongPtr(hWnd, GWL_EXSTYLE, (LONG_PTR)WindowExStyle);
    //		SetWindowLongPtr(hWnd, GWL_STYLE, (LONG_PTR)WindowStyle);
    //		UE_LOG(LogTemp, Warning, TEXT("Set Windows Success"));
    //	}
    //
    //#endif

     

    展开全文
  • Unreal4 后期处理材质

    千次阅读 2017-10-13 17:45:22
    后期处理材质   ...后期处理图表使用后期处理材质制作简单的后期处理材质后期处理材质的关键设置在不同材质实例之间进行混合材质表现“SceneTexture”使用 GBuffer ... / GBuffer 为何抖动UV 和屏幕位置过滤纹理...

    后期处理材质

    Teaser3.png Teaser0.png Teaser1.png Teaser2.png

    后期处理图表

    引擎已经拥有基于后期处理节点图表的复杂后期处理功能。后期处理材质 可 被额外插入部分特定位置。查看 FAQ r.CompositionGraphDebug 部分获得全图表的 dump 文件。 实际上,图表不仅执行后期处理,还执行部分灯光操作。我们计划利用材质编辑器 将更多部分变为自定义化。

    在多数情况下,图表自动创建中间的渲染目标。意味着如要与之前的色彩混合, 需要在选色器中执行混合(使用来自 PostProcessInput0 的输入)。

    后期处理材质应尽少使用,在极其需要时使用方位上策。在处理颜色校正或调整、光晕、景深和多种其他效果时,应尽可能使用后期处理体积域的固有设置(因为它们已经过优化,效率较高)。

    使用后期处理材质

    通过后期处理设置(通常以后期处理体积域或摄像机设置定义)可对所谓的可混合资源进行混合。 当前只有 材质 和 材质实例 为可混合资源。引擎提供了一些后期处理材质,但也可利用 此功能创建 自定义后期处理,无需程序员的协助。

    只需在 Blendables 部分将一个或多个后期处理材质指定到后期处理体积域上。首先按下 + 添加新的槽, 在 Content Browser 中选择一个材质,然后按下左箭头进行指定。顺序无关紧要,可无视未使用的槽。

    PostProcessSettings.png

    制作简单的后期处理材质

    可在 后期处理材质范例 中了解从零创建简单后期处理材质效果的综述。

    FinalPostEffect.png

    后期处理材质的关键设置

    后期处理材质需要指定材质域 后期处理

    DomainPostProcess.png

    材质只应使用 EmissiveColor 输出新色彩。此外,可定义在后期处理中何处应用此通路; 如有多个存在,定义其处理顺序(优先级):

    PostProcessMaterialProps.png

    混合位置

    描述

    Before Tonemapping

    PostProcessInput0 提供带 HDR 中所有灯光的场景颜色。使用它修复临时抗锯齿和 GBuffer 查找(如深度、法线)的问题。

    After Tonemapping

    性能优选位置,颜色为 LDR,因此需要的精确度和带宽较小。这发生在色调映射和颜色分级后。

    Before Translucency

    在流程中比“Before Tonemapping”更早,在半透明度和场景颜色组合之前。注意:SeparateTranslucency 晚于正常半透明度合成。

    Replacing the Tonemapper

    PostProcessInput0 提供 HDR 场景颜色,PostProcessInput1 拥有 SeparateTranslucency(透明度为遮罩),PostprocessInput2 拥有低分辨率光晕输入。

    典型的 postprocess 输入来自之前的通路。使用 PostProcessInput0 时,可通过 SceneTexture 材质表现获取颜色。使用 SceneColor 可能无法获得正确结果。

    在不同材质实例之间进行混合

    使用后期处理材质

    利用后期处理体积域可轻松在多个后期处理材质之间设置柔和过渡。在此例中我们使用一个标记为 unbound 的体积域和一个拥有较大混合半径的体积域(如 1000):

    BlendingAVolume.png

    BlendingAVolume1.png

    后期处理设为 Unbound

    后期处理束缚体积域

    每个体积域我们都将指定相同材质的一个不同材质实例。颜色作为一个材质参数进行指定,可在两个材质实例上进行不同设置。

    BlendMatInst1.png

    BlendMatInst2.png

    材质实例红

    材质实例绿

    处于混合半径中时,一个体积域设置将被使用和混合(基于摄像机位置):

    Blend1.png

    Blend2.png

    Blend3.png

    未束缚后期处理体积域材质实例(红色)设为 0.75

    混合半径 1000

    后期处理体积域材质实例(绿色)设为 0.75

    伴随着摄像机运动可感受到两个效果设置之间柔和的线性过渡。

    以下展示了一个拥有两个体积域的关卡顶视图。较大的未束缚体积域拥有一个红色材质实例,较小的体积域拥有一个指定为可混合的绿色材质实例。 较小的体积域拥有更高的优先级。材质参数基于摄像机位置进行混合。 模糊边界由体积域中指定的 BlendRadius 属性定义,可延伸体积域外形。

    设置正确后,全部混合将按预期进行。

    Bad Setup

    Bad Setup

    Good Setup

    Good Setup

    两个设置之间的差别是材质参数(标量或矢量)上指定的默认值。 良好设置的数值可使通路不存在任何效果(如乘以白色或以 0 插值)

    在两个设置中我们将看到:摄像机处于任意体积域的影响之外时,将不会对 postprocess 通路执行渲染(以灰色网格显示)。 如完全处于任意一个体积域内,我们也将看到正确的混合。

    较差设置:摄像机进入影响半径后,将出现一个硬性过渡,因其使用的是错误指定的默认参数。

    较好设置:进入摄像机影响半径的过渡被良好地隐藏起来,到体积域颜色的过渡流畅。

    无论属性复选框是否勾选,所有材质实例属性皆被混合 (如未勾选,其将对父项的属性进行混合)。这与后期处理设置(未勾选的属性没有效果)不同。 这意味着如果混合一个材质实例,所有属性均将被混合。

    材质表现“SceneTexture”

    可在材质中添加 SceneTexture 材质表现,并在表现属性中选择需要引用的纹理:

    SceneTextureProps.png

    节点拥有一个可选输入和多个输出:

    SceneTextureExpression.png

    利用 UV 输入可指定进行纹理查找的位置(只用于颜色输出)。 颜色输出为 4 通道输出(实际的通道分配取决于场景纹理 id)。Size 是带纹理宽度和高度的 2 组件 矢量。其倒转 (1/width, 1/height) 在 InvSize 输出中可用。以下例中的方式引用 临近样本非常便利:

    DepthNextTo.png

    材质表现计算当前像素到临近像素的深度差(如:In = 0,1 将透明度返回)

    使用 GBuffer 属性

    GBuffer 由存储材质(如表面下/镜面颜色、平整度...)和物体属性(如法线、深度)的多个纹理构成, 不存在进行着色计算的灯光(灯光如何与材质交互)。在延迟渲染器中,首先渲染 GBuffer,然后使用 GBuffer 属性 计算所有灯光(延迟)。如 UE4 使用延迟着色路径(如 DirectX 11 或高端 OpenGL),则可在后期处理中使用这些缓冲。

    抗锯齿将使其变得更加困难一些,因为 GBuffer 像素/纹素与输出像素不再是 1:1 相关(查看以下部分)。

    自定义深度

    这个单独功能可将特定物体渲染成另一个深度缓冲,从而形成遮罩(称作自定义深度缓冲)。 这会添加额外的绘制调用,但不会添加更多材质。因为只输出深度,渲染的消耗相当低。此功能可在网格体上启用 (如静态网格体属性 / 渲染自定义深度):

    CustomDepth.png

    在此场景中,我们在两个物体上启用此功能;但没有显示内容的后期处理通路,该功能仍为不可见:

    scene.png

    下图为自定义深度的展示:

    sceneCustomDepth.png

    下图是用于展示的材质:

    CustomDepthMat.png

    临时抗锯齿 / GBuffer 为何抖动

    临时抗锯齿是 UE4 的独特功能,可在中等性能消耗的基础上极大地提高图像质量。

    后期处理材质被默认插入后期处理图表的末尾(在色调映射器之后)。这意味着应用色调映射、颜色分级和临时抗锯齿后可获得最终 的 LDR 颜色。这是许多简单后期处理效果的最佳点 - 性能与易用。

    在此可了解如何使用自定义深度输入在特定物体周围显示轮廓:

    sceneAfterTonemapper.png

    注意前一张图轮廓上并不存在抗锯齿,但在动态下将看到轮廓出现一个像素左右的抖动。 这是因为临时抗锯齿按每帧一亚像素的频率移动整个场景的渲染。多张序列帧将合并在一起,形成最终的抗锯齿图像。 然而,我们可将材质移动到后期处理图表中更早的位置,以便修复此问题。

    下图为最终结果:

    sceneBeforeTonemapper.png

    我们获得了一个稳定的抗锯齿图像。在动态中临时抗锯齿可能出现一些穿帮。此功能使用深度缓冲替代旧图像。在物体内渲染边界时此功能正常, 但在物体外时我们需要调整深度缓冲(功能未完善,性能消耗较高), 功能完善后无需进行调整。

    UV 和屏幕位置

    可在屏幕中看到的后期处理材质为缓冲对齐,但需要知晓正确的 UV。 ScreenPosition 材质表现输出所需的 UV(0,0 位于视口左上方,1,1 位于右下方)。 使用 texture coordinate 材质表现可能获得不同的结果。这是因为实际纹理(正确而言其应为一个渲染目标)可能比视口更大。 它在编辑器中可能更大,因为我们在多个视口上共享这个纹理,最大的延展用于所有视口。 即时在游戏中,它有时也可能更大(如 SceneCaptureActors 可能拥有一个更小的视口、Matinee 黑边、分屏、VR...)。 纹理坐标材质表现为这个较大的纹理提供 UV。如只需要一个相对偏移(如像素尺寸边沿检测),需要缩放至正确的尺寸。SceneTexture 材质表现拥有对尺寸的输出和尺寸的倒转(对像素偏移有效有用)。 如希望获得视口 UV(如向视口映射纹理),可使用 ScreenPosition 材质表现或手动进行所需的计算(更多操控将使运行减慢)。 因此需要 ViewSize 材质表现。可使用控制台变量 r.ViewPortTest(可用于测试各种视口配置)进行全面测试。

    过滤纹理查找

    SceneTexture 材质表现拥有一个复选框,可获得 [双线性] 过滤查找。使用此选项将使渲染变慢,建议只在必要时使用。 许多屏幕空间纹理不支持过滤(如 GBuffer)。不公开此属性可使引擎根据需求压缩数据(打包将防止过滤)。

    替代色调映射器

    使用“Replacing the Tonemapper”可混合位置即可使用自定义色调映射器覆盖引擎色调映射器。此功能尚在开发中,功能仍不齐全,并可能进行修改。

    ReplacingTheTonemapper.png

    我们已开始将部分后期处理设置参数对色调映射器公开,但这部分仍可能进行较大幅度的修改。 这些数值作为材质参数公开,须设置准确的命名。

    矢量参数:

    Engine.FilmWhitePoint

    标量参数:

    Engine.FilmSaturation
    Engine.FilmContrast

    如要获得参数,须从后期处理材质创建材质实例!

    仍可使用自身的参数并以其他后期处理材质设定的方式进行混合。

    已知问题

    以下问题仍需修复:

    • 材质表现 SceneTexture

      • SeparateTranslucency 无法使用。

      • 部分查找无法在一些通路中使用(我们不会对一部分进行修复,因为它们对性能的消耗过大)。

      • MaterialFunction 可能报错,但仍能在有后期处理域的材质中使用。

    • 材质

      • PostProcessMaterial 中的 UV 可能不在 0-1 范围内(如在编辑器中减小视口尺寸时),它与查找对齐,但难以应用晕映之类的效果。

      • 后期处理材质的资源缩略图显示不正确。

      • 不支持透明度输出(须通过不透明度)。

      • 材质编辑器中的预览材质显示不正确。

      • 存在这样的情况 - 材质变更未反映到后期处理的变更中。应对方法:重启编辑器。

      • 利用 Content Browser 可对后期处理材质进行简单过滤。

    • 混合

      • 将两个后期处理体积域和一个混合半径混合时,可能出现非柔和过渡。结合默认材质实例设置使用未束缚的体积域可防止这种情况的发生。

    常见问题

    • 能将“Lighting only mode”纹理作为输入吗?

      不行,没有作为中间步骤的可用数据。对此查看模式,我们无视材质颜色将其 生成。如需将此作为快速选项,需要重建较大部分的渲染代码。

    • 为什么 SceneColor 查找显示有条带,但使用 PostProcessInput0 时却未显示?

      使用 SceneColor 时,我们创建了一个场景的低精度副本,使查找进入当前写入的纹理中 (通常情况是在不可能的位置进行网格体渲染)。 在后期处理中应该使用 PostProcessInput0。

    • 一次后期处理的内存消耗是多少?

      内存消耗取决于屏幕分辨率。色调映射前使用 HDR(每像素 8 字节),之后使用 LDR(每像素 4 字节)。

    • 如何降低后期处理的渲染消耗?

      测量目标平台、保持较低的纹理查找数、执行较少的数学运算、减少相关纹理查找、 避免随机纹理查找(可能因为纹理缓存缺失而变慢)。

    • 能使用多少次通路?

      每次通路均会增加性能消耗。建议只在必要时组合通路和启动通路。总体游戏功能 (为获得更佳的性能,可将 noise 添加到引擎通路)。

    • 后期处理和混合的 CPU 性能消耗如何?

      混合材质的性能消耗极低。所有材质实例属性都将被混合,只有一个包含这些设置的后期处理材质通路被渲染。

    • 我需要使用“Before Tonemapper”获得有效的临时抗锯齿。使用一种颜色时,它已经被色调映射,因此看起来存在色差。如何避免这些情况的出现?

      没有简单的解决方案。需要执行倒转色调映射操作(高消耗)。由于人眼存在适应性, 颜色可能仍然存在色差。可将 EyeAdaptation 层级对 SceneTextures 公开,以便对其进行补偿。

    • 如何获得后期处理图表的完整 dump 文件?

      r.CompositionGraphDebug 可将图表日志存入控制台。范例:

      FRenderingCompositePassContext:Debug 'PostProcessing' ---------
      Node#1 'SceneColor'
          ePId_Output0 (2D 1136x768 PF_FloatRGBA RT) SceneColor Dep:2
      Node#4 'Velocity'
          ePId_Output0 (2D 1136x768 PF_G16R16 RT) Velocity Dep:1
      Node#2 'SceneDepthZ'
          ePId_Output0 (2D 1136x768 PF_DepthStencil) SceneDepthZ Dep:1
      Node#5 'MotionBlurSetup0MotionBlurSetup1'
          ePId_Input0:Node#4 @ ePId_Output0 'Velocity'
          ePId_Input1:Node#1 @ ePId_Output0 'SceneColor'
          ePId_Input2:Node#2 @ ePId_Output0 'SceneDepthZ'
          ePId_Output0 (2D 568x384 PF_FloatRGBA RT) MotionBlurSetup0 Dep:2
          ePId_Output1 (2D 568x384 PF_FloatRGBA RT) MotionBlurSetup1 Dep:1
      Node#6 'QuarterResVelocity'
          ePId_Input0:Node#5 @ ePId_Output0 'MotionBlurSetup0MotionBlurSetup1'
          ePId_Input1:
          ePId_Output0 (2D 284x192 PF_FloatRGBA RT) QuarterResVelocity Dep:1
      Node#7 'VelocityBlurX'
          ePId_Input0:Node#6 @ ePId_Output0 'QuarterResVelocity'
          ePId_Input1:
          ePId_Output0 (2D 284x192 PF_FloatRGBA RT) VelocityBlurX Dep:1
      ...
    展开全文
  • UE4 VR 模式下全屏解决办法

    千次阅读 2017-03-10 17:02:10
    方法步骤: 1、打开关卡蓝图添加如下代码: 2、设置配置文件在工程目录里面找到 Config 文件夹在里面添加一个配置文件并命名为 DefaultGameUserSettings.ini 把如下内容贴到刚刚创建...//ResolutionSizeX=

    方法步骤:

    1、打开关卡蓝图添加如下代码:

    2、设置配置文件在工程目录里面找到 Config 文件夹在里面添加一个配置文件并命名为 DefaultGameUserSettings.ini

    把如下内容贴到刚刚创建的配置文件里面:

    [/Script/Engine.GameUserSettings]
    bUseVSync=False
    //ResolutionSizeX=1920
    //ResolutionSizeY=1080
    //LastUserConfirmedResolutionSizeX=1920
    //LastUserConfirmedResolutionSizeY=1080
    WindowPosX=-1
    WindowPosY=-1
    bUseDesktopResolutionForFullscreen=True
    FullscreenMode=0
    LastConfirmedFullscreenMode=0
    Version=5

    切记保存,完成以上设置重新打包项目运行以后效果如下

    这样虽然也全屏了,但是这并不是最终效果。接下来是屏幕黑边的去除办法,根据个人需要选择操作。

    黑边的移除方法与步骤:

    1、没下载引擎源码的自己去github 下载编译 ,这里给个传送门点击 引擎源码获取方法步骤

    2、按照如下方式定位到源代码文件:

    3、在源代码里面定位到if (WindowMirrorMode == 1)修改里面的方法调用RendererModule->DrawRectangle(。。。)把这个方法的调用替换成如下

    RendererModule->DrawRectangle(RHICmdList, 0, 0, ViewportWidth, ViewportHeight, 0.0f, 0.3f, 0.4f, 0.4f, FIntPoint(ViewportWidth, ViewportHeight), FIntPoint(1, 1), *VertexShader, EDRF_Default);

    4,编译解决方案,注意需要在Develop 和 Win64 模式下。

    5,编译完成后找到生成的编辑器用它打开项目,重新打包就搞定了.

    展开全文
  • 无论是 Cocos Creator、Unity、Unreal 还是其他游戏引擎,只要说到游戏性能优化,DrawCall 都是绝对少不了的一项。 本文将会介绍什么是 DrawCall,为什么要减少 DrawCall 以及在 Cocos Creator 项目中如何减少 Draw...

    前言

    在游戏开发中,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.

    展开全文
  • 无论是 Cocos Creator、Unity、Unreal 还是其他游戏引擎,只要说到游戏性能优化,DrawCall 都是绝对少不了的一项。 本文将会介绍什么是 DrawCall,为什么要减少 DrawCall 以及在 Cocos Creator 项目中如何减少 Draw...
  • creator DrawCall详解

    2020-09-03 17:00:24
    无论是 Cocos Creator、Unity、Unreal 还是其他游戏引擎,只要说到游戏性能优化,DrawCall 都是绝对少不了的一项。 本文将会介绍什么是 DrawCall,为什么要减少 DrawCall 以及在 Cocos Creator 项目中如何减少 Draw...
  • 前言在游戏开发中,DrawCall 作为一个非常重要的性能指标,直接影响游戏的整体性能表现。无论是 Cocos Creator、Unity、Unreal 还是其他游戏引擎,只要说到游戏性...
  • <html>

    2019-07-22 20:01:16
    --------------------------... 本翻译是參考、修正、整理的文档。如有错误,请善意提示;如需转载。请注上出处。谢谢!!。 官方文档传送门:点击打开链接 參考翻译文档:点击打开链接 --------------------...
  • 修改 UE3开发的游戏,但默认画质只有分辨率和亮度选项,毕竟,现在1060的配置,这样的画质很不舒服 下面教程比较杂,如果只想达到上图的画质,请直接跳到步骤3.   下面开始进入游戏目录修改画质: 1.修改...
  • VRCORE系列公开课第七站来到了美丽的西湖边,听讲师们聊一聊VR游戏艺术的寻找与探索、使用虚幻引擎制作VR内容以及眼球追踪技术在VR中的应用。 VRCORE系列公开课第七站来到了美丽的西湖边,闷热的高温天气也无法...
  • 本文首发于我的个人Blog阿西BUG,欢迎大家批评指正 文章目录前言正文什么是 DrawCallDrawCall 是如何影响性能的呢?如何减少 DrawCall针对图片资源静态合图自动图集资源(Auto Atlas)TexturePacker对比一下动态合...
  • 青瓷引擎研发

    2019-07-31 11:25:13
    我为什么要做青瓷引擎  写了十几年的游戏,从来没有想过自己去实现一个游戏引擎之类的。一来实现个游戏引擎并不是件容易的事;二来我不是个技术控的码农,不想自己去创造需求;三来算有点自知之明:水平距离那些...
  • 大型场景裁剪渲染

    千次阅读 2017-11-23 16:55:49
      3D游戏特别是网络在线游戏中,室外大场景渲染是一块非常重要的内容,它也是3D图形引擎的核心。它是图形学和图像处理理论最直接的应用,其涉及的技术还可以应用于其它领域,比如虚拟现实、3D GIS、数据可视...
1
收藏数 13
精华内容 5
关键字:

unreal4打包后黑边