模型无法在three.js上渲染

时间:2019-12-09 08:46:20

标签: three.js

我是Three.js的新手。我试图使用示例中的STLLoader加载STL模型。我要加载的model是艾菲尔铁塔模型。我下载了STL文件,该文件为ASCII格式,大小约为33 MB。我有以下设置来显示模型:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>My first three.js app</title>
        <style>
            body { margin: 5% auto; }
            canvas { width: 80%; height: 80% }
            #progress {
                margin-bottom: 2%;
                min-width: 50%;
            }
        </style>
        <script src="js/three.js"></script>
        <script src="js/STLLoader.js"></script>
    </head>
    <body>
        <div id="progress"></div>
        <script>
            // window properties
            const windowWidth = window.innerWidth;
            const windowHeight = window.innerHeight;

            // camera properties
            const FOV = 35;
            const ASPECT_RATIO = windowWidth / windowHeight;
            const NEAR = 0.1;
            const FAR = 1000;

            // scene settings
            const SCENE_BKG = new THREE.Color("rgb(220,220,220)");

            const scene = new THREE.Scene();
            scene.background = SCENE_BKG;

            const camera = new THREE.PerspectiveCamera( FOV, ASPECT_RATIO, NEAR, FAR );

            const STLLoader = new THREE.STLLoader();
            STLLoader.load('./sample_stl/Eiffel_tower_sample.STL', function(geometry) {
                console.dir(geometry);
                const materials = [];
                const nGeometryGroups = geometry.groups.length;

                let colorMap = []; // Some logic to index colors.
                let material;

                // create a random colorMap
                let startColor = 0x010101;
                let clr = startColor;
                let count = 0;
                while (count++ < nGeometryGroups) {
                    colorMap.push(clr);
                    clr = ( parseInt(clr, 16) + startColor ).toString();
                }
                console.log(colorMap);

                for (let i = 0; i < nGeometryGroups; i++) {

                        material = new THREE.MeshPhongMaterial({
                            color: colorMap[i],
                            wireframe: false
                        });

                }

                materials.push(material);
                const mesh = new THREE.Mesh(geometry, materials);
                console.dir(mesh);
                scene.add(mesh);
                // should i call animate here?


            }, function (xhr) {
                // show progress here
                progressBar.innerHTML = `<span style="color: green;">${(xhr.loaded/xhr.total) * 100}%</span> have been loaded`; 
            }, function(err) {
                console.error('[!] Fatal Error: Could not load model');
                console.error(err);
            });
            const renderer = new THREE.WebGLRenderer();
            renderer.setSize( windowWidth, windowHeight );

            const progressBar = document.querySelector('#progress');
            document.body.appendChild( renderer.domElement );

            const animate = () => {
                requestAnimationFrame(animate);
                renderer.render(scene, camera);
            };
            camera.position.set(0, 0, 10);
            animate();
        </script>
    </body>
</html> 

我不确定两件事。首先,colorMap数组是什么?我查看了MeshPhongMaterial类文档,发现它是十六进制颜色值。我直接从STLLoader示例文件夹here复制了此代码。我发现了一种快速的技巧,可以生成一些十六进制的颜色并填充colorMap数组(一个空数组会引发错误)。其次,我应该在哪里调用animate()函数?我尝试在modelLoaded处理程序内部以及外部调用它,唯一的区别是在处理程序内部调用了Violation: handler took 500ms。我检查了Firefox和Chromium上的“网络”选项卡,以查看STL文件是否已正确加载。我还在控制台中打印了Mesh对象,如下所示:

