【Three.js基础学习】8.3D Text

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

  课程要点:

    1.要使用的字体  字体加载器 FontLoading()

    引入: import { FontLoader } from 'three/examples/jsm/loaders/FontLoader.js'

        const fontLoading = FontLoading()  // 133 版本之后使用这种写法

    但是和纹理加载器使用方式不同

    文字立方体

    import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry'

    const textGeometry = new  TextGeometry() // 133版本之后需要使用这种写法

    bounding 边界

    边界是与几何形状相关的信息,它告诉我们几何体占用的空间信息

    为什么three.js有盒子和球体边界,这种称之为平截体剔除

    平截体剔除:是关于渲染和不渲染对象,如果对象在摄像机后面,则不希望渲染

    默认情况下使用球形边界,下面中使用框边界,计算来让文字剧中

    textGeometry.computeBoundingBox()


一、代码

import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import * as dat from 'lil-gui'
import { FontLoader } from 'three/examples/jsm/loaders/fontloader.js'
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry'


/**
 * Base
 */
// Debug
const gui = new dat.GUI()

// Canvas
const canvas = document.querySelector('canvas.webgl')

// Scene
const scene = new THREE.Scene()

/**
 * Textures
 */
const textureLoader = new THREE.TextureLoader()
const matcapTexture = textureLoader.load('/textures/matcaps/1.png')

/* 
    Axes helper
*/
const axesHelper = new THREE.AxesHelper()
scene.add(axesHelper)

/* 
    FontLoading
*/
const fontloader = new FontLoader()

fontloader.load(
    '/fonts/helvetiker_regular.typeface.json',
    (font)=>{
        const textGeometry = new TextGeometry(
            'Hello Three.js',
            {
                font, // 字体格式
                size:0.5,  // 大小
                height:0.2, // 高度
                curveSegments:5,
                bevelEnabled:true, // 斜切面启动
                bevelThickness:0.03, // 斜面的厚度
                bevelSize:0.02, // 斜切面 会影响计算boundingBox 的值
                bevelOffset:0, // 倒角偏移
                bevelSegments:5, // 

            }
        )
        // 文字居中
        // textGeometry.computeBoundingBox()
        // textGeometry.translate(
        //     - (textGeometry.boundingBox.max.x - 0.02) * 0.5,
        //     - (textGeometry.boundingBox.max.y - 0.02) * 0.5,
        //     - (textGeometry.boundingBox.max.z - 0.03) * 0.5,
        // )
        // console.log(textGeometry.boundingBox)
        
        textGeometry.center()

        // const textMaterial = new THREE.MeshBasicMaterial()

        const material = new THREE.MeshMatcapMaterial()
        material.matcap = matcapTexture
        // textMaterial.wireframe = true
        const text = new THREE.Mesh(textGeometry,material)
        scene.add(text)

        // 由于相同材质和几何体 ,那么不需要每次循环都创建 ,只需要生成网格时候 ,创建多个网格,然后应用到上面
        // 性能优化
        const donutGeometry = new THREE.TorusGeometry(0.3,0.2,20,45)
        // const donutMaterial = new THREE.MeshMatcapMaterial({matcap:matcapTexture})
        for(let i=0;i<300;i++){

            const dount = new THREE.Mesh(donutGeometry,material)
            dount.position.x = (Math.random() - 0.5) * 10
            dount.position.y = (Math.random() - 0.5) * 10
            dount.position.z = (Math.random() - 0.5) * 10

            dount.rotation.x = Math.random() * Math.PI
            dount.rotation.y = Math.random() * Math.PI

            const scale = Math.random()
            dount.scale.set(scale,scale,scale)

            scene.add(dount)
        }
    }
)


/**
 * Object
 */
// const cube = new THREE.Mesh(
//     new THREE.BoxGeometry(1, 1, 1),
//     new THREE.MeshBasicMaterial()
// )

// scene.add(cube)

/**
 * Sizes
 */
const sizes = {
    width: window.innerWidth,
    height: window.innerHeight
}

