Aether Engine:调了一个月体积云,我发现 AI 真正的瓶颈不在代码
上一篇把 Phase 5.x 的勾提前打上了。现在回头看,那个勾打得有点早。 那时候的云只能说能跑:一层 FBM 噪声铺在水平 slab 上,远看像云,近看像棉花糖。我心里其实清楚这事儿没完,但文章里已经写完了,就先那么放着。 最近一个月,晚上娃睡了之后,我又把云翻出来重搞了一轮。现在的效果长这样: 这张图是相机停在云层中间拍的。上半部分黑乎乎的,下面是蓬松的云。说实话,这画面本身算不算好看我也说不好,但它至少说明一件事:云终于有点体积了。 云能调成现在这样,我大概走了三轮,前两轮都不太顺。 第一轮:AI 的方案 这一轮最开始,我让 AI 看现在的云效果,让它给优化方案。 它给了好几条:改噪声、改密度模型、改光照、改步长。看起来都有道理,我就让它顺着往下做。结果改着改着,发现越改越坏。云的形状开始变形,边缘变硬,有时候直接变成一团灰雾。 但 AI 每一步都觉得自己是对的。它会告诉我这一步优化了什么、解决了什么问题、测试有没有通过。我看着那些"已完成"的任务,心里却越来越没底。 在这里卡了很久。每天打开 launcher,看一张比昨天更怪的截图,然后说&quo...
Aether Engine Phase 5:当 AI 开始看图验收
Phase 5 的代码已经合进 main 了。地形、大气、水体、CSM、GPU Timer,这一串功能清单全打上了勾。 要是放在以前,这篇文章大概会是一堆技术细节:Gerstner 波浪怎么实现、大气散射用了哪个模型、CSM 的分裂策略是什么。但这次我不太想这么写。因为 Phase 5 最让我印象深刻的,不是这些效果本身,而是我第一次让 AI 参与了"看图验收"。 Phase 5 先快速看一眼 水体效果: 大气散射: 水体和大气看起来还行,但说实话,这些效果本身不是 Phase 5 最让我兴奋的地方。 更让我兴奋的是,这一阶段我开始让 AI 参与验收——不是只看代码,而是直接看渲染结果。每次改完场景,把截图丢给 Kimi,问它"这看起来对不对",成了我新的日常。所以接下来想聊的,不是某个具体效果怎么实现,而是我最近摸索出来的这套 AI 视觉回归工作流: 技术上没什么要特别颠覆的,该写的 ADR 之前都写了。Phase 5 更像是一个大拼图——把前面搭好的 Deferred PBR、SSAO、SSR、Bloom,和新加入的地形、大气、水...
从手写到口述:我用 AI 重构了自己的引擎开发方式
距离上次更新 AetherEngine 的立项文章才过了两周,但感觉像是过了很久——大概是这两周发生的事情太多了。 白天上班,晚上回家带娃,等娃睡了差不多也就十点了,属于自己的时间被压缩得所剩无几。KongEngine 那会儿周末还能泡一整天在代码里,现在连完整的一个小时都是奢望。 但偏偏就是这种时候,我做了一件看起来挺疯狂的事:在两周内,让 AI 把 AetherEngine 从只有一个三角形的骨架,推到了拥有延迟渲染、阴影、IBL、SSAO、SSR 和编辑器基建的完整引擎。 为什么在这个时间点做这件事 说实话,AetherEngine 的立项多少有点"不务正业"。UE 渲染那块工作上的事情已经够忙了,回家还要带娃,哪有时间从零开始写一个引擎? 但有两个契机让我决定试试。 第一个契机是去年年底家里迎来了小宝宝。 joy 是真的 joy,累也是真的累。以前周末两天可以完整做自己的事,现在周末是全天候带娃模式。我算了一下,一周下来属于自己的整块时间,加起来可能不到五个小时。五个小时,连 KongEngine 一个功能的零头都写不完。 第二个契机是 AI 编程能力...
AetherEngine:从 KongEngine 到 Rust + wgpu 的现代渲染引擎重构
写了十年引擎,还在画三角形——这话放在我身上挺合适的。 KongEngine 是我用 C++ 和 OpenGL/Vulkan 写的个人渲染引擎,延迟渲染、级联阴影、SSR、水体这些效果都折腾过一遍,也写了不少文章记录。但说实话,C++ 那套东西越往后越累:模板报错能看半天,头文件改一处编译五分钟,手动管理 GPU 资源时不时漏个释放,内存泄漏查起来要命。更别提让 AI 帮忙写代码了——C++ 的宏魔法和复杂语法让 AI 生成的代码经常编译不过,改来改去还不如自己写。 正好这两年 Rust 在图形领域慢慢起来了,wgpu 提供了跨平台的统一渲染抽象,hecs 是个极简的 ECS 实现。想了想,干脆用现代架构和 Rust 重新搭一个引擎,AetherEngine 就这么立项了。 为什么重写 KongEngine 代码量上来之后,几个坑越来越深: 编译慢得离谱。改一行头文件,等五分钟编译,这谁受得了。 内存泄漏查起来要命。手动管 GPU 资源,几次忘了释放,查半天才发现是某个纹理没删。 AI 写 C++ 太费劲。宏魔法和复杂语法让 AI 生成的代码经常编译不过,改来改去还不如自己写。...
UE5 GAS 源码深度解析 | 第3篇:GameplayEffect 源码导读(上)
前言 第 2 篇把 AttributeSet 的数据结构讲完,属性值在内存里怎么存、怎么改、怎么同步已经清楚。但"谁在改、怎么改、改完怎么管"这个问题还没回答——这正是 GameplayEffect(GE)的职责。 上一篇文末预告的是 ASC,但效果这东西改属性、挂 Buff、管持续时间,几乎把 GAS 里"改数"这条线的核心逻辑都串起来了。理解了 GE 的源码,后面再读 ASC 的管理、网络预测、Stacking 会省不少力气,所以这篇先把 GameplayEffect 交代清楚。 GE 在架构里的角色 回顾 第 1 篇的图 2,GE 处在"修改层":负责"改属性和改状态"的原子操作。一个 GE 可以配置若干 Modifier(改哪个属性、怎么改、改多少),也可以改 GameplayTag(加/减状态标签),还可以授予技能、触发条件效果等。 这篇聚焦 GE 改属性的核心逻辑——Modifier 机制、GE 的静态定义、运行时实例(Spec)、DurationPolicy(Instant/Durati...
UE5 GAS 源码深度解析 | 第2篇:AttributeSet 源码导读
前言 第 1 篇把 GAS 的骨架串过一遍:UAbilitySystemComponent(ASC)管着能力、效果、属性与标签;真正决定「数值长什么样」的,是 UAttributeSet 和它的子类。这篇接着从源码里看:属性相关的几个核心类型、UAttributeSet 在 ASC 里怎么挂、数从哪进从哪出,以及改数时会踩到哪些回调。 上一篇文末原本想下一篇先写 ASC。属性这东西又薄又底层,Effect、预测、复制几乎都会碰到,所以这篇先把 AttributeSet 交代清楚,后面再读 GameplayEffect 和网络会省不少力气。 版本说明 本文依旧是以 Unreal Engine 5.7 插件源码为准,和你本地不一致的地方以你手里的代码为准。 主要会翻: Engine/Plugins/Runtime/GameplayAbilities/Source/GameplayAbilities/Public/AttributeSet.h Engine/Plugins/Runtime/GameplayAbilities/Source/GameplayAbilities/Priv...
UE5 GAS 源码深度解析 | 第1篇:整体架构与设计思想
前言 如果你正在用虚幻引擎做一款带复杂技能、Buff、连招的单机或者多人游戏,很大概率已经听说过 GAS(Gameplay Ability System)。 自从GAS在UE4上推出以来,GAS已经被应用在数不尽的项目中,现在,熟悉GAS几乎已经成为了UE Gameplay开发的必修课之一了。 现在网上也有着无数的GAS相关的文章,其中不乏介绍如何使用GAS的教程。这些内容对新手来说是非常有用的,但本系列并不会把重点放在如何使用GAS上。本系列默认读者你已经是一个对GAS略知一二,甚至有着利用GAS搭建一个小的RPG的经验了。这个系列的教程,会尽量的从设计理念和源码的角度,来剖析GAS。 GAS的起源 GAS的起源于Epic的一款叫做《Paragon》的第三人称MOBA游戏,在这款游戏中,Epic面临着以下几个设计难点: 极致的表现力:需要实现华丽且同步的3C技能效果。 复杂的逻辑:需要处理诸如击飞、眩晕、变身、持续伤害等多样化的技能机制。 严苛的网络环境:作为一款多人竞技游戏,它必须在服务器-客户端的网络架构下,保证所有玩家看到的技能效果和伤害计算是完全一致的。 可拓展能力和...
2026更新计划
好久不见。 又是一段时间没更新博客了,上次更新还是去年 11 月底,距今已有三个多月。 去年 11 月家里迎来了小宝宝,这几个月一直处在「新成员带来的喜悦」和「带娃与家务的疲惫」之间。最近终于找到了生活与工作的平衡,决定重新拾起学习和记录的习惯。 2025 年 8 月,我从后端与安卓开发转回 UE 开发,回到老本行、回到热爱的行业,是件值得高兴的事。但换工作不是学习的终点——回到 UE 之后,发现自己还有大量内容需要掌握、沉淀和重新拾起。于是给自己定了今年的发文计划,打算写以下几个系列: GAS 详细剖析:从设计到各模块的源码与实现细节,都会过一遍,把这个主题讲透。 UE 网络同步详解:结合 GAS,从设计到代码实现把 UE 的网络同步讲清楚,重点是网络调用与数据同步,以及网络架构设计。 UE 渲染入门:渲染一直是我感兴趣的方向,而修改 UE 渲染管线是门槛很高的技术。掌握这一块,无论以后迁移到其他引擎还是自己做渲染,都会是很大的助力。这部分要求很高,我尽量达到 UE 引擎开发的入门水准。 这三个系列之间会视情况穿插一些零散话题,不会全是长系列。 文章会同步发到知乎、CSDN...
UE中的变体
前言 最近在工作中,为了实现数据在多个关卡间的传递与管理,我在一个 GameInstanceSubsystem 中实现了如下方法: 1234567891011121314UCLASS()class UDataManageSubsystem : public UGameInstanceSubsystem{ GENERATED_BODY()public: UFUNCTION() void SetSharedData(const FName& Key, UObject* InData); UFUNCTION() bool GetSharedData(const FName& Key, UObject* OutData); private: UPROPERTY() TMap<FName, UObject*> SharedDataMap;}; 可以看到,我在Subsystem中创建了一个FName到UObject*的映射表,同时暴露了GetSharedData和SetSharedData两个接口...
基于GitLab Runner的CI\CD构建
前言 最近在工作中将各个部分的主流程代码都合并了起来,之前各个同事各自埋头苦干的工作汇总到一起后,遇到了不少坑,出现了很多bug,不过好歹最后是将整个流程串起来了。 在主流程合并后,我们的游戏整体也算是初步完成,后续需要维护一个稳定可用的版本来给各位同事去上手尝试,进行整体上的测试、打磨和迭代等等。于是乎,我便在这两天之内,抽空做了下项目的CI\CD流水线。 搭建流水线 技术选型 UE的持续集成流水线的方案网上应该有不少了,问下豆包、DS等AI都能够给一套比较完整且成熟的方案,比如说Jenkins等等。我们的项目代码是放在GitLab之上,于是就选用了GitLab的原生支持的方案——GitLab Runner。 在当前缺乏专用构建机的情况下,我选择以我的开发机器作为构建机,配置GitLab Runner。 GitLab Runner接入 GitLab Runner是GitLab附带的开源持续集成服务,它负责协调测试工作。 想要使用GitLab Runner,首先在下载安装页面下载对应版本的文件。我本地开发电脑室Windows,下面的流程都是基于Windows的流程。 注册Runn...







