-FxYaM- - -学海无涯-
type: channel
link: https://www.fxyam.cn/category/study/
items: 【AI】Codex 执行完成后自动发送飞书通知
items: 【UE】渲染框架学习路径-初次修改源码
items: 【UE】HLSLMaterialCreator_README
items: 【AI】Vibe Coding初体验
items: 【UE】自动创建材质，一起来试试吧！
items: 【UE】使用色板控制贴图方向
items: 【UE】自定义函数给蓝图提供接口
items: 【UE】移动端渲染相关-灯光/反射/优化
items: </>小泊</>
items: 【UE】【BP】在蓝图中Key关卡序列

【AI】Codex 执行完成后自动发送飞书通知
type: item
date: 2026-07-07T21:58:00+08:00
description: .NiceMapMarker{width:100%;height:300px}@media (min-width: 1024px) {.NiceMapMarker{height:450px}}简直了，让自己完全没时间摸鱼我愿称作高级牛马的自我修养——自己做皮鞭踩坑都是我自己遇到的，如果你没有遇到或者遇到别的可以飞书填写表单。可以帮你安装Hooks，爱发电购买玉米粒(6.6R)就可以！这篇文章记录一次从 0 到 1 搭建「VSCode Codex 执行完成后自动发送飞书单聊通知」的完整过程。最终效果是：在 VSCode 中使用 Codex 执行任务，任务结束后，飞书会自动收到一条来自应用机器人的单聊消息。消息中可以包含执行时间、电脑名、项目路径、模型名、Hook 事件类型，以及 Codex 最后一条回复。1. 总体思路与方案选择1.1 最终目标想实现的链路很简单：Codex 执行结束 ↓ Codex Stop Hook 触发 ↓ 本地 Python 脚本执行 ↓ 获取飞书 tenant_access_token ↓ 调用飞书发送消息接口 ↓ 飞书应用机器人单聊通知我最终飞书收到的消息类似：✅ Codex 执行完啦！ 时间：2026-06-18 16:09:09 电脑：DESKTOP-XXXXXXX 项目：D:\YourProject 模型：gpt-5.5 事件：Stop 最后回复： Hi. What do you want to work on?1.2 为什么使用 Codex Stop HookCodex Hooks 是 Codex 提供的生命周期扩展机制，可以在特定事件发生时执行本地脚本。这里最适合使用的是 Stop 事件，因为它会在 Codex 当前回合停止时触发。官方文档中提到，Hook 配置可以放在：~/.codex/hooks.json <repo>/.codex/hooks.json对于本文场景，我使用的是用户全局配置：C:\Users\YourName\.codex\hooks.json这样所有项目都可以复用同一套通知逻辑。1.3 为什么不用群机器人 Webhook一开始我考虑过飞书「自定义机器人 Webhook」。Webhook 方案很简单：Codex Hook → 调用 Webhook → 飞书群收到消息但自定义机器人更偏向群聊通知，如果目标是「机器人直接单聊发给我」，更适合使用飞书开放平台的应用机器人能力。所以最后采用的是：飞书自建应用机器人 + tenant_access_token + open_id + 发送消息 API这样可以让应用机器人直接给指定用户发送单聊消息。1.4 最终文件结构最后本地会有两个关键文件：C:\Users\YourName\.codex │ ├─ hooks.json │ └─ hooks └─ feishu_codex_done.py其中：hooks.json负责告诉 Codex：当 Stop 事件触发时，运行哪个命令。feishu_codex_done.py负责调用飞书接口，发送单聊通知。2. 飞书开放平台配置2.1 创建自建应用进入飞书开放平台，创建一个自建应用，例如：应用名称：Codex 应用类型：企业自建应用创建完成后，可以在「凭证与基础信息」中看到：App ID App Secret这里要注意：项目说明App ID应用 ID，可以写入环境变量App Secret应用密钥，相当于密码，不要公开open_id用户在当前应用下的身份 ID，后面需要获取如果 App Secret 曾经出现在截图、日志、博客草稿中，建议立刻重置。2.2 添加机器人能力在应用后台左侧找到：添加应用能力 → 机器人添加完成后，可以在飞书客户端中看到这个应用机器人。此时它已经具备作为机器人出现的基础能力，但还不能保证可以主动发消息。2.3 开通发送消息权限进入：权限管理 → 开通权限搜索：im:message需要确认至少有这个权限：以应用的身份发消息 im:message:send_as_bot如果已经显示「已添加」，就不需要重复添加。2.4 发布应用版本权限或机器人能力发生变更后，需要重新发布应用。路径一般是：应用发布 → 版本管理与发布 → 创建版本版本说明可以写：添加机器人发送消息权限如果页面提示「本次发布免审核」，保存并提交发布后即可使用。3. 获取接收人的 open_id3.1 为什么不用邮箱飞书发送消息接口支持多种 receive_id_type，例如：open_id user_id union_id email chat_id我这里不想用邮箱，而是希望机器人直接发给当前飞书用户，所以选择：receive_id_type = open_id3.2 open_id 的坑最开始我误用了 AP…

