Three.js中无法显示.jpg纹理问题求助
Three.js 纹理无法显示问题排查与解决方法
核心问题分析
你的代码里存在几个关键问题导致纹理无法正常显示:
- 缺少光照:
MeshLambertMaterial是受光照影响的材质,场景中没有添加任何光源时,材质会呈现全黑状态,纹理自然无法显示。 - 纹理加载异步未处理:直接在材质初始化时调用
TextureLoader.load(),纹理可能还未加载完成就已经开始渲染,导致纹理未生效。 - 材质参数干扰:设置了
color和emissive非默认值,会与纹理颜色混合,覆盖纹理效果。
分步解决
1. 添加场景光源
为场景添加基础照明,确保MeshLambertMaterial能被照亮:
// 添加环境光(提供基础全局照明) const ambientLight = new THREE.AmbientLight(0xffffff, 0.5); scene.add(ambientLight); // 添加方向光(模拟定向光源,增强明暗层次) const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8); directionalLight.position.set(5, 5, 5); scene.add(directionalLight);
2. 正确处理纹理加载(带错误回调)
统一创建TextureLoader实例,通过回调确保纹理加载完成后再更新材质,同时捕获加载错误:
// 初始化材质时先不设置map,避免异步加载导致的失效 const material = new THREE.MeshLambertMaterial({ color: 0xffffff, // 设为白色,避免干扰纹理原有颜色 emissive: 0x000000, // 关闭自发光,防止覆盖纹理 }); const material2 = new THREE.MeshLambertMaterial({ color: 0xffffff, emissive: 0x000000, side: THREE.DoubleSide, }); // 加载纹理并处理回调 const textureLoader = new THREE.TextureLoader(); textureLoader.load( 'trianglefabric.jpg', // 加载成功:更新材质并标记需要刷新 (texture) => { material.map = texture; material2.map = texture; material.needsUpdate = true; material2.needsUpdate = true; }, // 加载进度(可选) (xhr) => { console.log(`${(xhr.loaded / xhr.total * 100).toFixed(1)}% loaded`); }, // 加载错误:打印信息排查路径/文件问题 (error) => { console.error('纹理加载失败:', error); } );
3. 纹理适配调整(可选)
如果纹理显示拉伸或重复异常,可在加载成功回调中添加UV映射设置:
// 在加载成功回调内添加 texture.wrapS = THREE.RepeatWrapping; texture.wrapT = THREE.RepeatWrapping; texture.repeat.set(2, 2); // 根据几何体尺寸调整重复次数
4. 路径与权限确认
- 确保
trianglefabric.jpg与HTML文件处于同一目录,子目录需写清相对路径(如./assets/trianglefabric.jpg)。 - 检查Five Server的运行根目录是否正确,确保服务器能访问到图片文件。
修改后的完整代码
const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); gsap.to(".txt", {duration: 2, x:425}); const geometry = new THREE.BoxGeometry(3, 2, 2); const geometry2 = new THREE.SphereGeometry(1, 32, 32); const floorgeo = new THREE.PlaneGeometry(20, 20); // 初始化材质 const material = new THREE.MeshLambertMaterial({ color: 0xffffff, emissive: 0x000000, }); const material2 = new THREE.MeshLambertMaterial({ color: 0xffffff, emissive: 0x000000, side: THREE.DoubleSide, }); const wireframe = new THREE.MeshBasicMaterial({ color: 0xff0000, transparent: true, opacity: 0.5, wireframe: true, wireframeLinewidth: 3, }); const floor = new THREE.Mesh(floorgeo, material2); const cube = new THREE.Mesh(geometry, material); const sphere = new THREE.Mesh(geometry2, wireframe); scene.add(floor); scene.add(cube); scene.add(sphere); // 添加光源 const ambientLight = new THREE.AmbientLight(0xffffff, 0.5); scene.add(ambientLight); const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8); directionalLight.position.set(5, 5, 5); scene.add(directionalLight); // 设置物体位置 sphere.position.set(2, 0, 0); floor.position.set(0, -2, 0); floor.rotation.x = -Math.PI / 2; camera.position.z = 5; // 加载纹理 const textureLoader = new THREE.TextureLoader(); textureLoader.load( 'trianglefabric.jpg', (texture) => { material.map = texture; material2.map = texture; material.needsUpdate = true; material2.needsUpdate = true; }, (xhr) => { console.log(`${(xhr.loaded / xhr.total * 100).toFixed(1)}% loaded`); }, (error) => { console.error('纹理加载失败:', error); } ); function animate() { requestAnimationFrame(animate); cube.rotation.x += 0.01; cube.rotation.y += 0.01; sphere.rotation.y += -0.01; renderer.render(scene, camera); } animate();
验证步骤
- 运行修改后的代码,打开浏览器控制台查看是否有加载错误提示。
- 确认光源生效后,物体是否被照亮,纹理是否正常显示。
- 若仍有问题,更换另一张符合2幂次尺寸的图片测试,排除文件损坏可能。
内容的提问来源于stack exchange,提问作者Chariot
相关产品推荐
相关产品推荐

