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

Three.js立方体GLSL纹理映射异常:全显图片左上角像素求助

解决Three.js GLSL着色器仅显示纹理左上角像素的问题

核心问题排查与修复步骤

1. 确保UV坐标正确传递到片元着色器

立方体默认BoxGeometry自带UV坐标,但自定义着色器时必须手动传递:

  • 顶点着色器声明varying vec2 vUv;,并在main()中赋值vUv = uv;
  • 片元着色器通过这个vUv变量获取纹理采样坐标,而非固定值

示例顶点着色器:

varying vec2 vUv;

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

2. 修正纹理采样逻辑

片元着色器必须使用传递的vUv采样,不能用固定的左上角坐标vec2(0.0, 0.0):

uniform sampler2D uTexture;
varying vec2 vUv;

void main() {
  vec4 texColor = texture2D(uTexture, vUv);
  gl_FragColor = texColor;
}

3. 排除纹理加载与配置错误

  • 确保纹理加载完成后再传入着色器,可通过TextureLoader回调处理:
const textureLoader = new THREE.TextureLoader();
const sandTexture = textureLoader.load('sand.jpg', (texture) => {
  texture.needsUpdate = true;
});
  • 避免跨域问题:本地调试需用服务器打开页面,不能直接双击HTML文件
  • 无需修改wrapS/wrapT(立方体默认UV在0-1范围内),但如果需要重复纹理可设置为THREE.RepeatWrapping

4. 放弃使用sampler3D

sampler3D仅用于3D体积纹理,普通2D纹理必须用sampler2D,替换后只会导致采样失败,改回即可。

完整修正代码示例

// 基础场景初始化
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 加载纹理
const textureLoader = new THREE.TextureLoader();
const sandTexture = textureLoader.load('sand.jpg');

// 着色器代码
const vertexShader = `
varying vec2 vUv;
void main() {
  vUv = uv;
  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`;

const fragmentShader = `
uniform sampler2D uTexture;
varying vec2 vUv;
void main() {
  vec4 texColor = texture2D(uTexture, vUv);
  gl_FragColor = texColor;
}
`;

// 创建网格对象
const material = new THREE.ShaderMaterial({
  uniforms: {
    uTexture: { value: sandTexture }
  },
  vertexShader,
  fragmentShader
});
const geometry = new THREE.BoxGeometry(1, 1, 1);
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

camera.position.z = 5;

// 渲染循环
function animate() {
  requestAnimationFrame(animate);
  cube.rotation.x += 0.01;
  cube.rotation.y += 0.01;
  renderer.render(scene, camera);
}
animate();

额外排查技巧

  • 打开浏览器开发者工具控制台,筛选WebGL相关报错,查看是否有纹理加载或着色器编译错误
  • 检查纹理图片路径是否正确,确保文件存在且路径无拼写错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 08:07:20