这个案例主要是实现三维文字效果。效果如下:
首先是搭建基础环境,场景、相机、渲染器和控制器,不清楚的可以查看three.js基础案例day01.
1.创建平行光和点光源
const dirLight = new THREE.DirectionalLight(0xfffff, 0.125)
dirLight.position.set(0, 0, 1).normalize()
scene.add(dirLight)
const pointLight = new THREE.PointLight(0xffffff, 1.5)
pointLight.position.set(0, 100, 90)
scene.add(pointLight)
2.导入FontLoader 并使用
// 导入
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader.js'
// 使用
const loader = new FontLoader()
loader.load('static/fonts/helvetiker_bold.typeface.json', font => {
console.log(font)
})
3.导入TextGeometry 并使用
// 导入
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry.js'
// 使用 设置字体大小、高度厚度等等
const geometry = new TextGeometry('three.js', {
font: font,
size: 50,
height: 30,
curveSegments: 20,
bevelThickness: 2,
bevelSize: 1.5,
bevelEnabled: true,
})
const textMesh1 = new THREE.Mesh(geometry, materials)
textMesh1.position.set(0, 0, 0)
scene.add(textMesh1)
4.修改字体位置
const xOffset =
(geometry.boundingBox.max.x - geometry.boundingBox.min.x) / 2
const textMesh1 = new THREE.Mesh(geometry, materials)
textMesh1.position.set(-xOffset, 30, -15)
scene.add(textMesh1)
5.创建平面和第二个文字(文字反过来)
const plane = new THREE.Mesh(
new THREE.PlaneGeometry(10000, 10000),
new THREE.MeshBasicMaterial({
color: 0xffffff,
opacity: 0.5,
transparent: true,
}),
)
plane.position.y = -10
plane.rotation.x = -Math.PI / 2
scene.add(plane)
// 第二个文字
const textMesh2 = new THREE.Mesh(geometry, materials)
textMesh2.position.set(-xOffset, -30, 0)
textMesh2.rotation.x = Math.PI
scene.add(textMesh2)
全部代码
<template>
<div id="threeId" ref="elementRef"></div>
</template>
<script setup>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader.js'
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry.js'
import { ref, onMounted } from 'vue'
let width, height, scene, camera, renderer, controls
const elementRef = ref(null)
onMounted(() => {
const element = elementRef.value
width = element.offsetWidth
height = element.offsetHeight
initScene()
initLights()
initMeshes()
render()
})
function initScene() {
// 初始化场景: 创建场景,相机,物体,渲染器
scene = new THREE.Scene()
scene.fog = new THREE.Fog(0, 250, 1400)
console.log('three', THREE)
camera = new THREE.PerspectiveCamera(60, width / height, 1, 1000)
camera.position.set(0, 20, 260)
scene.add(camera)
// const axesHelper = new THREE.AxesHelper(40)
// scene.add(axesHelper)
renderer = new THREE.WebGLRenderer()
renderer.setSize(width, height)
elementRef.value.appendChild(renderer.domElement)
controls = new OrbitControls(camera, renderer.domElement)
controls.update()
}
function initLights() {
const dirLight = new THREE.DirectionalLight(0xfffff, 0.125)
dirLight.position.set(0, 0, 1).normalize()
scene.add(dirLight)
const pointLight = new THREE.PointLight(0xffffff, 1.5)
pointLight.position.set(0, 100, 90)
scene.add(pointLight)
}
function initMeshes() {
// plane
const plane = new THREE.Mesh(
new THREE.PlaneGeometry(10000, 10000),
new THREE.MeshBasicMaterial({
color: 0xffffff,
opacity: 0.5,
transparent: true,
}),
)
plane.position.y = -10
plane.rotation.x = -Math.PI / 2
scene.add(plane)
// font
const materials = [
new THREE.MeshPhongMaterial({
color: 0xffffff,
flatShading: true,
}), // front
new THREE.MeshPhongMaterial({ color: 0xffffff }), //side
]
const loader = new FontLoader()
loader.load('static/fonts/helvetiker_bold.typeface.json', font => {
const geometry = new TextGeometry('three.js', {
font: font,
size: 50,
height: 30,
curveSegments: 20,
bevelThickness: 2,
bevelSize: 1.5,
bevelEnabled: true,
})
geometry.computeBoundingBox()
const xOffset =
(geometry.boundingBox.max.x - geometry.boundingBox.min.x) / 2
const textMesh1 = new THREE.Mesh(geometry, materials)
textMesh1.position.set(-xOffset, 30, -15)
scene.add(textMesh1)
const textMesh2 = new THREE.Mesh(geometry, materials)
textMesh2.position.set(-xOffset, -30, 0)
textMesh2.rotation.x = Math.PI
scene.add(textMesh2)
})
}
function render() {
requestAnimationFrame(render)
controls.update()
renderer.render(scene, camera)
}
</script>
<style lang="scss" scoped>
#threeId {
width: 100%;
height: 100%;
}
</style>