在 SceneView 里,几何体是编辑器运行时创建的基础模型,例如立方体、球体、圆柱、圆锥、圆环和平面。用户反馈“几何体材质用不上”时,真正的问题通常发生在材质面板链路:几何体能渲染,也能在模型 tab 调整颜色和金属度,但材质 tab 找不到材质目标,材质预设也无法稳定应用。
外部 GLB、FBX、OBJ 模型会从加载器里带出材质名称和 mesh 信息;运行时几何体由代码创建,默认只有一个 THREE.MeshStandardMaterial。如果没有给这个材质补上稳定名称和元信息,材质系统就无法把 UI 里的“材质列表”和画布里的 Mesh.material 对上。
一、问题现象
- 新增几何体后,模型 tab 里的颜色、金属度、粗糙度可以调整。
- 切到材质 tab,材质列表为空,用户无法选择要替换的材质。
- 点击材质预设时提示先选择材质,几何体没有可选项。
- 同样的材质预设在外部模型上可用,在几何体上表现不一致。
这些现象说明渲染层有材质,编辑器数据层缺少“材质索引”。
二、外部模型和几何体的差异
外部模型加载完成后,编辑器会遍历 mesh,收集每个材质的名称,并生成 materialsMeta:
model.materialsMeta = {
CarPaint: { name: 'CarPaint', meshName: 'Body' },
Glass: { name: 'Glass', meshName: 'Window' }
}
材质 tab 正是依赖这份数据渲染列表。几何体创建时如果只写了下面这段代码,面板就拿不到材质条目:
const material = new THREE.MeshStandardMaterial({
color: new THREE.Color('#6366f1'),
metalness: 0.3,
roughness: 0.5
})
const mesh = new THREE.Mesh(geometry, material)
这段代码能让几何体出现在画布里,但没有 material.name,也没有 model.materialsMeta。材质面板自然无法知道“这个几何体有一个可编辑材质”。
三、根因:缺少默认材质目标
几何体材质链路需要满足三个条件:
| 条件 | 作用 |
|---|---|
material.name | 让预览和覆盖逻辑能按名称找到目标材质 |
model.materialsMeta | 让材质 tab 能显示“材质列表” |
| 默认选中目标 | 让几何体未手动选材质时也能应用材质预设 |
缺少任意一个条件,用户都会觉得“材质用不上”。
四、修复:给几何体补默认材质
创建几何体时,给材质一个稳定名称,并同步写入 materialsMeta:
const material = new THREE.MeshStandardMaterial({
color: model.material?.color ? new THREE.Color(model.material.color) : new THREE.Color('#6366f1'),
metalness: model.material?.metalness ?? 0.3,
roughness: model.material?.roughness ?? 0.5
})
material.name = '默认材质'
model.materialsMeta = {
默认材质: {
name: '默认材质',
meshName: model.name || '几何体'
}
}
这样几何体在材质 tab 中会显示一个“默认材质”条目,后续材质预设和覆盖编辑都能按同一套逻辑工作。
五、材质预设的兜底逻辑
为了减少操作成本,几何体没有手动选择材质时,可以自动把预设应用到默认材质:
const geometryDefaultMaterialName = '默认材质'
function applyMaterialPreset(preset) {
if (!selectedMaterialName.value) {
if (selectedModel.value.geometryType) {
selectedMaterialName.value = geometryDefaultMaterialName
} else {
ElMessage.warning('请先在材质列表中选择要替换的材质')
return
}
}
modelStore.updateModelMaterialOverride(
selectedModel.value.id,
selectedMaterialName.value,
preset.patch
)
}
外部模型仍要求用户先选材质,因为它可能有多个材质;几何体只有一个默认材质,可以直接兜底。
六、模型 tab 和材质 tab 的职责
修复过程中还需要明确两个面板的职责:
- 模型 tab:处理模型级属性,例如颜色、金属度、粗糙度、透明度、贴图、反射强度、缩放、位置和旋转。
- 材质 tab:处理材质槽位,例如材质列表、材质预设、单个材质覆盖编辑。
几何体既能在模型 tab 作为整体模型编辑,也能在材质 tab 作为一个拥有“默认材质”的模型编辑。这样用户不需要理解内部数据结构,也能得到一致的操作结果。
七、排查清单
几何体材质异常时,可以按下面顺序排查:
| 检查点 | 确认内容 |
|---|---|
| 几何体标记 | model.geometryType 是否存在 |
| 材质名称 | mesh.material.name 是否为稳定值,例如“默认材质” |
| 材质元信息 | model.materialsMeta 是否包含默认材质 |
| 预设目标 | 未选材质时是否自动落到默认材质 |
| 预览事件 | preview-model-material 是否带上正确的 modelId 和 materialName |
八、结论
几何体材质用不上的核心原因是运行时创建的 Mesh 缺少材质索引信息。渲染层有材质,编辑器层没有“可选材质”的数据,材质 tab 就无法工作。
稳定方案是为几何体补齐 material.name、materialsMeta 和材质预设默认目标。补齐这三项后,几何体就能和外部模型共用同一套材质列表、材质预设和覆盖编辑链路。