UV
UV 是一个二维坐标,主要作用是表示一张图片如何贴到一个几何体上。
叫做 UV 坐标是为了和 XY 坐标区分开来。
分别创建两个几何平面,一个使用 PlaneGeometry,一个使用 BufferGeometry,并且让它们使用同一张贴图。
// 加载贴图
const textureLoader = new THREE.TextureLoader()
const texture = textureLoader.load('/texture/uv_grid_opengl.jpg')
// 创建一个几何平面
const planeGeometry = new THREE.PlaneGeometry(2, 2)
const planeMaterial = new THREE.MeshBasicMaterial({ map: texture })
const plane = new THREE.Mesh(planeGeometry, planeMaterial)
plane.position.x = -2
scene.add(plane)
// 创建和上面 planeGeometry 尺寸一样的几何平面
const planeGeometry2 = new THREE.BufferGeometry()
const vertices = new Float32Array([
-1, -1, 0,
1, -1, 0,
1, 1, 0,
-1, 1, 0,
])
planeGeometry2.setAttribute('position', new THREE.BufferAttribute(vertices, 3))
const indices = new Uint16Array([0, 1, 2, 0, 2, 3])
planeGeometry2.setIndex(new THREE.BufferAttribute(indices, 1))
const planeMaterial2 = new THREE.MeshBasicMaterial({ map: texture })
const plane2 = new THREE.Mesh(planeGeometry2, planeMaterial2)
plane2.position.x = 2
scene.add(plane2)
可以看到第一个平面正确加载了贴图,第二个平面没有加载贴图。
打印一下 planeGeometry.attribute.uv
和 planeGeometry2.attribute.uv
,可以看到它们是不同的:
planeGeometry
的 uv
属性是 Float32Array
类型,而 planeGeometry2
的 uv
属性是 undefined
。
设置一下 planeGeometry2
的 uv
属性:
// 设置 uv 坐标
const uv = new Float32Array([
0, 0,
1, 0,
1, 1,
0, 1,
])
planeGeometry2.setAttribute('uv', new THREE.BufferAttribute(uv, 2))
可以看到第二个平面正确加载了贴图。
本节示例代码:https://github.com/wukaipeng-dev/threejs-demo/blob/main/03-geometry/src/main-uv.ts