㈠ ue4先学蓝图还是代码
先学蓝图,如果是想用代码写游戏的,可以先学透蓝图,因为蓝图所需要的编程思维,和其他所有面向对象的编程语言是一样的,之后学习c++就比较简单了。
蓝图在UE4中非常容易创建,并且更新快,编译速度也快,可以直观的展示流程。就实用性来说,蓝图与c++的实用性都很强,用UE4做大型游戏就用C++,做小型游戏使用蓝图就可以。
蓝图本身就是c++做成的蓝图可视化脚本,蓝图所调用的函数也是用C++写的。但如果使用虚拟机运行,蓝图成本会非常高,并且蓝图的性能无法和c+保持一致,对于程序中较为复杂的逻辑关系,还是推荐使用C++,蓝图比较偏向图形资源的控制上。
㈡ 使用FastBuild给UnrealEngine编译Shader加速
提升Unreal Engine Shader编译速度的实操指南
使用FastBuild加速编译Shader,优化流程,从环境搭建到具体配置,详细步骤如下:
1. 下载并安装FastBuild
前往FastBuild官网,下载适用于Windows平台的FastBuild可执行文件,解压后获得FBuild.exe和FBuildWorker.exe。
2. 替换引擎目录文件
将FBuild.exe和FBuildWorker.exe复制到``目录下,替换现有文件。
3. 创建网络共享文件夹
创建一个网络共享文件夹,确保所有参与编译的机器都能访问。步骤如下图所示。
4. 配置环境变量
在系统变量中添加`FASTBUILD_BROKERAGE_PATH`,值为创建的网络路径。
5. 运行测试联机环境
确认网络文件夹是否可访问。运行`FBuildWorker.exe`,界面应显示网络文件夹中的发起机IP,并检查网络路径中是否存在发起机IP的文件。
6. 开启Shader编译
在项目`DefaultEngine.ini`中添加配置以开启Shader编译。
7. 远程机配置
将FBuild.exe和FBuildWorker.exe拷贝至远程机,确保添加环境变量`FASTBUILD_BROKERAGE_PATH`与发起机一致。远程机运行`FBuildWorker.exe`,确认连接成功。
8. 运行Shader编译
打开项目Shader编译开关,直接运行编译Shader。如需测试,删除`DerivedDataCache`文件夹,确保Shader编译。
进阶步骤
根据需要,调整编译参数,限制CPU使用量,开启编译缓存,使用更多远程机加速编译。
编译UE4项目代码
如果需要编译UE4项目代码,需修改FastBuild源码。下载源码,配置环境变量和路径,使用命令行编译FastBuild,确保所有配置与编译Shader一致。
开启编译代码Cache
通过调整`BuildConfiguration.xml`文件,启用编译缓存,显着提升编译速度。
进阶优化
限制本地编译代码的核心数,避免CPU负载过高。利用编译缓存和更多远程机,提高整体编译效率。
使用FBDashboard监控
启动FBDashboard.exe,查看编译进度、使用资源等详细信息,便于调整优化。
结语
通过上述实操指南,可有效利用FastBuild加速Shader及UE4项目代码编译。如有疑问或建议,欢迎在下方留言交流。
㈢ 不减变体,从机制优化UE Shader内存(Vulkan)
全文8000+字,多图。
在游戏项目中,减少shader所使用的内存有多种方法,如本文将分享在UE4.26和Vulkan环境下如何通过优化shader使用机制来减少内存的经验。
在gl语境中,“Shader内存”通常指shader program的内存,而在Vk等现代API的语境中,它可能指单独的shader code/spirv内存,或者一切与Shader相关的对象(如shader mole,pipeline等)的内存总和。本文涉及的内存优化将涵盖上述内容。
创建一个Pipeline需要使用多少内存?哪些是可以卸载的?首先,我们将shader code/spirv序列化到内存中,然后将其传入VkShaderMoleCreateInfo.pCode创建VkShaderMole。创建好VkShaderMole后,传入.mole,最后使用创建Pipeline。如果不进行释放,内存中会有三份shader,分别在shader code,shader mole和pipeline中。
根据Vulkan的Spec,VkShaderMole创建好后,spirv中的数据可以被free掉。创建好VkPipelineCache之后,即使在使用pipeline时,其ShaderMole也可以被Destroy掉。理论上,在创建好pipeline之后以及在我们可以正确索引、使用这个pipeline的前提下,所有pipeline以外的内存都是可以释放的。
然而UE没有及时释放这些用于创建pipeline的内存。下面将分析UE本身的PSO cache机制。
已有许多文章介绍PSO机制,这里简单提几个重要点。*.upipelinecache是PSO的描述文件,体积很小,一般在2M以内。PSO binary cache一般指vkCreateGraphicsPipelines中VkPipelineCache这个参数,这部分binary data可以在runtime中作为cache,也可以主动提取数据并保存到硬盘中。
以下是UE4 Shader的加载和创建流程图。硬盘中的shader code由FShaderCodeArchive管理的file handle从硬盘中被读取出来,这部分数据如果走的是preload流程,则会保存在一份在内存中,创建好FVulkanShader后被释放;如果是在CreateShader的时候实时读取出来的,则会使用UE自己的FMemStack来加载,并被实时释放掉。
接下来将谈谈卸载掉这些用过的shader code的具体操作。
卸载前提:不影响pipeline的索引。UE的PSO cache和索引分了很多层级,其中作为Key的和FVulkanPSOKey的主要信息可以概括为ShaderHash保存在FRHIShader的成员变量Hash中,FRHIShader又被保存在FShaderLibraryInstance::RHIShaders中,独立于shader code存在。
卸载ShaderMole:上面提到,vkCreateGraphicsPipelines返回后就可以destroy掉,而UE4不仅没有在创建pipeline之后销毁,甚至在pipeline释放之后,其shader mole也没有释放。猜测是为了避免重复创建shader mole导致的开销,但是shader mole本身其实是shader code外很薄的一层封装,其创建和释放的开销相比pipeline的创建开销相差几个量级。
索引错误导致同样的PSO被多次创建:笔者在开发过程中发现一个现象,明明在加载界面预编译PSO的过程中已经把将要使用的PSO在内存中加载好了,但进入场景之后,又创建了一次这些PSO。排查之后,发现是和FVulkanPSOKey的hash函数和compare函数有问题,导致在Map中,同一个PSO有多个key(多个entry)。
卸载、不加载不必要的FShaderPreloadEntry:在material serialization时,会由GRHILazyShaderCodeLoading来决定是采取preload或者lazy load其中一种策略来加载shader code。
卸载Spirv:这一部分可以说是从机制上挤出shader内存的最后一点水分。上面提到,在game cache和user cache中的PSO预编译结束后,理想的状态下,内存中已经包含游戏需要的绝大部分的PSO了,又由于用于索引的信息独立于Spirv,所以可以安全卸载。
优化全部应用后的流程图项目大致数据分享:注:从左到右为叠加应用,而不是单一开启一项feature。可以看到,优化很有成效。
未来可能的改进:iOS同思路优化,Shader mole的卸载时机,Spirv重载后的卸载。
一些感受:熟悉工具,迭代速度,借鉴他人解决方案的同时保持质疑,重视测试。