跳到主要内容
腾讯题库 · Q28

原题 Q28 · 当前收录 27 / 49

学习状态 未开始

材质参数预览面板

工具与管线 editor · preview 对应课程:资产与工具链

面试官问

PDF 第 60 页

请说明你如何使用 Unity Editor 扩展开发“材质参数预览面板”,让美术可实时调整 Shader 参数。(必问题,结合经历)

学习进度

0/9 已勾

只保存在这台浏览器;勾满 9 项即视为本题完成。

先把题目说成人话

美术正在夜晚的战斗场景里调整一副骑士盔甲。火把在晃,人物在动,镜头也在转。她把盔甲调亮了一点,却无法判断变化来自材质,还是来自刚好扫过来的火光。

这题要做的,是在引擎编辑器(Unity Editor)里准备一张安静的材质工作台:固定模型、灯光、相机和曝光,让美术拖动参数以后立刻看到唯一对应的画面变化。试调时不能污染项目中的原材质,确认以后才能写回,而且写错了还必须能够撤销(Undo)。

这是虚构教学故事,不是个人项目经历。

场景:先让问题变得看得见

美术打开一个独立窗口。窗口中央只有一顶静止的头盔:相机不动,灯光不动,背景和曝光也不动。左边保留头盔原来的样子,右边显示正在试调的结果。

(右脑)画面:美术拖动“光滑程度”,右边头盔上的高光立刻从一大片朦胧白光收紧成清楚的亮线;左边头盔仍保持原样。她换成一件全息材质,原来的金属旋钮随即消失,窗口重新出现扫描线速度和边缘发光。她把发光拉得过强,点击取消,右边的试调结果整个消失,项目里的原材质没有留下变化。第二次调好以后,她点击应用,盔甲才真正换上新效果;随后按下撤销,又能完整回到应用前。整个过程中,窗口一直像一张安静的实验桌:一次动作只产生一个看得见的后果。

(左脑)对表:固定相机、灯光、模型、背景和曝光,是为了让两次观察具有可比性。控件随当前着色器(Shader)的属性定义生成,而不是预先手写。窗口打开时复制源材质得到临时材质(Temporary Material);拖动只改临时副本并重绘预览。取消会销毁副本;应用前先记录撤销,再把确认过的差异一次写回源材质。这里观察到的是“受控环境中的参数变化”,不能据此推出真实关卡中的最终画面一定相同。

小明:先形成一个完整猜测

小明先在编辑器窗口(EditorWindow)里手写颜色、金属度、光滑度和法线强度四个控件。美术拖动光滑度,头盔确实立即变亮,看起来已经完成了“实时预览”。

但她换成全息着色器以后,窗口仍然显示金属度和法线强度;真正需要的扫描线速度与边缘发光反而无处可调。更糟的是,小明让控件直接修改共享材质,鼠标每动一下,场景中两百名共用它的骑士都一起变化。这个失败留下两条证据:控件不能靠工具作者猜,试调也不能直接写进原件。

小红:把猜测放回现实检查

小红让窗口先读取当前着色器公开的属性。遇到颜色就生成颜色选择器,遇到有上下限的数值就生成滑杆,遇到纹理就生成纹理槽,遇到开关就生成勾选框。美术切换着色器,旧控件被清走,新控件根据新属性重新生成。

她随后复制一份源材质,让预览头盔只使用这份副本。她先只接通光滑度:拖动时,副本改变,预览重绘,源材质数值和游戏场景都不动。等这条最短链路得到证明后,她才继续接颜色、纹理、关键字和其他属性。于是“实时”终于只代表反馈立即出现,不再代表项目资产被持续改写。

我:用检查结果修正模型

我补上最后两道安全门。

第一道是明确的应用事务:点击应用以后,工具先对源材质建立撤销记录(Undo),再把临时副本中由本工具负责的差异一次性写回。取消只销毁副本;关闭窗口还必须释放临时相机、灯光、网格和材质。工具不能在每次拖动时制造一长串资产修改与保存操作。

第二道是真实场景回归。固定预览只能证明“在同一盏灯下,这个参数造成了什么变化”,不能证明它在夜间关卡、不同渲染管线、后处理和运行时脚本下仍然正确。美术确认预览以后,还要把材质放回项目真正使用它的场景验收。

(右脑)画面修正:现在窗口不再像一排直接连着仓库的危险旋钮。它先为原材质做一件可丢弃的试穿样衣,让所有尝试发生在固定灯光的预览台上;满意时才打开仓库,把确认过的差异写回,并留下一张能够返回修改前的票。预览解决“看清一次变化”,真实场景解决“这份结果能不能使用”,两次检查不能互相代替。

(左脑)严格对表:用着色器属性查询接口枚举名称、类型、范围、隐藏标记和属性特征;普通控件可由界面工具包(UI Toolkit)生成,复杂属性绘制可复用材质编辑器(MaterialEditor),旧版兼容时才评估着色器工具接口(ShaderUtil)。工具配置可通过序列化对象(SerializedObject)绑定,着色器参数仍由材质接口读写。预览工具(PreviewRenderUtility)持有固定相机、灯光和网格,临时材质变化后只触发重绘。应用前调用 Undo.RecordObject,再一次写回;取消与窗口关闭时清理临时资源。最后检查着色器切换、编译失败、纹理丢失、撤销与重做、关闭重开,并回到真实运行场景确认渲染管线、色彩空间、关键字和脚本覆盖。

你的公开网站能够证明你开发过自定义编辑器工具,例如网格化预制体查看器;它不能代替你自己提供这款材质预览面板的真实经历。这里若要结合经历,只能引用已有记录中的编辑器扩展经验,再明确说明本题中的材质面板是设计方案。

老师解惑

  • 属性从哪里来:当前版本优先用公开的 Shader.GetProperty* 系列读取着色器属性;复杂的自定义绘制不能只凭数值类型猜测。
  • 临时副本:用 new Material(sourceMaterial) 得到试调副本,预览对象使用副本,项目资产在应用前保持不变。
  • Undo 与保存:Undo.RecordObject 必须发生在写回源材质之前;是否立即保存资产,应放在明确的应用边界,而不是每次拖动时执行。
  • 预览不是最终画面:PreviewRenderUtility 提供稳定、可比较的观察环境;项目场景负责最后的运行时验收。

工具分工

  • EditorWindow + UI Toolkit:承载窗口,并根据当前材质生成相应控件。
  • Shader 属性接口 + MaterialEditor:读取属性定义,处理普通属性与复杂绘制语义。
  • 临时 Material + PreviewRenderUtility:隔离试调,并在固定环境中立即重绘结果。
  • SerializedObject + Undo:管理工具配置,并把一次正式应用做成可撤销事务。
  • 真实游戏场景:确认关键字、渲染管线、曝光、后处理和运行时覆盖后的最终结果。

记忆钩子

属性从 Shader 长出来,预览在固定环境里发生,每次真正写回都必须能 Undo。

这是教学场景,不是目标项目的真实捕获或个人经历。

下一步:验证这条因果

Shader 属性元数据怎样生成控件,并在固定 A/B 中区分临时 Material、资产写回、MaterialPropertyBlock、多选与 Undo。

教学边界:它不是实际 Unity EditorWindow,不会修改 Material,也不能证明运行时 Shader、SRP Batcher 或目标设备性能。

进入教学 Lab:「Unity 材质预览:控件来自 Shader,写回必须说清对象」