three.js使用(7)模型对象贴图的设置,以及对贴图的操作

8,656 阅读5分钟

这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战

纹理贴图

1.给模型对象设置纹理贴图

通过TextureLoader加载一张图片后返回一个纹理对象Texture,Texture可以作为模型材质颜色贴图.map属性的值,设置map属性后就不用再设置color属性了

// 纹理贴图映射到一个矩形平面上
var geometry = new THREE.PlaneGeometry(204, 102); //矩形平面
// TextureLoader创建一个纹理加载器对象,可以加载图片作为几何体纹理
var textureLoader = new THREE.TextureLoader();
// 执行load方法,加载纹理贴图成功后,返回一个纹理对象Texture
textureLoader.load('Earth.png', function(texture) {
  var material = new THREE.MeshLambertMaterial({
    // color: 0x0000ff,
    // 设置颜色纹理贴图:Texture对象作为材质map属性的属性值
    map: texture,//设置颜色贴图属性值
  }); //材质对象Material
  var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
  scene.add(mesh); //网格模型添加到场景中
function render() {
    renderer.render(scene, camera);
}
  //纹理贴图加载成功后,调用渲染函数执行渲染操作
  render();
})

通过图片加载器ImageLoader可以加载一张图片,所谓纹理对象Texture简单地说就是,纹理对象Texture的.image属性值是一张图片。

// 图片加载器
var ImageLoader = new THREE.ImageLoader();
// load方法回调函数,按照路径加载图片,返回一个html的元素img对象
ImageLoader.load('Earth.png', function(img) {
  // image对象作为参数,创建一个纹理对象Texture
  var texture = new THREE.Texture(img);
  // 下次使用纹理时触发更新
  texture.needsUpdate = true;
  var material = new THREE.MeshLambertMaterial({
    map: texture, //设置纹理贴图
  });
  var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
  scene.add(mesh); //网格模型添加到场景中
});

2.纹理贴图的平铺,旋转,偏移,动画

1. 平铺

var texture = textureLoader.load('太阳能板.png');
// 设置阵列模式   默认ClampToEdgeWrapping  RepeatWrapping:阵列  镜像阵列:MirroredRepeatWrapping
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
// uv两个方向纹理重复数量
texture.repeat.set(4, 2);

2 .偏移

texture.offset = new THREE.Vector2(0.3, 0.1)

2 .旋转

// 设置纹理旋转角度
texture.rotation = Math.PI/4;
// 设置纹理的旋转中心,默认(0,0)
texture.center.set(0.5,0.5);

3 .动画

在渲染函数中周期性的改变纹理贴图的属性,重复执行渲染函数就可以实现动画

function render() {
  renderer.render(scene, camera); //执行渲染操作
  requestAnimationFrame(render);
  // 使用加减法可以设置不同的运动方向
  // 设置纹理偏移
  texture.offset.x -= 0.06
}
render();

3.canvas画布、视频作为纹理贴图

4.凹凸贴图和法线贴图

这两种贴图都是为了处理模型顶点过多导致贴图不清晰的问题

var geometry = new THREE.SphereGeometry(100, 25, 25); //球体

//法线贴图

// TextureLoader创建一个纹理加载器对象,可以加载图片作为几何体纹理
var textureLoader = new THREE.TextureLoader();
// 加载纹理贴图
var texture = textureLoader.load('./Earth.png');
// 加载法线贴图
var textureNormal = textureLoader.load('./EarthNormal.png');
var material = new THREE.MeshPhongMaterial({
  map: texture, // 普通颜色纹理贴图
  normalMap: textureNormal, //法线贴图
  //设置深浅程度,默认值(1,1)。
  normalScale: new THREE.Vector2(1.2, 1.2),
}); //材质对象Material

//凹凸贴图

