sceneform-android

sceneform-android

Android增强现实开发框架Sceneform

Sceneform-android是基于ARCore的Android增强现实开发框架,采用Google Filament作为3D渲染引擎。该框架支持AR模型查看、增强图像、人脸特效、视频纹理、深度感知、云锚点、即时放置和光线估计等功能。作为Google Sceneform的延续项目,它集成了最新的ARCore SDK和Filament,支持直接使用gltf和glb格式的3D模型。Sceneform-android简化了OpenGL开发难度,同时兼容Java和Kotlin语言,为开发者提供便捷的AR应用开发体验。

SceneformARCoreAndroid SDK3D模型增强现实Github开源项目

Maven Central Discord

Android 平台的 Sceneform 维护版 SDK


⚠️ 本框架已不再更新。请考虑在您的项目中使用 Sceneview 替代。


Sceneform 维护版是一个以 Google Filament 为 3D 引擎的 ARCore Android SDK。这是 已归档的 Sceneform 的延续

Android 增强现实库:AR 模型查看器、增强图像、增强人脸、视频、深度、云锚点、即时放置、光线估计等,支持 Kotlin 和 Java


与我们交流

Discord 频道

(请不要在此提出问题,请转到 GitHub Issues 区域)


Sceneform 维护版和后继者:

