threejs学习

发布于:2024-10-13 ⋅ 阅读:(53) ⋅ 点赞:(0)

一、three.js文档本地搭建

​
1.下载地址
  https://github.com/mrdoob/three.js

2.压缩包加压

3.下载依赖
  npm install //下载依赖

4.启动项目
  npm run start

5.项目地址
  http://localhost:8080

​6.页面介绍
    docs/    文档
    editor/  编辑器
    manual/  教程

二、项目搭建

1.安装项目
    create-vite threejs
2.下载依赖
    npm install
3.启动项目
    npm run dev
4.下载three依赖
    npm install three

三、属性学习

1.创建基础几何图形
   1.1效果

   1.2代码
import { ref, render } from 'vue'
// 导入threejs文件
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 //设置在z轴位置
camera.position.y = 2 //设置在y轴位置
camera.position.x = 2 //设置在x轴位置
// 看向位置
camera.lookAt(0,0,0) //看向原点
// 渲染函数
const animate=()=> {
  requestAnimationFrame(animate) //每一帧调用函数
  // 旋转
  cube.rotation.x += 0.01 // X轴转
  cube.rotation.y += 0.01 // Y轴转
  renderer.render(scene, camera) // 重新渲染
}
animate()
2.轨道设置
  2.1效果
  2.2代码
// 导入threejs文件
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 //设置在z轴位置
camera.position.y = 2 //设置在y轴位置
camera.position.x = 2 //设置在x轴位置
// 看向位置
camera.lookAt(0,0,0) //看向原点
// 添加世界坐标辅助器
const axesHelper = new three.AxesHelper(5) // 5表示线段长度为5
scene.add(axesHelper)
// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true // 启用阻尼系数:值越大,阻尼越明显
controls.dampingFactor = 0.5 //设置阻尼值
controls.enableZoom = true // 启用缩放:值为false时禁止缩放
controls.autoRotate = true // 启用自动旋转:值为true时禁止手动旋转
controls.autoRotateSpeed = 0.5 // 自动旋转速度
// 渲染函数
const animate=()=> {
  controls.update()
  requestAnimationFrame(animate) //每一帧调用函数
  // 旋转
  cube.rotation.x += 0.01 // X轴转
  cube.rotation.y += 0.01 // Y轴转
  renderer.render(scene, camera) // 重新渲染
}
animate()
3.物体的移动、缩放和旋转
  3.1效果

  3.2代码
// 导入threejs文件
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 material2 = new three.MeshBasicMaterial({
  color: 0xffff00 //材质颜色 
})
// 创建网格
const cube = new three.Mesh(geometry, material) //物体一
const cube2 = new three.Mesh(geometry, material2) //物体二
// 物体移动
cube.position.set(-3,0,0) // 父物体根据原点移动
cube2.position.set(3,0,0) // 子物体根据父物体移动
// 加入子场景
cube.add(cube2) //将物体2放到物体一中
//设置物体的放大
cube.scale.set(5,5,5) // 物体放大5倍
cube2.scale.set(2,2,2) // 子物体会根据父物体放大2倍
// 绕着X轴旋转
cube.rotation.x = Math.PI / 4 // 物体绕着x轴转45°
cube2.rotation.x = Math.PI / 4 //子物体会根据父物体绕着x轴转45°
// 加入场景
scene.add(cube)
// 相机位置
camera.position.z = 5 //设置在z轴位置
camera.position.y = 2 //设置在y轴位置
camera.position.x = 2 //设置在x轴位置
// 看向位置
camera.lookAt(0,0,0) //看向原点
// 添加世界坐标辅助器
const axesHelper = new three.AxesHelper(5) // 5表示线段长度为5
scene.add(axesHelper)
// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true // 启用阻尼系数:值越大,阻尼越明显
controls.dampingFactor = 0.5 //设置阻尼值
controls.enableZoom = true // 启用缩放:值为false时禁止缩放
// controls.autoRotate = true // 启用自动旋转:值为true时禁止手动旋转
controls.autoRotateSpeed = 0.5 // 自动旋转速度
// 渲染函数
const animate=()=> {
  controls.update()
  requestAnimationFrame(animate) //每一帧调用函数
  // 旋转
  // cube.rotation.x += 0.01 // X轴转
  // cube.rotation.y += 0.01 // Y轴转
  renderer.render(scene, camera) // 重新渲染
}
animate()
4. 监听窗口变化重新渲染画布
// 导入threejs文件
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 //设置在z轴位置
// 看向位置
camera.lookAt(0,0,0) //看向原点
// 渲染函数
const animate=()=> {
  requestAnimationFrame(animate) //每一帧调用函数
  renderer.render(scene, camera) // 重新渲染
}
animate()
// 监听窗口变化
window.addEventListener('resize', () => {
  // 重置相机宽高比
  camera.aspect = window.innerWidth / window.innerHeight
  // 重置相机投影矩阵
  camera.updateProjectionMatrix()
  // 重置渲染器宽高比
  renderer.setSize(window.innerWidth, window.innerHeight)
})
5.画布的全屏
  5.1效果

  5.2代码