【UE】渲染框架学习路径-初次修改源码
type: item
date: 2026-06-05T21:45:00+08:00
description: .NiceMapMarker{width:100%;height:300px}@media (min-width: 1024px) {.NiceMapMarker{height:450px}}记录“第一次真正改 UE 源码”的学习笔记。我不一定完全是对的。纯流水账碎碎念。后续改高度雾等等做了很多更复杂的事情了，但是那些不可能开源，所以想了想还是先分享我的起步吧~本次练习的最小目标是：在 DirectionalLightComponent 的 Details 面板中增加一个布尔开关 UseYumiColorfulLight。当它被勾选时，这盏平行光在 PC Deferred Renderer 路径下可以蹦迪。我选择切入的方向我其实搜了很多教程，每个平台都尽可能找到相关搜索。很多 UE 源码教程会从“如何下载源码、生成项目文件、编译 Editor”开始，但编译成功之后，下一步呢？源码这么大，我到底该改哪里？这一块我之前学AngelScript的时候已经很熟了，感觉是冗余信息我觉得最合理的方式是先做一个最小闭环：只让一条数据链跑通，只在一个渲染路径里验证成功。所以这次的范围应该明确收窄：项目本次是否处理原因Directional Light是目标明确，容易观察结果PC Deferred Renderer是UE 桌面端常见路径，适合作为第一次练习（最近在移动端导出踩坑，累死我了）Details 面板普通属性是用 UPROPERTY 即可，不需要先写复杂 Detail CustomizationMobile Renderer否移动端光照路径不同，容易扩大范围Forward Renderer否Forward 与 Deferred 的灯光组织方式不同Path Tracing否路径完全不同，不适合作为第一次练习，而且暂时没有项目需要Static baked lighting否静态烘焙涉及 Lightmass / 烘焙数据，不适合最小闭环第一次练习的验收标准应该非常简单：勾选 UseYumiColorfulLight，平行光开始蹦迪。只要这个闭环成立，已经摸到了 UE 源码修改里最重要的一条路：编辑器属性 → Runtime 组件 → SceneProxy → Shader 参数 → HLSL 着色。UE 源码的基础地图在改源码之前，最重要的不是背函数名，而是先知道“功能大概属于哪一层”。UE 源码非常大，如果没有层级地图，搜索出来一堆同名文件时会很容易迷路。可以先用下面这张简化地图理解 UE 源码结构：UnrealEngine/ ├─ Engine/ │ ├─ Source/ │ │ ├─ Runtime/ 游戏运行时核心代码 │ │ ├─ Editor/ 编辑器相关代码 │ │ ├─ Developer/ 开发工具、调试工具 │ │ ├─ Programs/ UBT、UHT、UnrealPak 等独立工具 │ │ └─ ThirdParty/ 第三方库 │ │ │ ├─ Plugins/ 引擎插件 │ ├─ Content/ 引擎资源 │ └─ Config/ 引擎配置 │ ├─ Samples/ ├─ Templates/ └─ FeaturePacks/对源码学习来说，最核心的位置是：Engine/Source/以后查 Actor、Component、Renderer、RHI、Editor 工具、构建系统，大部分时间都会在这里面转。UE 源码的七个基础层级1. 构建系统：决定“什么会被编译”这里在我之前记录自己添加函数的时候有项目说明，包括link的官方文档。这里不展开细说了。UE 的 C++ 构建主要依赖 UnrealBuildTool，也就是 UBT。可以先这样记：.Target.cs = 我要编译什么目标？例如 Editor、Game、Server .Build.cs = 这个模块依赖哪些模块？ .h / .cpp = 真实代码一个普通模块大概长这样：MyModule/ ├─ MyModule.Build.cs ├─ Public/ │ └─ MyClass.h └─ Private/ └─ MyClass.cppBuild.cs 很重要，因为 UE 是模块化编译。如果在一个模块里调用了另一个模块的类型，但没有在 Build.cs 里声明依赖，就可能出现编译错误、链接错误，或者 IntelliSense 能找到但实际编不过的情况。不过本次练习主要是修改 UE 已有模块，不是新建模块，所以 Build.cs 不是重点。只需要先知道：UE 编译不是普通 C++ 工程直觉，它背后有自己的模块和构建规则。2. 模块系统：UE 不是一个巨大的单体工程UE 源码不是所有代码混在一起，而是按模块组织。常见模块包括：Core CoreUObjec…

