Three.js报错:THREE.MeshFaceMaterial已移除,求替代方案
解决Three.js中
THREE.MeshFaceMaterial已移除的报错问题 Hey Mike,我看到你在给立方体(其实是做天空盒)贴纹理的时候碰到了这个报错,这个问题在Three.js的版本更新里很常见,我马上帮你搞定它!
问题原因
Three.js从r125版本开始就正式移除了THREE.MeshFaceMaterial类,官方明确说明直接使用材质数组就能替代它的功能——原来你用MeshFaceMaterial包裹材质数组的操作,现在完全不需要了。
具体修改步骤
移除
MeshFaceMaterial的包装
你原来代码里的这两行:var cubeMaterial = new THREE.MeshFaceMaterial(cubeMaterials); var cube = new THREE.Mesh(geometry, cubeMaterial);直接改成:
// 直接将材质数组传给Mesh,无需MeshFaceMaterial包装 var cube = new THREE.Mesh(geometry, cubeMaterials);(可选但推荐)更新几何体名称
另外注意THREE.CubeGeometry在新版本里已经被重命名为THREE.BoxGeometry了,虽然旧名称暂时还能兼容,但换成新名称更符合当前的API规范:// 替换CubeGeometry为BoxGeometry var geometry = new THREE.BoxGeometry(10000, 10000, 10000);
修改后的完整代码
<script src="js/three.js"></script> <script src="js/OrbitControls.js"></script> <script src="js/ParallaxBarrierEffect.js"></script> <script> (function(){var script=document.createElement('script');script.onload=function(){var stats=new Stats();document.body.appendChild(stats.dom);requestAnimationFrame(function loop(){stats.update();requestAnimationFrame(loop)});};script.src='//rawgit.com/mrdoob/stats.js/master/build/stats.min.js';document.head.appendChild(script);})() var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); var renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); window.addEventListener('resize', function () { var width = window.innerWidth; var height = window.innerHeight; renderer.setSize(width, height); camera.aspect = width / height; camera.updateProjectionMatrix(); }); //var effect = new THREE.ParallaxBarrierEffect(renderer); //effect.setSize(window.innerWidth, window.innerHeight); controls = new THREE.OrbitControls(camera, renderer.domElement) /* var loader = new THREE.ObjectLoader(); loader.load ( 'models/skull.json', function(object) { scene.add(object); } ); */ // 替换CubeGeometry为BoxGeometry var geometry = new THREE.BoxGeometry(10000,10000,10000); var cubeMaterials = [ new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('skybox/right.png'), side: THREE.DoubleSide}), // RIGHT SIDE new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('skybox/left.png'), side: THREE.DoubleSide}), // LEFT SIDE new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('skybox/top.png'), side: THREE.DoubleSide}), // TOP SIDE new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('skybox/bottom.png'), side: THREE.DoubleSide}), // BOTTOM SIDE new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('skybox/front.png'), side: THREE.DoubleSide}), // FRONT SIDE new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('skybox/back.png'), side: THREE.DoubleSide}) // BACK SIDE ]; // 直接使用材质数组创建Mesh,无需MeshFaceMaterial var cube = new THREE.Mesh(geometry, cubeMaterials); scene.add(cube); camera.position.z = 3; var ambientLight = new THREE.AmbientLight(0xFFFFFF, 0.3); scene.add(ambientLight); var light1 = new THREE.PointLight(0xFF0040, 4, 5); //scene.add(light1); var light2 = new THREE.PointLight(0x0040FF, 2, 5); //scene.add(light2); var light3 = new THREE.PointLight(0x80FF80, 4, 5); //scene.add(light3); var directionalLight = new THREE.DirectionalLight(0xFFFFFF, 1); directionalLight.position.set(0,1,0); //scene.add(directionalLight); var spotLight = new THREE.SpotLight(0xFF45F6, 200); spotLight.position.set(0,3,3); //scene.add(spotLight); var update = function() { //cube.rotation.x += 0.01; //cube.rotation.z += 0.005; var time = Date.now() * 0.0005; light1.position.x = Math.sin(time + 0.7) * 30; light1.position.x = Math.cos(time + 0.5) * 40; light1.position.x = Math.cos(time + 0.3) * 30; light2.position.x = Math.cos(time + 0.3) * 30; light2.position.x = Math.sin(time + 0.5) * 40; light2.position.x = Math.sin(time + 0.7) * 30; light3.position.x = Math.sin(time + 0.7) * 30; light3.position.x = Math.cos(time + 0.3) * 40; light3.position.x = Math.sin(time + 0.5) * 30; }; var render = function() { renderer.render(scene, camera); }; var GameLoop = function() { requestAnimationFrame(GameLoop); update(); render(); }; GameLoop(); </script>
这样修改后,你的天空盒应该就能正常显示六个面的纹理了,再也不会出现那个API移除的报错啦!
内容的提问来源于stack exchange,提问作者Mike Bannon
相关产品推荐
相关产品推荐

