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

如何使用THREE.js极简加载并显示MPD文件(LEGO LDraw打包文件)

如何使用THREE.js极简加载并显示MPD文件(LEGO LDraw打包文件)

嘿,我懂你想要一个去掉冗余GUI和预加载器的极简实现——原示例的那些附加功能确实容易让新手绕晕,我帮你把代码精简到最核心的加载显示逻辑,保证能稳定运行~

核心思路说明

我们只保留THREE.js加载MPD文件必需的组件:基础的场景、相机、渲染器,LDrawLoader加载器,还有OrbitControls方便你交互操作模型。去掉所有GUI、多模型切换、预加载进度条这些非必要功能,只聚焦在“加载并显示MPD模型”这件事上。

极简版代码实现

<!DOCTYPE html>
<html lang="en">
<head>
    <title>THREE.js 极简显示MPD模型</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <style>
        body { margin: 0; }
        canvas { display: block; }
    </style>
</head>
<body>
    <script type="importmap">
        {
            "imports": {
                "three": "../build/three.module.js",
                "three/addons/": "./jsm/"
            }
        }
    </script>

    <script type="module">
        import * as THREE from 'three';
        import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
        import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';
        import { LDrawLoader } from 'three/addons/loaders/LDrawLoader.js';
        import { LDrawConditionalLineMaterial } from 'three/addons/materials/LDrawConditionalLineMaterial.js';

        let camera, scene, renderer, controls;
        let model;
        // 替换成你的MPD文件路径
        const mpdFilePath = 'models/car.ldr_Packed.mpd';

        init();
        animate();

        function init() {
            // 创建渲染器并添加到页面
            renderer = new THREE.WebGLRenderer({ antialias: true });
            renderer.setPixelRatio(window.devicePixelRatio);
            renderer.setSize(window.innerWidth, window.innerHeight);
            renderer.toneMapping = THREE.ACESFilmicToneMapping;
            document.body.appendChild(renderer.domElement);

            // 创建相机
            camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000);
            camera.position.set(150, 200, 250);

            // 创建场景和环境光
            const pmremGenerator = new THREE.PMREMGenerator(renderer);
            scene = new THREE.Scene();
            scene.background = new THREE.Color(0xdeebed);
            scene.environment = pmremGenerator.fromScene(new RoomEnvironment()).texture;

            // 添加轨道控制器,方便交互旋转缩放
            controls = new OrbitControls(camera, renderer.domElement);
            controls.enableDamping = true;

            // 监听窗口大小变化
            window.addEventListener('resize', onWindowResize);

            // 加载MPD模型
            loadMPDModel();
        }

        function loadMPDModel() {
            const loader = new LDrawLoader();
            loader.setConditionalLineMaterial(LDrawConditionalLineMaterial);
            loader.smoothNormals = true;
            // 设置模型文件所在的基础路径
            loader.setPath('models/')
                .load(mpdFilePath, function (modelGroup) {
                    model = modelGroup;
                    // 转换LDraw坐标系到THREE.js坐标系:绕X轴旋转180度
                    model.rotation.x = Math.PI;
                    scene.add(model);

                    // 自动调整相机位置到合适视角
                    const bbox = new THREE.Box3().setFromObject(model);
                    const center = bbox.getCenter(new THREE.Vector3());
                    const size = bbox.getSize(new THREE.Vector3());
                    const radius = Math.max(size.x, size.y, size.z) * 0.5;

                    controls.target.copy(center);
                    controls.position0.set(-2.3, 1, 2).multiplyScalar(radius).add(center);
                    controls.reset();
                }, undefined, function (error) {
                    console.error('加载MPD文件出错:', error);
                });
        }

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

        function animate() {
            requestAnimationFrame(animate);
            controls.update(); // 启用阻尼需要更新控制器
            renderer.render(scene, camera);
        }
    </script>
</body>
</html>

关键注意事项

  • 路径配置:确保importmap里的three和three/addons/路径和你的项目结构匹配,同时mpdFilePath和loader.setPath()的路径要指向你存放MPD文件的正确位置。
  • 必需模块:别忘了引入LDrawLoader、LDrawConditionalLineMaterial这些LDraw相关的附加模块,还有OrbitControls用来交互操作模型。
  • 坐标系转换:LDraw的坐标系和THREE.js的不一样,必须添加model.rotation.x = Math.PI;才能让模型正确显示。

备注:内容来源于stack exchange,提问作者Adam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 16:44:28