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

ShaderMaterial与Points结合无法正常工作问题咨询

排查Three.js ShaderMaterial与Points配合故障的核心要点

我来帮你捋捋这个问题——ShaderMaterial和Points配合出问题,通常都是没照顾到Points的特殊渲染逻辑,结合你给出的代码片段,咱们逐个排查可能的坑:

1. 顶点着色器缺失gl_PointSize设置

这是最常见的“粒子看不见”原因!默认的PointsMaterial会自动处理点的大小,但自定义ShaderMaterial完全需要你手动实现。如果你的顶点着色器里没写gl_PointSize,粒子会因为尺寸为0彻底隐身。

给你一个最基础的可用顶点着色器模板:

attribute vec3 position;
uniform float pointSize;
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;

void main() {
  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
  // 固定粒子大小,也可以根据相机距离动态调整
  gl_PointSize = pointSize;
  // 可选:让粒子随距离远近自动缩放(更真实)
  // gl_PointSize = pointSize * (1.0 / -gl_Position.z);
}

2. ShaderMaterial参数配置错误

创建ShaderMaterial时,必须开启几个Points相关的关键配置,否则要么渲染异常,要么看不到粒子:

  • 如果用顶点颜色,要设置vertexColors: true(你的代码里colors数组是空的,要是后续要加颜色,记得填充后给geometry加color属性)
  • 半透明粒子要开transparent: true,搭配合适的blending(比如THREE.AdditiveBlending),同时关闭depthWrite: false避免渲染顺序混乱

示例Material创建代码:

const material = new THREE.ShaderMaterial({
  vertexShader: `// 上面的顶点着色器代码`,
  fragmentShader: `
    void main() {
      // 可选:把方形粒子改成圆形,更像“粒子”
      float dist = distance(gl_PointCoord, vec2(0.5));
      if (dist > 0.5) discard;
      gl_FragColor = vec4(1.0, 0.5, 0.2, 1.0); // 自定义颜色
    }
  `,
  uniforms: {
    pointSize: { value: 2.0 } // 控制粒子大小的uniform
  },
  // 关键配置
  transparent: true,
  blending: THREE.AdditiveBlending,
  depthWrite: false
});

3. Geometry属性未正确初始化

你的代码里colors数组是空的,但如果你的着色器里引用了color这个attribute,就会直接报错。如果不需要颜色,就把着色器里的color相关代码删掉;如果需要用图片像素颜色,记得在循环里填充colors数组:

for (var i = 0; i < imgData.width; i++) {
  for (var j = 0; j < imgData.height; j++) {
    positions.push(i - imgData.width * 0.5, j - imgData.height * 0.5, 0);
    // 从imgData提取像素颜色,归一化到0-1范围
    const r = data[c++] / 255;
    const g = data[c++] / 255;
    const b = data[c++] / 255;
    c++; // 跳过alpha通道
    colors.push(r, g, b);
  }
}
// 给geometry添加color属性
geometry.addAttribute('color', new THREE.Float32BufferAttribute(colors, 3));

4. 相机相关Uniform未正确传递

Three.js会自动给ShaderMaterial注入projectionMatrix和modelViewMatrix这些核心uniform,但如果你手动覆盖了uniforms对象,要确保这些变量能被着色器正确访问——要是没了它们,粒子的位置会彻底错乱,甚至跑到相机视野外。

最后别忘了把Points添加到场景:

const particles = new THREE.Points(geometry, material);
scene.add(particles);

先检查顶点着色器里有没有gl_PointSize,这大概率是你当前的问题。要是还有异常,把完整的ShaderMaterial代码贴出来,我再帮你深挖~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:34:35