【UE】HLSLMaterialCreator_README
type: item
date: 2026-05-29T10:57:00+08:00
description: .NiceMapMarker{width:100%;height:300px}@media (min-width: 1024px) {.NiceMapMarker{height:450px}}HLSL Material CreatorHLSL Material Creator is an Unreal Engine editor plugin for creating materials from HLSL Custom node code.FeaturesCreate Unreal Engine materials from HLSL Custom node code.Supports Unlit Surface materials.Supports Post Process materials.Auto-generates material inputs for supported HLSL declarations.Supports float, float1, float2, float3, float4, and texture2d inputs.Supports selected special inputs such as Time, World Position, Object Position WS, Texture Coordinate, and Post Process scene textures.Supported Unreal Engine VersionsUnreal Engine 5.5Unreal Engine 5.6Unreal Engine 5.7Supported PlatformWindowsWin64DependenciesThis plugin has no third-party dependencies.InstallationDownload the plugin package for your Unreal Engine version.Copy the HLSLMaterialCreator folder into your project's Plugins folder.Restart Unreal Engine.Enable the plugin from Edit > Plugins.Restart Unreal Engine again if required.NotesThis is an editor-only plugin. It is intended to help artists and technical artists create Unreal Engine materials from HLSL Custom node code more efficiently.

