1. 介绍
简介
图形引擎服务(Scene Kit)是华为面向开发者提供的高性能、低功耗、轻量级的3D图形渲染引擎服务,为开发者提供高级描述性API,便于编辑、操作和渲染3D资源。
图形引擎服务为开发者提供了场景化接口SDK与原子化接口SDK,您可根据使用场景的不同选择合适的SDK进行集成:
- 原子化接口SDK提供了功能丰富且高自由度的图形接口,能够满足您在各种不同场景对图形开发的需求。
- 场景化接口SDK提供低自由度但简单易用的图形接口,只需使用少量代码即可完成特定场景的应用开发。
除此之外,图形引擎服务还提供了基于原子化接口的2D流体模拟SDK,可用于流体晃动的物理效果。
您将建立什么
跟随本篇Codelab您将学会如何快速集成图形引擎服务,并使用已经创建好的示例代码体验图形引擎服务在不同的使用场景提供的3D渲染能力。
通过示例代码您可以体验到:
- 原子化接口SDK:
- hms-scene-fine-grained-demo:创建并初始化SceneKit,使用RenderView进行布置场景,加载并使用一个具有动画的3D素材,使其播放动画。
- hms-scene-ar-face-demo:使用原子化接口SDK创建ARView与FaceView,实现一个简单的AR与头像替换应用。
- hms-scene-physics-engine-demo:使用物理引擎组件,仿真模拟物体的运动约束与碰撞效果。
- hms-scene-3d-fluid-demo:使用3D流体组件,自定义流体边界范围,设置流体液量,实现能够与用户交互的3D流体晃动效果。
- 场景化接口SDK:
hms-scene-demo包含3个不同场景的使用示例:- SceneView:设置天空盒,加载并渲染3D素材,并能够任意缩放、旋转。
- ARView:AR场景中识别环境中的平面,并在平面上放置虚拟物体,并能够选中进行移动、缩放、旋转。
- FaceView:识别检测人脸,并将人脸替换为3D卡通人物面部。
- 2D流体模拟SDK:
hms-scene-2d-fluid-demo:使用2D流体模拟SDK模拟水体的流动,转动手机时可观察到水流晃动的效果。
您将学到什么
跟随本篇Codelab您将学会:
- 如何集成图形引擎服务原子化接口SDK或场景化接口SDK。
- 使用原子化接口SDK进行初始化、添加渲染视图、加载资源、播放动画、使用物理引擎组件等。
- 使用场景化接口SDK在不同场景下完成特定功能的实现:普通和AR场景中完成3D素材显示,在面部AR场景中完成人脸替换的效果。
- 使用2D流体模拟SDK模拟水体流动的效果。
2. 您需要做什么
硬件要求
- 开发计算机(台式机或笔记本电脑)。
- HUAWEI手机(带数据线),用于真机调试集成图形引擎服务SDK的应用。
软件要求
- Android Studio 3.6.1及以上版本。
- JDK 1.8及以上版本。
- HMS Core(APK)4.0.2.300及以上版本。
- EMUI 10.0及以上版本。
需要的知识点
- 图形学基础知识。
- Android基础开发能力。
3. 接入能力准备
集成图形引擎服务需要按照以下流程完成开发准备:
- 创建AppGallery Connect应用
- 生成签名证书指纹
- 配置签名证书指纹
- 添加当前应用的AppGallery Connect配置文件
- 配置HMS Core SDK的Maven仓地址
- 添加编译依赖
- 配置混淆脚本
4. 集成SDK
添加当前应用的AppGallery Connect配置文件
如果在AppGallery Connect中开通了相关服务则需要将"agconnect-services.json"文件添加到您的App中。
步骤 1 - 登录AppGallery Connect网站,点击"我的项目"。
步骤 2 - 在项目列表中找到您的项目,在项目中点击需要集成HMS Core SDK的应用。
步骤 3 - 在"项目设置 > 常规"页面的"应用"区域,点击"agconnect-services.json"下载配置文件。
步骤 4 - 将"agconnect-services.json"文件拷贝到应用级根目录下。
—-结束
配置HMS Core SDK的Maven仓地址
Android Studio的代码库配置在Gradle 插件7.0以下版本、7.0版本和7.1及以上版本有所不同。请根据您当前的Gradle 插件版本,选择对应的配置过程。
7.0以下版本 | 7.0版本 | 7.1及以上版本 |
7.0以下版本
a. 打开Android Studio项目级"build.gradle"文件。
b. 添加HUAWEI agcp插件以及Maven代码库。
- 在"buildscript > repositories"中配置HMS Core SDK的Maven仓地址。
- 在"allprojects > repositories"中配置HMS Core SDK的Maven仓地址。
- 如果App中添加了"agconnect-services.json"文件则需要在"buildscript > dependencies"中增加agcp插件配置。
buildscript { repositories { google() jcenter() // 配置HMS Core SDK的Maven仓地址。 maven {url 'https://developer.huawei.com/repo/'} } dependencies { ... // 增加agcp插件配置,推荐您使用最新版本的agcp插件。 classpath 'com.huawei.agconnect:agcp:1.6.0.300' } } allprojects { repositories { google() jcenter() // 配置HMS Core SDK的Maven仓地址。 maven {url 'https://developer.huawei.com/repo/'} } }7.0版本
a. 打开Android Studio项目级"build.gradle"文件。
b. 添加HUAWEI agcp插件以及Maven代码库。
- 在"buildscript > repositories"中配置HMS Core SDK的Maven仓地址。
- 如果App中添加了"agconnect-services.json"文件则需要在"buildscript > dependencies"中增加agcp插件配置。
buildscript { repositories { google() jcenter() // 配置HMS Core SDK的Maven仓地址。 maven {url 'https://developer.huawei.com/repo/'} } dependencies { ... // 增加agcp插件配置,推荐您使用最新版本的agcp插件。 classpath 'com.huawei.agconnect:agcp:1.6.0.300' } }c. 打开项目级"settings.gradle"文件,配置HMS Core SDK的Maven仓地址。
dependencyResolutionManagement { ... repositories { google() jcenter() // 配置HMS Core SDK的Maven仓地址。 maven {url 'https://developer.huawei.com/repo/'} } }7.1及以上版本
a. 打开Android Studio项目级"build.gradle"文件。
b. 如果App中添加了"agconnect-services.json"文件则需要在"buildscript > dependencies"中增加agcp插件配置。
buildscript { dependencies { ... // 增加agcp插件配置,推荐您使用最新版本的agcp插件。 classpath 'com.huawei.agconnect:agcp:1.6.0.300' } }c. 打开项目级"settings.gradle"文件,配置HMS Core SDK的Maven仓地址。
pluginManagement { repositories { gradlePluginPortal() google() mavenCentral() // 配置HMS Core SDK的Maven仓地址。 maven { url 'https://developer.huawei.com/repo/' } } } dependencyResolutionManagement { ... repositories { google() mavenCentral() // 配置HMS Core SDK的Maven仓地址。 maven { url 'https://developer.huawei.com/repo/' } } }
添加编译依赖
步骤 1 - 打开应用级的"build.gradle"文件。
步骤 2 - 在"dependencies" 中添加如下编译依赖。
- 若使用原子化接口SDK,请添加如下依赖:
dependencies { implementation 'com.huawei.scenekit:scenekit-render-foundation:{version}' } - 若使用原子化接口SDK及扩展包,请添加如下依赖:
dependencies { implementation 'com.huawei.scenekit:scenekit-render-foundation:{version}' implementation 'com.huawei.scenekit:scenekit-render-extension:{version}' } - 若使用原子化接口数学库,请添加如下依赖:
dependencies { implementation 'com.huawei.scenekit:scenekit-math:{version}' } - 若使用原子化接口UX包,请添加如下依赖:
dependencies { implementation 'com.huawei.scenekit:scenekit-ux-ar:{version}' } - 若使用场景化接口SDK,请添加如下依赖:
dependencies { implementation 'com.huawei.scenekit:sdk:{version}' } - 若使用场景化接口Full-SDK,请添加如下依赖:
dependencies { implementation 'com.huawei.scenekit:full-sdk:{version}' } - 若使用2D流体模拟接口SDK,请添加如下依赖:
dependencies { implementation 'com.huawei.scenekit:scenekit-fluid-foundation:{version}' } - 若使用2D流体模拟接口SDK及扩展包,请添加如下依赖:
dependencies { implementation 'com.huawei.scenekit:scenekit-fluid-foundation:{version}' implementation 'com.huawei.scenekit:scenekit-fluid-extension:{version}' }
—-结束
5. 构建并运行demo
图形引擎服务对不同SDK提供了多个示例代码以供参考:
- hms-scene-fine-grained-demo:原子化接口SDK,RenderView的使用示例。
- hms-scene-ar-face-demo:原子化接口SDK,ARView与FaceView的使用示例。
- hms-scene-physics-engine-demo:原子化接口SDK,物理引擎组件的使用示例。
- hms-scene-3d-fluid-demo:原子化接口SDK,3D流体组件的使用示例。
- hms-scene-demo:场景化接口SDK,场景化SceneView、ARView、FaceView的使用示例。
- hms-scene-2d-fluid-demo:2D流体模拟SDK,水流模拟仿真的使用示例。
原子化接口SDK
RenderView示例代码
RenderView示例代码:hms-scene-fine-grained-demo。打开Android Studio工程同步完成后,点击"Run'app'"图标 ,运行打包生成APK,并安装在测试手机上。
运行效果如下左图所示,点击"RENDERVIERW DEMO"按钮,渲染效果如下右图所示:
|
|
RenderView Demo渲染效果图中使用的渲染素材为Spinosaurus_animation,作者:seirogan,未进行修改,License:CC Attribution,详情请见CC Attribution。
设置3D模型与环境贴图
private void loadModel() {
Model.builder()
// 可更换为其他3D模型资源。
.setUri(Uri.parse("Spinosaurus_animation/scene.gltf"))
.load(this, new ModelLoadEventListener(new WeakReference<>(this)));
}
private void loadTextures() {
Texture.builder()
// 可更换为其他天空盒素材。
.setUri(Uri.parse("Forest/output_skybox.dds"))
.load(this, new SkyBoxTextureLoadEventListener(new WeakReference<>(this)));
Texture.builder()
// 可更换为其他高光贴图,高光贴图需与天空盒素材匹配。
.setUri(Uri.parse("Forest/output_specular.dds"))
.load(this, new SpecularEnvTextureLoadEventListener(new WeakReference<>(this)));
Texture.builder()
// 可更换为其他漫反射贴图,漫反射贴图需与天空盒素材匹配。
.setUri(Uri.parse("Forest/output_diffuse.dds"))
.load(this, new DiffuseEnvTextureLoadEventListener(new WeakReference<>(this)));
}
ARView与FaceView示例代码
ARView与FaceView示例代码:hms-scene-ar-face-demo。打开Android Studio工程同步完成后,点击"Run'app'"图标 ,运行打包生成APK,并安装在测试手机上。
运行效果如下左图所示;点击"START ARVIERW DEMO"按钮,识别平面后点击放置3D模型,渲染效果如下中图所示;点击"START FACEVIERW DEMO"按钮,识别人脸后渲染效果如下右图所示:
|
|
|
ARView Demo渲染效果图中使用的渲染素材为Robo_OBJ_pose4,作者:Artem Shupa-Dubrova,未进行修改,License:CC Attribution-NoDerivs,详情请见CC Attribution-NoDerivs。
ARView设置3D模型
private void loadAsset() {
if (testModel != null) {
return;
}
Model.builder()
// 可更换为其他3D模型
.setUri(Uri.parse("Robot/scene.gltf"))
.load(getApplicationContext(), new Resource.OnLoadEventListener<Model>() {
@Override
public void onLoaded(Model model) {
Toast.makeText(ARViewActivity.this, "load success.", Toast.LENGTH_SHORT).show();
testModel = model;
}
@Override
public void onException(Exception exception) {
Toast.makeText(ARViewActivity.this, exception.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
FaceView设置3D模型
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_face_detection);
faceView = findViewById(R.id.container1);
setupIBL();
// 可设置为其他3D素材。
AssetFeature beaverAsset = new AssetFeature("Fox/fox.glb", FaceLandmark.TIP_OF_NOSE);
beaverAsset
// 设置模型的初始位置、大小与角度。
.setOffsetPosition(new Vector3(0.0f, -0.1f, 0.0f))
.setInitialScale(new Vector3(0.01f, 0.01f, 0.01f))
.setOffsetRotation(new Quaternion(new Vector3(1.0f, 0.0f, 0.0f), 0));
loadAsset(beaverAsset);
}
物理引擎组件
物理引擎组件示例代码:hms-scene-physics-engine-demo。打开Android Studio工程同步完成后,点击"Run'app'"图标 ,运行打包生成APK,并安装在测试手机上。
运行效果如下左图所示;点击"PHYSICS ENGINE DEMO 1"按钮,示例中模拟了弹性系数不同的4个小球同时下落的场景,渲染效果如下中图所示;点击"PHYSICS ENGINE DEMO 2"按钮,示例中模拟了不同类型的约束效果,渲染效果如下右图所示:
|
|
|
示例1:设置地面与小球的物理参数
@Override
public void onLoaded(Model model) {
PhysicsEngineSampleOneActivity sampleActivity = weakRef.get();
if (sampleActivity == null || sampleActivity.isDestroyed()) {
Model.destroy(model);
return;
}
// 设置地面的物理参数。
if (isGround) {
sampleActivity.groundModel = model;
Node groundNode = sampleActivity.renderView.getScene().createNodeFromModel(model);
groundNode.addComponent(Collider.descriptor())
.createBoxShape()
.setExtent(new Vector3(1000f, 1f, 1000f));
groundNode.getComponent(Transform.descriptor())
.setPosition(new Vector3(0f, -3f, 0f)).setScale(new Vector3(20f, 1f, 20f));
groundNode.addComponent(RigidBody.descriptor())
.setRestitution(1f)
.setGroup((short) 1)
.setKinematic(false)
.setFriction(10f)
.setMask((short) 1)
.setMass(0);
return;
}
sampleActivity.sphereModel = model;
// 设置小球的物理参数。
for (int index = 0; index < 4; index++) {
Node node = sampleActivity.renderView.getScene().createNodeFromModel(model);
Transform transform = node.getComponent(Transform.descriptor());
transform.setScale(new Vector3(0.6f, 0.6f, 0.6f));
transform.setPosition(new Vector3(-3.0f + 2 * index, 10.0f, 10.0f));
node.addComponent(Collider.descriptor())
.createSphereShape().setRadius(0.6f);
node.addComponent(RigidBody.descriptor())
.setMask((short) 1)
.setGroup((short) 1)
.setFriction(10.0f)
.setKinematic(false)
.setMass(1.0f)
.setRestitution( 0.3f * index);
}
}
示例2:设置点约束与铰链约束
// 设置点约束。
private void addPoint2PointConstraint() {
Node staticNode = loadModel(ballModel, new Vector3(0.1f, 0.1f, 0.1f), new Vector3(0, 15, 10));
staticNode.addComponent(RigidBody.descriptor())
.setMass(0)
.setKinematic(false)
.setGroup((short) 0)
.setMask((short) 0);
staticNode.addComponent(Collider.descriptor())
.createSphereShape()
.setRadius(0.1f);
Node targetNode = loadModel(ballModel, new Vector3(1f, 1f, 1f), new Vector3(2, 15, 10));
targetNode.addComponent(RigidBody.descriptor())
.setMass(1)
.setLinearDamping(0)
.setAngularDamping(0);
targetNode.addComponent(Collider.descriptor())
.createSphereShape()
.setRadius(0.77f);
Point2PointConstraint constraint = targetNode.addComponent(Point2PointConstraint.descriptor());
constraint.setPivotA(new Vector3(0, 0, 0));
constraint.setPivotB(new Vector3(0, 3, 0));
constraint.setNodeA(staticNode);
constraint.setNodeB(targetNode);
}
// 设置铰链约束。
private void addHingeConstraint() {
Node staticNode = loadModel(boxModel, new Vector3(0.2f, 8, 0.25f), new Vector3(0.12f, 5, 10));
staticNode.addComponent(Collider.descriptor()).createBoxShape().setExtent(new Vector3(0.1f, 4, 0.125f));
staticNode.addComponent(RigidBody.descriptor())
.setMass(0)
.setGroup((short) 0)
.setMask((short) 0);
Node targetNode = loadModel(boxModel, new Vector3(4, 8, 0.25f), new Vector3(-2, 5, 10));
targetNode.addComponent(Collider.descriptor()).createBoxShape().setExtent(new Vector3(1.98f, 4, 0.125f));
targetNode.addComponent(RigidBody.descriptor())
.setMass(1)
.setAngularDamping(0)
.setLinearDamping(0)
.applyImpulse(new Vector3(15, 0, 15), new Vector3(1, 0, 0));
HingeConstraint hinge = targetNode.addComponent(HingeConstraint.descriptor());
hinge.setNodeA(targetNode);
hinge.setNodeB(staticNode);
hinge.setLowerLimit(0.f)
.setUpperLimit((float) Math.PI)
.setPivotA(new Vector3(2, 0, 0))
.setPivotB(Vector3.ZERO)
.setAxisA(Vector3.UP)
.setAxisB(Vector3.UP);
}
3D流体组件
3D流体组件示例代码:hms-scene-3d-fluid-demo。打开Android Studio工程同步完成后,点击"Run'app'"图标 ,运行打包生成APK,并安装在测试手机上
运行效果如下左图所示;点击"START DEMO"按钮,摇晃手机使水体进行晃动,渲染效果如下右图所示:
|
|
场景化接口SDK
场景化接口SDK示例代码:hms-scene-demo。打开Android Studio工程同步完成后,点击"Run'app'"图标 ,运行打包生成APK,并安装在测试手机上。
运行效果如下左图所示;分别点击"SCENE VIEW DEMO"按钮、"AR VIEW DEMO"按钮、"FACE VIEW DEMO"按钮,渲染效果如下图:
|
|
|
|
- SceneView Demo渲染效果图中使用的渲染素材为Mjolnir,作者:Star Conflict,未进行修改,License:CC Attribution,详情请见CC Attribution。
- ARView Demo渲染效果图中使用的渲染素材为Robo_OBJ_pose4,作者:Artem Shupa-Dubrova,未进行修改,License:CC Attribution-NoDerivs,详情请见CC Attribution-NoDerivs。
2D流体模拟SDK
2D流体模拟SDK示例代码:hms-scene-2d-fluid-demo。打开Android Studio工程同步完成后,点击"Run'app'"图标 ,运行打包生成APK,并安装在测试手机上。
运行效果如下左图所示;点击"Start Demo"按钮,摇晃手机使水体进行晃动,渲染效果如下右图所示:
|
|
6. 恭喜您
干得好,您已经成功完成了Codelab所有步骤并学到了:
- 如何集成图形引擎服务原子化接口SDK、场景化接口SDK和2D流体模拟SDK。
- 使用原子化接口SDK进行初始化、添加渲染视图、加载资源、播放动画、使用物理引擎组件等。
- 使用场景化接口SDK在不同场景下完成特定功能的实现:普通和AR场景中完成3D素材显示,在面部AR场景中完成人脸替换的效果。
- 使用2D流体模拟SDK模拟水体流动的效果。
剩余














