为了账号安全,请及时绑定邮箱和手机立即绑定

Three.js 基础纹理贴图

本文简介

尽管 Three.js 文档已经比较详细了,但对于刚接触 Three.js 的工友来说,最麻烦的还是不懂如何组合。Three.js 的功能实在太多了,初学者很容易被大量的新概念冲晕。

本文主要讲解入门 Three.js 必须接触的基础贴图功能。本文只讲解常用的属性,学会了常用的属性设置就知道如何查阅文档使用其他属性了~

基础贴图

基础贴图用到的是基础材质 THREE.MeshBasicMaterialTHREE.TextureLoader

THREE.MeshBasicMaterial 是一个不受光照影响的材质,它可以直接给物体设置颜色,也可以将图片贴到物体表面。

THREE.TextureLoaderTHREE 提供的一个纹理加载器,通过它可以加载一些素材纹理。

在开始之前,先把画布必须项创建好。画布必须项包括:场景、相机、渲染器。

01.gif

<div id="canvasBox"></div>

<script type="module">
  import * as THREE from "./js/Three/src/Three.js"
  import { OrbitControls } from './js/Three/examples/jsm/controls/OrbitControls.js'

  // 创建场景
  const scene = new THREE.Scene()
  // 创建相机
  const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
  camera.position.set(1, 1, 5)
  camera.lookAt(scene.position)

  // 创建辅助坐标系
  const axesHelper = new THREE.AxesHelper(5)
  scene.add(axesHelper)

  // 创建渲染器
  const renderer = new THREE.WebGLRenderer()
  renderer.setSize(window.innerWidth, window.innerHeight)
  document.getElementById('canvasBox').appendChild(renderer.domElement)

  // 创建轨道控制器
  const controls = new OrbitControls(camera, renderer.domElement)
  controls.enableDamping = true

  // 循环执行
  function animate() {
    controls.update()
    renderer.render( scene, camera )
    requestAnimationFrame( animate )
  }

  // 执行动画函数
  animate()
</script>
复制代码

除了创建场景、相机和渲染器之外,我还创建了辅助坐标系 AxesHelper 和轨道控制器 OrbitControls,方便观察。

加载纹理