【AI】Vibe Coding初体验
type: item
date: 2026-05-10T23:57:00+08:00
description: .NiceMapMarker{width:100%;height:300px}@media (min-width: 1024px) {.NiceMapMarker{height:450px}}前言我觉得网上有很多关于 Vibe Coding 的内容，标题往往都很夸张..我用 AI 做了一个项目，赚了多少钱。普通人靠 AI 开发软件，实现副业变现。不会写代码，也能做出商业产品。这些说法当然很吸引人，让我也很好奇，五一花了点时间学习了一下。但以我自己的体验来看，至少在现阶段，我并不觉得它适合大多数人直接拿来做很商业化的项目。不太可能做到我做了一个某团，之类的。它确实很强，但强的地方不一定是“帮你立刻赚钱”。对我来说，它可以帮我做出完全符合自己需求的轻量工具。以前为了一个很小的功能，可能要找各种App，研究苹果快捷指令，或者下载一些功能复杂但并不真正适合自己的软件。用到最后，要么功能不够，要么操作太重，要么数据不在自己手里。要不就是要开会员，我真的交了很多智商税..现在不一样了。我自己能做的话，它不需要服务所有人，只要 100% 符合我自己的要求就够了。叠个甲：这就有点像魔兽插件。反正我也不卖钱，也不打算服务别人，自己用得舒服就行。所以如果你期待的是“如何用 AI 做出一个爆款产品”，那这篇可能不太符合你的预期。我的分享更偏向*普通人如何用 Vibe Coding 做出真正适合自己的个人工具。冷知识，不喜欢可以关闭该网页。制作链路这段时间，我大概做了六七个小工具。其中我需求最强的有两个：一个是个人生活管理和打卡 App。 一个是记录冰箱食材的工具。生活管理那个涉及比较多隐私，就不展开了。这里主要讲冰箱食材管理这个项目。这个工具的需求其实很简单：我想知道自己买了什么食材、花了多少钱、什么时候买的、什么时候过期、哪些东西快要吃完、哪些东西已经放太久了。听起来很小，但对我来说非常实用。因为现实生活里，家庭冰箱管理是一件很容易失控的事情。买菜的时候觉得自己很有计划，过几天就忘了冰箱里到底有什么。或者你买了菜，你妈不知道，第二天也买了一样的菜..等想起来的时候，菜已经坏了，肉已经冻了很久，调料也不知道开封多久了。所以我真正想解决的不是“记录食材”本身，而是让自己对生活里的消耗有感知。第一个版本：用有道云表格记录最早的时候，我只是用有道云的表格来记录。记录内容包括：买了什么消耗了什么花了多少钱什么时间购买什么时间过期这个方法很原始，但也能用。问题是，手动维护太麻烦了。每次买完东西都要打开表格、找到对应位置、手动输入信息。消耗食材的时候，也要再回去修改。更麻烦的是，表格本身不会主动提醒我哪些食材快过期。所以这个阶段，我其实只是把“冰箱记忆”从脑子里搬到了表格里，但它还没有真正变成一个工具。后来我发现，其实有道云也可以申请 API。理论上，可以通过 API 读取和处理表格数据，再做一些自动总结和提醒。但实际体验下来，在当时的开发环境和能力范围内，它能做的事情比较有限。比较适合做一些简单的数据总结、过期提醒，再复杂一点就会变得不太顺手。如果对这个方向感兴趣，可以去看官方文档。但对我来说，它并不是最理想的路线。第二个版本：做成微信小程序后来我尝试把它做成微信小程序。这个版本我做了一半，还给我妈试用了一下。微信小程序的好处是入口方便，手机上打开很自然。对于家庭成员来说，它也比网页、表格更容易理解。然后微信小程序做了一半，还给我妈试了一下，如果是免费的其实上能做的不多，而且数据是手机本地的，如果有两个手机，或者一个手机，又要电脑编辑。这个云是要钱的..这时候我想到，我自己就有服务器啊，为什么要再买个云。第三个版本：挂在自己的服务器上于是我做了第三个版本：网页端模拟 App。我把它部署在自己的服务器上，通过浏览器访问。没有对外开放接口，也不是公开产品。访问需要输入特定网址，还需要账号和密码。这个方案对我来说几乎是最合适的。只要有浏览器，所有设备都能用。 手机可以用，电脑可以用，平板也可以用。 数据存在自己的服务器上，不依赖某个 App，也不用额外买云服务。反正...家里人记录能有多少数据，这个项目完结在服务器上加上函数包也就1MB..这也是我对 Vibe Coding 最大的感受之一：它最适合解决那些“太个人化、太具体、太不值得商业化”的需求。这些需求找不到完美的现成软件，因为它们太私人了。 但正因为私人，它们对自己才最有价值。碎碎念怎么用很多人刚开始用 AI 做东西时，会直接说：帮我做一个管理冰箱食材的 App。AI 当然可以生成一个页面。 它可能会有新增食材、删除食材、分类展示、过期时间这些基础功能。看起来好像也能用。但问题是，它很可能不是你真正想要的东西。因为“管理冰箱食材”只是一个抽象需求。它没有说明你的生活方式，也没有说明你的操作习惯，更没有说明你…