// 导入threejs文件
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 //设置在z轴位置
// 看向位置
camera.lookAt(0,0,0) //看向原点
// 渲染函数
const animate=()=> {
  requestAnimationFrame(animate) //每一帧调用函数
  renderer.render(scene, camera) // 重新渲染
}
animate()
// 创建全屏按钮
const btn = document.createElement('button')
btn.innerHTML = '点击全屏'
btn.style.position = 'absolute'
btn.style.top = '10px'
btn.style.left = '10px'
btn.style.zIndex = '999'
btn.onclick = ()=>{
  // renderer.domElement.requestFullscreen() //画布全屏
  document.body.requestFullscreen() //body全屏
}
document.body.appendChild(btn)

// 退出全屏按钮
const btnExit = document.createElement('button')
btnExit.innerHTML = '退出全屏'
btnExit.style.position = 'absolute'
btnExit.style.top = '10px'
btnExit.style.left = '120px'
btnExit.style.zIndex = '999'
btnExit.onclick = ()=>{
  // renderer.domElement.exitFullscreen()//画布退出全屏
 if (document.fullscreenElement)   document.exitFullscreen()//body退出全屏
}
document.body.appendChild(btnExit)
6.GUI调试面板设置
  6.1效果

  6.2代码
// 导入threejs文件
import * as three from 'three'
// 导入GUI
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.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 material2 = new three.MeshBasicMaterial({
  color: 0xffff00 //材质颜色 
})
// 设置物体为线框模式
material.wireframe = true
// 创建网格
const cube = new three.Mesh(geometry, material) //物体一
const cube2 = new three.Mesh(geometry, material2) //物体二
// 物体移动
cube.position.set(-3,0,0) // 父物体根据原点移动
cube2.position.set(3,0,0) // 子物体根据父物体移动
// 加入子场景
cube.add(cube2) //将物体2放到物体一中
//设置物体的放大
cube.scale.set(5,5,5) // 物体放大5倍
cube2.scale.set(2,2,2) // 子物体会根据父物体放大2倍
// 绕着X轴旋转
cube.rotation.x = Math.PI / 4 // 物体绕着x轴转45°
cube2.rotation.x = Math.PI / 4 //子物体会根据父物体绕着x轴转45°
// 加入场景
scene.add(cube)
// 相机位置
camera.position.z = 5 //设置在z轴位置
camera.position.y = 2 //设置在y轴位置
camera.position.x = 2 //设置在x轴位置
// 看向位置
camera.lookAt(0,0,0) //看向原点
// 添加世界坐标辅助器
const axesHelper = new three.AxesHelper(5) // 5表示线段长度为5
scene.add(axesHelper)
// 渲染函数
const animate=()=> {
  requestAnimationFrame(animate) //每一帧调用函数
  renderer.render(scene, camera) // 重新渲染
}
animate()
// 创建方法
let eventObj = {
  Fullscreen:()=>{
    document.body.requestFullscreen() //body全屏
    // renderer.domElement.requestFullscreen() //画布全屏
  },
  ExitFullscreen:()=>{
     // renderer.domElement.exitFullscreen()//画布退出全屏
      if (document.fullscreenElement)   document.exitFullscreen()//body退出全屏
  }
}
const gui = new GUI()
// 添加按钮
gui.add(eventObj,'ExitFullscreen').name('退出全屏')

// 创建文件夹
let folder = gui.addFolder("物体设置")
// 控制物体位置
// 写法1
// min 最小 max最大 step 间隔 name 按钮名
folder.add(cube.position, 'x').min(-10).max(10).step(1).name('X轴位置') 
folder.add(cube.position, 'y').min(-10).max(10).step(1).name('Y轴位置').onFinishChange(val=>{
  // 拖动完触发
  console.log(val);
  
})
folder.add(cube.position, 'z').min(-10).max(10).step(1).name('Z轴位置').onChange(val=>{
  // 数据变化时触发
  console.log(val);
})
// 写法2
// gui.add(cube.position, 'x', -5, 5).name('X轴位置') // -5 5 最小/最大范围