window.addEventListener('resize', () =>
{
    // Update sizes
    sizes.width = window.innerWidth
    sizes.height = window.innerHeight

    // Update camera
    camera.aspect = sizes.width / sizes.height
    camera.updateProjectionMatrix()

    // Update renderer
    renderer.setSize(sizes.width, sizes.height)
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
})

/**
 * Camera
 */
// Base camera
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 0.1, 100)
camera.position.x = 1
camera.position.y = 1
camera.position.z = 2
scene.add(camera)

// Controls
const controls = new OrbitControls(camera, canvas)
controls.enableDamping = true

/**
 * Renderer
 */
const renderer = new THREE.WebGLRenderer({
    canvas: canvas
})
renderer.setSize(sizes.width, sizes.height)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))

/**
 * Animate
 */
const clock = new THREE.Clock()

const tick = () =>
{
    const elapsedTime = clock.getElapsedTime()

    // Update controls
    controls.update()

    // Render
    renderer.render(scene, camera)

    // Call tick again on the next frame
    window.requestAnimationFrame(tick)
}

tick()

二、知识点

1.fontLoading 字体加载器

import { FontLoader } from 'three/examples/jsm/loaders/fontloader.js'

fontLoading 参数对应显示 ,参数1:引入资源,;参数:回调函数  onLoad onProgress onError

2.平截体剔除

为什么three.js有盒子和球体边界,这种称之为平截体剔除

    平截体剔除:是关于渲染和不渲染对象,如果对象在摄像机后面,则不希望渲染

bounding 边界

    边界是与几何形状相关的信息,它告诉我们几何体占用的空间信息

3.TextGeometry 文字立方体

import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry'

结合字体加载器一起使用

const fontloader = new FontLoader()


fontloader.load(
    '/fonts/helvetiker_regular.typeface.json',
    (font)=>{
        const textGeometry = new TextGeometry(
            'Hello Three.js',
            {
                font, // 字体格式
                size:0.5,  // 大小
                height:0.2, // 高度
                curveSegments:5,
                bevelEnabled:true, // 斜切面启动
                bevelThickness:0.03, // 斜面的厚度
                bevelSize:0.02, // 斜切面 会影响计算boundingBox 的值
                bevelOffset:0, // 倒角偏移
                bevelSegments:5, // 

            }
        )
    }
)

TextGeometry(text : String, parameters : Object)

text — 将要显示的文本。
parameters — 包含有下列参数的对象:

  • font — THREE.Font的实例。
  • size — Float。字体大小,默认值为100。
  • height — Float。挤出文本的厚度。默认值为50。
  • curveSegments — Integer。(表示文本的)曲线上点的数量。默认值为12。
  • bevelEnabled — Boolean。是否开启斜角,默认为false。
  • bevelThickness — Float。文本上斜角的深度,默认值为20。
  • bevelSize — Float。斜角与原始文本轮廓之间的延伸距离。默认值为8。
  • bevelSegments — Integer。斜角的分段数。默认值为3。

如何文字居中,一种就是获取文字立方体的边界位置,通过计算实现textGeometry.computeBoundingBox()

   textGeometry.computeBoundingBox()
        textGeometry.translate(
            - (textGeometry.boundingBox.max.x - 0.02) * 0.5,
            - (textGeometry.boundingBox.max.y - 0.02) * 0.5,
            - (textGeometry.boundingBox.max.z - 0.03) * 0.5,
        )

或者直接

  textGeometry.center()

让我们在字体周围创建甜甜圈,看起来好看一点

TorusGeometry(radius : Float, tube : Float, radialSegments : Integer, tubularSegments : Integer, arc : Float)

radius - 环面的半径,从环面的中心到管道横截面的中心。默认值是1。
tube — 管道的半径,默认值为0.4。
radialSegments — 管道横截面的分段数,默认值为12。
tubularSegments — 管道的分段数,默认值为48。
arc — 圆环的圆心角(单位是弧度),默认值为Math.PI * 2。


总结

无语!

  • 20
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值