制作自己的引擎(四)资源保存
开篇 资源保存大概是引擎里最不显眼但最折磨人的部分。渲染有画面,物理有碰撞,脚本能写玩法,资源系统做对了往往没人注意,做错了就是“我草,我场景呢。昨天还能打开的,今天怎么全丢引用了”。 最早项目起步的时候确实可以偷懒:图片按路径加载,脚本记文件名,场景里直接写资源路径。只要文件不改名不移动,问题不大。但这显然不是编辑器项目的常态。资源会整理目录,Prefab 会复制,材质会换 Shader,Demo 做着做着文件夹就会开始膨胀。 所以最后还是得做 AssetDatabase、.meta、GUID、Scene 序列化和 Prefab。听起来有点像 Unity 那套,实际上小引擎做到这个阶段也很难绕开这些东西。 资源身份GUID 与 .meta 路径引用最大的问题是路径太脆。比如一张图原来在Assets/Sprites/Bird.png,将其挪到 Assets/Sprites/Characters/Bird.png,它本质上还是那张图,但所有保...
制作自己的引擎(三)渲染改进
开篇 最早写 Ditto 渲染时没什么包袱,OpenGL 能画就行。毕竟引擎起步阶段需要的是“屏幕上有些什么东西”,只要能把 mesh、sprite、UI 画出来,Editor 看着像那么回事,其他都可以往后放。但这种写法很快就会到头。刚开始一个 Renderer 管全部还挺爽,后面一是Game View、Scene View、RenderTarget,二是Shader 和 Material 也要变成资源,再加上 DX12、Vulkan 这些更为现代化后端,原来那套 OpenGL 直连就有点撑不住了,再继续往里塞只会使代码臃肿而难以修改维护。 渲染抽象RHI 边界 所以后面就把渲染层抽象成了 RHI(Rendering Hardware Interface)。名字听着挺高大上的,但实际想解决的问题很简单:上层无需在意底层到底是 OpenGL、Vulkan 还是 DirectX 12。RHI 并不是为了显得架构高级,毕竟这次抽象确实是被需求推出来的。上层真正需要的是创建,绑定,绘制这些高层的指令,这些需求如果全写在 OpenGL 里,后面...
制作自己的引擎(二)脚本支持
开篇 之前文章中讲述了引擎的初始架构和基础渲染、物理模拟与并行化,本想告一段落专心论文春招的,但某天刷到了隔壁的Krystallos Engine。就是一种很奇妙的心态,觉也睡不下去了,肝了一周有了这次大改。 上一篇已经把引擎的基本框架搭起来了,也有了一个能跑的Editor界面。但到这个阶段其实还挺尴尬的,它看起来像个引擎,用起来却更像一个 C++ Demo 框架,所以脚本系统就绕不过去了。Unity 用 C#,Godot 有 GD Script,UE 虽然主力是 C++,但蓝图本质上也是把 gameplay 逻辑从底层代码里拎出来。个人小引擎当然没必要一上来整套蓝图虚拟机,能把程序跑起来、访问常见组件、在 Editor 里调字段,就已经能让项目开发体验跨一个台阶。这里最后还是选了 C# + Mono。原因倒也简单:个人之前主用Unity,C# 语法熟悉,Mono Embedded API 虽然有点老旧但资料多,自己折腾起来也不至于完全黑盒。 脚本系统分层结构 脚本系统的结构大概分三层: 123456项目脚本 ...
制作自己的引擎(一) 基础框架
开篇前言 可能是想试下目前能力极限,证明下自己还是没忘引擎的本,顺便备战春招;也可能是受动物井,Games104等的启发;还有可能是最近拆了Godot以及Jolt的设计感觉好像也没那么难。总之就是开始写自己小引擎,值此新年之际算是有了阶段性成果,故而才有了这个系列。 来的应该基本都是内行,这里也就简单介绍下功能:物体树状组织,组件赋予功能,场景序列存取。渲染采用OpenGL+GPU Instance,模拟采用线程池+工作窃取。然后重点再介绍下名称和图标,名称与宝可梦的多变怪同名,因为开始就想的以物理模拟为主,毕竟个人很注重游戏中的交互体验,反馈到技术栈上就是图形学的模拟动画。图标形象则主要取自洛克王国的多灵,大概是个人页游退坑前夕出的宠物,很喜欢其背景设定的“传说中灵魂的收集者,通过吸收其他宠物的灵魂,来塑造自己的身躯”,个人在写引擎功能架构时也多有借鉴成熟引擎的操作。 准备 首先,在写之前应该对引擎架构及自己的能力有一定基本认知。按照Games104 ,引擎应该包含 5 层架构: 功能层:提供引擎表面的基础...
Godot Jolt并行对比
前言 前一篇Godot 物理源码分析把Godot内置的3D物理流程分析了下,接下来再扩展的话就是其在4.4版中集成的Jolt物理引擎了。本来想单开一篇介绍的,但看了下感觉Godot对Jolt也只是简易集成,功能方面与自己的已有的物理功能做了对齐阉割,性能方面接了个适配器又传回自己的通用线程池并行。与其介绍Godot中的Jolt,不如把两者独立开来,分别进行下介绍。 各物理引擎最为差异化的地方在哪?个人认为不在算法(Impulse, PBD),而是并行化处理。如何构建调整Island,如何设计ThreadPool,这直接决定了效率,且不同平台上可能表现截然相反。以下就将展开这两点进行比较。 构造约束 先从较为简单的构造约束讲起,毕竟Godot这边的逻辑十分简单。前文介绍过仅分了区域,刚体和软体三处不同逻辑,简单来说区域部分就是逮着一个就扔进去(毕竟不进行计算),刚体是检测与其关联的刚体软体,软体只检测与其关联的刚体。 v而Jolt的处理相对就复杂些,执行的是8位掩码图分割逻辑,其中7位并行,1位非并行,...
Godot 物理源码分析
前言 看引擎源码应该是引擎岗的基操了,且了解我的可能知道我主物理模拟。之前在项目组实习时改过Unity的源码,返校后就只能接触些开源引擎。UE的Chaos有些过重了:Init时Scene依次创建Scene、Solver、Evolution,Object依次RegisteEvent,CreateState,InitBody;Simu时先将游戏线程的AOS数据Push到SOA的物理线程中,经过一系列复杂的计算(毕竟个人比较在意移动端的表现)后将改动的脏数据Pull回去。而Godot的源码轻量,结构清晰,干脆就着拆解下3D物理部分。 看Godot最新版本4.5的文档其实还挺有趣的,如Godot的内存管理:对小对象采取预留空闲内存的堆分配,对大对象采取动态内存池 (用PooledList记录list和freelist)。与操作系统的分页选择截然不同,算是特化与通用的差异?以及Godot在21年发布的解释Godot为什么不基于ECS的架构和抽象层次的选择 (提供了一种新的视角,但个人其实不大认同,不过既然开源了有需要自己搭框架就好)。还有God...
Unity ML-Agents强化学习初探
前言 ML-Agents是Unity官方的一个强化学习框架,使用gRPC进行Python和Unity间的通信,让开发者得以仅在Unity中写C#,配置yaml训练参数就可训练所想要的模型 。个人在学习过程中找到的资料多为不兼容的旧版,故感觉还是有些必要记录下相关。 准备资源准备 参照官方文档,Unity端的话ML-Agents在Unity的Package Manager中可以直接安装。Python环境的话建议用Conda,毕竟Python3.10.1-3.10.12这版本要求还真不常见。之后克隆下官方Github代码库,键入 1234pip install mlagentscd /path/to/ml-agentspip install ./ml-agents-envspip install ./ml-agents 安装必要库即可。需要指正下cuda版本的torch不是刚需,这又不是练大模型,用Burst跑甚至兼容性更强。 大致用法 Unity代码中控制智能体的框架大抵如下。Heurist...
LLM PEFT微调 + Ollama运行初探
前言这几个月主要是在忙着秋招和硕士论文。承蒙之前我实习临座的那位AIGC工程师的关照,对AI有了进一步的了解,以及最后和他一前一后被开倒也挺有趣的。 整个秋招期间个人程序策划美术混投,多次被泡池子导致无缘同司的二志愿和补录。相反华为AI原本只是投着玩,倒是进展神速。这能怎么说,点AI春招接着转呗。现在想想和那些HR说话都太客气了,既然收到的多是冷漠而公式化的回答,那为什么不能同样冷漠而公式化的反制回去呢?说干就干,这就把冰冷的HR炼成我简历上温暖的项目。 准备前期研究总结而言有提示词工程,流程约束控制,RAG和模型微调四种方案。简单尝试了下光靠提示词的话稳定性不够,有时还会因文明礼貌的底层逻辑而拒绝任务;流程约束控制的话,风格这也不好写规则,评价是否足够冷漠而公式还得人工;RAG个人感觉主要是用于扩充知识库,冲不破它这文明礼貌的底层逻辑。所以最后采用的PEFT微调,在Ollama上运行验证。 方案 简介 优点 缺点 提示词工程 通过提示词描述表达规则,引导模型生成符合的文本。 实现简单,适合快速验证。对模型与部署环境无侵入。 风格稳定性有限,易受上下文影响。难以保证长...
Unity YooAsset + HybridCLR热更初探
前言 奇怪的技术栈招来了奇怪的暑期实习岗,概括而言目前作为技术美术在主导某个小游戏项目: 写策划案立项,做程序功能架构及负责美术表现。等美术资源时实在无聊,顺手把项目UI画了些,再试着研究下给项目上个热更,也以此确立下后续代码,美术资源规范。 准备前期研究 热更可以分为资源热更和代码热更两块:目前资源热更方案底层都是AssetBundles,AB包管理繁琐故有Addressable以及YooAsset以此延伸,各家公司貌似也都在此基础上自己魔改作为资源热更方案。据说Addressable坑有亿点多所以选择了后者;而代码热更则有Xlua,ILRuntime,InjectFix,HybridCLR。Xlua之前项目用过注入式对Update不友好,ILRuntime看着还行但也要插桩,InjectFix的话疑似Xlua Plus但HybridCLR的代码一致和原生性能直接杀死了比赛。 资源热更方案 Asset Bundle Addressable YooAsset 简介 Unity的传统资源打包与管理方案。 Unity推荐的资源管...
刚体模拟与破碎
前言几年前学完了GAMES103,跟着理了一遍图形学常用的刚体,布料,柔体,流体,算是入门了图形学的物理模拟,但之后呢?之后的路就得自己去探了,个人偏向追求实时计算以及视觉真实的游戏业界(毕竟感觉目前学界沉迷各种炼丹优化,或者拼接几种方法水论文),故打算重新审视下这几种模拟基本物体,看能否更进一步。 刚体模拟冲量法先热个身整下刚体模拟相关,对于刚体各引擎普遍采用线角速度更新,冲量处理碰撞(稳定,动量守恒)。大致流程如下图所示,感觉也不用多加赘述。 形状匹配相较而言形状匹配在游戏引擎中没怎么用到,其优势场景应该是在不同类物体交互(刚体,布料,柔体,流体混杂)的物理引擎(Flex)。不过考虑到PBD系列也是这个思路(先自由更新,再约束投影),也搓来玩玩当复健了。形状匹配大致思路就是先自由更新每个顶点,再最小化均方误差使其变为原形状(约束投影)。 在算法流程中值得说道下的也就形状匹配部分,首先由物体当前状态,我们可以得到协方差矩阵$S=∑(y_i−c)⋅r_i^T$ ,再由协方差矩阵和预计算的参考形状的协方差矩阵($Q= ∑r_i⋅r _i^T $)的逆计算...







