How to write a good technical article

技术文章是能够有效锻炼表达能力和进行技术积累的方法。与单纯的技术笔记不同,我认为的技术文章应该是对实际的问题新技术思路的解决方案,而不是技术点的简单堆砌。

对于如何写一篇我认为合格的技术文章, 最近做了一些思考,本篇文章会探讨我写文章时的一些思路和步骤,以及工具推荐和CI/CD自动化发布的实现。

阅读全文 »

ASTC texture compression analysis and efficiency optimization in UE

ASTCAdaptive Scalable Texture Compression的简称,是在移动端流行的贴图压缩方案。当平台使用ASTC打包时,UE默认使用Intel ISPC Texture Compressor压缩贴图,但它具有一些局限性,只支持8x8及以上的压缩规格,10x1012x12则不支持,如果在项目中指定它们,也是会使用8x8的规格。除ISPC外,引擎中也提供了ARM的astc-encoder压缩方式,可以支持8x8以下的规格,但默认未启用,而且引擎中的集成压缩效率非常低,在大规模资源中,使用astc-encoder压缩贴图对Cook耗时是非常大的挑战。

本篇文章分析UE中贴图使用ASTC压缩的配置以及实现方式,以及引擎中astc-encoder的压缩效率和优化思路。

阅读全文 »

Multi-stage automated resource inspection scheme in UE

在大型项目中,资源的规模非常庞大,涉及的制作团队也非常广泛,场景、角色、UI、动画、特效、蓝图、数据表格等等,随之而来就是资源量和资源规范的管理难以把控。

对于制定的资源规格,美术制作人员难以覆盖100%的情况,会存在不经意间漏掉,大多数情况下都是包内发现问题后再处理,而且对于存量的资源,需要耗费大量的人力处理,难以审查和修复。

基于这种痛点,我之前开发了一个资源扫描工具,可以方便地编辑规则对项目内的资源进行扫描。

近期,我对插件做了全方面地升级,增强了编辑时和自动化检查的能力,本篇文章会介绍如何利用ResScannerUE实现编辑时提交时CI定时或Hook任务Cook时等各个阶段的资源扫描,把错误地资源尽可能地在制作时暴露出来并提示解决,避免包内资源异常。

在插件的具体实现上,也针对扫描速度做了很多优化,尽可能把检查变成一个无感知的行为,文章内会具体介绍。

阅读全文 »

An Efficient ZSTD Shader Dictionary Training Scheme

在文章基于 ZSTD 字典的 Shader 压缩方案中,我介绍了一种利用ZSTD字典压缩UE的ShaderCode的方法,可以极大地提升ShaderLibrary的压缩比。但训练字典和使用字典进行压缩的流程仍然比较复杂,并不是一个高效的工程实现:

  1. 需关闭引擎默认的Shader压缩
  2. Cook一遍项目才能Dump每个Unique Shader的ShaderCode
  3. 基于Dump出的ShaderCode文件,使用ZSTD程序训练字典
  4. 再次执行完整的Cook过程,使用字典进行压缩,生成最终的shaderbytecode

根据上述的流程,需要变动引擎才能实现Dump ShaderCode;其次是流程的割裂,Dump ShaderCode之后需要拉起zstd程序执行训练才能得到字典;最后,仍需要再Cook一遍工程,使用训练出的字典压缩Shader。并且在关掉Shader的压缩后会导致使用LZ4压缩的DDC Cache Miss,重复Cook执行的时间开销巨大,在海量Shader的项目中耗时无法接受。

基于这种痛点,我研究并实现了一种高效的字典训练方法,无需修改引擎,并且十分快速地训练字典和基于字典压缩。能够直接从ushaderbytecode中训练字典,并生成使用ZSTD+字典压缩的ushaderbytecode,极大地提升了处理效率,完全Plugin-Only的实现,接入成本几乎为零,后续将作为HotPatcher的扩展模块发布。

阅读全文 »

A runtime reorganization scheme for Pak in Unreal Engine

Pak是UE中的UFS中的一环(Unreal File System),是在应用层构造的一种虚拟文件系统。用于把游戏相关的资源、文件打包至一个Pak文件中,避免在运行时对游戏资源的访问创建出大量的文件句柄,并且可以做读缓存(PakCache),提升加载效率。

并且,在UFS中,可以控制每个Pak的优先级,可以用来控制文件系统中文件的优先级。在通过UFS加载文件时,优先级高的Pak中的文件会被首先命中,就可以替换掉低优先级的文件,这也是UE实现热更新的关键,详见之前的热更新系列文章

