Three.js中纹理无法覆盖整个球体几何体的问题求助
解决Three.js球体纹理无法覆盖的问题
你在制作旋转月球时遇到的纹理无法覆盖整个球体的问题,主要由以下两点导致:
1. 变量拼写错误
动画函数里的moom.rotation.x是拼写错误,正确变量名应为moon。这个错误会触发JavaScript运行时异常,直接中断动画逻辑,进而导致纹理渲染异常。
2. 纹理包裹模式适配(可选)
虽然SphereGeometry默认自带适配整个球体的UV映射,但如果你的月球图片比例特殊,可手动设置纹理包裹模式确保完全覆盖:
moonTexture.wrapS = THREE.ClampToEdgeWrapping; moonTexture.wrapT = THREE.ClampToEdgeWrapping;
修复后的完整代码
import React, { useEffect } from "react"; import * as THREE from "three"; import {OrbitControls} from "three/examples/jsm/controls/OrbitControls" import moonImage from "../../images/moon.jpg" const Home = () => { useEffect(() => { const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 1, 1000); const canvas = document.querySelector(".homeCanvas"); const renderer = new THREE.WebGLRenderer({canvas}); // 初始化时设置画布尺寸,避免拉伸 renderer.setSize(window.innerWidth, window.innerHeight); const textureLoader = new THREE.TextureLoader(); const moonTexture = textureLoader.load(moonImage); // 设置纹理包裹模式,适配球体UV moonTexture.wrapS = THREE.ClampToEdgeWrapping; moonTexture.wrapT = THREE.ClampToEdgeWrapping; const moonGeo = new THREE.SphereGeometry(3, 64, 64); const moonMaterial = new THREE.MeshStandardMaterial({map: moonTexture}); const moon = new THREE.Mesh(moonGeo, moonMaterial); scene.add(moon); const pointLight = new THREE.PointLight(0xffffff, 1); pointLight.position.x = 20; scene.add(pointLight); const controls = new OrbitControls(camera, renderer.domElement); camera.position.z = 15; function animate() { requestAnimationFrame(animate); // 修正拼写错误,正常驱动月球旋转 moon.rotation.x += 0.01; moon.rotation.y += 0.01; renderer.render(scene, camera); } animate(); // 监听窗口大小变化,动态调整画布和相机 const handleResize = () => { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); } window.addEventListener('resize', handleResize); // 组件卸载时清理资源,避免内存泄漏 return () => { window.removeEventListener('resize', handleResize); controls.dispose(); renderer.dispose(); } }, []); return ( <> <div className="home"> <canvas className="homeCanvas"></canvas> </div> </> ) } export default Home
额外优化点
- 移除了
animate函数中每帧重复调用renderer.setSize的逻辑,改为监听窗口resize事件触发调整,提升渲染性能。 - 添加了组件卸载时的资源清理逻辑,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Haris Akram
相关产品推荐
相关产品推荐

