Texture
二维图像在 GPU 上的表示,控制采样方式、平铺、重复与色彩解释。
常用属性
| 属性 | 默认 | 说明 |
|---|---|---|
image | null | 图像源:Image、Canvas、ImageBitmap、Video 或数据数组 |
wrapS / wrapT | ClampToEdgeWrapping | 超出 0–1 的 UV 如何采样:夹边、重复、镜像重复 |
repeat | (1, 1) | UV 平铺倍数,需配合重复包裹 |
offset | (0, 0) | UV 平移 |
center | (0, 0) | 旋转中心 |
rotation | 0 | UV 旋转,弧度 |
minFilter | LinearMipmapLinearFilter | 缩小时的采样方式 |
magFilter | LinearFilter | 放大时的采样方式,设为 Nearest 得到像素风 |
anisotropy | 1 | 各向异性过滤,斜视地面时提升清晰度 |
colorSpace | NoColorSpace | 颜色贴图设为 SRGBColorSpace,数据贴图保持线性 |
generateMipmaps | true | 是否生成多级渐远纹理 |
flipY | true | 上传时是否翻转 Y。Canvas 与图片通常保持默认 |
needsUpdate | false | 图像内容变化后置 true,触发重新上传 |
包裹与平铺
const texture = new THREE.TextureLoader().load('/textures/ground.jpg');
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set(8, 8);
// 让地面贴图每个纹理单元对应 25 米
texture.anisotropy = renderer.capabilities.getMaxAnisotropy();
texture.colorSpace = THREE.SRGBColorSpace;
repeat 只是缩放 UV,真正决定边缘行为的是 wrapS 与
wrapT。保持默认的夹边模式时,即使把 repeat 调大,
超出 0–1 的部分仍会被拉伸而不是平铺。
各向异性过滤对俯视地面的贴图影响很大。默认值 1 时,远处地面会糊成一片; 设为硬件上限后,斜视角的清晰度显著提升,代价是带宽。
用 Canvas 生成贴图
const canvas = document.createElement('canvas');
canvas.width = 512;
canvas.height = 512;
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#15303f';
ctx.fillRect(0, 0, 512, 512);
ctx.strokeStyle = '#3f6c86';
for (let i = 0; i <= 512; i += 64) {
ctx.beginPath();
ctx.moveTo(i, 0);
ctx.lineTo(i, 512);
ctx.stroke();
}
const texture = new THREE.CanvasTexture(canvas);
texture.colorSpace = THREE.SRGBColorSpace;
Canvas 贴图适合生成网格、注记、图例、渐变与程序化纹理,不需要任何外部图片。
修改画布内容后要置 texture.needsUpdate = true,否则 GPU 上仍是旧图。
常用子类
| 类 | 用途 |
|---|---|
CanvasTexture | Canvas 内容作为贴图,改完置 needsUpdate |
DataTexture | 直接传类型化数组,适合高程、法线、遮罩等数据 |
VideoTexture | 视频帧作为贴图,每帧自动更新 |
CompressedTexture | KTX2 / Basis 等压缩纹理,显存占用低 |
CubeTexture | 立方体环境贴图,六张图或一张全景展开图 |
颜色贴图与数据贴图
同一张图上,色彩解释只能有一种。基础色、自发光这类「看起来的颜色」是 sRGB; 法线、粗糙度、金属度、环境光遮蔽、位移这类「参与计算的数值」必须线性。 把法线贴图标成 sRGB,光照方向会被压缩到错误的范围,表面细节会显得脏且方向不对。
非二次幂尺寸
WebGL2 环境下,非二次幂纹理也可以重复与生成 mipmap,限制已经比早期宽松很多。 但压缩纹理与部分移动端 GPU 仍有约束,贴图尺寸尽量取 2 的幂,可以减少兼容问题, 也让 mipmap 层级更规整。
释放
texture.dispose() 释放显存中的纹理对象。反复切换底图或重建 Canvas 贴图时,
旧纹理不会自动回收,需要显式销毁,否则显存会一路增长。
贴图尺寸不是越大越好。在屏幕上占几十个像素的物体,用 4096 的贴图纯属浪费。 按实际显示尺寸选择分辨率,比盲目提高精度更能改善帧率。
经纬志(2026)。《Texture》。https://www.jingweizhi.com/three/api/texture.html(访问日期 2026-11-03)。