Three.js立方体贴图失败,多环境运行均显示黑屏求助
Three.js 贴图黑屏问题排查与修复
核心问题分析
两段代码均出现黑屏,主要原因集中在本地图片路径错误和浏览器安全限制:
- 代码中使用了Windows绝对路径
C:\\Users\\User\\Desktop\\test.jpg,无论是直接打开HTML文件(file://协议)还是通过Node.js服务器运行,浏览器都无法正确读取该路径下的图片(同源策略限制,服务器环境下路径也不符合Web资源寻址规则)。 - 未添加纹理加载的错误处理,无法直观排查图片加载失败的问题。
- ChatGPT生成的立方体初始状态正面正对相机,若纹理加载失败,黑色材质会直接填满视野;Blackbox的平面若纹理加载失败,同样显示黑色。
修复步骤
- 调整文件结构:将
test.jpg与HTML文件放在同一目录下。 - 修改纹理路径:将绝对路径改为相对路径
./test.jpg。 - 添加加载回调:为
TextureLoader.load()添加加载完成、进度、错误回调,便于排查问题。 - 优化视觉反馈:给立方体/平面添加初始旋转或调整尺寸,确保即使纹理加载成功也能直观看到效果。
修正后的代码
ChatGPT版本(立方体)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Three.js cube</title> <script src="https://cdn.jsdelivr.net/npm/three@0.132.2/build/three.min.js"></script> <style> body { margin: 0; } canvas { display: block; } </style> </head> <body> <div id="canvas-container"></div> <script> const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 5; const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.getElementById('canvas-container').appendChild(renderer.domElement); const textureLoader = new THREE.TextureLoader(); // 使用相对路径,并添加加载回调 const texture = textureLoader.load( './test.jpg', () => console.log('纹理加载成功'), (progress) => console.log(`加载进度:${(progress.loaded / progress.total * 100).toFixed(2)}%`), (err) => console.error('纹理加载失败:', err) ); const material = new THREE.MeshBasicMaterial({ map: texture }); const geometry = new THREE.BoxGeometry(); const cube = new THREE.Mesh(geometry, material); // 添加初始旋转,便于看到立方体的多个面 cube.rotation.set(0.2, 0.3, 0); scene.add(cube); let isDragging = false; let previousMousePosition = { x: 0, y: 0 }; function onMouseMove(event) { const deltaMove = { x: event.offsetX - previousMousePosition.x, y: event.offsetY - previousMousePosition.y }; if (isDragging) { const deltaRotationQuaternion = new THREE.Quaternion() .setFromEuler(new THREE.Euler( toRadians(deltaMove.y * 1), toRadians(deltaMove.x * 1), 0, 'XYZ' )); cube.quaternion.multiplyQuaternions(deltaRotationQuaternion, cube.quaternion); } previousMousePosition = { x: event.offsetX, y: event.offsetY }; } function onMouseDown(event) { isDragging = true; previousMousePosition = { x: event.offsetX, y: event.offsetY }; } function onMouseUp() { isDragging = false; } document.addEventListener('mousedown', onMouseDown, false); document.addEventListener('mouseup', onMouseUp, false); document.addEventListener('mousemove', onMouseMove, false); function toRadians(degrees) { return degrees * (Math.PI / 180); } function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } animate(); </script> </body> </html>
Blackbox版本(平面)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Three.js Image Rotation</title> <style> body { margin: 0; } canvas { display: block; } </style> </head> <body> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> <script> const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 5; const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); const loader = new THREE.TextureLoader(); // 使用相对路径,并添加加载回调 const texture = loader.load( './test.jpg', () => console.log('纹理加载成功'), (progress) => console.log(`加载进度:${(progress.loaded / progress.total * 100).toFixed(2)}%`), (err) => console.error('纹理加载失败:', err) ); const geometry = new THREE.PlaneGeometry(3, 3); // 放大平面,便于观察 const material = new THREE.MeshBasicMaterial({ map: texture, side: THREE.DoubleSide }); const mesh = new THREE.Mesh(geometry, material); scene.add(mesh); function handleMouseMove(event) { const mouseX = (event.clientX / window.innerWidth) * 2 - 1; const mouseY = -(event.clientY / window.innerHeight) * 2 + 1; mesh.rotation.y = Math.atan2(mouseX, mouseY); } renderer.domElement.addEventListener('mousemove', handleMouseMove, false); function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } animate(); </script> </body> </html>
额外验证建议
- 运行服务器时,确保服务器根目录包含HTML文件和图片,访问地址为
http://localhost:端口号/test.html。 - 打开浏览器开发者工具(F12),查看Console面板是否有加载错误提示,Network面板查看图片请求状态。
内容的提问来源于stack exchange,提问作者Jason Vord
相关产品推荐
相关产品推荐

