1.安装依赖
npm install --save three
2.引入依赖
import * as THREE from 'three'
3.编写控件的页面,可以从网站 sketchfab 下载和导入3D建模的模型(需注册,有些是免费的),在这里用到的模型地址是https://sketchfab.com/3d-models/seraphine-c4d72965ffce45b8886d1e0ceab6728e
页面控件是跟着https://zhuanlan.zhihu.com/p/333615381这位博主写的,做了一些适配的小改动
import * as THREE from 'three'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
export default {
mounted() {
this.initThree()
},
methods: {
initThree() {
const scene = new THREE.Scene()
scene.background = new THREE.Color('#eee')
scene.fog = new THREE.Fog('#eee', 20, 100)
const canvas = document.querySelector('#three')
const renderer = new THREE.WebGLRenderer({ canvas, antialias: true })
renderer.shadowMap.enabled = true
const camera = new THREE.PerspectiveCamera(
50,
window.innerWidth / window.innerHeight,
0.1,
1000
)
camera.position.z = 10
const gltfLoader = new GLTFLoader()
gltfLoader.load('/seraphine/scene.gltf', (gltf) => {
let model = gltf.scene
//遍历模型每部分
model.traverse((o) => {
//将图片作为纹理加载
let explosionTexture = new THREE.TextureLoader().load(
'/seraphine/textures/Mat_cwfyfr1_userboy17.bmp_diffuse.png'
)
//调整纹理图的方向
explosionTexture.flipY = false
//将纹理图生成基础网格材质(MeshBasicMaterial)
const material = new THREE.MeshBasicMaterial({
map: explosionTexture,
})
//给模型每部分上材质
o.material = material
if (o.isMesh) {
o.castShadow = true
o.receiveShadow = true
}
})
scene.add(model)
})
const hemLight = new THREE.HemisphereLight(0xffffff, 0xffffff, 0.6)
hemLight.position.set(0, 48, 0)
scene.add(hemLight)
const dirLight = new THREE.DirectionalLight(0xffffff, 0.6)
//光源等位置
dirLight.position.set(-10, 8, -5)
//可以产生阴影
dirLight.castShadow = true
dirLight.shadow.mapSize = new THREE.Vector2(1024, 1024)
scene.add(dirLight)
let floorGeometry = new THREE.PlaneGeometry(8000, 8000)
let floorMaterial = new THREE.MeshPhongMaterial({
color: 0x857ebb,
shininess: 0,
})
let floor = new THREE.Mesh(floorGeometry, floorMaterial)
floor.rotation.x = -0.5 * Math.PI
floor.receiveShadow = true
floor.position.y = -0.001
scene.add(floor)
const controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true
function animate() {
controls.update()
renderer.render(scene, camera)
requestAnimationFrame(animate)
if (resizeRendererToDisplaySize(renderer)) {
const canvas = renderer.domElement
camera.aspect = canvas.clientWidth / canvas.clientHeight
camera.updateProjectionMatrix()
}
}
animate()
function resizeRendererToDisplaySize(renderer) {
const canvas = renderer.domElement
var width = window.innerWidth
var height = window.innerHeight
var canvasPixelWidth = canvas.width / window.devicePixelRatio
var canvasPixelHeight = canvas.height / window.devicePixelRatio
const needResize =
canvasPixelWidth !== width || canvasPixelHeight !== height
if (needResize) {
renderer.setSize(width, height, false)
}
return needResize
}
},
},
}
#three {
width: 100%;
height: 100%;
position: relative;
}
这里每个功能方法的使用这位博主https://zhuanlan.zhihu.com/p/333615381写的很详细了,可以去原帖子学习,最后贴上效果图片