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

ThreeJS中PointsMaterial的map属性加载纹理不显示无报错如何解决

问题原因及解决方案

  • 纹理加载为异步操作,你代码中同步执行渲染逻辑时,TextureLoader还未完成纹理的下载与解析,首次渲染时纹理并未就绪,自然无法显示。且纹理加载完成后没有触发重新渲染,后续画面也不会自动更新。
  • 未设置相机位置,PerspectiveCamera默认处于坐标原点(0,0,0),你生成的粒子坐标范围是±200,和相机处于同一空间范围,大部分粒子要么在近裁面(1)之前被剔除,要么在相机后方,不在视锥体可见范围内。
  • 透明粒子材质的默认配置会导致渲染异常,未配置alphaTest或关闭depthWrite时,半透明纹理的透明区域会被错误写入深度缓存,遮挡后续渲染的粒子,看起来就像纹理未生效。

修正后代码参考

const scene = new THREE.Scene();

const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  1,
  1000
);
// 新增:设置相机位置,拉开与粒子的距离,保证粒子处于视锥体可见范围
camera.position.z = 300;

const particleBufferGeometry = new THREE.BufferGeometry();
const positionArray = [];

for (let i = 0; i < 10000; i++) {
  positionArray.push((Math.random() * 2 - 1) * 200);
  positionArray.push((Math.random() * 2 - 1) * 200);
  positionArray.push((Math.random() * 2 - 1) * 200);
}

particleBufferGeometry.setAttribute("position", new THREE.Float32BufferAttribute(positionArray, 3));

const particlePointsMaterial = new THREE.PointsMaterial({
  size: 2, // 可适当调大尺寸,避免距离过远导致粒子过小不可见
  transparent: true,
  alphaTest: 0.001, // 过滤完全透明区域,避免深度缓存异常
  depthWrite: false // 关闭粒子深度写入,避免透明区域遮挡其他粒子
});
// 纹理加载完成后再赋值并触发重新渲染
const textureLoader = new THREE.TextureLoader();
textureLoader.load("./sparkle.png", (texture) => {
  particlePointsMaterial.map = texture;
  renderer.render(scene, camera);
});

const particlePoints = new THREE.Points(particleBufferGeometry, particlePointsMaterial);

const renderer = new THREE.WebGLRenderer({
  antialias: true,
  alpha: true,
  canvas: document.getElementById("three")
});

renderer.setClearColor(0x000000, 0);
renderer.setSize(
  window.innerWidth,
  window.innerHeight
);

scene.add(particlePoints);

renderer.render(scene, camera);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 07:45:03