当前位置: 首页> 科技> 数码 > 湖南平台网站建设企业_沈阳建设工程信息网 专家中项网_提高网站排名软件_济南seo

湖南平台网站建设企业_沈阳建设工程信息网 专家中项网_提高网站排名软件_济南seo

时间:2025/9/13 4:31:30来源:https://blog.csdn.net/xichji/article/details/144689619 浏览次数:0次
湖南平台网站建设企业_沈阳建设工程信息网 专家中项网_提高网站排名软件_济南seo

往期文章:

 threejs基础开发应用示例

【threejs教程2】threejs物体点击交互事件

【threejs教程3】threejs物体轮廓发光

前言
        在三维场景中,我们经常需要添加文字对场景物体等进行标注说明,本文将介绍如何添加三维场景的文字,并实现文字始终面向屏幕的效果。

1.准备工作
1.1引入必要的库
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader';
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry';
AI助手
1.2准备字体文件
        由于threejs添加文字必须要一个字体文件且没有默认提供字体文件,所以在使用时,需要准备一个字体文件。示例中的文件下载地址:点击下载字体,如果链接失效可以私信。

大家也可以使用facetype.js进行自定义文字转换,支持.ttf格式的字体文件,链接如下:

http://gero3.github.io/facetype.js/

本文使用的是华为开源免费字体HONOR_Sans_CN_Regular,具体字体资源可以私信获取。

2.创建文字
        首先创建字体加载器loader,并进行字体资源加载。回调函数中设定字体的样式,下面的函数创建了一个如图所示的白色半透明3d文字。

const loader = new FontLoader() // 创建字体加载器
function addText() {
    loader.load(
        // font资源URL
        './font/HONOR_Sans_CN_Regular.json',
        // onLoad回调
        function (font) {
            const geometry = new TextGeometry('测试文字', {
                font: font,
                size: 0.3, // 字体大小
                height: 0.1, // 挤出文本的厚度
            })
            geometry.center() // 居中文本
            const materials = new THREE.MeshBasicMaterial({
                color: 0xffffffff,
                transparent: true,
                opacity: 0.5,
            })
            const textMesh = new THREE.Mesh(geometry, materials)
            textMesh.position.set(0,0,0)
            scene.add(textMesh)
        }
    )
}
AI助手
字体其他可选的属性:

curveSegments:控制文本曲线的平滑度。默认值为 12,增加此值可以使文本更加平滑,但也会增加计算成本。

bevelEnabled:一个布尔值,用于指定是否启用文字的斜角。默认为 false。

bevelThickness:如果启用了斜角,此属性控制斜角的厚度。默认值为 6。

bevelSize:如果启用了斜角,此属性控制斜角的尺寸。默认值为 4。

bevelSegments:如果启用了斜角,此属性控制斜角的分段数。默认值为 3。

需要特别注意的是,代码中用到了一个geometry.center()方法,它的作用是把文字居中,如果没有这个,文字加载时会以左下角为中心。大家可以根据自己的需求进行设置。

3.让文字作为标注始终面向屏幕
在往期文章中,我们经常用到两个方块,下面的代码我们也将用两个方块进行文字标注的演示

1.添加两个方块
<template>
</template>
<script setup>
import * as THREE from 'three'
import { onMounted, ref } from 'vue'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader'
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry'
const msg = ref('')
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(
    75,
    window.innerWidth / window.innerHeight,
    0.1,
    1000
)
const renderer = new THREE.WebGLRenderer({ antialias: true })
const controls = new OrbitControls(camera, renderer.domElement)
const loader = new FontLoader() // 创建字体加载器
onMounted(() => {
    init()
})
function init() {
    camera.position.set(0, 0, 5)
    renderer.setSize(window.innerWidth, window.innerHeight)
    document.body.appendChild(renderer.domElement)
    const geometry = new THREE.BoxGeometry(1, 1, 1)
    const material1 = new THREE.MeshBasicMaterial({
        color: 0xff00a2d7,
        transparent: true,
        opacity: 0.5,
    })
    const material2 = new THREE.MeshBasicMaterial({
        color: 0xffd3e3fd,
        transparent: true,
        opacity: 0.5,
    })
    const cube1 = new THREE.Mesh(geometry, material1)
    const cube2 = new THREE.Mesh(geometry, material2)
    scene.add(cube1, cube2)
    cube1.position.set(0, 0, 0)
    cube1.name = '方块1'
    cube2.position.set(2, 0, 0)
    cube2.name = '方块2'
    cube1.position.x = -2
    controls.update()
    function animate() {
        requestAnimationFrame(animate)
        controls.update()
        cube1.rotation.y += 0.01
        cube2.rotation.y -= 0.01
        renderer.render(scene, camera)
    }
    animate()
    addEachText()
}
</script>
AI助手
2.为场景中的每个方块添加文字标注
        我们为每个方块添加了名字,可以根据名字进行筛选。大家也可以根据其他的信息,例如给物体添加userData自定义信息等方法进行筛选。

