一、Three.js介绍
Three.js是一个基于WebGL的JavaScript库,它使得在网页上创建和显示3D图形变得简单。Three.js提供了一套易于使用的API,封装了WebGL的复杂性,让开发者能够快速地创建3D内容,而无需深入了解WebGL的细节。简而言之就是一个网页端轻量化渲染3d的库,我们可以用它结合VUE\REACT来做一些数字孪生的前端项目。
二、关于Three.js的一些资料
使用前请下载并配置完Node.js
官方文件包:https://github.com/mrdoob/three.js/releases
中文教程网:http://www.webgl3d.cn/
三、具体使用
首先我们要了解three.js的结构,其中包括场景、相机、渲染器、几何体、材质、网格、光源等(以vue3为例)。
在使用之前我们要引入three库
在终端输入
script标签内导入
1
| import * as THREE from "three"
|
1.场景
场景可以理解为存放所有3d对象的容器,粗略的理解为与div一样,只是前者存放3d对象,后者存放dom元素。
创建场景(示例)
1
| scene = new THREE.Scene()
|
2.相机
相机可以理解为人眼的视角,我们所看到场景内的3d对象都是那一面的照片,我们通过移动相机可以观察到3d对象每一面的照片,也就有了3d感
创建相机
1 2 3 4 5 6 7 8
| camera = new THREE.PerspectiveCamera( 75, container.value.clientWidth / container.value.clientHeight, 0.1, 1000 ) camera.position.z = 5
|
不知道如何判断相机位置可以借助世界坐标辅助器,可以在页面看到辅助坐标轴
1 2 3 4
| axesHelper=new THREE.AxesHelper(5)
scene.add(axesHelper)
|
3.渲染器
渲染器将相机“拍”到的画面渲染到页面
渲染器代码示例
1 2 3 4 5 6
| renderer = new THREE.WebGLRenderer({ antialias: true }) renderer.setSize(container.value.clientWidth, container.value.clientHeight) document.body.appendChild(renderer.domElement);
|
4.几何体、材质、网格
几何体也就是3d对象,材质则是3d对象视觉上的质感、网格则是将几何体与材质结合在一起
接下来我们创建一个绿色的正方体,并将其添加入场景
1 2 3 4 5 6 7 8 9 10
| const geometry = new THREE.BoxGeometry(1, 1, 1)
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }) cube = new THREE.Mesh(geometry, material) scene.add(cube)
|
5.光源
设置光源体现出立体感,
1 2 3
| const directionalLight = new THREE.DirectionalLight(0xffffff, 4); directionalLight.position.set(30, 10, 20); scene.add(directionalLight);
|
6.其他
可以设置函数令其旋转
1 2 3 4 5 6 7 8 9 10 11
| function animate() { animationId = requestAnimationFrame(animate) cube.rotation.x += 0.01 cube.rotation.y += 0.01 renderer.render(scene, camera) }
|
除以上外,还有其他api可以调用
1 2 3 4 5 6 7 8 9 10 11 12 13
| controls = new OrbitControls(camera, renderer.domElement); controls.enableDamping=true controls.dampingFactor=0.05 controls.autoRotate=true
camera.position.z = 5 camera.position.x=0.5 camera.position.y=0.5
|
四、代码示例
vue3代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
| <script setup>
import { onMounted, onUnmounted, ref } from 'vue'
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"
import * as THREE from 'three'
const container = ref(null)
let scene, camera, renderer, cube, animationId, axesHelper, controls const textureLoader = new THREE.TextureLoader(); textureLoader.setCrossOrigin('anonymous');
onMounted(() => { initThree() setupResizeHandler() animate() })
onUnmounted(() => { cancelAnimationFrame(animationId) window.removeEventListener('resize', handleResize) scene = null })
function initThree() {
scene = new THREE.Scene()
camera = new THREE.PerspectiveCamera( 75, container.value.clientWidth / container.value.clientHeight, 0.1, 1000 )
renderer = new THREE.WebGLRenderer({ antialias: true }) renderer.setSize(container.value.clientWidth, container.value.clientHeight) container.value.appendChild(renderer.domElement)
const geometry = new THREE.BoxGeometry(1, 1, 1) const material = new THREE.MeshLambertMaterial({ color: 0x00ff00 }) cube = new THREE.Mesh(geometry, material) scene.add(cube) const directionalLight = new THREE.DirectionalLight(0xffffff, 4); directionalLight.position.set(30, 10, 20); scene.add(directionalLight);
axesHelper = new THREE.AxesHelper(5) scene.add(axesHelper) controls = new OrbitControls(camera, renderer.domElement); controls.enableDamping = true controls.dampingFactor = 0.05 camera.position.z = 5 camera.position.x = 0.5 camera.position.y = 0.5 }
function animate() { controls.update() animationId = requestAnimationFrame(animate)
renderer.render(scene, camera) }
function handleResize() { camera.aspect = container.value.clientWidth / container.value.clientHeight camera.updateProjectionMatrix() renderer.setSize(container.value.clientWidth, container.value.clientHeight) }
function setupResizeHandler() { window.addEventListener('resize', handleResize) } </script>
<template> <div ref="container" class="three-container"></div> </template>
<style scoped>
.three-container { width: 100vw; height: 100vh; position: fixed; top: 0; left: 0; overflow: hidden; } </style>
|