华为应用市场在2022年HDC大会期间发布了一款3D水流主题,基于华为HMS Core Scene Kit服务能力,展现立体灵动的水流岛屿,可跟随用户指尖实现实时流体波动效果,既趣味又解压。
让变幻莫测的物质来实现我们在影视和游戏等多种应用场景中的奇思妙想,从早期步骤繁重的特效制作演变到如今,已经有了更为轻量易用的解题范式,只需花费10分钟便可打造一个逼真的3D流体效果。
什么是Scene Kit流体模拟?
Scene Kit即图形引擎服务,提供轻量级3D图形渲染引擎,可以为游戏、AR & VR等移动端应用提供易于使用的渲染接口,助力打造精致酷炫的视觉体验。
Scene Kit的3D流体技术,目前支持移动端水、油、岩浆等不同类型的物理真实流体模拟。服务中包含原子化接口,场景话接口,离线简模插件,实时光追插件等。
性能优越:基于三维图形渲染框架和算法,提供高性能低功耗的三维立体场景构建能力。
轻量易用:提供场景化移动应用接口,简化三维图形应用开发,易于为二维图形应用拓展构建三维立体场景。
效果逼真:基于物理的渲染能力,提供高画质三维场景效果和沉浸式图形体验。
实操环节:用3D流体实现逼真水流效果
开发环境
安装Android Studio 3.6.1及以上。
JDK 1.8(推荐)。
您的应用应满足以下条件:
minSdkVersion 19及以上。
targetSdkVersion 30(推荐)。
compileSdkVersion 30(推荐)。
Gradle 5.4.1及以上(推荐)。
如果同时使用多个HMS Core的服务,则需要使用各个Kit对应的最大值。
测试应用的设备:Android 4.4及以上。
开发配置
详细准备步骤请参考图形引擎服务开发者联盟官网。
开发准备
Android Studio的代码库配置在Gradle插件7.0以下版本、7.0版本和7.1及以上版本有所不同。请根据您当前的Gradle插件版本,选择对应的配置过程。
-
在“buildscript > repositories”中配置HMS Core SDK的Maven仓地址。
-
如果App中添加了“agconnect-services.json”文件则需要在“buildscript > dependencies”中增加agcp插件配置。打开项目级“settings.gradle”文件,配置HMS Core SDK的Maven仓地址。
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
'
}
}
dependencyResolutionManagement {
...
repositories {
google()
jcenter()
// 配置HMS Core SDK的Maven仓地址。
maven {url 'https://developer.huawei.com/repo/'}
}
}
添加权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
<uses-permission android:name="android.permission.CAMERA" />
开发步骤
-
创建两个Activity:MainActivity和SampleActivity。其中MainActivity负责完成SceneKit初始化,SampleActivity用于容纳渲染视图,并呈现最终效果。
-
在MainActivity中添加初始化标识和初始化方法。在初始化方法中设置SceneKit全局属性,并使用同步初始化接口initializeSync初始化SceneKit。
private static final int REQ_CODE_UPDATE_SCENE_KIT = 10001;
private boolean initialized = false;
private void initializeSceneKit() {
// 如果已经初始化,不再重复初始化。
if (initialized) {
return;
}
// 创建SceneKit属性,配置AppId与图形后端API。
SceneKit.Property property = SceneKit.Property.builder()
.setAppId("${app_id}")
.setGraphicsBackend(SceneKit.Property.GraphicsBackend.GLES)
.build();
try {
// 使用同步接口进行初始化。
SceneKit.getInstance()
.setProperty(property)
.initializeSync(getApplicationContext());
initialized = true;
Toast.makeText(this, "SceneKit initialized", Toast.LENGTH_SHORT).show();
} catch (UpdateNeededException e) {
// 捕获需要升级异常,拉起升级Activity。
startActivityForResult(e.getIntent(), REQ_CODE_UPDATE_SCENE_KIT);
} catch (Exception e) {
// 处理初始化异常。
Toast.makeText(this, "failed to initialize SceneKit: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
- 复写MainActivity的onActivityResult方法,处理升级结果
// resultCode为-1时代表升级成功,其他resultCode均代表升级失败。
private static final int RES_CODE_UPDATE_SUCCESS = -1;
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// 如果升级成功,尝试重新初始化。
if (requestCode == REQ_CODE_UPDATE_SCENE_KIT
&& resultCode == RES_CODE_UPDATE_SUCCESS) {
try {
SceneKit.getInstance()
.initializeSync(