当前位置: 首页 > news >正文

【iOS ARKit】3D文字

   首先,3D场景中渲染的任何虚拟元素都必须具有网格(顶点及顶点间的拓扑关系),没有网格的元素无法利用GPU 进行渲染,因此,在3D 场景申渲染 3D文字时,文字也必须具有网格。在计算机系统中,文字以平面点阵的形式存储和表示,所以进行3D文字渲染,需要将平面点阵转换为3D网格。

       在 RealityKit 中,开发人员可以程序化地生成立方体、球体、圆柱体等3D虚拟对象,这个过程其实就是利用算法生成立方体、球体、圆柱体的网格信息、法线信息、UV坐标信息的过程,有了这些基础信息,CPU与 GPU 就知道如何将虚拟对象渲染出来。

       RealityKit 也提供了根据指定文字自动生成文字网格、法线信息、UV坐标信息的方法 generateText(),该方法返回 MeshResource 类型对象,利用这个对象就可以对文字进行3D 渲染。在 RealityKit 中,生成3D文字的典型代码如代码如下所示。

//
//  Text3DView.swift
//  ARKitDeamo
//
//  Created by zhaoquan du on 2024/3/21.
//import SwiftUI
import ARKit
import RealityKit
import Combinestruct Text3DView: View {@State var change: String = "中文汉字"var body: some View {Text3DViewContainer(change: change).overlay(VStack{Spacer()TextField( LocalizedStringKey(""), text: $change).foregroundColor(.black).background(Color.white).frame(width:300,height:50).cornerRadius(5).opacity(0.6).offset(y:-330).padding(.bottom, 300)}).navigationTitle("3D文字").edgesIgnoringSafeArea(.all)}
}struct Text3DViewContainer:UIViewRepresentable {var change:String = ""func makeUIView(context: Context) -> some ARView {let arView = ARView(frame: .zero)context.coordinator.arView = arViewlet config = ARWorldTrackingConfiguration()config.planeDetection = .horizontalcontext.coordinator.createPlane()arView.session.run(config)return arView}func updateUIView(_ uiView: UIViewType, context: Context) {if !change.isEmpty {context.coordinator.chengeText(text: change)}}func makeCoordinator() -> Coordinator {Coordinator()}class Coordinator: NSObject {var arView: ARView!var text: String = ""var textEntity: ModelEntity!func createPlane() {let planeAnchor = AnchorEntity(plane: .horizontal)let textr = MeshResource.generateText("中文汉字",extrusionDepth: 0.05,font: .systemFont(ofSize: 15),containerFrame: .zero,alignment: .left,lineBreakMode: .byWordWrapping)let textMetiral = SimpleMaterial(color: .red, isMetallic: true)textEntity = ModelEntity(mesh: textr, materials: [textMetiral])textEntity.generateCollisionShapes(recursive: false)planeAnchor.addChild(textEntity)arView.scene.addAnchor(planeAnchor)arView.installGestures(.all, for: textEntity)}func chengeText(text: String) {let planeAnchor = AnchorEntity(plane: .horizontal)let textr = MeshResource.generateText(text,extrusionDepth: 0.05,font: .systemFont(ofSize: 2),containerFrame: .zero,alignment: .left,lineBreakMode: .byWordWrapping)let textMetiral = SimpleMaterial(color: .red, isMetallic: true)textEntity.removeFromParent()textEntity = ModelEntity(mesh: textr, materials: [textMetiral])textEntity.generateCollisionShapes(recursive: false)planeAnchor.addChild(textEntity)arView.scene.addAnchor(planeAnchor)arView.installGestures(.all, for: textEntity)}}
}
#Preview {Text3DView()
}

   从代码可以看到,生成3D文字的过程与生成其他程序化虚拟模型对象的过程完全一致,唯一区别是生成 3D 文字网格的方法要求设置的参数更多,generateText()方法原型

static func generateText (_ string: String, extrusionDepth: Float = 0. 25, font: MeshResource. Font = .systemPont(ofSize: MeshResource. Font. systemFontSize), containerFrame: CGRect = CGRect. zero, alignment: CTTextAlignment =. left, lineBreakMode: CTLineBreakMode = byTruncatingTail) - > MeshResource