var textureLoader = new THREE.TextureLoader();
// 加载颜色纹理贴图
var texture = textureLoader.load('./凹凸贴图/diffuse.jpg');
// 加载凹凸贴图
var textureBump = textureLoader.load('./凹凸贴图/bump.jpg');
var material = new THREE.MeshPhongMaterial({
  map: texture,// 普通纹理贴图
  bumpMap:textureBump,//凹凸贴图
  bumpScale:3,//设置凹凸高度,默认值1。
}); //材质对象Material

5.光照贴图(给模型添加阴影)

三维模型加载器可以自动设置,不需要程序员通过代码去设置,但还是操作一下

//创建一个平面几何体作为投影面
var planeGeometry = new THREE.PlaneGeometry(300, 200);

planeGeometry.faceVertexUvs[1] = planeGeometry.faceVertexUvs[0];
var textureLoader = new THREE.TextureLoader();
// 加载光照贴图
var textureLight = textureLoader.load('shadow.png');
var planeMaterial = new THREE.MeshLambertMaterial({
  color: 0x999999,
  lightMap:textureLight,// 设置光照贴图
  // lightMapIntensity:0.5,//烘培光照的强度. 默认 1.
});
var planeMesh = new THREE.Mesh(planeGeometry, planeMaterial); //网格模型对象Mesh

Geometry属性.faceVertexUvs

一般几何体有两套UV坐标,对于Geometry类型几何体而言 Geometry.faceVertexUvs[0]包含的纹理坐标用于颜色贴图map、法线贴图normalMap等,Geometry.faceVertexUvs[1]包含的第二套纹理贴图用于光照贴图 一般通过Threejs几何体API创建的几何体默认只有一组纹理坐标Geometry.faceVertexUvs[0],所以为了设置光照阴影贴图,需要给另一组纹理坐标赋值Geometry.faceVertexUvs[1] = Geometry.faceVertexUvs[0];

BufferGeometry属性.uv和.uv2

一般通过Threejs加载外部模型,解析三维模型数据得到的几何体类型是缓冲类型几何体BufferGeometry,对于BufferGeometry而言两套纹理坐标分别通过.uv和.uv2属性表示。

geometry.attributes.uv2 = geometry.attributes.uv;

6.高光贴图(设置模型不同区域的亮度值)

设置模型不同区域的亮度值,(高光贴图属性.specularMap和高光属性.specular是对应的,也就是说只有高光网格材质对象MeshPhongMaterial才具备高光贴图属性.specularMap)

// 加载纹理贴图
var texture = textureLoader.load('earth_diffuse.png');
// 加载高光贴图
var textureSpecular = textureLoader.load('earth_specular.png');
var material = new THREE.MeshPhongMaterial({
  // specular: 0xff0000,//高光部分的颜色
  shininess: 30,//高光部分的亮度,默认30
  map: texture,// 普通纹理贴图
  specularMap: textureSpecular, //高光贴图
}); //材质对象Material

7.环境贴图(给模型的周围环境添加贴图)

首先引入CubeTextureLoader(只有环境贴图用CubeTextureLoader,其他贴图用的是TextureLoader),然后给材质对象设置envMap属性,一般情况下高光网格材质MeshPhongMaterial和物理PBR材质MeshStandardMaterial会使用环境贴图

var geometry = new THREE.BoxGeometry(100, 100, 100); //立方体

var loader = new THREE.CubeTextureLoader();
// 所有贴图在同一目录下,可以使用该方法设置共用路径
loader.setPath('环境贴图/');
// 立方体纹理加载器返回立方体纹理对象CubeTexture
var CubeTexture = loader.load(['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg']);
//材质对象Material
var material = new THREE.MeshPhongMaterial({
  //网格模型设置颜色,网格模型颜色和环境贴图会进行融合计算
  // color:0xff0000,
  envMap: CubeTexture, //设置环境贴图
  // 环境贴图反射率   控制环境贴图对被渲染三维模型影响程度
  // reflectivity: 0.1,
});
console.log(CubeTexture.image);
var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
scene.add(mesh); //网格模型添加到场景中