【UE】自动创建材质，一起来试试吧！
type: item
date: 2026-04-20T23:27:00+08:00
description: .NiceMapMarker{width:100%;height:300px}@media (min-width: 1024px) {.NiceMapMarker{height:450px}}现在很多材质ai已经可以写了，但是拿到hlsl以后还需要去创建材质，添加custom，手动添加材质，然后加各种参数，填写默认值，还是很麻烦这些步骤本身并不难，却很消耗耐心。尤其当你需要反复验证效果、频繁替换代码，加一个input，删两个input的时候，这种身心上的成本会比想象中更重。所以我花了两个晚上的时间，写了这个小脚本。为什么做这个功能我一直觉得，AI 帮我们写出一段代码，和这段代码真正进入生产流程，中间其实隔着很长一段距离。尤其是材质系统相关的内容，它并不是“代码能跑”就结束了。 它还要能被整理、能被复用、能被其他人理解，也要能以更稳定的形式进入项目。 如果每一次都要从头手工搭建一遍材质节点和参数，那前面节省下来的时间，很容易又在后面被一点点消耗掉。所以这个脚本想解决的，并不是“如何生成 HLSL”，而是另一个更实际的问题：如何让 HLSL 更顺畅地进入 Unreal 的材质工作流。把这一步补上之后，AI、现成的 shader 逻辑、或者自己手写的 HLSL，才算真正开始变得好用。关于这次演示用到的 HLSL这次演示里的 HLSL，可以在 Shadertoy 找到对应的 GLSL。 而 GLSL 转 HLSL 这件事，其实在 GitHub上已经有比较成熟的方案了。就我自己的体验来说，在“语法映射”和“结构转换”这个层面上，这类现成方案往往比 AI 更稳定，也更可控。上不了Git，B站上搜“ue shadertoy”也有相当多的教程。AI 的优势更适合用在辅助理解这些环节 ，但如果是偏工程化、偏规则映射的工作，成熟方案通常还是更可靠一些。它真的有概率会瞎改里面逻辑。我并不是在否定 AI。恰恰相反，我觉得 AI 已经非常有用了。 只是它更适合作为工具链中的一环，而不是替代一切的答案。真的，不要太迷信Vibe Coding...一些AI写材质的想法这里和具体用哪个模型关系不大。 我更想表达的是AI 是否真的能帮到你，很大程度上取决于你自己现在站在哪个阶段。我经历过几个阶段，我觉得使用ai会出现两种情况。第一种：你已经有一定的 HLSL 基础如果你对 HLSL 已经有一定理解，并且脑子里很清楚自己想实现什么效果、需要哪些逻辑、哪里应该怎么拆，那么 AI 大概率会成为一个很好的加速器。AI去实现逻辑是非常好的。它可以帮你省去很多重复劳动，比如补函数、整理结构、快速试不同写法，或者把一个已经成型的思路更快地展开。 我自己是从 2023 年开始接触 HLSL 的。 在 CSDN 上还能看到我当时纯手写的一些 Groom 材质内容。现在回头看，那时的实现当然还很简单，但它对我来说很重要，因为很多理解都是从那个阶段一点点建立起来的。 后面我也写过一些后处理相关的内容，其中一部分已经开源，另外一些还没有整理出来。第二种：你只是想靠 AI 直接抽出结果另一种情况就在一些情况下很常见了。 你并没有真正理解代码，但你希望通过不断描述效果，让 AI 直接给你抽出一个满意的结果。这当然不是不可以，只是它很像抽卡。因为 AI 对“逻辑”的理解，通常远远强于它对“美术效果描述”的理解。 你说“我想要一种更柔一点、轻一点、空气感更强的边缘变化”，对人类美术来说这可能是很自然的表达； 但对 AI 来说，这样的描述往往并不稳定，它更容易抓住结构性的指令，而不是审美里的微妙差异。所以最后经常会变成： ..你可能要抽很多次，才接近你想要的东西。也可能抽很久，仍然得不到真正符合预期的结果。如果在这个过程中你又完全看不懂代码，那会很被动。因为你既无法判断它到底写得对不对，也无法自己做最后那一步修正。所以我觉得如果想认真把 AI 用进 shader 工作流里，至少先学一点基础语法。不用一开始就学得很深。 先能看懂输入输出，能理解函数结构，知道一个效果大概是怎么被组织出来的，这就已经很有帮助了。我是纯美术出身，大学连数学课都没认真上过几节。 但我后来还是一点点把这些东西学下来了。 所以如果你现在也正站在这个门口，不用太怀疑自己。 我可以学会，你也可以。（说实话，有那个时间等抽卡，教程已经看完了..）如果你想直接看 C++ 的实现如果你更关心这个工具本身是怎么落地的，尤其是如何直接通过 C++ 去生成对应结构，可以看我的上一篇博客。也可以看我AngelScript那一篇。只是AS不能直接在默认创建的C++项目里面用，比较麻烦。这里的h和cpp我发到我的git了，之前有权限的朋友可以直接获取。如果你打开是404，说明你没有权限目前支持的参数写法现在这个 HLSL 解析方式，支持三种输入…

