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

three.js使用WebGLRenderer与灯光时TextureLoader纹理显示黑面问题

Three.js 立方体纹理映射贴图面显示纯黑色问题修复

问题现象

  • 已将渲染器从CanvasRenderer替换为WebGLRenderer,材质从MeshBasicMaterial替换为MeshPhongMaterial
  • 立方体无贴图的黄色纯色面渲染正常,绑定了外部纹理的面始终显示纯黑色

现有相关代码

渲染逻辑

const renderer = new THREE.WebGLRenderer();
function render() {
  renderer.render(scene, camera);
}

灯光配置

const light = new THREE.PointLight("white", 1, 100);
light.position.set(7, 10, 10);
scene.add(light);

立方体与纹理加载逻辑

const loader = new THREE.TextureLoader();
const cube1geometry = new THREE.BoxGeometry(1, 1, 1);
const textureCube1 = [
  new THREE.MeshPhongMaterial({ map: loader.load("cat1.jpg") }),
  new THREE.MeshPhongMaterial({ color: "yellow" }),
  new THREE.MeshPhongMaterial({ map: loader.load("cat1.jpg") }),
  new THREE.MeshPhongMaterial({ color: "yellow" }),
  new THREE.MeshPhongMaterial({ color: "yellow" }),
  new THREE.MeshPhongMaterial({ color: "yellow" }),
];
const cube1mesh = new THREE.Mesh(cube1geometry, textureCube1);
cube1mesh.position.set(0.0, 0.0, 2.0);

问题原因

TextureLoader.load()是异步接口,调用后会立刻返回空的纹理占位对象,实际图片资源需要等网络请求完成后才会填充到纹理对象中。当前代码仅在初始化阶段执行一次render(),纹理加载完成后没有触发重新渲染,带贴图的面就会一直停留在初始渲染的黑色状态。纯色材质不需要加载外部资源,初始化时就可以完成渲染,因此显示正常。

修复方法

  • 优先使用渲染循环方案,适配绝大多数Three.js场景:修改渲染逻辑,加入requestAnimationFrame实现持续渲染,资源加载、场景变换都会自动刷新画面
const renderer = new THREE.WebGLRenderer();
function render() {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
}
// 启动渲染循环
render();
  • 如果不想开持续渲染循环,可以在纹理加载完成的回调中手动触发一次重绘,同时复用纹理对象避免重复发起资源请求:
const loader = new THREE.TextureLoader();
const cube1geometry = new THREE.BoxGeometry(1, 1, 1);
// 复用同一张纹理,减少不必要的资源请求
const catTexture = loader.load("cat1.jpg", () => {
  // 纹理加载完成后重新渲染一次
  render();
});
const textureCube1 = [
  new THREE.MeshPhongMaterial({ map: catTexture }),
  new THREE.MeshPhongMaterial({ color: "yellow" }),
  new THREE.MeshPhongMaterial({ map: catTexture }),
  new THREE.MeshPhongMaterial({ color: "yellow" }),
  new THREE.MeshPhongMaterial({ color: "yellow" }),
  new THREE.MeshPhongMaterial({ color: "yellow" }),
];
const cube1mesh = new THREE.Mesh(cube1geometry, textureCube1);
cube1mesh.position.set(0.0, 0.0, 2.0);
  • 额外排查项:如果修改后纹理仍为黑色,打开浏览器开发者工具控制台,检查是否存在图片404报错、跨域报错。本地开发时不要直接双击HTML文件通过file协议打开,需要启动本地静态服务访问页面,避免浏览器安全策略拦截本地资源加载。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 17:39:18