如何为带UV映射的FBX模型创建Three.js四象限纹理材质?
问题解决:生成四象限纹理的MeshToonMaterial
你的代码存在三个核心问题,导致生成的纹理显示全黑,以下是问题说明和修正后的完整代码:
问题分析
- 颜色值范围错误:
Uint8Array存储的颜色通道值为0-255的整数,你直接赋值了0-1的小数,导致颜色几乎趋近于黑色。 - 纹理数据索引计算错误:计算
stride时应使用i * width + j,而非i * height + j,错误的索引逻辑会导致像素位置错乱。 - 未触发纹理更新:创建
DataTexture后必须设置texture.needsUpdate = true,否则Three.js不会识别新的纹理数据。
修正后的代码
const createUVTexture = () => { const width = 2; const height = 2; const size = width * height; const getColor = (i, j) => { if (i === 0 && j === 0) { // 左下象限(对应UV(0,0)) return { r: 255, g: 255, b: 255 }; // 白色 } if (i === 0 && j === 1) { // 右下象限(对应UV(1,0)) return { r: 0, g: 255, b: 0 }; // 绿色 } if (i === 1 && j === 0) { // 左上象限(对应UV(0,1)) return { r: 0, g: 0, b: 255 }; // 蓝色 } if (i === 1 && j === 1) { // 右上象限(对应UV(1,1)) return { r: 255, g: 0, b: 0 }; // 红色 } return { r: 0, g: 0, b: 0 }; // 默认黑色 }; const data = new Uint8Array(4 * size); for (let i = 0; i < height; i++) { for (let j = 0; j < width; j++) { // 修正索引计算:i为行号,每行包含width个像素 const stride = (i * width + j) * 4; const { r, g, b } = getColor(i, j); data[stride] = r; data[stride + 1] = g; data[stride + 2] = b; data[stride + 3] = 255; // Alpha通道设为完全不透明 } } const texture = new THREE.DataTexture(data, width, height); // 小纹理使用最近邻过滤避免模糊 texture.magFilter = THREE.NearestFilter; texture.minFilter = THREE.NearestFilter; texture.needsUpdate = true; // 必须设置,触发纹理数据更新 const material = new THREE.MeshToonMaterial({ map: texture }); return material; };
额外说明
如果模型的UV象限对应关系和代码中的逻辑不符,可调整getColor函数内的i、j判断条件,匹配实际的UV坐标分布;MeshToonMaterial默认会使用渐变阴影,若不需要可添加gradientMap参数或调整光照设置。
内容的提问来源于stack exchange,提问作者Ammar Ahmed
相关产品推荐
相关产品推荐