Mesh
castShadow: false
children: []
drawMode: 0
frustumCulled: true
geometry: BufferGeometry
attributes: {position: Float32BufferAttribute, normal: Float32BufferAttribute}
boundingBox: null
boundingSphere: Sphere {center: Vector3, radius: 71.76963889659893}
drawRange: {start: 0, count: Infinity}
groups: [{…}]
index: null
morphAttributes: {}
morphTargetsRelative: false
name: ""
type: "BufferGeometry"
userData: {}
uuid: "28A4B269-2828-477D-9C6D-5C9A30E95A7F"
_listeners: {dispose: Array(1)}
drawcalls: (...)
id: 7
offsets: (...)
__proto__: EventDispatcher
layers: Layers
mask: 1
__proto__: Object
material: Array(1)
0: MeshPhongMaterial {uuid: "1E33986A-A979-49C0-ADF5-823CACC6F3AA", name: "", type: "MeshPhongMaterial", fog: true, blending: 1, …}
length: 1
__proto__: Array(0)
matrix: Matrix4
elements: Array(16)
0: 1
1: 0
2: 0
3: 0
4: 0
5: 1
6: 0
7: 0
8: 0
9: 0
10: 1
11: 0
12: 0
13: 0
14: 0
15: 1
length: 16
__proto__: Array(0)
__proto__: Object
matrixAutoUpdate: true
matrixWorld: Matrix4
elements: Array(16)
0: 1
1: 0
2: 0
3: 0
4: 0
5: 1
6: 0
7: 0
8: 0
9: 0
10: 1
11: 0
12: 0
13: 0
14: 0
15: 1
length: 16
__proto__: Array(0)
__proto__: Object
matrixWorldNeedsUpdate: false
name: ""
parent: Scene
autoUpdate: true
background: Color {r: 0.8627450980392157, g: 0.8627450980392157, b: 0.8627450980392157}
castShadow: false
children: [Mesh]
fog: null
frustumCulled: true
layers: Layers {mask: 1}
matrix: Matrix4 {elements: Array(16)}
matrixAutoUpdate: true
matrixWorld: Matrix4 {elements: Array(16)}
matrixWorldNeedsUpdate: false
name: ""
overrideMaterial: null
parent: null
position: Vector3 {x: 0, y: 0, z: 0}
quaternion: Quaternion {_x: 0, _y: 0, _z: 0, _w: 1, _onChangeCallback: ƒ}
receiveShadow: false
renderOrder: 0
rotation: Euler {_x: 0, _y: 0, _z: 0, _order: "XYZ", _onChangeCallback: ƒ}
scale: Vector3 {x: 1, y: 1, z: 1}
type: "Scene"
up: Vector3 {x: 0, y: 1, z: 0}
userData: {}
uuid: "3F9C4993-4CB4-4541-9C64-34FCBB12B1E3"
visible: true
_listeners: {dispose: Array(2)}
eulerOrder: (...)
id: 4
modelViewMatrix: Matrix4 {elements: Array(16)}
normalMatrix: Matrix3 {elements: Array(9)}
useQuaternion: (...)
__proto__: Object3D
position: Vector3 {x: 0, y: 0, z: 0}
quaternion: Quaternion {_x: 0, _y: 0, _z: 0, _w: 1, _onChangeCallback: ƒ}
receiveShadow: false
renderOrder: 0
rotation: Euler {_x: 0, _y: 0, _z: 0, _order: "XYZ", _onChangeCallback: ƒ}
scale: Vector3 {x: 1, y: 1, z: 1}
type: "Mesh"
up: Vector3 {x: 0, y: 1, z: 0}
userData: {}
uuid: "72BA29AF-F939-45F8-869A-D074E6696D7F"
visible: true
eulerOrder: (...)
id: 10
modelViewMatrix: Matrix4 {elements: Array(16)}
normalMatrix: Matrix3 {elements: Array(9)}
useQuaternion: (...)
__proto__: Object3D

这是打印的网格对象。我不确定有什么问题,如果有人可以向我解释如何使用colorMap属性,并在animate函数调用范围内给我一个明确的答案,我将很高兴。

编辑 添加了小提琴here

1 个答案:

答案 0 :(得分:1)

  

首先,什么是colorMap数组?

示例中的代码假定模型的几何图形具有多个groups。如果是这样,则可以将多个材质分配给单个3D对象。但是,这不是强制性的。如果您只想使用一种颜色,请执行以下操作:

const material = new THREE.MeshPhongMaterial( { color: 0x0000ff } );
const mesh = new THREE.Mesh( geometry, material );
  

第二,我应该在哪里调用animate()函数?

three.js示例通常具有一个init()和一个animate()函数。这意味着您要在初始化场景(创建相机,渲染器,灯光等)之后立即开始动画制作。您也可以在应用程序中执行此操作,但是STL文件将在其加载和解析进度完成后立即弹出。另外,您也可以在onLoad()回调中开始动画制作。这实际上取决于您的用例(因此没有对与错)。

three.js R111

相关问题