generateText()方法参数众多,但实际除了 string 其余参数都可以使用默认值,各参数的意义如下表所示。

               表11-1 生成3D文字网格的参数属性

参数名

描述

string

需要3D渲染的文字,使用内置的systemFont 可以渲染中文汉字与英文字符,如果使用其他字体渲染中文汉字需要确保字体支持

extrusionDepth

渲染的文字厚度,即在Z轴上的长度,以米为单位

font

渲染所用字体,渲染中文汉字需要字体支持,使用该属性可以指定字体大小。默认使用系统字体

containerFrame

该属性指定文字所占空间尺寸,类似于 Word文字排版软件中的文本框指定文字所占尺寸,当指定该值时,如果文字渲染超出该尺寸则会以 lineBreakMode 属性指定的方式截断。默认为(0,0),会以最合适的大小包裹所有文字

alignment

文字在 containerFrame 中的对齐方式,可以为 center(居中对齐)、justified(分散对齐)、left(左对齐)、natural(两端对齐)、right(右对齐)之一,该属性会影响缩放、旋转3D文字时的定位点

lineBreakMode

文字超出 containerFrame 范围时的截断方式,可以 byWordWrapping(以单词/汉字为单位显示,超出部分不显示)、byCharWrapping(以字符/汉字单位显示,超出部分不显示)、byClipping(剪切与containerFrame 尺寸一致的内容长度,后半部分被截断)、byTruncatingHead(前面文字被截断,用省略号显示)、byTruncatingTail(后面文字被截断,用省略号显示)、byTruncatingMiddle(两端文字保留,中间文字被省略,用省略号显示)之一

       generateText()方法生成的文字 3D网格可以与其他程序化虚拟模型对象一样被赋子材质,包括纹理,也可以使用 ARAnchor 将其固定到场景中。

       在 RealityKit 中生成的文字 3D网格不可修改,因此,无法通过网格修改的方式更新谊染的3D文字,果需要更新已生成的3D文字,则只能重新生成新的文字3D网格。

       上述代码我们直接使用 changeText()方法重新生成新的文字3D网格,然后重新生成 textEntity 实体更新渲染的3D文字。在实际开发中,也可以通过扩展(extension) Entity 或者 ModelEntity 类,添加更新 3D文字的方法达到更方便使用的目的。

http://www.lryc.cn/news/327222.html

相关文章:

  • 第二百二十八回
  • Java设计模式之单例模式(多种实现方式)
  • Miracast投屏探索
  • 2024年幻兽帕鲁服务器优惠价格表手动整理,最全报价
  • 使用Python自动备份重要文件:一步一步的教程
  • python学习
  • 【使用redisson完成延迟队列的功能】使用redisson配合线程池完成异步执行功能,延迟队列和不需要延迟的队列
  • Linux 性能分析工具 perf 的使用指南
  • 【QT入门】 Qt代码创建布局之水平布局、竖直布局详解
  • C 传递数组给函数
  • 二次开发Flink-coGroup算子支持迟到数据通过测输出流提取
  • 【容器源码篇】Set容器(HashSet,LinkedHashSet,TreeSet的特点)
  • 网络工程师实验命令(华为数通HCIA)
  • AI大模型学习:AI大模型在特定领域的应用
  • Channel 结合 Select 使用
  • LeetCode-1669题:合并两个链表(原创)
  • 微服务高级篇(三):分布式缓存+Redis集群
  • 机器学习——元学习
  • day56 动态规划part13
  • Mybatis别名 动态sql语句 分页查询
  • 【算法题】三道题理解算法思想--滑动窗口篇
  • go env 命令详解
  • flutter 单例模式
  • 1.7.2 python练习题15道
  • python如何获取word文档的总页数
  • python解压RAR文件
  • 灯哥驱动器端口讲解----foc电机驱动必看
  • lua 获取指定路径下的所有文件夹
  • #Linux(SSH软件安装及简单使用)
  • Android中运动事件的处理