You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Three.js ObjectLoader导入Blender场景的颜色纹理位置问题排查

问题分析与解决方案

看起来你遇到的问题大概率是代码逻辑错误+Blender导出设置不当共同导致的,咱们一步步拆解解决:

一、代码里的几个明显问题

1. 错误包裹加载后的模型

你写了mesh = new THREE.Mesh(loadedObj);,但loadedObj本身就是Three.js能直接识别的Object3D/Group对象,不需要再用Mesh包裹它——这会直接破坏模型的层级结构,导致位置、材质全部混乱。直接删掉这行代码就行。

2. 相机视锥体范围太小

你的相机far值设为10,如果Blender里的场景尺寸超过10个单位,物体就会被裁切掉或者显示异常。把far调大,比如改成1000:

camera = new THREE.PerspectiveCamera(70, WIDTH / HEIGHT, 1, 1000);

3. 光照不足导致颜色异常

仅用AmbientLight虽然能照亮场景,但如果Blender里用的是PBR材质或者依赖方向光的材质,单一环境光会让颜色显得灰暗、失真。建议添加一个方向光辅助:

function initLights() {
  var ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
  scene.add(ambientLight);
  
  // 添加方向光,模拟太阳光
  var directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
  directionalLight.position.set(5, 10, 7.5);
  scene.add(directionalLight);
}

二、Blender导出的关键注意事项(这是核心!)

很多新手忽略Blender导出的细节,这往往是模型显示异常的根源:

1. 必须使用Three.js官方导出插件

确保你在Blender里安装了Three.js Exporter(Blender 2.8+可以在插件市场搜索安装),不要用默认的JSON导出,要选择Three.js格式导出。

2. 导出前的模型准备

  • 给所有物体应用变换:选中所有物体,按Ctrl+A,依次选择位置、旋转、缩放——如果不应用,导出后的模型会带有隐藏的变换数据,在Three.js里位置、大小完全不对。
  • 检查平面的UV展开:如果平面没有正确UV展开,即使赋予了纹理,导出后也无法显示。在Blender里进入编辑模式,按U选择合适的UV展开方式(比如智能UV投影)。

3. 导出设置要点

  • 勾选Include Materials和Include Textures:不勾选的话,材质和纹理根本不会被导出,自然显示异常。
  • 坐标转换:Blender是Z轴向上,Three.js是Y轴向上,导出时一定要勾选Convert to Three.js Coordinate System,否则模型会整体旋转90度,位置完全错乱。
  • 纹理路径设置:选择Relative Path(相对路径),确保纹理文件和导出的city.json在同一目录下,否则Three.js找不到纹理文件,平面就会显示缺失纹理的状态。

三、修正后的完整代码示例

var scene, camera, renderer;
var WIDTH = window.innerWidth;
var HEIGHT = window.innerHeight;

function init() {
  scene = new THREE.Scene();
  initCamera();
  initLights();
  initRenderer();
  document.body.appendChild(renderer.domElement);
  // 监听窗口大小变化
  window.addEventListener('resize', onWindowResize, false);
}

function initCamera() {
  camera = new THREE.PerspectiveCamera(70, WIDTH / HEIGHT, 1, 1000);
  camera.position.set(0, 3.5, 5);
  camera.lookAt(scene.position);
}

function initRenderer() {
  renderer = new THREE.WebGLRenderer({ antialias: true });
  renderer.setSize(WIDTH, HEIGHT);
  // 开启阴影(如果需要)
  renderer.shadowMap.enabled = true;
}

function initLights() {
  var ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
  scene.add(ambientLight);
  
  var directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
  directionalLight.position.set(5, 10, 7.5);
  directionalLight.castShadow = true;
  scene.add(directionalLight);
}

// 加载模型
var loader = new THREE.ObjectLoader();
loader.load('./city.json', function(loadedObj) {
  // 直接添加加载后的对象,不需要再包裹Mesh
  scene.add(loadedObj);
  
  // 可以在这里调试单个物体
  console.log(loadedObj.getObjectByName("plane"));
  console.log(loadedObj.getObjectByName("building1"));
});

function onWindowResize() {
  WIDTH = window.innerWidth;
  HEIGHT = window.innerHeight;
  camera.aspect = WIDTH / HEIGHT;
  camera.updateProjectionMatrix();
  renderer.setSize(WIDTH, HEIGHT);
}

function render() {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
}

init();
render();

按照上面的步骤调整后,应该能解决颜色、纹理、位置的问题。如果还有异常,可以打开浏览器控制台看是否有纹理加载失败的报错,或者检查Blender里的材质是否正确设置。

内容的提问来源于stack exchange,提问作者DaChoj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:22:57