sroxck

sroxck

ThreeJS 学习笔记

基础案例#

<script setup>
  import * as three from 'three'

  // 创建场景
  const scene = new three.Scene()

  // 创建相机
  const camera = new three.PerspectiveCamera(
    45, // 视角
    window.innerWidth / window.innerHeight, // 宽高比
    0.1, // 近平面
    1000 // 远平面
  )

  // 创建渲染器
  const renderer = new three.WebGLRenderer()
  renderer.setSize(window.innerWidth, window.innerHeight)
  document.body.appendChild(renderer.domElement)

  // 创建几何体
  const geometry = new three.BoxGeometry(1, 1, 1)

  // 创建材质
  const material = new three.MeshBasicMaterial({ color: 0x00ff00 })
  // 创建网格
  const cube = new three.Mesh(geometry, material)
  // 将网格添加到场景中
  scene.add(cube)

  // 设置相机位置
  camera.position.z = 5
  // 看向
  camera.lookAt(0, 0, 0)

  // 渲染函数
  function animate() {
    // 再下一帧继续执行,达到一直执行动画的效果
    // 每一帧都移动x和y 相当于让他做旋转动画
    requestAnimationFrame(animate)
    // 设置几何体x轴移动
    cube.rotation.x += 0.01
    cube.rotation.y += 0.01
    // 渲染
    renderer.render(scene, camera)
  }
  animate()
</script>

<template>
  <div> </div>
</template>

<style scoped></style>

世界座标辅助器#

蓝色 z 轴
红色 x 轴
绿色 y 轴

<script setup>
  import * as three from 'three'

  // 创建场景
  const scene = new three.Scene()

  // 创建相机
  const camera = new three.PerspectiveCamera(
    45, // 视角
    window.innerWidth / window.innerHeight, // 宽高比
    0.1, // 近平面
    1000 // 远平面
  )

  // 创建渲染器
  const renderer = new three.WebGLRenderer()
  renderer.setSize(window.innerWidth, window.innerHeight)
  document.body.appendChild(renderer.domElement)

  // 创建几何体
  const geometry = new three.BoxGeometry(1, 1, 1)

  // 创建材质
  const material = new three.MeshBasicMaterial({ color: 0x00ff00 })
  // 创建网格
  const cube = new three.Mesh(geometry, material)
  // 将网格添加到场景中
  scene.add(cube)

  // 设置相机位置
  camera.position.z = 5
  camera.position.y = 2
  camera.position.x = 2
  // 看向
  camera.lookAt(0, 0, 0)

  // 添加世界座标辅助器
  const axesHelper = new three.AxesHelper(5)
  scene.add(axesHelper)

  // 渲染函数
  function animate() {
    // 再下一帧继续执行,达到一直执行动画的效果
    // 每一帧都移动x和y 相当于让他做旋转动画
    requestAnimationFrame(animate)
    // 设置几何体x轴移动
    // cube.rotation.x +=0.01
    // cube.rotation.y += 0.01
    // 渲染
    renderer.render(scene, camera)
  }
  animate()
</script>

<template>
  <div> </div>
</template>

<style scoped></style>

轨道控制器#

<script setup>
  import * as three from 'three'
  // 导入轨道控制器
  import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
  // 创建场景
  const scene = new three.Scene()

  // 创建相机
  const camera = new three.PerspectiveCamera(
    45, // 视角
    window.innerWidth / window.innerHeight, // 宽高比
    0.1, // 近平面
    1000 // 远平面
  )

  // 创建渲染器
  const renderer = new three.WebGLRenderer()
  renderer.setSize(window.innerWidth, window.innerHeight)
  document.body.appendChild(renderer.domElement)

  // 创建几何体
  const geometry = new three.BoxGeometry(1, 1, 1)

  // 创建材质
  const material = new three.MeshBasicMaterial({ color: 0x00ff00 })
  // 创建网格
  const cube = new three.Mesh(geometry, material)
  // 将网格添加到场景中
  scene.add(cube)

  // 设置相机位置
  camera.position.z = 5
  camera.position.y = 2
  camera.position.x = 2
  // 看向
  camera.lookAt(0, 0, 0)

  // 添加世界座标辅助器
  const axesHelper = new three.AxesHelper(5)
  scene.add(axesHelper)

  // 创建控制器, 可以修改第二个参数来选择哪个dom来控制事件
  const controls = new OrbitControls(camera, renderer.domElement)
  // 设置带阻尼,拖动会有惯性
  controls.enableDamping = true
  // 设置阻尼系数
  controls.dampingFactor = 0.04
  // 设置自动旋转
  controls.autoRotate = true
  // 渲染函数
  function animate() {
    // 更新控制器
    controls.update()
    // 再下一帧继续执行,达到一直执行动画的效果
    // 每一帧都移动x和y 相当于让他做旋转动画
    requestAnimationFrame(animate)
    // 设置几何体x轴移动
    cube.rotation.x += 0.01
    cube.rotation.y += 0.01
    // 渲染
    renderer.render(scene, camera)
  }
  animate()
