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
相关产品推荐
相关产品推荐