与 Google Sceneform(1.15.0、1.16.0、1.17.0 和 1.17.1)的区别

  • 无需插件:直接使用 assets、res/raw、本地文件或 http/https 链接中的 gltf 和 glb 3D 模型文件,代替 sfa、sfb、fbx、obj 等
  • 最新版本的 ARCore SDKGoogle Filament
  • 最新的 gradle 依赖,包括 AndroidX、LifecycleScope/Coroutines(仅限 SceneView)等
  • 可作为 mavenCentral() 依赖使用
  • 支持增强图像
  • 支持增强人脸
  • 使用 glbgltf 作为 3D 模型(支持动画
  • 使用 hdrktx 作为环境(间接光 + 天空盒)
  • 支持纯 3D 使用,无需 ARCore 的单一依赖(仅限 SceneView
  • VideoNode 用于 MediaPlayer(mp4、avi 等)视频 3D 节点
  • 水平/垂直平面放置
  • 深度遮挡和放置(仅限 SceneView
  • 即时放置仅限 SceneView
  • HDR 光线估计,可在更加壮观或真实之间调整
  • 简单的模型查看器,仅需 ArSceneView 参数即可实现基本用途(仅限 SceneView
  • 减少对 OpenGL 知识的需求

本仓库最初是 Sceneform 的一个分支。版权所有 (c) 2021 Google Inc. 保留所有权利。

依赖

app/build.gradle

dependencies { implementation "com.gorisse.thomas.sceneform:sceneform:1.23.0" }

更多...

使用方法(简单模型查看器)

更新您的 AndroidManifest.xml

AndroidManifest.xml

<uses-permission android:name="android.permission.CAMERA" /> <application> ... <meta-data android:name="com.google.ar.core" android:value="optional" /> </application>

更多...

View 添加到您的 layout

res/layout/main_activity.xml

<androidx.fragment.app.FragmentContainerView android:id="@+id/arFragment" android:name="com.google.ar.sceneform.ux.ArFragment" android:layout_width="match_parent" android:layout_height="match_parent" />

示例...

编辑您的 ActivityFragment

src/main/java/.../MainActivity.java

override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 从 assets 文件夹或 http 链接加载 model.glb (supportFragmentManager.findFragmentById(R.id.arFragment) as ArFragment) .setOnTapPlaneGlbModel("model.glb") }

src/main/java/.../MainFragment.java

override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 从 assets 文件夹或 http 链接加载 model.glb (childFragmentManager.findFragmentById(R.id.arFragment) as ArFragment) .setOnTapPlaneGlbModel("https://storage.googleapis.com/ar-answers-in-search-models/static/Tiger/model.glb") }

Kotlin 示例...

Java 示例...

示例

带动画的 glTF

完整视频
完整视频...

arFragment.setOnTapArPlaneListener { hitResult, plane, motionEvent -> // 创建锚点 arFragment.arSceneView.scene.addChild(AnchorNode(hitResult.createAnchor()).apply { // 创建可变换模型并将其添加到锚点 addChild(TransformableNode(arFragment.transformationSystem).apply { renderable = model renderableInstance.animate(true).start() }) }) }

Kotlin 示例项目...

Java 示例项目...

深度遮挡

深度遮挡 01深度遮挡 02深度遮挡 03
arFragment.apply { setOnSessionConfigurationListener { session, config -> if (session.isDepthModeSupported(Config.DepthMode.AUTOMATIC)) { config.depthMode = Config.DepthMode.AUTOMATIC } } setOnViewCreatedListener { arSceneView -> // 可用模式:DEPTH_OCCLUSION_DISABLED, DEPTH_OCCLUSION_ENABLED arSceneView.cameraStream.depthOcclusionMode = CameraStream.DepthOcclusionMode.DEPTH_OCCLUSION_ENABLED } }

文档...

示例项目...

增强图像

增强图像 01

示例项目...

增强人脸

增强人脸 01增强人脸 02增强人脸 03

这里提供了一个可用于创建自己模型的Blender文件增强人脸模板:点击这里

骨骼中的四个骨头在运行时会移动到相应的ARCore姿势。可以将物体附加到骨头上或为顶点分配权重,以根据ARCore姿势定位物体或修改更大的网格。Blender文件中骨头的位置给出了最终结果的大致外观,因此附加对象的相对变换很重要。

图片

面部纹理应作为单独的文件准备。可以使用此模板创建面部纹理:canonical_face.png

你还可以根据骨骼和分配给顶点的权重来改变模型形状,移动头部周围的一些小物体,缩放它们等...

你甚至可以为所有这些制作动画。

示例项目...

云锚点

图片图片
// 创建一个新的锚点 = ARCore将尝试使用ARCore云锚点服务和提供的cloudAnchorId来解析其姿态 sceneView.session?.resolveCloudAnchor(cloudAnchorId)?.let { resolvedAnchor -> sceneView.scene.addChild(AnchorNode(resolvedAnchor).apply { addChild(VideoNode(context, MediaPlayer.create(context, R.raw.restaurant_presentation).apply { this.start() },null) ) }) }

环境光照

环境光照 01环境光照 02环境光照 03
环境光照 04环境光照 05环境光照 06

https://user-images.githubusercontent.com/83349532/144654379-a4476baf-8a22-45aa-8088-4f5e3fc7384b.mp4

// 如果你希望你的对象更接近真实效果,请使用此模式 arSceneView.lightEstimationConfig = LightEstimationConfig.REALISTIC
// 如果你希望你的对象效果更加壮观,请使用此模式 arSceneView.lightEstimationConfig = LightEstimationConfig.SPECTACULAR
// 如果你只想应用ARCore光照的颜色和强度,请使用此模式 arSceneView.lightEstimationConfig = LightEstimationConfig.AMBIENT_INTENSITY
// 如果你想禁用所有ARCore光照估计,请使用此模式 arSceneView.lightEstimationConfig = LightEstimationConfig.DISABLED

示例项目...

视频纹理

视频纹理 01视频纹理 02视频纹理 03
arFragment.setOnTapArPlaneListener { hitResult, plane, motionEvent -> // 创建锚点 arFragment.arSceneView.scene.addChild(AnchorNode(hitResult.createAnchor()).apply { addChild(VideoNode(context, MediaPlayer.create(context, R.raw.video).apply { start() }, chromaKeyColor, null)) }) }

示例项目...

动态材质/纹理

动态材质 01动态材质 02

示例项目...

非AR用途

非AR用途 01

示例项目...

演示

在Google Play上获取

YouTubeYouTube

模拟器

已知可用配置

图片

更多...

贡献 - 提交拉取请求

复刻仓库或在 Discord 上申请贡献者权限

图片

安装 GitHub Android Studio 插件

图片

直接从 Android Studio 创建 Pull Request

图片

更多...

深入探讨

AR 必需 vs AR 可选

如果你的应用需要 ARCore(AR 必需)而不仅仅是(AR 可选),请使用此清单来表明该应用需要 Google Play Services for AR(AR 必需),这将导致该应用仅在支持 ARCore 的设备上的 Google Play 商店中可见:

<uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera.ar" android:required="true"/> <application> ... <meta-data android:name="com.google.ar.core" android:value="required" /> </application>

更多...

节点

要在用户点击平面时向场景添加一个或多个节点,你可以重写 BaseArFragment.OnTapArPlaneListeneronTapPlane 函数:

arFragment.setOnTapArPlaneListener(::onTapPlane)
arFragment.setOnTapArPlaneListener { hitResult, plane, motionEvent -> // 创建锚点 arFragment.arSceneView.scene.addChild(AnchorNode(hitResult.createAnchor()).apply { // 创建可变换模型并将其添加到锚点 addChild(TransformableNode(arFragment.transformationSystem).apply { renderable = model renderableInstance.animate(true).start() // 添加相对于父模型的子模型 addChild(Node().apply { // 定义相对位置 localPosition = Vector3(0.0f, 1f, 0.0f) // 定义相对缩放 localScale = Vector3(0.7f, 0.7f, 0.7f) renderable = modelView }) }) }) }

示例...

移除或隐藏节点

从场景中移除锚点节点

anchorNode.anchor = null

从场景中移除模型节点、视频节点、增强人脸节点等

node.parent = null

显示/隐藏节点 = 不渲染它

node.enabled = false

文档...

帧率(FPS 限制)

上限

渲染的更新率受 ARCore 使用的相机配置限制。对大多数智能手机来说是 30 fps,对 Pixel 智能手机来说是 60 fps。用户可以手动更改这个值(你应该知道你在做什么)。

arFragment.setOnViewCreatedListener { arSceneView -> // 设置更高的帧率上限 arSceneView.setMaxFramesPerSeconds(60) }

默认值是 60

文档...

动画

到目前为止,只有 RenderableInstance 是可动画的。下面的 model 对应于从 node.getRenderableInstance() 返回的 RenderablaInstance

基本用法

对于一个非常基础的 3D 模型,比如一个单一的无限旋转球体,你可能不需要使用 ModelAnimator,而只需调用:

model.animate(repeat).start();

单一模型与单一动画

如果你想将单个模型动画化到特定的时间线位置,请使用:

ModelAnimator.ofAnimationFrame(model, "AnimationName", 100).start();
ModelAnimator.ofAnimationFraction(model, "AnimationName", 0.2f, 0.8f, 1f).start();
ModelAnimator.ofAnimationTime(model, "AnimationName", 10.0f)}.start();

我在哪里可以找到 "AnimationName"?

动画名称是在 3D 模型级别定义的。 你可以将其比作播放与模型中特定行为相对应的轨道。

例如,在 Blender 中,"AnimationName" 可以对应:

  • 非线性动画视图端口 中定义的动作
  • 时间线视图端口 中的单个对象行为

要知道 glb/gltf 文件的实际动画名称,你可以将其拖到 glTF 查看器上,比如这里,然后在动画列表中找到它。

  • 单一的时间、帧或分数值将从实际位置到达所需值
  • 两个值意味着从值1到值2
  • 超过两个值意味着从值1到值2然后到值3

单一模型与多个动画

如果模型是一个角色,例如,可能有一个用于行走循环的 ModelAnimation,第二个用于跳跃,第三个用于横向移动,等等:

顺序播放

AnimatorSet animatorSet = new AnimatorSet(); animatorSet.playSequentially(ModelAnimator.ofMultipleAnimations(model, "walk", "run")); animatorSet.start();

自动取消

这里你可以看到不需要调用animator.cancel(),因为animator.setAutoCancel(boolean)默认设置为true

ObjectAnimator walkAnimator = ModelAnimator.ofAnimation(model, "walk"); walkButton.setOnClickListener(v -> walkAnimator.start()); ObjectAnimator runAnimator = ModelAnimator.ofAnimation(model, "run"); runButton.setOnClickListener(v -> runAnimator.start());

多个模型的多个动画

对于同步动画集,如动画化包含多个模型的完整场景,请考虑使用带有每个步骤参数化的ModelAnimatorAnimatorSet

AnimatorSet completeFly = new AnimatorSet(); ObjectAnimator liftOff = ModelAnimator.ofAnimationFraction(airPlaneModel, "FlyAltitude",0, 40); liftOff.setInterpolator(new AccelerateInterpolator()); AnimatorSet flying = new AnimatorSet(); ObjectAnimator flyAround = ModelAnimator.ofAnimation(airPlaneModel, "FlyAround"); flyAround.setRepeatCount(ValueAnimator.INFINITE); flyAround.setDuration(10000); ObjectAnimator airportBusHome = ModelAnimator.ofAnimationFraction(busModel, "Move", 0); flying.playTogether(flyAround, airportBusHome); ObjectAnimator land = ModelAnimator.ofAnimationFraction(airPlaneModel, "FlyAltitude", 0); land.setInterpolator(new DecelerateInterpolator()); completeFly.playSequentially(liftOff, flying, land);

变形动画

假设一个角色对象有一个骨骼,一个关键帧轨道可以存储下臂骨骼随时间变化的位置数据,另一个轨道存储同一骨骼的旋转变化数据,第三个轨道存储另一个骨骼的位置、旋转或缩放,以此类推。显然,ModelAnimation可以作用于许多这样的轨道。

假设模型有变形目标(例如一个变形目标显示友好的面部表情,另一个显示愤怒的面部表情),每个轨道都保存了在动画片段执行过程中某个变形目标的影响如何变化的信息。

在glTF上下文中,这个{@link android.animation.Animator}根据glTF动画和蒙皮定义更新矩阵。

ModelAnimator可用于两个用途

  • 根据模型动画定义更新TransformManager组件中的矩阵。
  • 更新RenderableManager组件中的骨骼矩阵。

动画

每个修改动画时间位置的PropertyValuesHolder必须使用ModelAnimation.TIME_POSITION而不是自己的Property,以便可能取消在同一ModelAnimation上操作时间修改的任何ObjectAnimator。

更多...

许可证

请查看LICENSE文件。

品牌指南

Sceneform商标是Google的商标,不受GitHub上Apache 2.0许可的Sceneform存储库中包含的版权或专利许可授权的约束。除这些指南中允许的使用外,任何使用Sceneform商标的行为都必须事先得到Google的批准。

品牌指南的目的

这些指南的存在是为了确保Sceneform项目可以在开源许可下共享其技术,同时确保"Sceneform"品牌作为一个有意义的来源标识符得到保护,符合商标法。通过遵守这些指南,你有助于促进使用和开发高质量Sceneform技术的自由。

可接受的使用

由于我们开源了Sceneform技术,你可以在未经事先书面许可的情况下使用Sceneform商标来指代该项目。这些批准的引用示例包括:

  • 指代Sceneform项目本身;
  • 指代GitHub上Sceneform存储库共享的未经修改的源代码或其他文件;
  • 准确地表明你的设计或实现是基于、用于或与Sceneform技术兼容。

示例:

  • "[你的产品]用于Sceneform。"
  • "[你的产品]是Sceneform项目的一个分支。"
  • "[你的产品]与Sceneform兼容。"

使用指南

  • Sceneform名称绝不能以可能导致对Google赞助、附属或认可产生混淆的方式使用或注册。
  • 不要将Sceneform名称或类似的容易混淆的术语用作你的公司名称、产品名称、域名或社交媒体资料的一部分。
  • 除这些指南允许的情况外,Sceneform名称不应与其他商标、术语或来源标识符组合使用。
  • 不要删除、扭曲或更改Sceneform名称。这包括修改Sceneform名称,例如通过连字符、组合或缩写。不要缩短、缩写或创造Sceneform名称的首字母缩写词。
  • 不要以与周围文本不同的样式、颜色或字体显示Sceneform名称。
  • 不要将Sceneform一词用作动词,也不要使用其所有格形式。

条款和条件

通过下载Android版Sceneform SDK,你同意Google API服务条款管理你对其的使用。

用户隐私要求

你必须在应用程序中突出显示并方便用户访问Google Play Services for AR (ARCore)的使用情况以及它如何收集和处理数据。你可以通过在主菜单或通知屏幕上添加以下文字来实现这一点:"本应用程序运行在Google Play Services for AR (ARCore)上,该服务由Google LLC提供,并受Google隐私政策管理"。

编辑推荐精选

Trae

Trae

字节跳动发布的AI编程神器IDE

Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。

AI工具TraeAI IDE协作生产力转型热门
问小白

问小白

全能AI智能助手,随时解答生活与工作的多样问题

问小白,由元石科技研发的AI智能助手,快速准确地解答各种生活和工作问题,包括但不限于搜索、规划和社交互动,帮助用户在日常生活中提高效率,轻松管理个人事务。

热门AI助手AI对话AI工具聊天机器人
Transly

Transly

实时语音翻译/同声传译工具

Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球,无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。

讯飞智文

讯飞智文

一键生成PPT和Word,让学习生活更轻松

讯飞智文是一个利用 AI 技术的项目,能够帮助用户生成 PPT 以及各类文档。无论是商业领域的市场分析报告、年度目标制定,还是学生群体的职业生涯规划、实习避坑指南,亦或是活动策划、旅游攻略等内容,它都能提供支持,帮助用户精准表达,轻松呈现各种信息。

AI办公办公工具AI工具讯飞智文AI在线生成PPTAI撰写助手多语种文档生成AI自动配图热门
讯飞星火

讯飞星火

深度推理能力全新升级,全面对标OpenAI o1

科大讯飞的星火大模型,支持语言理解、知识问答和文本创作等多功能,适用于多种文件和业务场景,提升办公和日常生活的效率。讯飞星火是一个提供丰富智能服务的平台,涵盖科技资讯、图像创作、写作辅助、编程解答、科研文献解读等功能,能为不同需求的用户提供便捷高效的帮助,助力用户轻松获取信息、解决问题,满足多样化使用场景。

热门AI开发模型训练AI工具讯飞星火大模型智能问答内容创作多语种支持智慧生活
Spark-TTS

Spark-TTS

一种基于大语言模型的高效单流解耦语音令牌文本到语音合成模型

Spark-TTS 是一个基于 PyTorch 的开源文本到语音合成项目,由多个知名机构联合参与。该项目提供了高效的 LLM(大语言模型)驱动的语音合成方案,支持语音克隆和语音创建功能,可通过命令行界面(CLI)和 Web UI 两种方式使用。用户可以根据需求调整语音的性别、音高、速度等参数,生成高质量的语音。该项目适用于多种场景,如有声读物制作、智能语音助手开发等。

咔片PPT

咔片PPT

AI助力,做PPT更简单!

咔片是一款轻量化在线演示设计工具,借助 AI 技术,实现从内容生成到智能设计的一站式 PPT 制作服务。支持多种文档格式导入生成 PPT,提供海量模板、智能美化、素材替换等功能,适用于销售、教师、学生等各类人群,能高效制作出高品质 PPT,满足不同场景演示需求。

讯飞绘文

讯飞绘文

选题、配图、成文,一站式创作,让内容运营更高效

讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。

热门AI辅助写作AI工具讯飞绘文内容运营AI创作个性化文章多平台分发AI助手
材料星

材料星

专业的AI公文写作平台,公文写作神器

AI 材料星,专业的 AI 公文写作辅助平台,为体制内工作人员提供高效的公文写作解决方案。拥有海量公文文库、9 大核心 AI 功能,支持 30 + 文稿类型生成,助力快速完成领导讲话、工作总结、述职报告等材料,提升办公效率,是体制打工人的得力写作神器。

openai-agents-python

openai-agents-python

OpenAI Agents SDK,助力开发者便捷使用 OpenAI 相关功能。

openai-agents-python 是 OpenAI 推出的一款强大 Python SDK,它为开发者提供了与 OpenAI 模型交互的高效工具,支持工具调用、结果处理、追踪等功能,涵盖多种应用场景,如研究助手、财务研究等,能显著提升开发效率,让开发者更轻松地利用 OpenAI 的技术优势。

下拉加载更多