</script>

<template>
  <div> </div>
</template>

<style scoped></style>

三维物体#

这是 Three.js 中大部分对象的基类,提供了一系列的属性和方法来对三维空间中的物体进行操纵。

请注意,可以通过.add (object) 方法来将对象进行组合,该方法将对象添加为子对象,但为此最好使用 Group(来作为父对象)。

三维向量 Vector3#

表示 x, y, z 三个方向上的坐标,可以直接修改三维向量的 x, y, z 属性

position: Vector3 移动属性#

对象局部坐标点 vector3 座标 基于父元素,如果没有父元素,则是世界坐标

<script setup>
  import * as three from 'three'
  // 导入轨道控制器
  import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
  // 创建场景
  const scene = new three.Scene()
  // 创建相机
  const camera = new three.PerspectiveCamera(
    45, // 视角
    window.innerWidth / window.innerHeight, // 宽高比
    0.1, // 近平面
    1000 // 远平面
  )
  // 创建渲染器
  const renderer = new three.WebGLRenderer()
  renderer.setSize(window.innerWidth, window.innerHeight)
  document.body.appendChild(renderer.domElement)
  // 创建几何体
  const geometry = new three.BoxGeometry(1, 1, 1)
  // 创建材质 父元素红色 子元素绿色
  const material = new three.MeshBasicMaterial({ color: 0x00ff00 })
  const parentMaterial = new three.MeshBasicMaterial({ color: 0xff0000 })
  // 创建网格
  // 创建父元素
  let parentCube = new three.Mesh(geometry, parentMaterial)
  // 创建子元素
  const cube = new three.Mesh(geometry, material)
  // 子元素添加到父元素中
  parentCube.add(cube)
  // 设置父元素的位移
  parentCube.position.set(-3, 0, 0)
  // 设置子元素的位移,是基于父元素的
  cube.position.set(3, 0, 0)
  // 将网格添加到场景中,只需要添加一个父元素即可
  scene.add(parentCube)

  // 设置相机位置
  camera.position.z = 5
  camera.position.y = 2
  camera.position.x = 2
  // 看向
  camera.lookAt(0, 0, 0)

  // 添加世界座标辅助器
  const axesHelper = new three.AxesHelper(5)
  scene.add(axesHelper)

  // 创建控制器, 可以修改第二个参数来选择哪个dom来控制事件
  const controls = new OrbitControls(camera, renderer.domElement)
  // 设置带阻尼,拖动会有惯性
  controls.enableDamping = true
  // 设置阻尼系数
  controls.dampingFactor = 0.04
  // 设置自动旋转
  // controls.autoRotate = true
  // 渲染函数
  function animate() {
    // 更新控制器
    controls.update()
    // 再下一帧继续执行,达到一直执行动画的效果
    // 每一帧都移动x和y 相当于让他做旋转动画
    requestAnimationFrame(animate)
    // 设置几何体x轴移动
    // cube.rotation.x +=0.01
    // cube.rotation.y += 0.01
    // 渲染
    renderer.render(scene, camera)
  }
  animate()
</script>

<template>
  <div> </div>
</template>

<style scoped></style>

scale: Vector3 缩放属性#

物体的局部缩放,基于父元素

<script setup>
  import * as three from 'three'
  // 导入轨道控制器
  import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
  // 创建场景
  const scene = new three.Scene()

  // 创建相机
  const camera = new three.PerspectiveCamera(
    45, // 视角
    window.innerWidth / window.innerHeight, // 宽高比
    0.1, // 近平面
    1000 // 远平面
  )

  // 创建渲染器
  const renderer = new three.WebGLRenderer()
  renderer.setSize(window.innerWidth, window.innerHeight)
  document.body.appendChild(renderer.domElement)

  // 创建几何体
  const geometry = new three.BoxGeometry(1, 1, 1)

  // 创建材质
  const material = new three.MeshBasicMaterial({color:0x00ff00})
  const parentMaterial = new three.MeshBasicMaterial({color:0xff0000})
  // 创建网格

  let parentCube = new three.Mesh(geometry,parentMaterial)
  
  const cube = new three.Mesh(geometry,material)
  parentCube.add(cube)
  parentCube.position.set(-3,0,0)
  cube.position.set(3,0,0)
  // 设置立方体的放大
  cube.scale.set(2,2,2)
  parentCube.scale.set(2,2,2)
  // 将网格添加到场景中
   scene.add(parentCube)
  // scene.add(cube)

  // 设置相机位置
  camera.position.z = 5
  camera.position.y = 2
  camera.position.x = 2
  // 看向
  camera.lookAt(0,0,0)

  // 添加世界座标辅助器
  const axesHelper = new three.AxesHelper(5)
  scene.add(axesHelper)
 
  // 创建控制器, 可以修改第二个参数来选择哪个dom来控制事件
  const controls = new OrbitControls(camera,renderer.domElement)
  // 设置带阻尼,拖动会有惯性
  controls.enableDamping = true
  // 设置阻尼系数
  controls.dampingFactor = .04
  // 设置自动旋转
  // controls.autoRotate = true
  // 渲染函数
  function animate(){
    // 更新控制器
    controls.update()
    // 再下一帧继续执行,达到一直执行动画的效果
    // 每一帧都移动x和y 相当于让他做旋转动画
    requestAnimationFrame(animate)
    // 设置几何体x轴移动
    // cube.rotation.x +=0.01
    // cube.rotation.y += 0.01
    // 渲染
    renderer.render(scene,camera)
  }
 animate()
</script>

<template>
  <div> </div>
</template>

<style scoped></style>

Euler 欧拉角对象#

欧拉角指定一个轴,来旋转物体,旋转的顺序按照轴的顺序,默认 xyz 顺序

rotation: Euler 旋转属性#

物体的局部旋转,基于父元素

<script setup>
  import * as three from 'three'
  // 导入轨道控制器
  import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
  // 创建场景
  const scene = new three.Scene()

  // 创建相机
  const camera = new three.PerspectiveCamera(
    45, // 视角
    window.innerWidth / window.innerHeight, // 宽高比
    0.1, // 近平面
    1000 // 远平面
  )

  // 创建渲染器
  const renderer = new three.WebGLRenderer()
  renderer.setSize(window.innerWidth, window.innerHeight)
  document.body.appendChild(renderer.domElement)

  // 创建几何体
  const geometry = new three.BoxGeometry(1, 1, 1)

  // 创建材质
  const material = new three.MeshBasicMaterial({color:0x00ff00})
  const parentMaterial = new three.MeshBasicMaterial({color:0xff0000})
  // 创建网格

  let parentCube = new three.Mesh(geometry,parentMaterial)
  
  const cube = new three.Mesh(geometry,material)
  parentCube.add(cube)
  parentCube.position.set(-3,0,0)
  cube.position.set(3,0,0)
  // 设置立方体的放大
  // cube.scale.set(2,2,2)
  // 绕x轴旋转

  cube.rotation.x = Math.PI/4
  // parentCube.scale.set(2,2,2)
  // 将网格添加到场景中
   scene.add(parentCube)
  // scene.add(cube)

  // 设置相机位置
  camera.position.z = 5
  camera.position.y = 2
  camera.position.x = 2
  // 看向
  camera.lookAt(0,0,0)

  // 添加世界座标辅助器
  const axesHelper = new three.AxesHelper(5)
  scene.add(axesHelper)
 
  // 创建控制器, 可以修改第二个参数来选择哪个dom来控制事件
  const controls = new OrbitControls(camera,renderer.domElement)
  // 设置带阻尼,拖动会有惯性
  controls.enableDamping = true
  // 设置阻尼系数
  controls.dampingFactor = .04
  // 设置自动旋转
  // controls.autoRotate = true
  // 渲染函数
  function animate(){
    // 更新控制器
    controls.update()
    // 再下一帧继续执行,达到一直执行动画的效果
    // 每一帧都移动x和y 相当于让他做旋转动画
    requestAnimationFrame(animate)
    // 设置几何体x轴移动
    // cube.rotation.x +=0.01
    // cube.rotation.y += 0.01
    // 渲染
    renderer.render(scene,camera)
  }
 animate()
</script>

<template>
  <div> </div>
</template>

<style scoped></style>

响应式画布与自适应#

<script setup>
  import * as three from 'three'
  // 导入轨道控制器
  import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
  // 创建场景
  const scene = new three.Scene()

  // 创建相机
  const camera = new three.PerspectiveCamera(
    45, // 视角
    window.innerWidth / window.innerHeight, // 宽高比
    0.1, // 近平面
    1000 // 远平面
  )

  // 创建渲染器
  const renderer = new three.WebGLRenderer()
  renderer.setSize(window.innerWidth, window.innerHeight)
  document.body.appendChild(renderer.domElement)

  // 创建几何体
  const geometry = new three.BoxGeometry(1, 1, 1)

  // 创建材质
  const material = new three.MeshBasicMaterial({ color: 0x00ff00 })
  const parentMaterial = new three.MeshBasicMaterial({ color: 0xff0000 })
  // 创建网格

  let parentCube = new three.Mesh(geometry, parentMaterial)

  const cube = new three.Mesh(geometry, material)
  parentCube.add(cube)
  parentCube.position.set(-3, 0, 0)
  cube.position.set(3, 0, 0)
  // 将网格添加到场景中
  scene.add(parentCube)
  // 设置相机位置
  camera.position.z = 5
  camera.position.y = 2
  camera.position.x = 2
  // 看向
  camera.lookAt(0, 0, 0)

  // 添加世界座标辅助器
  const axesHelper = new three.AxesHelper(5)
  scene.add(axesHelper)

  // 创建控制器, 可以修改第二个参数来选择哪个dom来控制事件
  const controls = new OrbitControls(camera, renderer.domElement)
  // 设置带阻尼,拖动会有惯性
  controls.enableDamping = true
  // 设置阻尼系数
  controls.dampingFactor = 0.04
  // 设置自动旋转
  // controls.autoRotate = true
  // 渲染函数
  function animate() {
    // 更新控制器
    controls.update()
    // 再下一帧继续执行,达到一直执行动画的效果
    // 每一帧都移动x和y 相当于让他做旋转动画
    requestAnimationFrame(animate)
    // 设置几何体x轴移动
    // cube.rotation.x +=0.01
    // cube.rotation.y += 0.01
    // 渲染
    renderer.render(scene, camera)
  }
  animate()
  // 监听窗口大小变化重新渲染画布
  window.addEventListener('resize', () => {
    // 重置渲染器宽高比
    renderer.setSize(window.innerWidth, window.innerHeight)
    // 重置相机宽高比
    camera.aspect = window.innerWidth / window.innerHeight
    // 更新相机投影矩阵
    camera.updateProjectionMatrix()
  })

  let btn = document.createElement('button')
  btn.innerHTML = '点击'
  btn.style.position = 'absolute'
  btn.style.top = '10%'
  btn.style.left = '50%'
  btn.style.zIndex = '9999'
  document.body.appendChild(btn)

  btn.addEventListener('click', () => {
    //  全屏画布
    renderer.domElement.requestFullscreen()
  })
</script>

<template>
  <div> </div>
</template>

<style scoped></style>

全屏画布#

renderer.domElement.requestFullscreen()

dom.requestFullscreen () 方法会将当前窗口调整为全屏模式

退出全屏#

document.exitFullscreen()

基础案例代码#