// 切换线框模式
gui.add(material,'wireframe').name('线框模式')
// 设置物体颜色
let colorParams ={
  cub2Color:"0xffff00"
}
gui.addColor(colorParams,'cub2Color').name('物体2颜色').onChange(val=>{
  // 颜色变化时触发
  cube2.material.color.set(val)
})
7.设置几个面不同材质
   7.1效果
   7.2代码
// 导入threejs文件
import * as three from 'three'
// 导入轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.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 geomentry = new three.BoxGeometry(1, 1, 1)
// 创建材质
const material1 = new three.MeshBasicMaterial({ color: 0x00ff00 })
const material2 = new three.MeshBasicMaterial({ color: 0xffc0cb })
const material3 = new three.MeshBasicMaterial({ color: 0x808080 })
const material4 = new three.MeshBasicMaterial({ color: 0x87ceeb })
const material5 = new three.MeshBasicMaterial({ color: 0xb0c4de })
const material6 = new three.MeshBasicMaterial({ color: 0xb0c4de })

// 创建网格
const cube = new three.Mesh(geomentry, [material1, material2, material3, material4, material5, material6,])

// 加入场景
scene.add(cube)
// 相机位置
camera.position.z = 5 //设置在z轴位置
camera.position.y = 2 //设置在y轴位置
camera.position.x = 2 //设置在x轴位置
// 看向位置
camera.lookAt(0, 0, 0) //看向原点
// 添加世界坐标辅助器
const axesHelper = new three.AxesHelper(5) // 5表示线段长度为5
scene.add(axesHelper)
// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true // 启用阻尼系数:值越大,阻尼越明显
controls.dampingFactor = 0.5 //设置阻尼值
controls.enableZoom = true // 启用缩放:值为false时禁止缩放
// controls.autoRotate = true // 启用自动旋转:值为true时禁止手动旋转
controls.autoRotateSpeed = 0.5 // 自动旋转速度
// 渲染函数
const animate = () => {
  controls.update()
  requestAnimationFrame(animate) //每一帧调用函数
  // 旋转
  // cube.rotation.x += 0.01 // X轴转
  // cube.rotation.y += 0.01 // Y轴转
  renderer.render(scene, camera) // 重新渲染
}
animate()
 8.雾属性设置
     8.1属性
scene.fog = new three.Fog(0x999999, 0.1, 50)   // 线性雾(基于距离的雾效。随着物体离相机越来越远,它们逐渐被雾的颜色所取代。)
参数1表示颜色  
参数2表示雾开始影响物体的距离,单位为世界坐标系中的单位长度。  
参数3表示雾完全覆盖物体的距离

scene.fog = new three.FogExp2(0x999999,0.1)   //指数雾(基于距离的指数衰减雾效。随着物体离相机越来越远,它们逐渐被雾的颜色所取代,但这种效果是指数级的,因此远处的物体比近处的物体更快地被雾覆盖。)    
参数1表示颜色  
参数2雾的密度,决定了雾效的衰减速率。较大的值会导致雾效更快地覆盖物体。

scene.background = new three.Color(0x999999)  // 设置背景颜色
     8.2效果

     8.3代码
// 导入threejs文件
import * as three from 'three'
// 导入轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
// 导入GUI
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.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 geomentry = new three.BoxGeometry(1, 1, 100)
// 创建材质
const material = new three.MeshBasicMaterial({
  color: 0x00ff00, //颜色
  })
// 创建网格
const cube = new three.Mesh(geomentry, material)
// 加入场景
scene.add(cube)
// 设置场景雾
// scene.fog = new three.Fog(0x999999, 0.1, 50) //线性雾 
scene.fog = new three.FogExp2(0x999999,0.1)  //指数雾     
// 设置背景颜色
scene.background = new three.Color(0x999999)
// 相机位置
camera.position.z = 5 //设置在z轴位置
// 看向位置
camera.lookAt(0, 0, 0) //看向原点
// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true // 启用阻尼系数:值越大,阻尼越明显
controls.dampingFactor = 0.5 //设置阻尼值
controls.enableZoom = true // 启用缩放:值为false时禁止缩放
// controls.autoRotate = true // 启用自动旋转:值为true时禁止手动旋转
controls.autoRotateSpeed = 0.5 // 自动旋转速度
// 渲染函数
const animate = () => {
  controls.update()
  requestAnimationFrame(animate) //每一帧调用函数
  // 旋转
  // cube.rotation.x += 0.01 // X轴转
  // cube.rotation.y += 0.01 // Y轴转
  renderer.render(scene, camera) // 重新渲染
}
animate()