img2threejs 这类单图转三维流程,重建上限主要由原图是否含有可信深度线索决定;参数和提示词只能在这个上限内调整。判断顺序建议反过来:先在原图上找遮挡、接触阴影、地面接触点、线性透视这四类线索,能读出前后关系再谈重建;读不出的部分通常交给 Three.js 手工补做,不要指望模型猜对。
适用场景:只有一张图、又想得到能直接进 Three.js 的网格时,先做深度线索判读。操作动作:按遮挡、接触阴影、地面接触点、线性透视逐项判断,综合为强、弱、无三级。验证方式:把生成的模型放进带 OrbitControls 的场景绕一圈,看穿插、地面接触和背面是否穿帮。风险边界:分级只约束可接受的输出形态,不保证几何精度;判为「无」时,结果只能当造型参考。
找出图里能直接读出前后关系的线索
先把「感觉这张图挺立体」换成可指认的画面证据。下面四类线索都能在图上指出来;指不出来,就按缺失处理。
- 遮挡:前景物体边缘切断背景物体。判读方法是放大到边缘,看轮廓线是干净连续,还是被另一条轮廓截断;截断处就是前后关系成立的位置。遮挡层数越多,可读出的相对深度越可靠。
- 接触阴影:物体与支撑面贴合处的暗部,通常窄、暗、紧贴轮廓。判读方法是看底部有没有从边缘向外渐变的暗带;只有均匀投影、没有贴合暗部,多半是合成或后期加的假投影。
- 地面接触点:物体落在平面上的那一条线或那几个点。判读方法是看交界线走向与画面地平线是否一致;交界线漂浮、悬空或根本没有交点,地面就定不下来。
- 线性透视:桌沿、墙脚、地砖缝这类平行线向消失点收拢。判读方法是沿两条可见平行边延长,看是否交于同一点;能交于一点,相机高度与朝向可反推,地平面就能建。
给线索分级:强、弱、无
分级标准建议按「可判读性」而不是「好不好看」来定,四类线索各自记,再取综合等级:
- 强:该线索在画面上能直接指出位置,换个人看也能指出同一处,比如明确的截断轮廓、贴合暗部、可延长的透视线。
- 弱:线索存在但只能定性判断,位置有争议,比如阴影方向不一致、透视线只剩一条、交界线被遮住一半。
- 无:找不到该线索,或所有边都平行于画面、物体四周亮度一致,常见于纯色背景棚拍和平面插画。
三类以上为强记综合「强」;两强两弱、或一强多弱记「弱」;其余只剩弱和无的记「无」。三张图的判读示例:
- 室内实拍:桌面边缘遮住后方椅子腿,遮挡强;杯底与桌面有贴合暗部,接触阴影强;桌沿与地砖缝朝同一侧收拢,线性透视强;接地点清晰。综合判为强。
- 白背景产品图:主体轮廓完整但背后没有别的物体,遮挡无;底部只有一圈均匀投影、没有贴合暗部,接触阴影弱;背景无透视线,线性透视无;底边与画面平行、定不出地面,地面接触点弱。综合判为弱。
- 平面插画或抠图素材:所有元素挤在同一层,轮廓互不截断,亮度一致没有阴影,也没有可延长的平行线。综合判为无。
对照等级写下预期能重建到什么程度
把等级先翻译成「能接受什么、不能接受什么」,验收就不会跑偏。
| 等级 | 可接受的结果形态 | 不可接受的结果形态 | 验收动作 |
|---|---|---|---|
| 强 | 主体前后遮挡关系正确,接地点位置与图中一致,透视线方向一致 | 背面与内部凹槽无中生有,接触处出现明显穿插 | 绕场景一周看轮廓与接地点 |
| 弱 | 整体体块与比例对得上,正面主要面片可用 | 侧向厚度、景深层次、多物体相对距离被当成准确结果 | 回到正面视角与原图逐边对比 |
| 无 | 单层贴图或轻度挤出的浮雕式表达 | 任何三维位置关系与遮挡推导 | 只以正面视角使用,不做交互旋转 |
建议把这张表原样写进任务说明或验收单,下游按行对照,不要靠口头描述「差不多立体」。
列出图里注定要手动补做的部分
缺失侧面、地面延伸、材质通道这三块是单图重建后的固定欠账,提前写成清单比事后返工省事。模板可直接放进仓库当 checklist 使用:
{
"source": "single_image.png",
"depth_grade": "weak",
"manual_todo": {
"missing_sides": ["左侧面", "背面", "底部"],
"ground_extension": { "need": true, "contact_points": ["主物体底边"], "method": "平面 + 接触阴影补片" },
"material_channels": {
"map": "原图裁切后作为颜色贴图",
"roughnessMap": "原图不含,需人工指定",
"normalMap": "需重绘,或从高度信息挤出",
"alphaMap": "抠图残留的边缘需清理"
}
},
"verify": ["OrbitControls 绕场一周无穿插", "接地点与地面贴合", "正面视角与原图对齐"]
}
Three.js 侧的最小骨架,用来补地面延伸和材质通道,执行位置是加载重建模型之后:
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, innerWidth / innerHeight, 0.1, 100);
const renderer = new THREE.WebGLRenderer({ antialias: true });
document.body.appendChild(renderer.domElement);
// 地面延伸:用一个平面承接接触点,尺寸取包围盒的整数倍,避免物体悬在半空
const box = new THREE.Box3().setFromObject(model);
const size = box.getSize(new THREE.Vector3());
const ground = new THREE.Mesh(
new THREE.PlaneGeometry(size.x * 4, size.z * 4),
new THREE.MeshStandardMaterial({ color: 0xcccccc, roughness: 1 })
);
ground.rotation.x = -Math.PI / 2;
ground.position.y = box.min.y; // 与原图接地点对齐
scene.add(ground, model);
// 材质通道:颜色贴图沿用原图,粗糙度和法线单独给,不要指望原图提供
const mat = model.material ?? new THREE.MeshStandardMaterial();
if (mat.map) mat.map.colorSpace = THREE.SRGBColorSpace;
mat.roughness = 0.8;
if (renderer.info.render.triangles === 0) {
console.warn('模型为空或未加载成功,先排查资源路径再谈补面');
}
清单里每一项都要在场景里能指到对应对象:缺失侧面对应补的几何或背面挤出,地面延伸对应上面这个 Plane,材质通道对应 map、roughnessMap、normalMap 三张贴图的来源说明。指不到对象的条目,就是还没补完。
按分级决定直接转、先补图还是换图
- 强:直接转。取舍理由是四类线索同时可用,结果能支撑前后关系与接地点;动作是转换完立刻做一次绕场验收,穿插严重的局部拿到建模工具里修,而不是反复重跑参数。
- 弱:先补图再转。补图指给同一物体补一张侧面或俯视参考,或重拍时加一块地面、加一个光源制造贴合暗部;取舍理由是原图缺约束,补一张辅助参考比在 Three.js 里靠猜补侧面省事。补图后仍缺的部分,按上一节清单转手工补做。
- 无:换图,或明确降级为平面用法。取舍理由是这张图不含可判读的深度信息,继续调参数只会得到看着立体、实际到处穿帮的模型;如果业务只要正面展示,用平面贴图或轻度挤出即可,不要承诺可旋转的三维交互。
三种动作共用一套验证:加载后开 wireframe 看补面密度,用 OrbitControls 绕到侧后方,检查接地是否贴合、背面是否穿空,再切回正面视角与原图对轮廓。这三步过不去,说明分级给高了一档,应退回上一级重新处理。