Three材质纹理 (总结二)

1、几何体顶点与UV和法向量

几何体顶点

three.js的长方体BoxGeometry、球体SphereGeometry等几何体都是基于BufferGeometry类构建的,BufferGeometry是一个没有任何形状的空几何体,我们可以通过BufferGeometry自定义任何几何形状,就是定义顶点数据

1、设置顶点坐标来绘制几何体。注意:面是由 2 个三角形组成的,所以要传入 2 个三角形顶点坐标

const geometry = new THREE.BufferGeometry()

 利用js中的类型化数组Float32Array创建xyz坐标数据来表示顶点坐标

const vertices = new Float32Array([
  // z 轴正面两个三角形组成面
  -1.0, -1.0, 1.0,
  1.0, -1.0, 1.0,
  -1.0, 1.0, 1.0,

  1.0, -1.0, 1.0,
  1.0, 1.0, 1.0,
  -1.0, 1.0, 1.0,

  // x 轴正面
  1.0, -1.0, 1.0,
  1.0, -1.0, -1.0,
  1.0, 1.0, 1.0,

  1.0, -1.0, -1.0,
  1.0, 1.0, -1.0,
  1.0, 1.0, 1.0,

  // z 轴背面
  1.0, -1.0, -1.0,
  -1.0, -1.0, -1.0,
  1.0, 1.0, -1.0,

  -1.0, -1.0, -1.0,
  -1.0, 1.0, -1.0,
  1.0, 1.0, -1.0,

  // x 轴背面
  -1.0, -1.0, -1.0,
  -1.0, -1.0, 1.0,
  -1.0, 1.0, -1.0,

  -1.0, -1.0, 1.0,
  -1.0, 1.0, 1.0,
  -1.0, 1.0, -1.0,

  // y 轴正面
  -1.0, 1.0, 1.0,
  1.0, 1.0, 1.0,
  -1.0, 1.0, -1.0,

  1.0, 1.0, 1.0,
  1.0, 1.0, -1.0,
  -1.0, 1.0, -1.0,

  // y 轴背面(顺时针写,其他逆时针写)
  -1.0, -1.0, -1.0,
  1.0, -1.0, 1.0,
  -1.0, -1.0, 1.0,

  -1.0, -1.0, -1.0,
  1.0, -1.0, -1.0,
  1.0, -1.0, 1.0,
])

创建属性缓冲区对象,每3个为一组,分别表示一个顶点的xyz坐标

const attribue = new THREE.BufferAttribute(vertices, 3)

设置几何体attributes属性的位置属性

geometry.attributes.position = attribue

自己设置用了 108 个点坐标组成了立方体,为何 three.js 用了 72 个顶点坐标就可以了?

console.log(cube)
console.log(cube.geometry.attributes.position.array) // 72 个数值

 

因为每个面是由 4 个顶点坐标组成,每个顶点坐标x,y,z坐标值是 3 个数字,所以一个面由 12 个数字组成,6 个面就是 72 个顶点坐标。

设置 index 属性可以复用两个三角形重复的顶点坐标 

const geometry = new THREE.BufferGeometry()
// z 轴正面两个三角形坐标
const vertices = new Float32Array([
  1.0, 1.0, 1.0,
  -1.0, 1.0, 1.0,
  -1.0, -1.0, 1.0,
  1.0, -1.0, 1.0,
])
const attribue = new THREE.BufferAttribute(vertices, 3)
geometry.attributes.position = attribue

 index 属性:允许顶点在多个三角面片间可以重用(注意要和上面顶点数组顺序对应),则0代表上面属性的第一组

const indexes = new Uint16Array([
  2, 3, 1, 3, 0, 1
])

 

设置为 1 个数字代表上面一组坐标(3 个数字,xyz 坐标位置)

geometry.index = new THREE.BufferAttribute(indexes, 1)

顶点着色,每一个顶点都可以设置自己的颜色。

const colors = new Float32Array([
  0, 1, 0, // 绿色
  1, 0, 0, // 红色
  0, 0, 1, // 蓝色
  0, 1, 1, // 蓝绿色
])

 设置几何体attributes属性的颜色color属性,三个为一组。

geometry.attributes.color = new THREE.BufferAttribute(colors, 3)

让材质开启顶点着色功能

const material = new THREE.MeshBasicMaterial({ vertexColors: true })

 

UV

UV属性是一组二维坐标,每个顶点都有一个对应的UV坐标。在三维模型上贴上二维的纹理贴图时,需要将所有顶点映射到纹理上的对应位置。UV属性的取值范围一般是[0,1],表示纹理上的相对位置。

console.log(cube.geometry.attributes.uv.array) // 48 个数值

UV 贴图实际类似把一个立方体展开铺开,只有 x,y 两个方向的坐标,原点在左下角,右向是 U 方向(x),值为 0 - 1, 纵向向上是 V 方向(y),值为 0 - 1; 所以每个点平面坐标,一个面只需要 8 个数值表示 4 个点坐标的 x,y 坐标数值

法向量

