封面图

第178期:threejs中的材质(一)_线框

画画这个东西就是想画就画,不想画就不画,跟写文章一样,想写就写,不想写就不写。因为画画这本身就是一件陶冶性情的事儿,既然是为了陶冶性情,那么自己高兴就好了,就好比我儿子画了一幅画,然后很高兴的对我说:看,我画了一条超级大鲨鱼。虽然我看不懂他画的内容,但这其实无关紧要,他自己高兴就好。

就好像写文章一样,我写文章的本质就是记录一下自己想法,可能某一个时刻对某些技术产生了一种强烈的想法,或者在工作中遇到了一些问题,又或者对生活中的一些问题有些自己的见解,随手记录一下,能分享的风分享一下,当然,既然是分享,那么就尽可能的将问题描述清楚,以方便有同样问题的同学做个参考,仅此而已。

材质

LineBasicMaterial

线条基本材质,用于绘制线框样式几何图形的材质。

它的构造器接收的参数是一个对象,这个对象中有以下几个属性:

  • color-材质的颜色,默认情况下设置为白色(0xffffff)。
  • linewidth-控制线条厚度。默认值为1。
  • inecap- 定义线条端点的外观。可能的值有“butt”、“round”和“square”。默认值为“圆形”。
  • linejoin-定义线条连接的外观。可能的值有“round”、“bevel”和“mite”。默认值为“圆形”
  • map-使用纹理中的数据设置线条的颜

我们在实际开发过程中,尤其是在加载模型的过程当中最常用map来添加贴图纹理。

它的具体的使用示例代码如下:

const material = new THREE.LineBasicMaterial( {
  color: 0xffffff,
  linewidth: 1,
  linecap: 'round', //ignored by WebGLRenderer
  linejoin:  'round' //ignored by WebGLRenderer
} );

官网有一个非常炫酷的示例,如下:

第178期:threejs中的材质(一)_JavaScript_02

这个示例是将PointsMaterial 和 LineBasicMaterial结合在一起形成的效果,在后面的示例中我们会慢慢的一起了解它的实现过程,在此之前,我们需要系统的学习和了解threejs中所包含的基本的材质有哪些。

LinerDashedMaterial

用于绘制具有虚线的线框样式几何图形的材质。

它的构造器接收以下参数:

  • dashSize-笔划之间的间隙。默认值为3。
  • gapSize-间隙的大小。默认值为1。
  • isLineDashedMaterial-只读标志,用于检查给定对象的类型是否为LineDashedMaterial。
  • scale-直线虚线部分的比例。默认值为1。

当然除此之外,它还继承了linebasicmaterial材质的属性。

它的使用时的示例代码如下:

const material = new THREE.LineDashedMaterial( {
  color: 0xffffff,
  linewidth: 1,
  scale: 1,
  dashSize: 3,
  gapSize: 1,
} );

官网的示例如图所示:

第178期:threejs中的材质(一)_前端_03

MeshBasicMaterial

一种用于以简单的着色(平面或线框)方式绘制几何图形的材质。

这种材质不受灯光的影响。

官方给了一个下面的示例:

第178期:threejs中的材质(一)_前端_04

它这里应该是用了一个十字结的几何体,然后赋了一个meshbasicmaterial的材质,然后修改环境光的颜色,材质并不受其影响。

meshbasicmaterial的构造器参数对象包括以下属性:

  • alphaMap- alphaMap是一个灰度纹理,用于控制整个曲面的不透明度(黑色:完全透明;白色:完全不透明)。
  • aoMap-该纹理的红色通道用作环境光遮挡贴图。默认值为null。aoMap需要第二组UV。
  • aoMapIntensity-环境光遮挡效果的强度。默认值为1。零表示没有遮挡效果。
  • color-材质的颜色,默认情况下设置为白色(0xffffff)。
  • combine-如何将曲面颜色的结果与环境贴图相结合(如果有)。选项为THREE.MultlyOperation(默认)、THREE.MixOperation、THREE.AddOperation。如果选择了mix,则使用.reflexibility在两种颜色之间混合。
  • envMap-环境地图。默认值为null。
  • fog-材质是否受到雾的影响。默认值为true。
  • lightMap-光照贴图。默认值为null。lightMap需要第二组UV。
  • lightMapIntensity- 光照贴图强度。
  • map-贴图。可以选择包括alpha通道,通常与.transparent或.alphaTest组合使用。默认值为null。
  • reflectivity-反射率。环境贴图对曲面的影响程度;默认值为1,有效范围介于0(无反射)和1(全反射)之间。
  • specularMap-镜面反射贴图。材质使用的镜面反射贴图。默认值为null。
  • wireframe-将几何体渲染为线框。默认值为false。
  • wireframeLinecap-定义线条端点的外观。可能的值有“butt”、“round”和“square”。默认值为“square”。
  • wireframeLinejoin-定义线条连接的外观。可能的值有"round", "bevel" 以及 "miter".。默认值为“round”。
  • wireframeLinewidth-控制线框厚度。默认值为1。

