three.js学习笔记2-纹理

671 阅读4分钟

本篇主要是了解threejs中的纹理贴图,这里主要记录的是纹理材质和环境纹理。

纹理(Texture)

官方解释:创建一个纹理贴图,将其应用到一个表面,或者作为反射/折射贴图。

我的理解:包裹在物体表面的包装纸。可以使用一个或多个不同作用的纹理贴图叠加,使物体更逼真。

纹理的常用属性

    import {Scene,PerspectiveCamera,WebGLRenderer, BoxGeometry, MeshBasicMaterial,Mesh,AxesHelper,TextureLoader, MirroredRepeatWrapping, RepeatWrapping} from 'three'
    
    const textureLoader = new TextureLoader()
    const customerColorTexture = textureLoader.load('/cute.jpg')

    // 纹理常用属性
    // 设置纹理偏移
    // customerColorTexture.offset.x = 0.5
    // customerColorTexture.offset.y = 0.5
    // customerColorTexture.offset.set(.1,.1)

    // 纹理旋转
    // 设置旋转的原点
    // customerColorTexture.center.set(.1,.1)
    // 旋转45°
    // customerColorTexture.rotation = Math.PI / 4

    // 设置纹理的重复
    customerColorTexture.repeat.set(2,3)

    // 设置纹理的重复模式
    customerColorTexture.wrapS = MirroredRepeatWrapping
    customerColorTexture.wrapT = RepeatWrapping

纹理贴图的区分

纹理贴图:在材质中加载纹理,通过Material的map属性进行加载。

有时候我们拿到一组纹理素材时,会发现里面有各种不同的贴图,常见的大概是以下几种:

图片.png

或者我们可以通过以下一些关键词来区分不同的纹理贴图,然后设置材质的相应属性:

图片.png

纹理贴图的使用

以下是纹理贴图的主要代码,注释中对不同的贴图的作用也进行了说明: MeshStandardMaterial-API

    // 导入纹理
    const textureLoader = new TextureLoader()
    
    // 贴图纹理
    const customerColorTexture = textureLoader.load('/imgs/door.png')

    // 透明贴图  黑遮白显  指显示所需要展示部分
    // 灰度纹理  用于控制整个表面的不透明度(黑:完全透明,白:完全不透明, 灰:半透明)
    const alpha = textureLoader.load('/imgs/alpha.png')

    // AO环境遮挡贴图
    // 模拟物体之间所产生的阴影,增强空间感、真实感。遮挡贴图提供环境光遮蔽高低的(间接光照来自环境光照和反射)信息
    // 白色表示应接受完全间接光照的区域,以黑色表示没有间接光照
    const aoTexture = textureLoader.load('/imgs/ao.png')

    // 置换贴图(高度图、视差贴图、凹凸贴图)  负责定义和渲染表面额外的大型凸起  
    // 根据颜色的深浅物体凸出的程度不同,高度值变化范围是在0和255之间。0 (黑色)表示最低高度,255 (白色)表示最大高度。
    const height = textureLoader.load('/imgs/height.png')

    // 导入粗糙度贴图
    const roughness = textureLoader.load('/imgs/roughness.png')

    // 金属贴图  光照时会有金属光泽
    const metalness = textureLoader.load('/imgs/metalness.png')

    // 法线贴图   改变纹理表面的光照
    const normal = textureLoader.load('/imgs/normal.png')
   
    // 创建几何体
    let geometry = new BoxBufferGeometry(1,1,1,100,100,100)
    geometry.setAttribute('uv2',new BufferAttribute(geometry.attributes.uv.array,2))
    将上述导入的贴图依次运用材质的相应属性上:
    
    let material = new MeshStandardMaterial({color:0xffffff,
      map:customerColorTexture,
      alphaMap:alpha,
      transparent:true,
      aoMap:aoTexture,
      displacementMap:height,
      displacementScale:0.05,
      roughness:1,
      roughnessMap:roughness,
      metalness:1,
      metalnessMap:metalness,
      normalMap:normal
    })

    // 添加环境光
    const light = new AmbientLight(0xffffff,.5)
    scene.add(light)

    // 添加平行光
    const directionalLight = new DirectionalLight(0xffffff,.5)
    directionalLight.position.set(10, 10, 10)
    scene.add(directionalLight)

    // 根据几何体和材质创建物体
    let cube = new Mesh(geometry, material)

    // 改变物体的位置
    cube.position.set(1,0,1)

    //将物体添加到场景中
    scene.add(cube)

环境纹理

根据素材类型的不同,我们可以选择不同的方式来设置环境纹理。

立方纹理(CubeTexture)

创建一个由6张图片所组成的纹理对象。 效果如下:

图片.png

主要代码如下:

import {Scene,PerspectiveCamera,WebGLRenderer,Mesh,CubeTextureLoader, MeshStandardMaterial,

AmbientLight, DirectionalLight, SphereBufferGeometry} from 'three'


    const cubeTexture = new CubeTextureLoader()

    const envMapTexture = cubeTexture.load([

      '/imgs/env/posx.jpg',

      '/imgs/env/negx.jpg',

      '/imgs/env/posy.jpg',

      '/imgs/env/negy.jpg',

      '/imgs/env/posz.jpg',

      '/imgs/env/negz.jpg',

    ])


    const sphereGeometry = new SphereBufferGeometry(1, 20, 20)

    const material = new MeshStandardMaterial({

      metalness:.7,

      roughness:.1,

      // envMap: envMapTexture   //这里的贴图的优先级高于场景的环境贴图

    })


    const sphere = new Mesh(sphereGeometry,material)

    scene.add(sphere)

    // 给场景添加背景

    scene.background = envMapTexture

    // 给场景所有的物体添加默认的环境贴图

    scene.environment = envMapTexture

   
   // 环境光

    const light = new AmbientLight(0xffffff,.5)

    scene.add(light)

    // 平行光

    const directionalLight = new DirectionalLight(0xffffff,.5)

    directionalLight.position.set(10, 10, 10)

    scene.add(directionalLight)

HDR或者EXR

根据素材的不同格式,导入相应的加载器。我这里加载的是.exr格式的素材。 效果图:

图片.png

主要代码如下:
import {Scene,PerspectiveCamera,WebGLRenderer,Mesh, MeshStandardMaterial, AmbientLight, DirectionalLight,  EquirectangularReflectionMapping, SphereBufferGeometry} from 'three'

import {EXRLoader} from 'three/examples/jsm/loaders/EXRLoader'
// 如果是加载hdr格式的素材,则导入RGBELoader
// import {RGBELoader} from 'three/examples/jsm/loaders/RGBELoader'

    // 加载exr环境图
    const exrLoader = new EXRLoader()
    exrLoader.loadAsync('/imgs/hdr/HdrOutdoorCityPathDayClear001_HDR_2K.exr').then((texture) => {
      texture.mapping = EquirectangularReflectionMapping
      scene.background = texture
      scene.environment = texture
    })

    const sphereGeometry = new SphereBufferGeometry(1, 20, 20)
    const material = new MeshStandardMaterial({
      metalness:.7,
      roughness:.1,
    })

    const sphere = new Mesh(sphereGeometry,material)
    scene.add(sphere)
    
    //添加环境光
    const light = new AmbientLight(0xffffff,.5)
    scene.add(light)
    //添加平行光
    const directionalLight = new DirectionalLight(0xffffff,.5)
    directionalLight.position.set(10, 10, 10)
    scene.add(directionalLight)

素材来源

poliigon

环境纹理贴图素材

本篇就记录这么多。music~

b5af6672b1d6444da871404b629b2c90.gif