法向属性是每个顶点的法向量,用于确定顶点所在面的方向和光照效果。在three.js中,光照效果是基于每个顶点的法向量和光线方向计算的。因此,为了让模型的光照效果更真实,在创建几何体时需要设置每个顶点的法向量信息。通过修改法向属性,可以调整模型的光照效果和表面平滑度。

法向量(每个顶点朝向-如何折射光)

console.log(cube.geometry.attributes.normal.array) // 72 个数值

 

2、基础网格材质 

材质就像物体的皮肤,决定了几何体的外表。例如,材质可以定义一个几何体看起来像金属还是木板,是否透明,什么颜色等,然后添加到Mesh中才可以添加到场景中进行渲染。

光照模型

Three.js会提供一些的光照模型来模拟物体表面的光照,光照模型就一种模拟光照的计算方法。MeshPhysicalMaterialMeshLambertMaterial一样都是渲染网格模型的材质,但是他们用的光照模型不同,具体点说就是材质模拟Mesh反射光照的代码算法不同,算法不同,自然模拟光照的真实程度也不同。

  • MeshLambertMaterial: Lambert光照模型(漫反射)

  • MeshPhongMaterial:Phong光照模型(漫反射、高光反射)

  • MeshStandardMaterial和MeshPhysicalMaterial:基于物理的光照模型(微平面理论、能量守恒、菲涅尔反射...)

金属度metalness

金属度属性.metalness表示材质像金属的程度, 非金属材料,如木材或石材,使用0.0,金属使用1.0。

new THREE.MeshStandardMaterial({
    metalness: 1.0,//金属度属性
})

mesh.material.metalness = 1.0;//金属度

粗糙度roughness

粗糙度roughness表示模型表面的光滑或者说粗糙程度,越光滑镜面反射能力越强,越粗糙,表面镜面反射能力越弱,更多地表现为漫反射。

粗糙度roughness,0.0表示平滑的镜面反射,1.0表示完全漫反射,默认0.5。

new THREE.MeshStandardMaterial({
    roughness: 0.5,//表面粗糙度
})

mesh.material.roughness = 0.5;//表面粗糙度

颜色贴图

通过纹理贴图加载器TextureLoader.load()方法加载一张图片可以返回一个纹理对象Texture

立方体纹理加载器CubeTextureLoader.load()方法是加载6张图片,返回一个立方体纹理对象CubeTexture

立方体纹理对象CubeTexture的父类是纹理对象Texture

 图片转成纹理对象,设置给材质作为贴图

const mapTexture = new THREE.TextureLoader().load('texture/basecolor.jpg')

颜色通道-设置SRGB才是原图样子

mapTexture.colorSpace = THREE.SRGBColorSpace

 创建网格材质,装入纹理

const material = new THREE.MeshBasicMaterial({
    map: mapTexture // 颜色贴图
  })

  const mesh = new THREE.Mesh(geometry, material)
  scene.add(mesh)

纹理对象详细控制 

纹理偏移,旋转等

纹理位移(二维向量,值范围是 0 - 1,默认值是 0)

mapTexture.offset.x = 0.5

 纹理旋转(弧度)- 默认绕左下角为中心旋转

mapTexture.rotation = Math.PI / 3

物件中心点为旋转中心点

mapTexture.center.set(0.5, 0.5)

物件重复(但是只绘制一次)

mapTexture.repeat.set(2, 2)

纹理贴图在水平方向上将如何包裹,在UV映射中对应于U。

mapTexture.wrapS = THREE.RepeatWrapping // 重复

 纹理贴图在垂直方向上将如何包裹,在UV映射中对应于V

mapTexture.wrapT = THREE.RepeatWrapping // 重复

透明度贴图   创建透明度贴图-纹理对象

const alphaTexture = new THREE.TextureLoader().load('texture/opacity.jpg')
alphaTexture.colorSpace = THREE.SRGBColorSpace

const material = new THREE.MeshBasicMaterial({
    map: mapTexture, // 颜色贴图
    alphaMap: alphaTexture, // 2. 传入透明纹理对象
    transparent: true, // 3. 开启透明材质
    opacity: 0.1 // 全透明
  })

环境遮挡贴图

计算灯光的阴暗/明亮的对比效果,基础网格材质是模拟效果,受光照影响的材质设置环境遮挡贴图需要加环境光才有效果

const aoTexture = new THREE.TextureLoader().load('texture/ambientOcclusion.jpg')
  aoTexture.colorSpace = THREE.SRGBColorSpace

  const material = new THREE.MeshBasicMaterial({
    map: mapTexture, // 颜色贴图
    alphaMap: alphaTexture, // 透明度贴图
    transparent: true,
    // opacity: 0.1,
    aoMap: aoTexture, // 2. 环境遮挡贴图(把透明度注释掉,为了看到效果)
    // aoMapIntensity: 1 // 环境遮挡效果的强度。默认值为1。零是不遮挡效果。
  })

  const mesh = new THREE.Mesh(geometry, material)
  scene.add(mesh)
  • 18
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值