【UE】使用色板控制贴图方向
type: item
date: 2026-04-20T22:43:00+08:00
description: .NiceMapMarker{width:100%;height:300px}@media (min-width: 1024px) {.NiceMapMarker{height:450px}}碎碎念：一般网上用rgba来控制uv的方案好像多一点，但是我感觉色环直接上下左右拉好像更直观更爽一点，网上没有看到类似方案，于是我自己写了一个。主要参考的是ronja的方案：HSV Color Space主要思路：这个颜色拆成 色相 Hue 和 饱和度 Saturation。Hue 决定往哪个方向偏移，Saturation 决定偏移有多。然后用这个结果去改 UV，最后再用新的 UV 去采样 MainTex。HSV 里 Hue 本来就可以看成一个圆周角度，而 Saturation 可以理解成离灰色中心有多远HLSL:float3 C = max(ControlColor, 0.0); float maxC = max(C.r, max(C.g, C.b)); if (maxC > 0.00001) { C /= maxC; } float cMax = max(C.r, max(C.g, C.b)); float cMin = min(C.r, min(C.g, C.b)); float delta = cMax - cMin; float sat = 0.0; if (cMax > 0.00001) { sat = delta / cMax; } float hue = 0.0; if (delta > 0.00001) { if (cMax == C.r) { hue = (C.g - C.b) / delta; if (hue < 0.0) { hue += 6.0; } } else if (cMax == C.g) { hue = (C.b - C.r) / delta + 2.0; } else { hue = (C.r - C.g) / delta + 4.0; } hue /= 6.0; } float angle = hue * 6.28318530718 + AngleOffsetDeg * 0.01745329252; float2 dir = float2(cos(angle), -sin(angle)); float sat01 = saturate((sat - MinSat) / max(0.00001, (1.0 - MinSat))); float mag = OffsetStrength * pow(sat01, SatPower); float2 newUV = UV - dir * mag; newUV = saturate(newUV); float3 texColor = Texture2DSample(MainTex, MainTexSampler, newUV).rgb; return texColor;

【UE】自定义函数给蓝图提供接口
type: item
date: 2026-04-12T20:31:22+08:00
description: .NiceMapMarker{width:100%;height:300px}@media (min-width: 1024px) {.NiceMapMarker{height:450px}}还是有一些项目需要维护蓝图，之前已经写的太复杂了，我不想再花很多时间再写一遍as，虽然有ai辅助，但是现在盲目相信ai还是不行的，需要自己理解。然后有一些接口就是没有，接口没有的话，as和bp都是处理不了的。我搞了一整天要崩溃了，也不想总麻烦同事...自己写吧。然后我发现写结接口是最简单的，编译引擎又翻车了，但是这次不是编译本身，是P4V的问题..我查了很多资料以后有一个最简单的流程：这是总体官方文档，需要知道的内容这个链接也link了其他部分，基本能知道所有的信息。之前的文章有人私信我说打不开，epic的文档404一般换地区就可以解决..实在不行换版本，除了新功能其实文章内容都不是差非常多。我是c++项目，什么都没调整过的原生项目长这样:然后手动加这两个文件，按照格式规范书写内容，这里尝试了一个最简单的，其他静态函数的内容官方文档写的蛮仔细了..这里是官网链接https://dev.epicgames.com/documentation/en-us/unreal-engine/blueprint-function-libraries-in-unreal-engine这里是我简陋的测试代码：cpp：#include "Test55_CFunctionLibrary.h" #include "CoreMinimal.h" // 添加此行以确保FString已定义 FString UTest55_CFunctionLibrary::HelloYumi() { return TEXT("Hello from Yumi's VS"); }h：//这里不用写系统应该会自己创建，这个意思是这个头文件只允许被编译器包含一次。 #pragma once //把“蓝图函数库”这个父类请进来 #include "CoreMinimal.h" #include "Kismet/BlueprintFunctionLibrary.h" //反插一次，这样才能显示 #include "Test55_CFunctionLibrary.generated.h" UCLASS() class TEST55_C_API UTest55_CFunctionLibrary : public UBlueprintFunctionLibrary { GENERATED_BODY() public: UFUNCTION(BlueprintCallable, Category = "Test55_C") static FString HelloYumi(); };然后就有了，就这么简单^ ^

【UE】移动端渲染相关-灯光/反射/优化
type: item
date: 2026-03-22T20:57:53+08:00
description: .NiceMapMarker{width:100%;height:300px}@media (min-width: 1024px) {.NiceMapMarker{height:450px}}项目主要是移动端，恶补ing..总览与适用范围1. 总览UE 移动端渲染的整体框架UE 的移动端渲染可以理解为三层选择：平台/图形 API（Android / iOS；Vulkan / OpenGL ES / Metal）→ 渲染器路径（Mobile Forward / Mobile Deferred）→ 具体功能开关（阴影、反射、后处理等）。在 UE 5.5 的“移动侧”更新中，官方明确强调 Mobile Forward 增强（包括矩形区域光、胶囊阴影、体积雾、Niagara 粒子灯、以及移动端 SSR 等）。 1从“渲染管线”角度，移动端一帧通常仍然遵循：可见性（InitViews/剔除）→ 阴影深度（ShadowDepths）→（可选）深度预通过（PrePass）→ BasePass（输出颜色/或写入移动 GBuffer）→ 光照/阴影合成 → 半透明 → 后处理。移动端的具体 pass 结构，和 Mobile Forward / Mobile Deferred 的分叉，在 UE 的移动渲染分析文章中有较清晰的 RenderDoc 截帧与流程拆解（FMobileSceneRenderer）。 2移动端“延迟着色”的引入，本质上是为了把“每个物体都要按灯算一遍”的成本，部分转换为“先写 GBuffer、再按屏幕算光”的成本，从而更适合“灯多/局部灯多”的场景；但它也会显著增加 Render Target、带宽与内存压力。 3 2 4与 PC/主机渲染相比的关键差异移动端相比 PC/主机，差异不在“概念”，而在“默认策略 + 可用硬件特性 + 可持续功耗”。1) 硬件架构更偏 TBDR（Tile-Based Deferred Rendering）/片上 tile memory，强调“减少系统内存读写、减少过度绘制、减少不必要的 pass 依赖”。 5 2) 带宽与功耗是长期瓶颈：移动 GPU 想一直维持高性能更难，通常需要你主动把“每像素的读写/采样/分支/后处理”压下去，否则很快触发热降频。 6 7 8 3) 功能层面：PC/主机常见的“高端动态光影与反射体系”（例如大规模动态阴影、复杂 GI/反射）在移动端要么是阉割版、要么是高端机/实验性路径。UE 5.5 对移动端新增特性明显集中在“Mobile Forward 画质补齐 + 移动 SSR 打通”。 1 9 10 4) Shader 与 RT（Render Target）策略更保守：移动端的“每像素 texture bandwidth”很宝贵（含 GBuffer 写入、后处理读写、阴影/反射采样）。Arm 的优化建议里直接把“纹理带宽”作为 fragment shader 关键瓶颈之一。 8注：原 Deep Research 在线图像轮播占位符已移除；Markdown 导出不支持该交互组件。为什么移动端在灯光、阴影、反射上限制更多移动端“贵”的根因，通常不是某个功能“算不出来”，而是算得出来但算不久/算不稳/算不齐：带宽（Bandwidth）： 灯光/反射/阴影经常意味着额外 RT、额外采样、额外读写（ShadowMap、GBuffer、SceneColor/Depth/Normal）。纹理读写一多，fragment shader 就容易“喂不饱”，性能直接被带宽卡死。 8 5Overdraw（过度绘制）： 透明、粒子、UI、复杂半透明叠加，会把“每像素的着色次数”乘上去；Forward 路径下尤其典型，因为光照计算往往发生在物体被绘制时。Apple 直接把“最小化 overdraw、减少不必要依赖与 load/store”作为性能优化核心主题之一。 5 2Shader 复杂度与纹理采样： 高光/法线/清漆/多层材质/SSR/PPR 都会明显增加 ALU 和采样，且采样常常就是带宽。 8 2分辨率与后处理： 大多数后处理按像素成本线性或近似线性随分辨率增长；SSR、Bloom、TAA、色调映射都属于“屏幕空间”类，分辨率一上去，成本就非常直接。 2 3 11热降频与电池： Android 官方把“热状态”视为应用潜在性能上限，并建议监控 thermal headroom 并动态下调工作负载。长时间运行（例如 10–20 分钟）比短跑 benchmark 更能暴露“灯光/反射太重导致掉帧”的真实问题。 6 7影响移动端画面与性能的核心瓶颈（你在项目里应该怎么理解）带宽：像素越多、RT 越多、采样越多 → 越容易被卡。 8Overdraw：透明/粒子/叠层 UI/大量重叠几何 → “…

