中文 英文 本质 解释
材质 Materail 数据集 核心在于 物体对光的交互 ,供渲染器读取数据集,包括贴图纹理,光照算法
纹理贴图 Texture mapping 图像映射规则 核心在于 把存在内存的位图 ,通过UV坐标映射到渲染物体表面

Three.js一共提供了如下几种材质:

  • LineBasicMaterial
  • LineDashedMaterial
  • MeshBasicMaterial
  • MeshDepthMaterial
  • MeshDistanceMaterial
  • MeshLambertMaterial
  • MeshMatcapMaterial
  • MeshNormalMaterial
  • MeshPhongMaterial
  • MeshPhysicalMaterial
  • MeshStandardMaterial
  • MeshToonMaterial
  • PointsMaterial
  • RawShaderMaterial
  • ShaderMaterial
  • ShadowMaterial
  • SpriteMaterial
  • 下面选择几个重点介绍一下

    有2种方法可以设置大部分的材质属性。 一种是在实例化的时候设置

    const material = new THREE.MeshPhongMaterial({
      color: 0xFF0000,    // 红色 (也可以使用CSS的颜色字符串)
      flatShading: true,
    

    另一种是在实例化之后设置

    const material = new THREE.MeshPhongMaterial();
    material.color.setHSL(0, 1, .5);  // 红色
    material.flatShading = true;
    

    THREE.Color

    Three.js中,对颜色的操作都是通过THREE.Color实现的,可以通过多种凡是去设置属性。

    material.color.set(0x00FFFF);    // 同 CSS的 #RRGGBB 风格
    material.color.set(cssString);   // 任何 CSS 颜色字符串, 比如 'purple', '#F32',
                                     // 'rgb(255, 127, 64)',
                                     // 'hsl(180, 50%, 25%)'
    material.color.set(someColor)    // 其他一些 THREE.Color
    material.color.setHSL(h, s, l)   // 其中 h, s, 和 l 从 0 到 1
    material.color.setRGB(r, g, b)   // 其中 r, g, 和 b 从 0 到 1
    

    在实例化时,你可以传递一个十六进制数字或CSS字符串作为参数。

    const m1 = new THREE.MeshBasicMaterial({color: 0xFF0000});         // 红色
    const m2 = new THREE.MeshBasicMaterial({color: 'red'});            // 红色
    const m3 = new THREE.MeshBasicMaterial({color: '#F00'});           // 红色
    const m4 = new THREE.MeshBasicMaterial({color: 'rgb(255,0,0)'});   // 红色
    const m5 = new THREE.MeshBasicMaterial({color: 'hsl(0,100%,50%)'); // 红色
    

    接下来看看three.js的几种材质的效果。

    MeshBasicMaterial、MeshLambertMaterial、MeshPhongMaterial

    首先是MeshBasicMaterial,其特点在于不受光照的影响。而MeshLambertMaterial 只在顶点计算光照,然后 MeshPhongMaterial 则在每个像素计算光照,并且MeshPhongMaterial 还支持镜面高光。

    对于MeshPhongMaterialshininess(光泽度) 设置决定了镜面高光的光泽度。它的默认值是30。通过设置不同的数值,可以看到下面的效果:

    需要注意一点的是将 MeshLambertMaterialMeshPhongMaterial 的 emissive( 发光度 属性设置为颜色,并将颜色设置为黑色(phong的 shininess 为0),最终看起来就像 MeshBasicMaterial 一样。

    在实际工作应用场景中,可以根据不同的场景需求选用不同的材质,这也是为什么Three.js提供了这几种基本材质的原因。因为是更复杂的材质会消耗更多的GPU功耗。在一个较慢的GPU上,比如说手机,一般使用一个不太复杂的材质来减少绘制场景所需的GPU功耗。同样,如果不需要额外的功能,那就使用最简单的材质,已达到最佳的性能。如果你不需要照明和镜面高光,那么就使用 MeshBasicMaterial 。

    MeshToonMaterial

    MeshToonMaterial MeshPhongMaterial 类似,但有一个很大的不同。它不是平滑地着色,而是使用一个渐变图(一个X乘1的纹理(X by 1 texture))来决定如何着色。默认使用的渐变图是前70%的部分,使用70%的亮度,之后的部分使用100%的亮度,我们可以定义自己的渐变图。这最终会给人一种两种色调的感觉。使用MeshToonMaterial材质之后的效果如下:

    MeshStandardMaterial

    接下来介绍一下图形学上经常提到的PBR,其全称是Physically Based Rendering,俗称物理渲染。Three.js提供了两种材质用于物理渲染,分别是MeshStandardMaterialMeshPhysicalMaterial

    上面提到的材质只是使用简单的数学来实现的,虽然看起来是3D的,但它们并不是现实世界中实际存在的东西。而MeshStandardMaterialMeshPhysicalMaterialPBR材质使用的是更复杂的数学来实现接近现实世界中的效果。

    MeshPhongMaterialMeshStandardMaterial 最大的区别是它们使用的参数不同MeshPhongMaterial一个参数用来设置 shininess 属性。MeshStandardMaterial2个参数用来分别设置 roughnessmetalness 属性。

    在某种意义上将,roughness(粗糙度)shininess(光泽度)是相反的 。粗糙度(roughness)高的东西,比如棒球,就不会有很强烈的反光,而不粗糙的东西,比如台球,就很有光泽。其设置范围从0到1。

    另一个设定,metalness,说的是材质的金属度。金属与非金属的表现不同。0代表非金属,1代表金属。

    下图是一个MeshStandardMaterial 快速示例,从左至右看,粗糙度从0到1,从上至下看,金属度从0到1。

    MeshPhysicalMaterial

    MeshPhysicalMaterial 与 MeshStandardMaterial 相同,但它增加了一个clearcoat 参数,该参数从0到1,决定了要涂抹的清漆光亮层的程度,还有一个 clearCoatRoughness 参数,指定光泽层的粗糙程度。

    这里是和上面一样的以二维网格的形式对比,但可以设置 clearcoatclearCoatRoughness

    各种标准材质的创建速度从最快到最慢顺序如下: MeshBasicMaterial -> MeshLambertMaterial-> MeshPhongMaterial-> MeshStandardMaterial-> MeshPhysicalMaterial 创建速度越慢的材质,做出的场景越逼真,但在低功率或移动设备上可能会有性能问题,所以在实际应用中需要根据具体场景进行优化。

    接下来的3种材质有特殊用途。

    ShadowMaterial 用于获取阴影创建的数据。

    MeshDepthMaterial 渲染每个像素的深度,其中处在摄像机负近端面的像素其深度为0,处在摄像机负远端面的像素其深度为1。使用这个属性可以实现一些特殊效果。一个简单的例子

  • side:要显示三角形的哪个面。默认值是 THREE.FrontSide,其他值THREE.BackSideTHREE.DoubleSide(正反两面)。Three.js中,大多数3D对象可能都是不透明的实体,所以不需要绘制反面(面向实体内部的面)。设置 side 的最常见的原因是用于绘制平面或其他非实体对象,在这些对象中通常会看到三角形的反面。
  • 下面是用 THREE.FrontSideTHREE.DoubleSide 绘制的6个平面对比效果

    material.needsUpdate:Three.js会在使用材质时应用材质设置,也就是使用了材质的物体会被渲染。有些材质设置只应用一次,因为改变材质需要消耗很多资源。在这种情况下,需要设置 material.needsUpdate = true 来告诉 three.js 应用材质的变化。当你在使用材质后再去更改设置,需要去设置 needsUpdate的最常见的几种情况:

    flatShading

    添加或删除纹理,改变纹理是可以的,但是如果想从使用无纹理切换到使用纹理,或者从使用纹理切换到无纹理,那么你需要设置 needsUpdate = true。

    本文介绍了Three.js的材质相关的内容,包含了MeshBasicMaterial、MeshLambertMaterial、MeshPhongMaterial、MeshToonMaterial、MeshStandardMaterial、MeshPhysicalMaterial,希望对有帮助

    本文发布自 云图三维大前端团队,文章未经授权禁止任何形式的转载。

    分类:
    前端
    标签: