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

如何在THREE.JS中使用ShaderMaterial为BoxGeometry各面添加指定纹理?

解决BoxGeometry每个面使用ShaderMaterial加载纹理的问题

你遇到的问题核心是ShaderMaterial必须手动编写着色器代码来处理纹理采样,不像Three.js内置材质会自动处理纹理渲染。只传递uniform纹理但没写对应的着色器逻辑,纹理自然无法显示。以下是具体解决方案:

关键步骤说明

  • 必须为ShaderMaterial提供vertexShader和fragmentShader:顶点着色器需要传递UV坐标给片元着色器,片元着色器通过UV完成纹理采样。
  • 确保纹理加载完成后再创建材质:避免纹理未就绪导致的空白显示。
  • BoxGeometry的每个面对应材质数组的一个元素:这个用法是正确的,只要每个ShaderMaterial的着色器逻辑正确即可生效。

完整代码示例

// 顶点着色器:将模型UV坐标传递到片元着色器
const vertexShader = `
varying vec2 vUv;

void main() {
  vUv = uv;
  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`;

// 片元着色器:采样纹理,可扩展叠加逻辑
const fragmentShader = `
uniform sampler2D texture;
varying vec2 vUv;

void main() {
  // 基础纹理采样
  vec4 texColor = texture2D(texture, vUv);
  // 示例:如需叠加效果,可添加额外纹理uniform并混合
  // vec4 overlayColor = texture2D(overlayTexture, vUv);
  // gl_FragColor = mix(texColor, overlayColor, 0.5);
  gl_FragColor = texColor;
}
`;

createMaterials(texture) {
  return new THREE.ShaderMaterial({
    uniforms: {
      texture: { value: texture }
    },
    vertexShader: vertexShader,
    fragmentShader: fragmentShader,
    // 若需要透明叠加效果,开启以下配置
    // transparent: true
  });
}

// 确保纹理加载完成后创建立方体(以TextureLoader为例)
const loader = new THREE.TextureLoader();
loader.load('brown-texture.jpg', (brownImageTexture) => {
  loader.load('texture1.jpg', (texture1) => {
    loader.load('texture2.jpg', (texture2) => {
      loader.load('texture3.jpg', (texture3) => {
        loader.load('texture4.jpg', (texture4) => {
          loader.load('texture5.jpg', (texture5) => {
            const geometry = new THREE.BoxGeometry(1, 1, 1);
            const mat0 = this.createMaterials(brownImageTexture);
            const mat1 = this.createMaterials(texture1);
            const mat2 = this.createMaterials(texture2);
            const mat3 = this.createMaterials(texture3);
            const mat4 = this.createMaterials(texture4);
            const mat5 = this.createMaterials(texture5);

            const cube = new THREE.Mesh(geometry, [mat0, mat1, mat2, mat3, mat4, mat5]);
            scene.add(cube);
          });
        });
      });
    });
  });
});

纹理叠加扩展提示

如果需要实现纹理叠加效果,只需在片元着色器中添加额外的uniform纹理,然后通过mix()、add()等GLSL函数混合颜色。例如:

// 片元着色器中新增叠加纹理uniform
uniform sampler2D overlayTexture;

// 在main函数中完成混合
void main() {
  vec4 baseColor = texture2D(texture, vUv);
  vec4 overlayColor = texture2D(overlayTexture, vUv);
  // 按50%比例混合两张纹理
  gl_FragColor = mix(baseColor, overlayColor, 0.5);
}

同时修改createMaterials函数,使其支持传入多个纹理参数即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 13:27:17