关于贴图,这里有几个概念需要注意:

  • alphaMap
  • aoMap
  • envMap
  • lightMap
  • map
  • specularMap

这里先简单提出这个问题,后面会慢慢的详细解释这几个贴图的异同点。

meshbasicmaterial的使用方式示例代码如下:

// 围墙
  obj.children[0].material = new THREE.MeshBasicMaterial({
    side: THREE.DoubleSide,
    map: textLan,
    transparent: true,
  })

MeshDepthMaterial

一种按深度绘制几何图形的材料。“深度”基于摄影机的近平面和远平面。白色是最近的,黑色是最远的。

第178期:threejs中的材质(一)_默认值_05

它的构造器参数如下:

  • alphaMap- alphaMap是一个灰度纹理,用于控制整个曲面的不透明度(黑色:完全透明;白色:完全不透明)。
  • depthPacking-深度填料类型。默认值为BasicDepthPacking。
  • displacementMap-置换贴图。置换贴图会影响网格顶点的位置。与其他仅影响材质明暗度的贴图不同,置换的顶点可以投射阴影、阻挡其他对象,并以其他方式充当真实的几何体。置换纹理是一个图像,其中每个像素的值(白色是最高的)都映射到网格的顶点,并重新定位网格的顶点。
  • displacementScale-位移比例。换贴图对网格的影响程度(其中黑色表示无置换,白色表示最大置换)。如果未设置位移贴图,则不会应用此值。默认值为1。
  • displacementBias-位移偏移。置换贴图的值在网格顶点上的偏移。如果未设置位移贴图,则不会应用此值。默认值为0。
  • fog-材质是否受到雾的影响。默认值为true。
  • map-贴图。可以选择包括alpha通道,通常与.transparent或.alphaTest组合使用。默认值为null。
  • wireframe-将几何体渲染为线框。默认值为false。
  • wireframeLinewidth-控制线框厚度。默认值为1。

最后

关于threejs中的材质今天先介绍到这里,因为最近一直想把文档中的内容细致的过一遍,然后结合自己能找的案例,以及之前写过的项目中所涉及到的车道线的部分系统的学习一下threejs ,所以这个专栏会不定时的更新关于threejs 的内容,有兴趣的同学可以关注一下,一起学习。

其他

这两天遇到的一个关于加载模型时候的一个问题:通常情况下,我们加载obj模型,原本是可以直接加载mtl文件格式的贴图,但是从模型网站下载了一个模型,附带的有mtl 的文件,当我用代码加载的时候,贴图就是不展示,我怀疑这个mtl的文件应该是少点什么内容。

第178期:threejs中的材质(一)_线框_06

代码如下:

const renderGeomtry = () => {

  const mtlLoader = new MTLLoader()
  const objLoader = new OBJLoader()
  /**
  * OBJ和材质文件mtl加载
  */
  var OBJLoaderer = new OBJLoader(); //obj加载器
  var MTLLoaderer = new MTLLoader(); //材质文件加载器
  MTLLoaderer.load('src/assets/IRONMAN/Ironman.mtl', function (materials) {
    // 返回一个包含材质的对象MaterialCreator
    materials.preload()
    console.log('materials', materials);
    //obj的模型会和MaterialCreator包含的材质对应起来
    OBJLoaderer.setMaterials(materials);
    // OBJLoaderer.setPath('')
    OBJLoaderer.load('src/assets/Ironman.obj', function (obj) {
      console.log(obj);
    
      scene.add(obj); //返回的组对象插入场景中
      
    })
  })
}

理论上OBJLoaderer.setMaterials(materials);执行过之后,mtl贴图应该就可以展示出来了,但是却没展示出来,如果哪位同学有关于mtl文件格式的资料,可以推荐给我学习一下,谢谢。