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)
    // 渲染
    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


載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。