使用 Three.js 加载 OBJ 模型时 MTLLoader 报错的解决方案

本文旨在解决在使用 Three.js 加载 OBJ 模型时,遇到的 `Uncaught TypeError: THREE.MTLLoader is not a constructor` 错误。通过分析问题原因,提供正确的模块导入方式,帮助开发者成功加载模型,并避免类似问题的再次发生。

在 Three.js 开发中,加载外部模型是一项常见的任务。当尝试使用 THREE.MTLLoader 加载包含材质的 OBJ 模型时,可能会遇到 Uncaught TypeError: THREE.MTLLoader is not a constructor 错误。这通常是由于模块导入方式不正确导致的。以下是解决此问题的详细步骤和注意事项。

问题分析

该错误表明 THREE.MTLLoader 未被正确定义,这意味着 JavaScript 无法找到 MTLLoader 构造函数。 这通常发生在使用了 ES 模块化的项目中,并且没有正确地导入 MTLLoader。

解决方案

  1. 确认文件路径

    首先,确保 MTLLoader.js 和 OBJLoader.js 文件确实存在于你指定的路径下,并且路径是正确的。 检查 HTML 文件中的

  2. 使用正确的 ES 模块导入方式

    如果你的项目使用了 ES 模块(即使用了 import 和 export),那么需要使用正确的导入语法。 MTLLoader 和 OBJLoader 是作为具名导出(named exports)提供的,因此需要使用花括号 {} 来导入。

    将以下代码:

    替换为:

    import { MTLLoader } from './js/libs/MTLLoader.js';
    import { OBJLoader } from './js/libs/OBJLoader.js';

    或者,如果你想将 MTLLoader 和 OBJLoader 绑定到 THREE 对象上(不推荐,但某些旧代码可能依赖这种方式),可以这样做:

    import * as THREE from 'three';
    import { MTLLoader } from './js/libs/MTLLoader.js';
    import { OBJLoader } from './js/libs/OBJLoader.js';
    
    THREE.MTLLoader = MTLLoader;
    THREE.OBJLoader = OBJLoader;
  3. 修改加载模型代码

    确保你的 loadModel 函数正确使用了导入的 MTLLoader。

    function loadModel(path, objName, mtlName) {
        var onProgress = function(xhr) {
            if (xhr.lengthComputable) {
                var percentComplete = xhr.loaded / xhr.total * 100;
                console.log(Math.round(percentComplete, 2) + '% downloaded');
            }
        };
        var onError = function(xhr) { };
    
        var mtlLoader = new MTLLoader(); // 使用导入的 MTLLoader
        mtlLoader.setPath(path);
    
        mtlLoader.load(mtlName, function(materials) {
            materials.preload();
            var objLoader = new OBJLoader(); // 使用导入的 OBJLoader
            objLoader.setMaterials(materials);
            objLoader.setPath(path);
    
            objLoader.load(objName, function (object) {
                object.position.x = 0;
                object.position.y = 0;
                object.position.z = 0;
                object.scale.set(0.2, 0.2, 0.2);
    
                scene.add(object);
    
            }, onProgress, onError);
        });
    }

完整示例

以下是一个完整的示例,展示了如何正确导入和使用 MTLLoader 和 OBJLoader:




    
    Three.js OBJ Loader Example
    


    

注意事项

  • 确保 Three.js 版本与 MTLLoader.js 和 OBJLoader.js 版本兼容。
  • 如果仍然遇到问题,检查浏览器的开发者工具控制台,查看是否有其他错误信息。
  • 确认你的 Web 服务器正确配置了 MIME 类型,以便正确加载 JavaScript 文件。

总结

Uncaught TypeError: THREE.MTLLoader is not a constructor 错误通常是由于 ES 模块导入方式不正确引起的。通过使用正确的 import 语句,可以解决此问题。 确保文件路径正确,并遵循 Three.js 官方文档提供的指导,可以避免类似错误的发生,并成功加载 OBJ 模型。