但默认情况下,Pak的打包都是在UE端进行的,PakUtilitiesUnrealPak都是开发端的功能,运行时不存在,这意味着不能在运行时创建出Pak文件。但Pak本身是Archive的文件形式,理论上是可以进行运行时重组的。

本篇文章就从Pak的创建、文件格式、UFS分析、运行时重组可行性等方面着手,探讨运行时重组Pak的实现细节以及应用方向。

阅读全文 »

Shader compression scheme based on ZSTD dictionary

随着项目规模的日益增大,UE里Shader的变体数量逐渐累增,往往能够达到数百万的Shader变体,虽然UE为了避免Shader的重复存储提供了Share Material Shader Code功能,可以把Shader序列化到一个独立的ushaderbytecode文件中,但也会占用几百M的包体大小。而UE默认情况下,把这些NotUAsset文件默认进Chunk0,即必须进基础包,对于移动端的基础包影响很大,几百M的空间,可以放很多资源了。

为了解决这个问题,只能从三个方面入手:

  1. 降低项目中的变体数量,Dump出项目中的Shader信息,分析哪些是不必要的;
  2. 拆分shaderbytecode,基础包中只包含必要的Shader,其余按需下载。但UE默认没有提供这样的机制,可以使用我开发的HotPatcher拆分基础包,生成多个shader lib,使用热更流程动态下载资源和所需的shaderbytecode。
  3. 使用压缩率更高的算法来对ShaderCode进行压缩,引擎中默认使用LZ4;

第一种方式需要TA和美术协同实现,想要有显著的提升较为困难。第二种方案详见之前的热更新系列文章(Unreal Engine#热更新)。本篇文章从第三种方式入手,为Shader实现了一种特殊的压缩方式,可以有效地降低shaderbytecode的大小,大幅度提升Shader的压缩比,并且可以与方案2结合使用,在拆分shaderbytecode的同时,大幅度提高压缩率。

阅读全文 »

Efficient Debugging: Start UE Android App with command line parameters

在使用UE开发的过程中,指定命令行参数(Command Line)是一个经常会用到的功能,可以方便地控制部分流程、开关等。UE也是大量地使用了Comandline来控制引擎的行为,官方文档:Command-Line Arguments,不同的模块都可以从Commandline中读取或检查参数,实现自定义的命令行参数功能。

但是,对于移动端Android平台,并不能很方便地指定启动参数,需要编辑ue4commandline.txt文件,非常繁琐。

基于这种痛点需求,我利用元旦的假期开发一个UE的Android的插件,可以让Android的程序像PC一样方便启动和指定命令行参数,并且不需要修改引擎,启用插件后打包Apk即可使用,开源在Github上:hxhb/AppCmderUE

本篇文章分析了UE在Androdid端Commandline的读取规则,并介绍了AppCmderUE插件的实现原理与使用方法。

阅读全文 »

UE Resource Management: Engine Packaging Resource Analysis

默认情况下,在UE中打包项目时,会拉起BuildCookRun来执行Compile/Cook/Pak/Stage等一系列流程。在UE中,只有参与Cook的资源才会被打包,但是通常会包含很多预期之外的资源,可能会造成困扰,到底引擎依赖哪些资源?以及该如何管理UE参与打包的资源。

本篇文章从UE打包时分析资源进行Cook的规则入手,研究在打包时究竟会将哪些资源进行Cook,了解这一点对于资源管理很有作用,基于此可以实现自定义的Cook过程,将Cook任务分配至不同的进程乃至机器实现并行化,加速UE的构建过程。

除了uasset这些资源外,打包时还有很多Non-Asset文件,如ini、Shader Library、AssetRegistry、或者项目中添加的脚本文件等等,在之前的文章UE热更新:需求分析与方案设计中有过介绍,UE对于它们的收集并不在Cook阶段(Shader Library和AssetRegistry是在Cook阶段生成),本篇文章暂不作讨论,后续会写一篇专门介绍的文章。

阅读全文 »

My 2021 Annual Summary

我一直希望做的所有事情都是可以量化、能够被记录的,不然一年又一年循环往复会记不起自己到底做了什么事情,所以会做一个年度总结。

2021年马上结束,回想这一年,发生了许多事,有了很多新的想法,也是对我影响最大的一年。

阅读全文 »

Things to Analyze Blog Traffic Data

近期查看了博客Google Analysic的访问数据,通过流量分析发现一些很有意思的点,能够在一定程度上体现出在使用虚幻引擎进行游戏开发方面的用户特征。文章内的数据样本为本站2021.11.14-2021.11.20一周的访问流量,总体数据量有限不一定能体现出真实趋势,仅供参考。

阅读全文 »