UE5 shader instructions

因为 3.0 是常量,y 是变量------编译器对它们的处理方式完全不同。


核心原因

复制代码
Power(x, 3.0)     ← 编译期就知道指数是 3.0
                  → 编译器:我可以把 pow(x,3.0) 替换成 x*x*x

Power(x, y)       ← y 是一个 Scalar Parameter,编译期不知道它的值
  y = 3.0          → 这个 3.0 是运行时的值,不是编译期的常量
                  → 编译器:我不知道 y 在运行时会是多少,必须保留 pow()

发生在不同时间:

复制代码
编译期(Shader 编译时)         运行时(游戏跑起来后)
─────────────────────         ─────────────────────
3.0 → 编译器认识,是个字面量     3.0 → GPU 不认识,是数据

y   → 编译器不认识,是个变量      y  → GPU 从 Uniform Buffer 里读到 3.0
     来自 Parameter Node              然后用 pow(x, 3.0) 算一遍

可视化的对比

复制代码
材质图中的写法                 编译器视角                 实际 GPU 指令
─────────────────────────────────────────────────────────────────
Power                             
 ├─ x ──○                      "指数是 3.0"               mul r0, x, x
 └─ 3.0 ──○                    → 折叠掉!                mul r1, r0, x

Power
 ├─ x ──○                      "指数是 y,运行时         log r0, x
 └─ ScalarParam[y] ──○          才能知道是多少"          mul r1, r0, y
   (值 = 3.0)                  → 保留 pow()!            exp r2, r1

更深一层:为什么编译器不能"看一眼" y 的值

Shader 编译发生在打包阶段(Cook),这时候:

  • Material Instance 的参数值还没有设置好
  • 即使设置了,同一个 Shader 可能被多个 MI 复用,每个 MI 的 y 值都不同
  • y 甚至可以通过 Blueprint / C++ 在运行时动态修改

所以编译器必须假设 y 是任意值 ,走最通用的 pow() 实现。


这也解释了为什么 Parameter 不能太多

每个 Scalar Parameter 不仅占一个 Uniform 槽位,还会阻止编译器优化:

复制代码
Power(x, 0.5)    → 编译器直接替换成 Sqrt(x),1 条指令
Power(x, y)      → 必须用 pow() 通用实现,8-12 条指令
  (即使 y 默认值就是 0.5 也没用,除非你把 Parameter 改成字面量)

这个差值不是 Power 节点本身的问题,而是常量 vs 变量的根本鸿沟------编译器无法跨越编译期和运行时的边界做优化。

常量 等价结果 优化特点 你看到的趋势
(1,1,1) Texture.rgb 整个 Multiply 是恒等操作,直接删掉 最低,约 13
(0,0,0) float3(0,0,0) 结果完全是黑色常量,理论上贴图采样依赖也可删除 最强优化
(5,1,1) (Texture.r*5, Texture.g, Texture.b) G/B * 1 被省,只有 R 需要缩放 约 14
(5,25,1) (Texture.r*5, Texture.g*25, Texture.b) B * 1 被省,R/G 缩放可能打包处理 约 14
(5,25,0) (Texture.r*5, Texture.g*25, 0) B * 0 让蓝通道变常量,蓝通道依赖死掉 可降到约 13
(5,25,5) RGB 都要乘非 1 常量 没有通道能原样通过或死掉 约 15
(5,5,5) Texture.rgb * 5 虽然三个系数一样,但 RGB 三个通道都必须缩放 约 15

关键总结:

复制代码
* 1:省掉乘法,但通道还活着
* 0:结果变常量,通道依赖可能死掉
全 1:整个 Multiply 节点消失
全 0:Multiply 结果变纯常量,甚至贴图依赖也可能消失
全非 1:RGB 都要参与缩放,代价最高
相同非 1,比如 5,5,5:不是免费,仍然要缩放 RGB
相关推荐
洋就在江州7 小时前
gitlab-cicd 离线集成——springboot-cicd (非docker形式,shell形式)
java·spring boot·后端·ci/cd·gitlab·gitlab-runner
Nebula_g7 小时前
JavaSE加强:线程Thread(线程安全重点)
java·开发语言·jvm·算法·javase·技术栈
令狐少侠20117 小时前
centos7 下,使用docker 部署IOT 调试平台,ThingsBoard 并完美启动
java·spring boot·iot
小灰灰搞电子7 小时前
Rust+Slint 实现一个终端软件源码分享(半成品)
开发语言·rust
大鹏说大话7 小时前
C++ STL 容器怎么选?vector、list、map、unordered_map 对比
开发语言·c++·list
JAVA面经实录9177 小时前
Java高级后端 · 全套面试通关手册(线上故障排查)
java·jvm·面试
IT_Octopus7 小时前
【零基础入门 LLM 开发 · Day 11】:ChatOpenAI vs init_chat_model——一行换供应商
java·前端·javascript
宇卿.7 小时前
C#语句:
开发语言·c#
ComPDFKit7 小时前
用 ComPDF DocSlight 提取 PDF 表格:三种样本实测与 Python 接入
开发语言·python·pdf·pdf表格提取
Wang's Blog8 小时前
Java 中间件之 RabbitMQ 快速入门: MQ 常见技术选型对比
java·中间件·java-rabbitmq