最近在做自定义几何体(平面)示例的时候,发现加上贴图后并没有得到想要的结果,代码是这样的:
//创建几何体
var geometry=new THREE.Geometry();
var vertices=[
new THREE.Vector3(0,0,0),
new THREE.Vector3(100,0,0),
new THREE.Vector3(100,100,0),
new THREE.Vector3(0,100,0),
];
var faces=[
new THREE.Face3(0, 1, 2),
new THREE.Face3(0, 2, 3)
];
geometry.vertices = vertices;
geometry.faces = faces;
geometry.computeFaceNormals();//计算法向量 这决定了对光做出的反应
material = new THREE.MeshLambertMaterial({
map:new THREE.TextureLoader().load("./img/pic1.jpg"),
side: THREE.DoubleSide,
// color: "red",
opacity: 1,
depthWrite: false,
transparent: true // 定义此材质是否透明
});
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
理想的结果:
实际的结果:
然后想到了,自定义的geometry是不会自动设置UV坐标的,那如何给它设置合适的UV坐标呢。这需要对UV坐标有一定的了解。
可以将需要贴图的图片,给它设定一个坐标系作为图片的定位,该坐标系就是UV坐标了。在贴图时,可以根据图片的UV坐标,对应到Three.js的每个三角面进行贴图。
在Three.js中可以定义好uv坐标,与每个三角面一一对应。
代码如下:
//创建几何体
var geometry=new THREE.Geometry();
var vertices=[
new THREE.Vector3(0,0,0),
new THREE.Vector3(100,0,0),
new THREE.Vector3(100,100,0),
new THREE.Vector3(0,100,0),
];
var faces=[
new THREE.Face3(0, 1, 2),
new THREE.Face3(0, 2, 3)
];
geometry.vertices = vertices;
geometry.faces = faces;
geometry.computeFaceNormals();//计算法向量 这决定了对光做出的反应
material = new THREE.MeshLambertMaterial({
map:new THREE.TextureLoader().load("./img/pic1.jpg"),
side: THREE.DoubleSide,
// color: "red",
opacity: 1,
depthWrite: false,
transparent: true // 定义此材质是否透明
});
//几何体UV坐标定义
var t0 = new THREE.Vector2(0, 0); //图片左下角
var t1 = new THREE.Vector2(1, 0); //图片右下角
var t2 = new THREE.Vector2(1, 1); //图片右上角
var t3 = new THREE.Vector2(0, 1); //图片左上角
var uv1 = [t0, t1, t2]; //选中图片一个三角区域像素——用于映射到一个三角面
var uv2 = [t0, t2, t3]; //选中图片一个三角区域像素——用于映射到一个三角面
geometry.faceVertexUvs[0][0] = uv1;
geometry.faceVertexUvs[0][1] = uv2;
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
效果:
如果想要重复多次贴图或者只贴一部分,只需要设计好贴图的UV坐标既可以了,如下修改UV部分代码:
//几何体UV坐标定义
var t0 = new THREE.Vector2(0, 0); //图片左下角
var t1 = new THREE.Vector2(0.5, 0); //图片右下角
var t2 = new THREE.Vector2(0.5, 0.5); //图片右上角
var t3 = new THREE.Vector2(0, 0.5); //图片左上角
var uv1 = [t0, t1, t2]; //选中图片一个三角区域像素——用于映射到一个三角面
var uv2 = [t0, t2, t3]; //选中图片一个三角区域像素——用于映射到一个三角面
geometry.faceVertexUvs[0][0] = uv1;
geometry.faceVertexUvs[0][1] = uv2;
效果:
实际上我们的几何体是有非常多的三角面组合而成的,为每个三角面设置好合适的uv坐标就可以实现多种多样的个性化贴图了。
贴图与uv坐标