WebGL three.js学习笔记 6种类型的纹理介绍及应用

WebGLthree.js学习笔记6种类型的纹理介绍及应用本文所使用到的demo演示:高光贴图Demo演示反光效果Demo演示(因为是加载的模型,所以速度会慢)(一)普通纹理计算机图形学中的纹理既包括通常意义上物体表面的纹理即使物体表面呈现凹凸不平的沟纹,同时也包括在物体的光滑表面上的彩色图案,所谓的纹理映射就是在物体的表面上绘制彩色的图案。在three.js中使用纹理可以实现很多不同的效果,但是...

WebGL three.js学习笔记 6种类型的纹理介绍及应用

WebGL three.js学习笔记 6种类型的纹理介绍及应用

本文所使用到的demo演示:

高光贴图Demo演示

反光效果Demo演示(因为是加载的模型,所以速度会慢)

(一)普通纹理

计算机图形学中的纹理既包括通常意义上物体表面的纹理即使物体表面呈现凹凸不平的沟纹,同时也包括在物体的光滑表面上的彩色图案,所谓的纹理映射就是在物体的表面上绘制彩色的图案。

在three.js中使用纹理可以实现很多不同的效果,但是最基本的就是为网格体的每个像素指定颜色。等同于将一张纹理图片应用在一个几何体的材质上。

使用的方式很简单,只需要设置
material.map = 需要设置的纹理对象
纹理对象的获得方式也很简单,只需要使用THREE.TextureLoader().load(url)函数就可以为url指定路径的纹理图片创建一个对象。具体的使用方式如下:

  let texture = new THREE.TextureLoader().load(“../../../Image/metal-rust.jpg“);  let material = new THREE.MeshBasicMaterial();  material.map = texture;  let geometry = new THREE.BoxGeometry(10,10,10);  let cube = new THREE.Mesh(geometry,material);  scene.add(cube);

其中,“../../../Image/metal-rust.jpg“是我使用的纹理的路径,图片就是下面这一张
纹理贴图1
创建出来的带有上图纹理的cube就是这样的
普通纹理
除了THREE.TextureLoader()这个加载器以为,three.js还为我们提供了其他自定义的加载器,如dds格式,pvr格式,tga格式。

就拿tga格式举例,我们要加载tga格式的纹理,首先需要引用TGALoader.js这个文件,然后创建一个tga格式的加载器
let loader = new THREE.TGALoader();
我们就可以使用loader这个加载器,像上面一样的加载tga格式的纹理了。
具体代码如下:

  let loader = new THREE.TGALoader();  let texture = loader.load(“../../../Image/crate_color8.tga“);  let material = new THREE.MeshBasicMaterial();  material.map = texture;  let geometry = new THREE.BoxGeometry(10,10,10);  let cube = new THREE.Mesh(geometry,material);  scene.add(cube);

下面是我使用的tga格式的纹理图片(只能上传截图,tga格式图片的这里上传不了)
tga纹理图片
运行出来是这个样子的
tga纹理
其他格式的加载也是和tga格式加载方法一样的,只需要引入相应的js文件就可以使用了。

(二)凹凸贴图

凹凸纹理用于为材质添加厚度与深度,如字面意思一样,可以让材质看上去是凹凸不平的。凹凸贴图只包含像素的相对高度,像素的密集程度定义凹凸的高度,所以想要让物体好看,首先还是应该设置一个普通的纹理,再在这个基础上添加一个凹凸纹理,就可以实现凹凸不平的物体效果。
凹凸贴图的创建方法很简单,和普通纹理类似,只是我们设置的不是map,而是bumpMap
material.bumpMap = 需要设置的纹理对象

特别需要注意的是,这里的材质只能使用MeshPhongMaterial,凹凸贴图才会有效果。
具体的设置方法如下:

  let geom = new THREE.BoxGeometry(10, 10, 10);    //创建普通纹理材质  let texture = new THREE.TextureLoader().load(“../../../Image/stone.jpg“);  let material = new THREE.MeshPhongMaterial({map:texture  });  cube = new THREE.Mesh(geom,material);  cube.position.set(-7,0,0);  scene.add(cube);  //创建凹凸纹理材质  let bumpTexture = new THREE.TextureLoader().load(“../../../Image/stone-bump.jpg“);  let bumpMaterial = new THREE.MeshPhongMaterial({map:texture,bumpMap:bumpTexture,bumpScale:2  });  bumpCube = new THREE.Mesh(geom,bumpMaterial);  bumpCube.position.set(7,0,0);  scene.add(bumpCube);