要使用纹理,需要做以下几步:

  1. 创建一个物体,用来承载纹理
  2. 引入纹理加载器 [THREE.TextureLoader,并加载纹理 (load() 方法)
  3. 将纹理添加给基础材质 [THREE.MeshBasicMaterial]

由于前面已经创建了基础的画布所需项,所以这里会省略这部分代码

02.gif

// 省略部分代码...

// Three提供的纹理加载器
const textureLoader = new THREE.TextureLoader()
// 导入纹理贴图基础贴图
const chungeLoader = textureLoader.load('./assets/images/chunge_flower.png')

// 创建立方体
const geometry = new THREE.BoxGeometry(1, 1, 1)
const material = new THREE.MeshBasicMaterial({
  map: chungeLoader // 纹理贴图
})
const cube = new THREE.Mesh(geometry, material)
scene.add(cube)
复制代码

THREE.MeshBasicMaterial 的 [map] 属性可以设置纹理贴图。

正反面渲染

前面的例子我们创建的立方体,如果此时我们把图贴到平面上,默认情况下它只显示正面。

本例用到下面这张图片

chunge_flower.png

  1. 创建一个平面
  2. 贴图

03.gif

// 省略部分代码...

// Three提供的纹理加载器
const textureLoader = new THREE.TextureLoader()
// 导入纹理贴图基础贴图
const chungeLoader = textureLoader.load('./assets/images/chunge_flower.png')

// 创建一个圆形
const circleGeometry = new THREE.CircleGeometry(0.5, 32)
const material = new THREE.MeshBasicMaterial({
  map: chungeLoader // 贴图
})
const circle = new THREE.Mesh(circleGeometry, material)
scene.add(circle)
复制代码

如果此时希望正方面都有贴图效果,可以将 [side]设置为 THREE.DoubleSide

side 的默认值是 [THREE.FrontSide]。其他选项有[THREE.BackSide], [THREE.DoubleSide] 和 [THREE.TwoPassDoubleSide]

04.gif

// 省略部分代码...

// Three提供的纹理加载器
const textureLoader = new THREE.TextureLoader()
// 导入纹理贴图基础贴图
const chungeLoader = textureLoader.load('./assets/images/chunge_flower.png')

// 创建一个圆形
const circleGeometry = new THREE.CircleGeometry(0.5, 32)
const material = new THREE.MeshBasicMaterial({
  map: chungeLoader, // 贴图
  side: THREE.DoubleSide // 正反面都贴图
})
const circle = new THREE.Mesh(circleGeometry, material)
scene.add(circle)
复制代码

纹理偏移

在加载完纹理之后,可以设置纹理的 offset 属性进行纹理偏移。

本例用到下面这张图片

chunge.png

05.png

// 省略部分代码...

// Three提供的纹理加载器
const textureLoader = new THREE.TextureLoader()
// 导入纹理贴图基础贴图
const chungeLoader = textureLoader.load('./assets/images/chunge_flower.png')

// 纹理偏移
chungeLoader.offset.set(0.1, -0.5)

// 创建一个圆形
const circleGeometry = new THREE.CircleGeometry(0.5, 32)
const material = new THREE.MeshBasicMaterial({
  map: chungeLoader, // 贴图
  side: THREE.DoubleSide // 正反面都贴图
})
const circle = new THREE.Mesh(circleGeometry, material)
scene.add(circle)
复制代码

其中,以下代码等价于 chungeLoader.offset.set(0.1, -0.5)

chungeLoader.offset.x = 0.1
chungeLoader.offset.y = -0.5
复制代码

x轴方向是正数时,纹理向右偏移;负数则向左偏移。

y轴方向是正数时,纹理向下偏移;负数则向上偏移。

旋转纹理

加载完纹理后,可以通过修改 rotation 属性旋转纹理。

旋转纹理要注意以下几点:

  1. 通过 rotation 旋转纹理
  2. 旋转时,是以弧度为单位。角度转弧度比较直观的公式是:角度度数 * Math.PI / 180
  3. 通过 center 设置旋转中心点

如果不设置旋转中心点,默认是以左上角为中心点进行旋转。

06.png

// 省略部分代码...

// Three提供的纹理加载器
const textureLoader = new THREE.TextureLoader()
// 导入纹理贴图基础贴图
const chungeLoader = textureLoader.load('./assets/images/chunge_flower.png')

// 旋转贴图
chungeLoader.rotation = 45 * Math.PI / 180

// 创建一个圆形
const circleGeometry = new THREE.CircleGeometry(0.5, 32)
const material = new THREE.MeshBasicMaterial({
  map: chungeLoader, // 贴图
  side: THREE.DoubleSide // 正反面都贴图
})
const circle = new THREE.Mesh(circleGeometry, material)
scene.add(circle)
复制代码

本例将贴图旋转了45度,如果希望以元素的中心点作为旋转中心点,可以将 center 设置成 (0.5, 0.5),此时x轴和y轴都是以元素的中心点作为旋转中心点了。

07.png

// 省略部分代码...

// 旋转贴图
chungeLoader.rotation = 45 * Math.PI / 180
// 设置旋转中心点
chungeLoader.center.set(0.5, 0.5)
复制代码

重复渲染

设置纹理的 repeat 属性可以控制重复渲染的次数。通过 [wrapS]和 wrapT 可以分别设置水平方向和垂直方向的的重复渲染模式。

wrapSwrapT 默认值是 [THREE.ClampToEdgeWrapping],即纹理边缘将被推到外部边缘的纹素。 其它的两个选项分别是 [THREE.RepeatWrapping]和 [THREE.MirroredRepeatWrapping]。

THREE.RepeatWrapping 是正常的重复,THREE.MirroredRepeatWrapping 是镜像重复。

接下来拿[『春哥』]练练手。

08.png

// 省略部分代码...

// Three提供的纹理加载器
const textureLoader = new THREE.TextureLoader()
// 导入纹理贴图基础贴图
const chungeLoader = textureLoader.load('./assets/images/chunge_flower.png')

// 水平重复3次,垂直重复2次
chungeLoader.repeat.set(3, 2)
chungeLoader.wrapS = THREE.RepeatWrapping // 水平重复
chungeLoader.wrapT = THREE.MirroredRepeatWrapping // 垂直镜像重复

// 创建立方体
const geometry = new THREE.BoxGeometry(1, 1, 1)
const material = new THREE.MeshBasicMaterial({
  map: chungeLoader // 纹理贴图
})
const cube = new THREE.Mesh(geometry, material)
scene.add(cube)
复制代码

灰度纹理

如果你想把花背景隐藏掉,可以使用灰度纹理。

此时需要2张图。

chunge_flower.png

chunge_alpha.png

黑白这张图是一个蒙版层,和PS的图层蒙版是一个道理。

黑色表示要完全隐藏的部分,白色表示要完成显示的部分。如果用灰色,会根据灰色的深浅设置一个半透明的效果。

使用 alphaMap 可以设置灰度纹理层,同时还要将 transparent 设置为 true 才有效。

09.gif

// 省略部分代码...

// Three提供的纹理加载器
const textureLoader = new THREE.TextureLoader()
// 导入纹理贴图基础贴图
const chungeLoader = textureLoader.load('./assets/images/chunge_flower.png')
// 导入蒙版贴图
const chungeAlphaTexture = textureLoader.load('./assets/images/chunge_alpha.png')

// 创建立方体
const geometry = new THREE.BoxGeometry(1, 1, 1)
const material = new THREE.MeshBasicMaterial({
  map: chungeLoader, // 纹理贴图
  alphaMap: chungeAlphaTexture, // 设置透明纹理层
  transparent: true // 允许材质透明
})
const cube = new THREE.Mesh(geometry, material)
scene.add(cube)
复制代码

从上图可以看到,花背景已经被隐藏掉了。

如果此时将 side 设置成 THREE.DoubleSide 就可以双面展示了。

10.gif

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消