3.1纹理基础 3. 纹理 (Textures) 与材质贴图 3.1 纹理基础 纹理在 Three.js 中扮演着至关重要的角色,它们为 3D 模型赋予了视觉细节、表面特征和真实感。简单来说,纹理就像是贴在模型表面的“皮肤”,可以包含颜色、图案、凹凸、光泽等信息。 3.1.1 纹理的概念 纹理本质上是图像数据,可以是常见的 JPG、PNG、GIF 等格式。Three.js 将这些图像数据加载到 GPU 中,并根据 UV 坐标将纹理像素(纹素,Texel)映射到 3D 模型的表面。 3.1.2 UV 坐标 UV 坐标是 3D 模型表面上每个顶点对应的二维坐标,范围通常在 0 到 1 之间。U 坐标表示水平方向,V 坐标表示垂直方向。UV 坐标定义了纹理如何“粘贴”到模型表面。 3.1.
3. 纹理 (Textures) 与材质贴图
3.1 纹理基础
纹理在 Three.js 中扮演着至关重要的角色,它们为 3D 模型赋予了视觉细节、表面特征和真实感。简单来说,纹理就像是贴在模型表面的“皮肤”,可以包含颜色、图案、凹凸、光泽等信息。
3.1.1 纹理的概念
纹理本质上是图像数据,可以是常见的 JPG、PNG、GIF 等格式。Three.js 将这些图像数据加载到 GPU 中,并根据 UV 坐标将纹理像素(纹素,Texel)映射到 3D 模型的表面。
3.1.2 UV 坐标
UV 坐标是 3D 模型表面上每个顶点对应的二维坐标,范围通常在 0 到 1 之间。U 坐标表示水平方向,V 坐标表示垂直方向。UV 坐标定义了纹理如何“粘贴”到模型表面。
3.1.3 创建和加载纹理
Three.js 提供了 THREE.TextureLoader 类来加载纹理图像。
代码示例:
// 1. 创建纹理加载器 const textureLoader = new THREE.TextureLoader(); // 2. 加载纹理图像 textureLoader.load( 'textures/wood.jpg', // 纹理图像的 URL function (texture) { // 纹理加载完成后的回调函数 const material = new THREE.MeshBasicMaterial({ map: texture }); const geometry = new THREE.BoxGeometry(1, 1, 1); const cube = new THREE.Mesh(geometry, material); scene.add(cube); render(); // 重新渲染场景 }, function (xhr) { // 可选:纹理加载过程中的回调函数,用于显示加载进度 console.log((xhr.loaded / xhr.total * 100) + '% loaded'); }, function (error) { // 可选:纹理加载出错时的回调函数 console.error('An error happened', error); } );
代码详解:
THREE.TextureLoader(): 创建一个纹理加载器实例。
textureLoader.load(url, onLoad, onProgress, onError): 加载纹理图像。
url: 纹理图像的 URL 路径。
onLoad(texture): 纹理加载成功后执行的回调函数。texture 参数是加载完成的 THREE.Texture 对象。
onProgress(xhr): (可选)纹理加载过程中执行的回调函数,可以用来显示加载进度。xhr 参数包含加载进度信息。
onError(error): (可选)纹理加载出错时执行的回调函数。
3.1.4 纹理属性
THREE.Texture 对象有很多属性,可以控制纹理的显示方式:
wrapS 和 wrapT: 定义纹理在水平 (S) 和垂直 (T) 方向上的包裹方式。常用的值有:
THREE.RepeatWrapping: 重复纹理。
THREE.ClampToEdgeWrapping: 拉伸纹理边缘的像素。
THREE.MirroredRepeatWrapping: 镜像重复纹理。
minFilter 和 magFilter: 定义纹理在缩小 (minification) 和放大 (magnification) 时的过滤方式。 过滤方式影响纹理的清晰度和性能。常用的值有:
THREE.NearestFilter: 使用最近邻插值,速度快,但可能出现锯齿。
THREE.LinearFilter: 使用线性插值,效果较好,但速度稍慢。
THREE.NearestMipmapNearestFilter, THREE.LinearMipmapNearestFilter, THREE.NearestMipmapLinearFilter, THREE.LinearMipmapLinearFilter: 使用 Mipmap 技术,可以提高性能和减少锯齿。
repeat: THREE.Vector2 类型,定义纹理在水平和垂直方向上的重复次数。 例如,texture.repeat.set(2, 3) 会使纹理在水平方向重复 2 次,在垂直方向重复 3 次。
offset: THREE.Vector2 类型,定义纹理的偏移量。 例如,texture.offset.set(0.5, 0.25) 会使纹理在水平方向偏移 0.5 个单位,在垂直方向偏移 0.25 个单位。
rotation: 定义纹理的旋转角度(弧度制)。
center: THREE.Vector2 类型,定义纹理旋转的中心点。
代码示例:
const texture = textureLoader.load('textures/brick.jpg'); // 设置纹理重复方式 texture.wrapS = THREE.RepeatWrapping; texture.wrapT = THREE.RepeatWrapping; // 设置纹理重复次数 texture.repeat.set(4, 4); // 设置纹理过滤方式 texture.minFilter = THREE.LinearFilter; texture.magFilter = THREE.LinearFilter; const material = new THREE.MeshBasicMaterial({ map: texture });
3.1.5 纹理类型
除了直接加载图像文件,Three.js 还支持其他类型的纹理:
CanvasTexture: 使用 HTML5 Canvas 作为纹理源。 可以动态绘制纹理。
VideoTexture: 使用 HTML5 <video> 元素作为纹理源。 可以播放视频作为纹理。
CubeTexture: 立方体纹理,用于创建天空盒或模拟反射效果。 需要加载 6 张图像分别对应立方体的 6 个面。
DataTexture: 使用自定义的像素数据作为纹理源。
3.1.6 使用 CanvasTexture 动态创建纹理
代码示例:
// 1. 创建 Canvas 元素 const canvas = document.createElement('canvas'); canvas.width = 256; canvas.height = 256; const ctx = canvas.getContext('2d'); // 2. 在 Canvas 上绘制内容 ctx.fillStyle = 'red'; ctx.fillRect(0, 0, 256, 256); ctx.fillStyle = 'white'; ctx.font = '48px Arial'; ctx.textAlign = 'center'; ctx.fillText('Hello', 128, 128); // 3. 创建 CanvasTexture const texture = new THREE.CanvasTexture(canvas); // 4. 将纹理应用到材质 const material = new THREE.MeshBasicMaterial({ map: texture });
代码详解:
创建一个 HTML5 Canvas 元素,并设置其宽度和高度。
获取 Canvas 的 2D 渲染上下文。
使用 Canvas API 在 Canvas 上绘制内容,例如绘制一个红色背景,并在中心位置绘制白色文字 "Hello"。
使用 THREE.CanvasTexture(canvas) 创建一个 CanvasTexture 对象,并将 Canvas 元素作为参数传入。
将 CanvasTexture 应用到材质的 map 属性。
3.1.7 纹理优化
纹理尺寸: 使用合适的纹理尺寸。 过大的纹理会占用大量内存,降低性能。 通常建议使用 2 的幂次方尺寸(例如 64x64, 128x128, 256x256, 512x512, 1024x1024)。
纹理格式: 选择合适的纹理格式。 JPG 格式适合存储照片,PNG 格式适合存储带有透明度的图像。
Mipmapping: 启用 Mipmapping 可以提高性能和减少锯齿。
纹理压缩: 使用纹理压缩技术可以减少纹理的存储空间和加载时间。
3.1.8 总结
纹理是 Three.js 中非常重要的概念,掌握纹理的基础知识是创建逼真 3D 场景的关键。 通过加载图像、设置纹理属性、使用不同类型的纹理,以及进行纹理优化,可以为 3D 模型赋予丰富的视觉细节和真实感。
希望这篇文章能够帮助你更好地理解 Three.js 中的纹理基础。在实际项目中,可以根据具体需求选择合适的纹理类型和属性,并进行相应的优化,以达到最佳的视觉效果和性能。