// 为每个物体添加文字标注
function addEachText() {
    // 遍历场景中的所有物体
    scene.children.forEach((child) => {
        if (child.name.includes('方块')) {
            addText(child)
        }
    })
}
// 为指定物体添加文字标注
function addText(obj) {
    loader.load(
        // font资源URL
        './font/HONOR_Sans_CN_Regular.json',
        // onLoad回调
        function (font) {
            const geometry = new TextGeometry(obj.name, {
                font: font,
                size: 0.3, // 字体大小
                height: 0.1, // 挤出文本的厚度
            })
            geometry.center() // 居中文本
            const materials = new THREE.MeshBasicMaterial({
                color: 0xffffffff,
                transparent: true,
                opacity: 0.5,
            })
            const textMesh = new THREE.Mesh(geometry, materials)
            textMesh.position.copy(obj.position)
            textMesh.position.y = 1.2
            scene.add(textMesh)
        }
    )
}
'AI助手
运行运行
3.让文字始终面向屏幕
我们需要创建一个循环渲染的函数。使用lookAt()让文字一直面向相机的位置。

function animate() {
                requestAnimationFrame(animate)
                textMesh.lookAt(camera.position)
            }
            animate()
AI助手
4.完整效果代码如下所示
<template>
    <div
        style="
            font-size: 24px;
            color: #ffffff;
            text-align: center;
            position: absolute;
            top: 20%;
            left: 50%;
            transform: translate(-50%, -50%);
        "
    >
        {{ msg }}
    </div>
</template>
<script setup>
import * as THREE from 'three'
import { onMounted, ref } from 'vue'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader'
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry'
const msg = ref('')
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(
    75,
    window.innerWidth / window.innerHeight,
    0.1,
    1000
)
const renderer = new THREE.WebGLRenderer({ antialias: true })
const controls = new OrbitControls(camera, renderer.domElement)
const loader = new FontLoader() // 创建字体加载器
onMounted(() => {
    init()
})
function init() {
    camera.position.set(0, 0, 5)
    renderer.setSize(window.innerWidth, window.innerHeight)
    document.body.appendChild(renderer.domElement)
    const geometry = new THREE.BoxGeometry(1, 1, 1)
    const material1 = new THREE.MeshBasicMaterial({
        color: 0xff00a2d7,
        transparent: true,
        opacity: 0.5,
    })
    const material2 = new THREE.MeshBasicMaterial({
        color: 0xffd3e3fd,
        transparent: true,
        opacity: 0.5,
    })
    const cube1 = new THREE.Mesh(geometry, material1)
    const cube2 = new THREE.Mesh(geometry, material2)
    scene.add(cube1, cube2)
    cube1.position.set(0, 0, 0)
    cube1.name = '方块1'
    cube2.position.set(2, 0, 0)
    cube2.name = '方块2'
    cube1.position.x = -2
    controls.update()
    function animate() {
        requestAnimationFrame(animate)
        controls.update()
        cube1.rotation.y += 0.01
        cube2.rotation.y -= 0.01
        renderer.render(scene, camera)
    }
    animate()
    addEachText()
}
// 为每个物体添加文字标注
function addEachText() {
    // 遍历场景中的所有物体
    scene.children.forEach((child) => {
        if (child.name.includes('方块')) {
            addText(child)
        }
    })
    console.log('添加文字', scene)
}
// 为指定物体添加文字标注
function addText(obj) {
    loader.load(
        './font/HONOR_Sans_CN_Regular.json',
        function (font) {
            const geometry = new TextGeometry(obj.name, {
                font: font,
                size: 0.3, // 字体大小
                height: 0.1, // 挤出文本的厚度
            })
            geometry.center() // 居中文本
            const materials = new THREE.MeshBasicMaterial({
                color: 0xffffffff,
                transparent: true,
                opacity: 0.5,
            })
            const textMesh = new THREE.Mesh(geometry, materials)
            textMesh.position.copy(obj.position)
            textMesh.position.y = 1.2
            scene.add(textMesh)
            // 可选:在渲染循环中保持文字面向摄像机
            function animate() {
                requestAnimationFrame(animate)
                textMesh.lookAt(camera.position)
            }
            animate()
        }
    )
}
</script>
AI助手
 文章如有技术相关错误请各位批评指正 
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/c_wengy/article/details/138049183

关键字:湖南平台网站建设企业_沈阳建设工程信息网 专家中项网_提高网站排名软件_济南seo

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: