3.2纹理映射


文档摘要

3.2纹理映射 Three.js 纹理映射详解 纹理 (Textures) 与材质贴图 在 Three.js 中,纹理和材质贴图是为 3D 模型添加细节和视觉效果的关键。它们可以模拟表面的颜色、光泽、粗糙度等属性,从而使模型看起来更逼真。 3.2 纹理映射 (Texture Mapping) 纹理映射是一种将 2D 图像(纹理)“粘贴”到 3D 模型表面的技术。它允许我们为模型添加复杂的细节,而无需增加模型的几何复杂度。简单来说,就是将图像的像素(纹素)映射到 3D 模型的表面。 3.2.1 纹理映射的原理 纹理映射的核心在于建立纹理坐标 (UV 坐标) 与 3D 模型表面顶点之间的对应关系。UV 坐标是 2D 坐标,通常范围在 0 到 1 之间,分别代表纹理图像的水平和垂直方向。

3.2纹理映射

Three.js 纹理映射详解

3. 纹理 (Textures) 与材质贴图

在 Three.js 中,纹理和材质贴图是为 3D 模型添加细节和视觉效果的关键。它们可以模拟表面的颜色、光泽、粗糙度等属性,从而使模型看起来更逼真。

3.2 纹理映射 (Texture Mapping)

纹理映射是一种将 2D 图像(纹理)“粘贴”到 3D 模型表面的技术。它允许我们为模型添加复杂的细节,而无需增加模型的几何复杂度。简单来说,就是将图像的像素(纹素)映射到 3D 模型的表面。

3.2.1 纹理映射的原理

纹理映射的核心在于建立纹理坐标 (UV 坐标) 与 3D 模型表面顶点之间的对应关系。UV 坐标是 2D 坐标,通常范围在 0 到 1 之间,分别代表纹理图像的水平和垂直方向。

当 Three.js 渲染模型时,它会根据顶点的 UV 坐标从纹理图像中采样颜色,并将该颜色应用于顶点。然后,通过插值计算,可以得到模型表面上每个像素的颜色。

3.2.2 UV 坐标

UV 坐标定义了纹理图像如何“包裹”在 3D 模型上。不同的模型可能需要不同的 UV 坐标,以实现所需的纹理映射效果。

  • 标准 UV 坐标: 通常,UV 坐标的原点 (0, 0) 位于纹理图像的左下角,(1, 1) 位于右上角。

  • UV 展开 (UV Unwrapping): 将 3D 模型的表面“展开”成 2D 平面,并为每个顶点分配 UV 坐标的过程。这是创建良好纹理映射的关键步骤。

  • UV 映射类型: Three.js 支持多种 UV 映射类型,例如平面映射、立方体映射、球形映射等。

3.2.3 Three.js 中的纹理映射

在 Three.js 中,可以使用 THREE.TextureLoader 加载纹理图像,然后将其分配给材质的 map 属性。

代码示例:

// 创建场景、相机和渲染器 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 geometry = new THREE.BoxGeometry(); // 加载纹理 const textureLoader = new THREE.TextureLoader(); const texture = textureLoader.load('path/to/your/texture.jpg'); // 替换为你的纹理图像路径 // 创建材质并将纹理分配给 map 属性 const material = new THREE.MeshBasicMaterial({ map: texture }); // 创建网格 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();

代码详解:

  1. 创建场景、相机和渲染器: 这是 Three.js 应用程序的标准设置。

  2. 创建立方体: 使用 THREE.BoxGeometry 创建一个立方体几何体。

  3. 加载纹理: THREE.TextureLoader 用于异步加载纹理图像。load() 方法接受纹理图像的 URL 作为参数。

  4. 创建材质: THREE.MeshBasicMaterial 是一种简单的材质,它不受光照影响,直接显示纹理颜色。将加载的纹理分配给材质的 map 属性,即可将纹理应用于模型。

  5. 创建网格: THREE.Mesh 将几何体和材质组合在一起,形成一个可渲染的 3D 对象。

  6. 渲染循环: animate() 函数不断更新模型的位置和旋转,并使用 renderer.render() 渲染场景。

3.2.4 纹理属性

THREE.Texture 对象具有许多属性,可以控制纹理的显示方式:

  • wrapSwrapT: 定义纹理在水平和垂直方向上的重复方式。常用的值包括:

    • THREE.RepeatWrapping (重复)

    • THREE.ClampToEdgeWrapping (拉伸边缘像素)

    • THREE.MirroredRepeatWrapping (镜像重复)

  • minFiltermagFilter: 定义纹理在缩小和放大时的过滤方式。常用的值包括:

    • THREE.NearestFilter (最近邻插值,像素化效果)

    • THREE.LinearFilter (线性插值,平滑效果)

    • THREE.NearestMipmapNearestFilter

    • THREE.LinearMipmapLinearFilter

  • repeat: 控制纹理在水平和垂直方向上的重复次数。

  • offset: 控制纹理在水平和垂直方向上的偏移量。

  • rotation: 控制纹理的旋转角度。

  • center: 旋转的中心点

代码示例:

// 设置纹理的重复方式和重复次数 texture.wrapS = THREE.RepeatWrapping; texture.wrapT = THREE.RepeatWrapping; texture.repeat.set(4, 4); // 设置纹理的过滤方式 texture.minFilter = THREE.LinearFilter; texture.magFilter = THREE.LinearFilter;
3.2.5 材质贴图的种类

除了颜色贴图 (diffuse map),还有许多其他类型的材质贴图可以用于增强模型的视觉效果:

  • 法线贴图 (Normal Map): 模拟表面的凹凸细节,而无需增加模型的几何复杂度。

  • 粗糙度贴图 (Roughness Map): 控制表面的粗糙程度,影响光线的反射方式。

  • 金属度贴图 (Metalness Map): 控制表面的金属程度,影响光线的反射方式。

  • 环境光遮蔽贴图 (Ambient Occlusion Map): 模拟物体表面的阴影效果,增加深度感。

  • 高度贴图 (Height Map) / 位移贴图 (Displacement Map): 实际改变模型的顶点位置,创建真实的凹凸效果。

代码示例 (使用法线贴图):

// 加载法线贴图 const normalTexture = textureLoader.load('path/to/your/normal_map.jpg'); // 创建材质并将法线贴图分配给 normalMap 属性 const material = new THREE.MeshStandardMaterial({ map: texture, // 颜色贴图 normalMap: normalTexture });
3.2.6 性能考虑

纹理映射会消耗 GPU 资源,因此需要注意以下几点:

  • 纹理大小: 使用适当大小的纹理。过大的纹理会浪费内存,过小的纹理会导致图像模糊。

  • 纹理格式: 使用压缩纹理格式 (如 DDS, PVRTC, ETC) 可以减少纹理的内存占用。

  • Mipmapping: 启用 Mipmapping 可以提高渲染性能,尤其是在观察远处物体时。

  • 纹理重复: 合理使用纹理重复可以减少纹理的数量。

3.2.7 总结

纹理映射是 Three.js 中一项强大的技术,可以为 3D 模型添加丰富的细节和视觉效果。通过理解 UV 坐标、纹理属性和不同类型的材质贴图,可以创建出令人惊叹的 3D 场景。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U