3.3纹理应用技巧 Three.js 纹理应用技巧详解 3.3 纹理应用技巧 纹理的应用不仅仅是将图像简单地贴在物体表面。通过巧妙地使用纹理的各种属性和技术,我们可以实现各种各样的视觉效果。 3.3.1 纹理映射模式 (Mapping Modes) 纹理映射模式决定了纹理如何包裹在物体表面。Three.js 提供了多种映射模式,常用的有: : 这是最常用的映射模式,它使用物体的 UV 坐标来确定纹理的映射位置。UV 坐标是定义在 0 到 1 范围内的二维坐标,用于指定纹理上的哪个部分对应于物体的哪个表面。 : 用于创建环境反射效果,通常与立方体贴图一起使用。立方体贴图是一组六张图片,代表了物体周围环境的各个方向。 : 用于创建折射效果,类似于玻璃或水。
纹理的应用不仅仅是将图像简单地贴在物体表面。通过巧妙地使用纹理的各种属性和技术,我们可以实现各种各样的视觉效果。
纹理映射模式决定了纹理如何包裹在物体表面。Three.js 提供了多种映射模式,常用的有:
THREE.UVMapping: 这是最常用的映射模式,它使用物体的 UV 坐标来确定纹理的映射位置。UV 坐标是定义在 0 到 1 范围内的二维坐标,用于指定纹理上的哪个部分对应于物体的哪个表面。
THREE.CubeReflectionMapping: 用于创建环境反射效果,通常与立方体贴图一起使用。立方体贴图是一组六张图片,代表了物体周围环境的各个方向。
THREE.CubeRefractionMapping: 用于创建折射效果,类似于玻璃或水。
代码示例: UVMapping
import * as THREE from 'three'; // 创建场景、相机和渲染器 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(1, 1, 1); // 加载纹理 const textureLoader = new THREE.TextureLoader(); const texture = textureLoader.load('path/to/your/texture.jpg'); // 创建材质 const material = new THREE.MeshBasicMaterial({ map: texture }); // 创建网格 const cube = new THREE.Mesh(geometry, material); scene.add(cube); camera.position.z = 3; // 渲染循环 function animate() { requestAnimationFrame(animate); cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render(scene, camera); } animate();
代码示例: CubeReflectionMapping
import * as THREE from 'three'; // 创建场景、相机和渲染器 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.SphereGeometry(1, 32, 32); // 加载立方体贴图 const cubeTextureLoader = new THREE.CubeTextureLoader(); const cubeTexture = cubeTextureLoader.load([ 'path/to/posx.jpg', 'path/to/negx.jpg', 'path/to/posy.jpg', 'path/to/negy.jpg', 'path/to/posz.jpg', 'path/to/negz.jpg' ]); scene.background = cubeTexture; // 将立方体贴图设置为背景 // 创建材质 const material = new THREE.MeshStandardMaterial({ envMap: cubeTexture, roughness: 0.1, metalness: 1 }); // 创建网格 const sphere = new THREE.Mesh(geometry, material); scene.add(sphere); camera.position.z = 3; // 渲染循环 function animate() { requestAnimationFrame(animate); sphere.rotation.x += 0.01; sphere.rotation.y += 0.01; renderer.render(scene, camera); } animate();
Mermaid 图表:UVMapping
纹理重复决定了当纹理的 UV 坐标超出 0 到 1 范围时,如何处理纹理。Three.js 提供了以下几种重复模式:
THREE.RepeatWrapping: 纹理在水平和垂直方向上重复。
THREE.ClampToEdgeWrapping: 纹理边缘的像素被拉伸到超出 0 到 1 范围的区域。
THREE.MirroredRepeatWrapping: 纹理在重复时进行镜像翻转。
代码示例: RepeatWrapping
import * as THREE from 'three'; // 创建场景、相机和渲染器 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.PlaneGeometry(5, 5); // 加载纹理 const textureLoader = new THREE.TextureLoader(); const texture = textureLoader.load('path/to/your/texture.jpg'); // 设置纹理重复 texture.wrapS = THREE.RepeatWrapping; texture.wrapT = THREE.RepeatWrapping; texture.repeat.set(4, 4); // 在水平和垂直方向上重复 4 次 // 创建材质 const material = new THREE.MeshBasicMaterial({ map: texture }); // 创建网格 const plane = new THREE.Mesh(geometry, material); scene.add(plane); camera.position.z = 3; // 渲染循环 function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } animate();
Mermaid 图表:Texture Wrapping
纹理过滤用于控制纹理在放大或缩小时的显示效果。Three.js 提供了以下几种过滤模式:
THREE.NearestFilter: 使用最近的像素进行采样,产生像素化的效果。
THREE.LinearFilter: 使用线性插值进行采样,产生平滑的效果。
THREE.NearestMipmapNearestFilter: 使用最近的mipmap层和最近的像素进行采样。
THREE.LinearMipmapLinearFilter: 使用线性插值mipmap层和线性插值像素进行采样,通常是最佳选择。
代码示例: LinearMipmapLinearFilter
import * as THREE from 'three'; // 创建场景、相机和渲染器 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.PlaneGeometry(5, 5); // 加载纹理 const textureLoader = new THREE.TextureLoader(); const texture = textureLoader.load('path/to/your/texture.jpg'); // 设置纹理过滤 texture.minFilter = THREE.LinearMipmapLinearFilter; texture.magFilter = THREE.LinearFilter; // 创建材质 const material = new THREE.MeshBasicMaterial({ map: texture }); // 创建网格 const plane = new THREE.Mesh(geometry, material); scene.add(plane); camera.position.z = 3; // 渲染循环 function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } animate();
Mermaid 图表:Texture Filtering
我们可以通过 texture.offset、texture.rotation 和 texture.repeat 属性来变换纹理的 UV 坐标,从而实现纹理的平移、旋转和缩放。
代码示例: UV 变换
import * as THREE from 'three'; // 创建场景、相机和渲染器 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.PlaneGeometry(5, 5); // 加载纹理 const textureLoader = new THREE.TextureLoader(); const texture = textureLoader.load('path/to/your/texture.jpg'); // 设置纹理重复 texture.wrapS = THREE.RepeatWrapping; texture.wrapT = THREE.RepeatWrapping; texture.repeat.set(2, 2); // 创建材质 const material = new THREE.MeshBasicMaterial({ map: texture }); // 创建网格 const plane = new THREE.Mesh(geometry, material); scene.add(plane); camera.position.z = 3; // 渲染循环 function animate() { requestAnimationFrame(animate); // 改变纹理偏移 texture.offset.x += 0.01; texture.offset.y += 0.01; // 改变纹理旋转 texture.rotation += 0.01; renderer.render(scene, camera); } animate();
材质贴图允许我们使用纹理来控制材质的各种属性,例如:
map: 漫反射贴图,控制物体的颜色。
normalMap: 法线贴图,模拟物体表面的凹凸细节。
roughnessMap: 粗糙度贴图,控制物体表面的粗糙程度。
metalnessMap: 金属度贴图,控制物体表面的金属程度。
aoMap: 环境光遮蔽贴图,模拟物体表面的阴影效果。
displacementMap: 位移贴图,实际改变物体表面的几何形状。
代码示例: 使用法线贴图
import * as THREE from 'three'; // 创建场景、相机和渲染器 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); renderer.shadowMap.enabled = true; // 启用阴影 document.body.appendChild(renderer.domElement); // 添加灯光 const light = new THREE.DirectionalLight(0xffffff, 1); light.position.set(5, 5, 5); light.castShadow = true; // 允许灯光投射阴影 scene.add(light); const ambientLight = new THREE.AmbientLight(0x404040); scene.add(ambientLight); // 创建一个球体 const geometry = new THREE.SphereGeometry(1, 32, 32); // 加载纹理 const textureLoader = new THREE.TextureLoader(); const texture = textureLoader.load('path/to/your/texture.jpg'); const normalMap = textureLoader.load('path/to/your/normalMap.jpg'); // 创建材质 const material = new THREE.MeshStandardMaterial({ map: texture, normalMap: normalMap, }); // 创建网格 const sphere = new THREE.Mesh(geometry, material); sphere.castShadow = true; // 允许球体投射阴影 sphere.receiveShadow = true; // 允许球体接收阴影 scene.add(sphere); // 创建地面 const groundGeometry = new THREE.PlaneGeometry(10, 10); const groundMaterial = new THREE.MeshStandardMaterial({ color: 0x808080 }); const ground = new THREE.Mesh(groundGeometry, groundMaterial); ground.rotation.x = -Math.PI / 2; ground.receiveShadow = true; // 允许地面接收阴影 scene.add(ground); camera.position.z = 3; // 渲染循环 function animate() { requestAnimationFrame(animate); sphere.rotation.x += 0.01; sphere.rotation.y += 0.01; renderer.render(scene, camera); } animate();
Mermaid 图表:材质贴图
纹理和材质贴图是 Three.js 中实现逼真视觉效果的关键。通过理解和掌握纹理映射模式、纹理重复、纹理过滤、UV 变换以及各种材质贴图的应用,我们可以创造出令人惊叹的 3D 场景。希望本文提供的代码示例和图表能够帮助你更好地理解和应用 Three.js 中的纹理技术。