其中material.bumpScale可以设置凹凸的高度,如果为负值,则表示的是深度。

运行程序截图如下:
左边材质的是普通的纹理贴图,右边的材质是带有凹凸纹理的,当前bumpScale设置的是2,两者看上去有比较明显的不同
凹凸纹理
使用的纹理图片如下:
纹理2
凹凸纹理图片:
凹凸纹理

我们可以发现,凹凸图只包含了像素的相对高度,没有任何的倾斜的方向信息,所以使用凹凸纹理能表达的深度信息有限,如果想用实现更多的细节可以使用下面介绍的法向贴图。

(三)法向贴图

法向贴图保存的不是高度的信息,而是法向量的信息,我们使用法向贴图,只需要很少的顶点和面就可以实现很丰富的细节。
同样的,实现法向贴图和凹凸贴图也很类似,只需要设置
material.normalMap = 需要设置的纹理对象

同样也是在MeshPhongMaterial材质中才有效果,还要注意的一点是设置normalScale指定材质的凹凸程度时,normalScale需要接受的是一个THREE.Vector2类型

具体的代码如下:

  let geom = new THREE.BoxGeometry(10, 10, 10);  //创建普通纹理材质  let texture = new THREE.TextureLoader().load(“../../../Image/plaster.jpg“);  let material = new THREE.MeshPhongMaterial({map:texture  });  cube = new THREE.Mesh(geom,material);  cube.position.set(-7,0,0);  scene.add(cube);  //创建凹凸纹理材质  let normalTexture = new THREE.TextureLoader().load(“../../../Image/plaster-normal.jpg“);  let normalMaterial = new THREE.MeshPhongMaterial({map:texture,normalMap:normalTexture,normalScale:new THREE.Vector2(1,1)  });  normalCube = new THREE.Mesh(geom,normalMaterial);  normalCube.position.set(7,0,0);  scene.add(normalCube);

场景如下图,右边的是带有法向纹理的物体,明显感觉出材质的细节多出来了很多。
法向贴图
用到的纹理图
plaster
法向纹理图:
plaster-normal
虽然法向纹理能带给物体更逼真的效果,但是想要创建法向纹理图,本身就比较困难,需要ps或者blender这样的特殊工具。

(四)光照贴图

如果我们想在场景中添加阴影,three.js给我们提供了renderer.shadowMapEnabled = true这个办法,但是这对于资源的消耗是很大的。如果我们只是需要对静态的物体添加阴影效果,我们就有一种开销很小的办法,那就是光照贴图。
光照贴图是预先渲染好的阴影贴图,可以用来模拟真实的阴影。我们能使用这种技术创建出分辨率很高的阴影,并且不会损耗渲染的性能。因为是提前根据场景渲染好的,所以只对静态的场景有效。

比如下面这张光照贴图:
光照贴图
设置光照贴图的方式很简单,只需要设置
material.lightMap = 需要设置的纹理对象
和前面两个没什么太大的区别。当纹理设置好以后,我们还需要把我们的物体摆放在正确的位置,这样阴影效果才会真实的显现出来。

  let lightMap = new THREE.TextureLoader().load(“../../../Image/lm-1.png“);  let map =  new THREE.TextureLoader().load(“../../../Image/floor-wood.jpg“);  //创建地板  let planeGeo = new THREE.PlaneGeometry(95,95,1,1);  planeGeo.faceVertexUvs[1] = planeGeo.faceVertexUvs[0];  let planeMat = new THREE.MeshBasicMaterial({color:0x999999,lightMap:lightMap,//在地板的材质上添加光照贴图map:map//地板的普通纹理材质  });  let plane = new THREE.Mesh(planeGeo,planeMat);  plane.rotation.x = -Math.PI / 2;  plane.position.y = 0;  scene.add(plane);  //创建大的cube  var boxGeo = new THREE.BoxGeometry(12,12,12);  var material = new THREE.MeshBasicMaterial();  material.map = new THREE.TextureLoader().load(“../../../Image/stone.jpg“);  var box = new THREE.Mesh(boxGeo,material);  box.position.set(0.9,6,-12);  scene.add(box); 
源文地址:https://www.guoxiongfei.cn/cntech/17078.html