<script setup>
  // 导入three
  import * as three from 'three'
  // 导入轨道控制器
  import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
  // 创建场景
  const scene = new three.Scene()
  // 创建相机
  const camera = new three.PerspectiveCamera(
    45, // 视角
    window.innerWidth / window.innerHeight, // 宽高比
    0.1, // 近平面
    1000 // 远平面
  )
  // 创建渲染器
  const renderer = new three.WebGLRenderer()
  // 设置渲染器大小
  renderer.setSize(window.innerWidth, window.innerHeight)
  // 将渲染器添加到body中
  document.body.appendChild(renderer.domElement)
  // 创建几何体
  const geometry = new three.BoxGeometry(1, 1, 1)
  // 创建材质
  const material = new three.MeshBasicMaterial({ color: 0x00ff00 })
  // 创建网格
  const cube = new three.Mesh(geometry, material)
  // 设置网格位置
  cube.position.set(3, 0, 0)
  // 将网格添加到场景中
  scene.add(cube)
  // 设置相机位置
  camera.position.z = 5
  camera.position.y = 2
  camera.position.x = 2
  // 相机看向
  camera.lookAt(0, 0, 0)
  // 创建世界座标辅助器
  const axesHelper = new three.AxesHelper(5)
  // 将辅助器添加到场景中
  scene.add(axesHelper)
  // 创建控制器, 可以修改第二个参数来选择哪个dom来控制事件
  const controls = new OrbitControls(camera, renderer.domElement) 
  // 设置带阻尼,拖动会有惯性 
  controls.enableDamping = true 
  // 设置阻尼系数
  controls.dampingFactor = 0.04 
  // 设置自动旋转
  controls.autoRotate = true
  // 渲染函数
  function animate() {
    // 更新控制器
    controls.update()
    // 再下一帧继续执行,达到一直执行动画的效果,每一帧都移动x和y 相当于让他做旋转动画
    requestAnimationFrame(animate)
    // 设置几何体x轴移动
    cube.rotation.x += 0.01 
    cube.rotation.y += 0.01
    // 渲染
    renderer.render(scene, camera)
  }
  animate()
  // 监听窗口大小变化重新渲染画布
  window.addEventListener('resize', () => {
    // 重置渲染器宽高比
    renderer.setSize(window.innerWidth, window.innerHeight)
    // 重置相机宽高比
    camera.aspect = window.innerWidth / window.innerHeight
    // 更新相机投影矩阵
    camera.updateProjectionMatrix()
  })

</script>

<template>
  <div></div>
</template>

<style scoped></style>

GUI 工具#

  1. 导入

import {GUI} from 'three/examples/jsm/libs/lil-gui.module.min.js'

  1. 使用

const gui = new GUI()

  1. 定义

标准定义对象

let eventObje = {
    fullScreen: () => {
        document.body.requestFullscreen()
    },
    exitfullScreen: () => {
        document.exitFullscreen()
    }
}
  1. 使用
gui.add(eventObje,'fullScreen')
gui.add(eventObje,'exitfullScreen')
  1. 修改中文名称
gui.add(eventObje, 'fullScreen').name = '全屏'
gui.add(eventObje, 'exitfullScreen').name = '退出全屏'
  1. 循环添加
let eventObje = {
    fullScreen: {
        name: '全屏',
        on: () => {
            document.body.requestFullscreen()
        }
    },
    exitfullScreen: {
        name: '退出全屏',
        on: () => {
            document.exitFullscreen()
        }
    }
}
const gui = new GUI()
for (const [key, value] of Object.entries(eventObje)) {
    gui.add({
        [key]: value.on
    }, key).name(value.name)
}
  1. 设置立方体属性
folder.add(cube.position, 'x').min(-10).max(10).name('x轴').onChange(val => console.log(val))

min 设置最小值
max 设置最大值
step 设置步长
onChange 设置改变时触发的事件
onFinishChange 设置改变完成时触发的事件

  1. 设置材质属性
gui.add(material, 'wireframe').name('线框')
gui.addColor(material, 'color').name('颜色')
  1. wireframe 设置是否线框模式
  2. addColor 设置颜色

使用顶点绘制平面#

立方体都是由平面三角形组成,三角形又由 3 个顶点组成

  1. 创建平面
    const geo = new three.BufferGeometry()

使用缓冲区几何体

  1. 设置顶点数据
    需要使用 32 位浮点数数组,顶点是有顺序的,逆时针为正面

绘制一个三角形

cosnt vertices = new Float32Array([
    -1, -1, 0
    1, -1, 0
    1, 1, 0
])

参数为顶点数组,一个三角形三个顶点,每个顶点都有 x, y, z 坐标

  1. 设置顶点数据到几何体
    ` geo.setAttribute('position', new three. BufferAttribute(vertices.3))

  2. 设置正方形
    只需要在绘制一个三角形和这个三角形相邻即可

// const vertices = new Float32Array([
//   -1.0, -1.0, 0.0,
//   1.0, -1.0, 0.0,
//   1.0, 1.0, 0.0,
//   1.0,1.0,0.0,
//   -1.0,1.0,0.0,
//   -1.0,-1.0,0.0,
// ])
// 设置定点数据到几何体定点位置属性上
// geometry.setAttribute('position', new three.BufferAttribute(vertices, 3))
  1. 使用索引

由于两个三角形相邻,其实有部分顶点是可以共用的,上述做法正方形有 6 个顶点,使用索引可以优化为 4 个
::: tip
使用索引需要指定 4 个顶点坐标,既正方形 4 个点
:::

// 使用索引绘制4个顶点
const vertices = new Float32Array([
    -1.0, -1.0, 0.0,
    1.0, -1.0, 0.0,
    1.0, 1.0, 0.0,
    -1.0, 1.0, 0.0,
])
// 创建索引 使用0,1,2创建一个三角形,使用2,3,0创建一个三角形
// 组合为正方形,节约2个顶点
const indices = new Uint16Array([
    0, 1, 2,
    2, 3, 0
])
// 设置索引
geometry.setIndex(new three.BufferAttribute(indices, 1))
geometry.setAttribute('position', new three.BufferAttribute(vertices, 3))

不同面设置不同的材质#

  1. 设置顶点组
// 设置两个顶点组
geometry.addGroup(0, 3, 0)
geometry.addGroup(3, 3, 1)
geometry.setAttribute('position', new three.BufferAttribute(vertices, 3))
// 创建网格时 材质可以传一个数组,每个顶点组对应一个材质
const material = new three.MeshBasicMaterial({
    color: 0x00ff00,
    side: three.DoubleSide
})
const material2 = new three.MeshBasicMaterial({
    color: 0xff0000,
    side: three.DoubleSide
})
const cube = new three.Mesh(geometry, [material, material2])

内置集合体#

  1. 立方缓冲几何体
const geometry = new THREE.BoxGeometry( 1, 1, 1 );
const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );

构造器
BoxGeometry(width : Float, height : Float, depth : Float, widthSegments : Integer, heightSegments : Integer, depthSegments : Integer)

width — X 轴上面的宽度,默认值为 1。

height — Y 轴上面的高度,默认值为 1。

depth — Z 轴上面的深度,默认值为 1。

widthSegments — (可选)宽度的分段数,默认值是 1。

heightSegments — (可选)高度的分段数,默认值是 1。

depthSegments — (可选)深度的分段数,默认值是 1。

  1. 圆形缓冲几何体
const geometry = new THREE.CircleGeometry( 5, 32 );
const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
const circle = new THREE.Mesh( geometry, material );
scene.add( circle );

构造器

CircleGeometry(radius : Float, segments : Integer, thetaStart : Float, thetaLength : Float)

radius — 圆形的半径,默认值为 1

segments — 分段(三角面)的数量,最小值为 3,默认值为 8。

thetaStart — 第一个分段的起始角度,默认为 0。(three o'clock position)

thetaLength — 圆形扇区的中心角,通常被称为 “θ”(西塔)。默认值是 2*Pi,这使其成为一个完整的圆。

  1. 圆锥缓冲几何体

const geometry = new THREE.ConeGeometry( 5, 20, 32 );
const material = new THREE.MeshBasicMaterial( {color: 0xffff00} );
const cone = new THREE.Mesh( geometry, material );
scene.add( cone );

构造器

BoxGeometry(width : Float, height : Float, depth : Float, widthSegments : Integer, heightSegments : Integer, depthSegments : Integer)

width — X 轴上面的宽度,默认值为 1。

height — Y 轴上面的高度,默认值为 1。

depth — Z 轴上面的深度,默认值为 1。

widthSegments — (可选)宽度的分段数,默认值是 1。

heightSegments — (可选)高度的分段数,默认值是 1。

depthSegments — (可选)深度的分段数,默认值是 1。

其他几何体 https://www.three3d.cn/docs/index.html?q=geo#api/zh/core/BufferGeometry

添加纹理贴图#

在创建材质的时候,配置对象中传入 map 属性,值为纹理对象

  1. 创建纹理加载器
    const loader = new three.TextureLoader()
  2. 创建纹理对象
    const texture = loader.load('./img/texture.png')
  3. 创建材质
    const material = new three.MeshBasicMaterial({map: texture})
  4. 设置贴图
  • 透明度贴图(Alpha Map)

作用:用于控制模型表面的透明度(Alpha 值)。黑色部分完全透明,白色部分完全不透明,灰色部分则是部分透明。
使用场景:适用于制作窗户、玻璃等部分透明的物体。

  • 光照贴图(Light Map)

作用:存储预先计算好的光照信息,以减少实时计算光照的负担。这种贴图包含了阴影和亮度信息。
使用场景:用于提高静态场景的渲染效率,适合光照变化不大的场景,比如建筑物的内部。

  • 高光贴图(Specular Map)

作用:控制模型表面哪些部分有高光效果。高光贴图中的亮度值决定了该部分表面的反射强度。
使用场景:适用于需要精细控制高光区域的模型,如金属物品、皮革等。

  • 环境贴图(Environment Map)

作用:模拟环境反射,用于实现物体表面的环境反射效果,使物体看起来更为真实。
使用场景:常用于反射性强的物体,如水面、金属球体等。

  • AO 贴图(Ambient Occlusion Map)

作用:模拟环境光遮蔽效果,增强物体表面的阴影和深度感。AO 贴图中的黑色区域表示光被遮蔽(阴影部分),白色区域表示光没有被遮蔽。
使用场景:适用于增强模型的细节,常用于复杂的模型和场景,增加视觉深度和真实感

// 创建纹理加载器
const textureLoader = new THREE.TextureLoader();

// 加载贴图
const alphaMap = textureLoader.load('path/to/alphaMap.png');
const lightMap = textureLoader.load('path/to/lightMap.png');
const specularMap = textureLoader.load('path/to/specularMap.png');
const envMap = textureLoader.load('path/to/envMap.png');
const aoMap = textureLoader.load('path/to/aoMap.png');

// 创建材质
const material = new THREE.MeshStandardMaterial({
  color: 0xffffff,
  alphaMap: alphaMap,
  transparent: true,
  lightMap: lightMap,
  specularMap: specularMap,
  envMap: envMap,
  aoMap: aoMap,
  aoMapIntensity: 1.0 // AO贴图的强度
});

// 创建网格
const geometry = new THREE.BoxGeometry(1, 1, 1);
const mesh = new THREE.Mesh(geometry, material);

// 将网格添加到场景
scene.add(mesh);

全景环境贴图#

// 创建hdr加载器
const hdrLoader = new RGBELoader()
// hdr加载器有回调函数,在里面表示加载完毕 可以进行配置
const envMap = hdrLoader.load('/sandsloot_4k.hdr', (envMap) => {
  // 设置图片为球形映射,全景图片这样使用
  envMap.mapping = three.EquirectangularReflectionMapping
  // 设置环境贴图
  scene.background = envMap
  // 设置场景环境贴图
  scene.environment = envMap
  // 设置 立方体 材质环境贴图
  material.envMap = envMap

})
const geometry = new three.PlaneGeometry(1, 1)
//  创建几何体

const material = new three.MeshBasicMaterial({
  side: three.DoubleSide, // 双面
  color: 0xffffff, // 颜色
  map: texture, // 纹理贴图
  transparent: true, // 透明
  aoMap: aoTexture, // ao 环境遮挡贴图
  reflectivity: 0.2, // 反射强度
  alphaMap:alphaTexture, // 透明度贴图
  lightMap: lightMapTexture, // 光照贴图
  specularMap: bumpMap, // 高光贴图
  aoMapIntensity: 0.5 // ao 环境遮挡强度
})
const cube = new three.Mesh(geometry, material)
scene.add(cube)

贴图切换 srgb 模式色彩空间#

const texture = loader.load('/texture/watercover/CityNewYork002_COL_VAR1_1K.png')
// 默认是线性色彩空间,手动指定srgb,更符合人眼感知
texture.colorSpace = three.SRGBColorSpace
  1. NoColorSpace - 默认值,表示没有色彩空间转换。

  2. SRGBColorSpace - sRGB 色彩空间,适用于显示设备。

  3. LinearSRGBColorSpace - 线性色彩空间,适用于计算机图形学。

动态更新色彩空间需要调用更新函数

texture.needsUpdate = true

#

  1. 线性雾

  2. 指数雾

此文由 Mix Space 同步更新至 xLog
原始链接为 http://www.sroxck.top/posts/fontend/three


加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。