2.2 Blackboard 属性:把参数暴露给材质面板


2.2 Blackboard 属性:把参数暴露给材质面板

本节摘要:Blackboard 是图与外界之间的参数接口:属性暴露后出现在材质面板上,改值不需要重新编译。本节把属性类型、模式、参考名三个概念讲透,并把 1.2 节的渐变图升级成"颜色、渐变速度、方向都可调"的参数化版本。

从一个真实需求说起

想象一个常见的排期场景:场景里有一百个能量水晶,美术要求它们用同一个着色器,但每颗的颜色深浅、呼吸快慢不同。如果颜色写死在图里,你就得做一百张图——显然不对。正确的做法是把"变化的量"做成 Blackboard 属性,图只有一张,材质有一百个,每个材质填自己的值。

这个"变化与不变的分界线"就是属性设计的核心判断:所有实例共用的逻辑留在图里,逐实例不同的数据做成属性。

属性类型速览

Blackboard 加号下有一长串类型,日常真正高频使用的是下面这些。每种类型对应着色器里的一种数据结构,选对类型能避免后面连线的类型转换麻烦。

属性类型 用途 材质面板形态 注意点
Color 纯色、发光色 颜色选择器 默认带透明通道,注意 Alpha 值
Vector1 标量参数 滑条或数字框 设 Min Max 后变滑条,调参手感最好
Vector2 或 Vector4 坐标、偏移量 多字段输入 UV 平铺偏移常用 Vector2
Texture2D 贴图 贴图槽 需配合采样节点使用
Boolean 开关 勾选框 常配合关键字做分支
Gradient 渐变 渐变编辑器 内部按关键帧生成纹理采样

点击画布上的属性节点(或 Blackboard 里的条目),检查器里出现关键字段。默认值(Default)是新材质的初始值;模式(Mode)对 Color 属性可选 HDR——勾上后颜色亮度可以超过一,配合泛光后处理能做出"过曝发光",第 5 章全息案例会用到;参考名(Reference)是脚本访问用的内部名,见下文。

暴露与参考名:两个最容易误解的字段

暴露(Exposed)勾选框决定该属性是否出现在材质面板上。听起来"不暴露就没意义",其实不然:不暴露的属性会退化为编辑器内的常量(相当于图内默认值),用处是在你保留一个数值但同时想允许 C# 代码通过材质属性块在运行时覆盖它的场景。初学阶段建议全部保持暴露勾选,概念先简单化。

**参考名(Reference)**是脚本里用 material.SetFloat("参考名", 值) 访问时的字符串。Unity 自动生成的参考名带下划线前缀加哈希(形如 _Vector1_a1b2c),又长又不可读。只要这个图会被代码调用,就手动把参考名改成可读形式,比如 _DissolveAmount_OutlineWidth——脚本对接时你会感谢现在的自己。

图:属性从 Blackboard 到材质面板再到脚本的通路

图:属性从 Blackboard 到材质面板再到脚本的通路

实操:把渐变图参数化

回到 1.2 节的渐变图,做四个改动。改动一:添加 Color 属性命名 TopColor,默认浅黄,拖进画布接到 Lerp 的 B 端;同法添加 BottomColor 接 A 端。改动二:添加 Vector1 属性命名 GradientSpeed,Min 设 0、Max 设 10,先不接线——下一章讲 Time 节点时让它派上用场。改动三:把 UV 拆出的 G 接 T 的路径保持不变,保存。改动四:在场景里复制三个立方体,给它们各自的材质把 TopColor 调成不同颜色——三个物体同一张图、三种外观,参数化的价值一目了然。

顺手做一个对照实验:把 GradientSpeed 属性的暴露勾选去掉,保存后看材质面板——滑条消失了,但属性节点还在画布上。这个状态就是"图内常量",适合那种"暂时写死、以后可能开放"的中间态参数。

脚本怎么调用属性

给接手项目的程序留个底:属性暴露后,代码侧通过材质或属性块写入。下面这段脚本让物体的颜色在两个颜色间来回过渡(挂到任意物体上,把材质拖到字段里即可运行):

using UnityEngine; public class ColorPulse : MonoBehaviour { public Material targetMaterial; // 使用该图的材质 public Color colorA = Color.blue; // 一端的颜色 public Color colorB = Color.yellow; // 另一端的颜色 public float speed = 1f; // 过渡速度 void Update() { // 按参考名写属性,与 Blackboard 里的 Reference 字段一致 float t = Mathf.PingPong(Time.time * speed, 1f); targetMaterial.SetColor("_TopColor", Color.Lerp(colorA, colorB, t)); } }

跑起来后你在场景里会看到颜色随时间摆动——这就是"图定义逻辑、属性喂数据"的完整闭环。注意 SetColor 的第一个参数必须与参考名完全一致,大小写敏感;参考名没改过就用自动生成的长串,别凭感觉猜。

问题:属性数量多少算合适?

经验区间是三到八个。少于三个,效果往往缺乏可调性(比如只有颜色的渐变图,换个亮度需求就得改图);多于八个,材质面板变成考卷,使用者根本不知道哪个滑条管什么。超出的需求怎么办?把相关的参数合并:四个分离的颜色输入往往可以合并成"渐变两端加中点"三个;速度与幅度这类独立物理量保持独立,别为了凑数合并语义不同的参数。

滑条范围设计的两个细节

Min 与 Max 的取值决定了调参手感。细节一:范围要覆盖"合理使用域"而不是"数学合法域"——波高滑条给 0 到 1,美术不会去拖 500,但 0 到 500 的滑条每次微调都像抽签。细节二:默认值放在常用区间而不是区间中点:溶解进度默认 0(未溶解)比默认 0.5(半溶解)符合直觉。两个细节合起来一句话:滑条是给人用的,先想清楚谁在拖、拖到哪。

用属性做"效果开关"的陷阱

常见做法是把某个强度属性的默认值设为 0 来"关闭"效果——运行时零成本,看似完美。陷阱在于:图里那段计算仍然每次执行(乘以零还是乘法),并且美术可能随手把滑条拉起来,触发你从未测试过的状态。如果这个效果"开与关"是明确的二元状态,7.3 节的关键字才是正解;如果只是"弱到看不见",属性归零才是对的。两者的分界线是:关掉后那段节点链还该不该存在。

一张参数化图的验收清单

属性做完后过一遍验收:每个属性有可读的名字与合理的范围;默认值让物体在新建材质时就表现正常;脚本要用的属性已改参考名;材质面板上逐个拖动,效果响应方向与数值方向一致(拉大波高应该更浪而不是更平)。最后一条看似废话,但方向接反的属性在交付后才发现,返工的尴尬远大于检查的三分钟。

本节要点回顾

  • 属性即接口:共用逻辑留在图里,逐实例变化的数据做成属性。
  • 参考名要手动改:脚本对接靠 Reference 字段,命名规范一次做好。
  • 改值不重编译:属性赋值只是换参数,这是参数化工作流的性能前提。
  • 类型选对省事:标量配滑条、坐标配 Vector2、发光色开 HDR,类型决定手感。

参数已经可以调了,下一节我们把视线转向数据流的终点——主栈的块与端口,弄清 Alpha、Emission 这些端口分别通向渲染管线的什么机制。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U