You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中使用Three.js无法将纹理应用到球体的问题

解决Next.js中Three.js球体显示黑色无纹理的问题

核心问题分析

你遇到的黑色球体问题,大概率和纹理异步加载、渲染时机或者Next.js静态资源路径有关,下面是针对性的解决步骤:

解决办法

1. 处理纹理异步加载的渲染更新

TextureLoader.load()是异步操作,你当前只在初始化时调用了一次renderer.render(),此时纹理还没加载完成,球体自然显示黑色。要在纹理加载完成后触发重新渲染:

const textureLoader = new THREE.TextureLoader();
textureLoader.load(
  "/earth_texture.jpg",
  (texture) => {
    texture.colorSpace = THREE.SRGBColorSpace;
    // 加载完成后更新材质并触发渲染
    material.map = texture;
    material.needsUpdate = true;
    renderer.render(scene, camera);
  },
  undefined,
  (err) => {
    console.error("纹理加载失败:", err);
  }
);

2. 检查Next.js静态资源路径

确保earth_texture.jpg放在项目根目录的public文件夹下,Next.js会把public内的资源作为静态资源暴露,此时/earth_texture.jpg的路径才会生效。如果图片放在子文件夹(比如public/textures/earth_texture.jpg),路径要对应改成/textures/earth_texture.jpg。

3. 添加渲染循环(可选但推荐)

如果需要球体动画或后续画面更新,用requestAnimationFrame创建渲染循环,纹理加载完成后会自动更新画面:

function animate() {
  requestAnimationFrame(animate);
  // 可在此添加球体旋转等动画逻辑
  sphere.rotation.y += 0.005;
  renderer.render(scene, camera);
}
animate();

4. 材质初始化兜底(可选)

可以给材质设置默认颜色,避免加载前完全黑屏:

let material = new THREE.MeshPhongMaterial({
  shininess: 100,
  color: 0x808080 // 灰色兜底
});

调整后的完整代码示例

const scene = new THREE.Scene();

const camera = new THREE.PerspectiveCamera(75, 1 / 1, 0.1, 100);
camera.position.z = 20;

// 灯光设置
const aLight = new THREE.AmbientLight(0xffffff, 0.1);
const light = new THREE.DirectionalLight(0xffffff, 3);
light.position.set(-10, 5, 5);
scene.add(light);
scene.add(aLight);

const geometry = new THREE.SphereGeometry(10, 64, 64);
// 先创建带兜底颜色的材质
let material = new THREE.MeshPhongMaterial({
  shininess: 100,
  color: 0x808080
});

let sphere = new THREE.Mesh(geometry, material);
sphere.castShadow = true;
sphere.receiveShadow = true;
scene.add(sphere);

const renderer = new THREE.WebGLRenderer({
  alpha: true,
  antialias: true
});
renderer.setSize(500, 500);
containerRef.current?.appendChild(renderer.domElement);

// 加载纹理并更新材质
const textureLoader = new THREE.TextureLoader();
textureLoader.load(
  "/earth_texture.jpg",
  (texture) => {
    texture.colorSpace = THREE.SRGBColorSpace;
    material.map = texture;
    material.needsUpdate = true;
  },
  undefined,
  (err) => {
    console.error("纹理加载失败:", err);
  }
);

// 启动渲染循环
function animate() {
  requestAnimationFrame(animate);
  sphere.rotation.y += 0.005;
  renderer.render(scene, camera);
}
animate();

内容的提问来源于stack exchange,提问作者ruben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 13:42:39