</>小泊</>
type: item
date: 2026-03-21T13:26:00+08:00
description: .NiceMapMarker{width:100%;height:300px}@media (min-width: 1024px) {.NiceMapMarker{height:450px}}UETech【BP】在蓝图中Key关卡序列【AngelScript】学习路径与资料库【EUW】自动化导入DAZ资产并创建PBR材质思路VFXAssets【Groom】Xgen 到 Unreal Engine 添加自定义属性实测流程【HLSL】屏幕模糊-hlsl编写初体验【VDB】【Landscape】雪山场景摸鱼MayaQtpy【Qtpy】自动化清理maya文件，带材质abc导入unreal（maya插件制作初体验）Plugin三渲二 Pencil+ 4 for Maya 线稿渲染Stable Diffusion【Sora】【Hunyuan3d】写实模型ai转风格化资产探索depth-anything-v2 模型机制总结并测试ComfyUI-nunchaku 安装并测试Prompt【Prompt】HUMAN 3.0

【UE】【BP】在蓝图中Key关卡序列
type: item
date: 2026-03-15T21:09:43+08:00
description: .NiceMapMarker{width:100%;height:300px}@media (min-width: 1024px) {.NiceMapMarker{height:450px}}以前都是处理资产标准化，遍历材质和相关param和refrence相关就可以，第一次接触Seq，还挺有意思。但是因为后续多半是使用As来编写逻辑了，不会使用蓝图了，所以这个文档多半不会再更新。学习思路和实际上的实现逻辑是接近的，一般节点和function能关联上，所以文档在Seq遍历的理解上上也有一定价值，作为一个存档吧。And，我的网课开始了，没精力了...Runtime 控制 vs Editor 编辑你对 Sequence 的需求通常分两类：Runtime（运行时）= “播放控制、动态替换绑定”常见任务：Play / Pause / Stop / Reverse / LoopJump/Seek 到某个时间或帧动态换绑定：同一段镜头，换角色/道具/相机（Rebinding）这类通常用 LevelSequenceActor / LevelSequencePlayer 完成。Editor（编辑器）= “改资产、做批处理”常见任务：批量遍历 Content Browser 里选中的多个 Level Sequence修复丢失引用（Binding 断了）批量加 Track / Section批量打 Key / 改曲线批量 Bake/导出 AnimSequence这类通常在 Editor Utility Widget（EUW） 或 Editor Utility Blueprint 里做，靠 Sequencer Scripting 提供的扩展库。1. Sequencer 的数据结构：你到底在改什么？把 Level Sequence 想成“时间轴资产”，它内部关键结构是一条链：LevelSequence（资产） → MovieScene（根时间轴容器） → Object Bindings（对象绑定：这条轨控制谁） → Tracks（轨道：控制什么类型数据，如 Transform / CameraCut / Property） → Sections（片段：轨道上的时间区间） → Channels（通道：Transform.X 等） → Keys（关键帧：时间+值）你做工具时，“编辑 Sequence”= 找到 Binding → 创建/修改 Track → 创建/修改 Section → 拿到 Channel → 写 Keys → 刷新 UI → 保存资产这一篇知乎说的还蛮清楚的。精髓就是这两张图。当然我在实战的时候发现其实也是变化比较多的，需要自己去官方文档一点点推理。比如这里设置相机就是很标准的上述流程，不管是蓝图还是As，都是这个层级这个套路。如果是As的话，大概是这样的，基本一样这里是修改相机Z轴，前面TargetZ已经定义过了： private bool TryUpdateCameraBindingTrackZ(FMovieSceneBindingProxy Binding, float TargetZ) { SetLogsText("[Step] Searching camera transform tracks"); TArray<UMovieSceneTrack> Tracks = Binding.FindTracksByType(UMovieScene3DTransformTrack::StaticClass()); SetLogsText(f"[Info] Transform track count: {Tracks.Num()}"); bool bUpdated = false; int UpdatedChannelCount = 0; for (auto Track : Tracks) { if (Track == nullptr) { continue; } TArray<UMovieSceneSection> Sections = Track.GetSections(); for (auto Section : Sections) { if (Section == nullptr) { continue; } TArray<UMovieSceneScriptingChannel> Channels = Section.GetAllChannels(); for (auto Channel : Channels) { if (Channel == nullptr) { continue; } if (Channel.ChannelName == n"Location.Z") { if (ApplyTargetZToScripti…