鸿蒙5.0实战开发:3D图形>ArkGraphics 3D场景搭建以及管理 ...

打印 上一主题 下一主题

主题 1530|帖子 1530|积分 4590

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
HarmonyOS NEX开发实战往期文章必看:(持续更新......)

HarmonyOS NEXT应用开发性能实践总结(持续更新......)
HarmonyOS NEXT应用开发案例实践总结合集(持续更新......)
一分钟了解”纯血版!鸿蒙HarmonyOS Next应用开发
“非常具体的” 鸿蒙HarmonyOS Next应用开发学习路线!(从零基础入门到精通)

一个3D场景通常由光源、相机、模型三个关键部门构成。


  • 光源:为整个3D场景提供光照,使得3D场景中的模型变得可见。与真实物理场景一致,没有光源场景将变得一片漆黑,得到的渲染结果也就是全黑色。
  • 相机:为3D场景提供一个观察者。3D渲染本质上是从一个角度观察3D场景并投影到一张2D图片上。没有相机就没有3D场景的观察者,也就不会得到渲染结果。
  • 模型:3D场景中的模型用于形貌对象的外形、结构和外观,一样平常具有网格、材质、纹理、动画等属性。常见的3D模型格式有OBJ、FBX、glTF等。
模型加载后,可以通过ArkUI的Component3D渲染组件呈现给用户,Component3D也可以对3D模型做自定义渲染。开发者也可以使用ArkTS API对相机和光源进行调节,获得合适的观察角度和光照效果。ArkTS API可通过napi调用AGP中由C++实现的相应能力。
模型的加载及呈现

模型的格式多种多样,现在ArkGraphics 3D仅支持glTF模型的加载,glTF是一种对于3D场景形貌的格式,就像图片有png格式一样,glTF作为一种开源3D场景格式在业界被广泛采用。关于glTF的先容可以参照glTF-2.0。
一个glTF模型可以包含光源、相机、模型等3D场景关键要素,如果一个glTF模型中包含相机,使用ArkGraphics 3D提供的接口加载glTF就可以直接完成该相机视角下3D场景的渲染。如果不包含相机,也可以使用ArkGraphics 3D创建一个相机完成渲染。由于3D模型往往数据量很大,通常采用异步方式进行加载,加载成功后将返回一个scene对象,通过该对象可对整个3D场景进行编辑。
glTF模型可用Scene提供的load接口加载,示例代码如下:
  1. import { Image, Shader, MaterialType, Material, ShaderMaterial, Animation, Environment, Container, SceneNodeParameters,
  2.   LightType, Light, Camera, SceneResourceParameters, SceneResourceFactory, Scene, Node } from '@kit.ArkGraphics3D';
  3. function loadModel() : void {
  4.   // 加载模型
  5.   let scene: Promise<Scene> = Scene.load($rawfile("gltf/DamagedHelmet/glTF/DamagedHelmet.gltf"));
  6.   scene.then(async (result: Scene) => {});
  7. }
  8. <strong>ts</strong>
复制代码
模型加载成功后,可通过SceneResourceFactory实例创建相机、光源等,再对相机和光源的参数做调节,调解观察角度和光照效果。最后,将Scene实例和ModelType作为SceneOptions传给Component3D组件显示到屏幕。
模型显示的示例代码如下:
  1. import { Image, Shader, MaterialType, Material, ShaderMaterial, Animation, Environment, Container, SceneNodeParameters,
  2.   LightType, Light, Camera, SceneResourceParameters, SceneResourceFactory, Scene, Node } from '@kit.ArkGraphics3D';
  3. @Entry
  4. @Component
  5. struct Model {
  6.   scene: Scene | null = null;
  7.   @State sceneOpt: SceneOptions | null = null;
  8.   cam: Camera | null = null;
  9.   onPageShow(): void {
  10.     this.Init();
  11.   }
  12.   Init(): void {
  13.     if (this.scene == null) {
  14.       // 加载模型,将gltf文件放置到相关路径,加载时以实际路径为准
  15.       Scene.load($rawfile('gltf/DamagedHelmet/glTF/DamagedHelmet.gltf'))
  16.       .then(async (result: Scene) => {
  17.         this.scene = result;
  18.         let rf:SceneResourceFactory = this.scene.getResourceFactory();
  19.         // 创建相机
  20.         this.cam = await rf.createCamera({ "name": "Camera" });
  21.         // 设置合适的相机参数
  22.         this.cam.enabled = true;
  23.         this.cam.position.z = 5;
  24.         this.sceneOpt = { scene: this.scene, modelType: ModelType.SURFACE } as SceneOptions;
  25.       })
  26.       .catch((reason: string) => {
  27.         console.log(reason);
  28.       });
  29.     }
  30.   }
  31.   build() {
  32.     Row() {
  33.       Column() {
  34.         if (this.sceneOpt) {
  35.           // 通过Component3D呈现3D场景
  36.           Component3D(this.sceneOpt)
  37.         } else {
  38.           Text("loading ...")
  39.         }
  40.       }.width('100%')
  41.     }.height('60%')
  42.   }
  43. }
  44. <strong>ts</strong>
复制代码
相机的创建及管理

相机作为3D场景中的重要部门,决定了整个3D场景向2D图片的投影过程,相机的近远平面、Fov角等关键参数也会对整个3D渲染产生重要的影响。开发者可以通过对于相机参数的设置。控制这个渲染过程,得到开发者想要的渲染效果。
相机相干控制的示例代码如下:
  1. import { Image, Shader, MaterialType, Material, ShaderMaterial, Animation, Environment, Container, SceneNodeParameters,
  2.   LightType, Light, Camera, SceneResourceParameters, SceneResourceFactory, Scene, Node } from '@kit.ArkGraphics3D';
  3. function createCameraPromise() : Promise<Camera> {
  4.   return new Promise(() => {
  5.     let scene: Promise<Scene> = Scene.load($rawfile("gltf/CubeWithFloor/glTF/AnimatedCube.gltf"));
  6.     scene.then(async (result: Scene) => {
  7.       let sceneFactory: SceneResourceFactory = result.getResourceFactory();
  8.       let sceneCameraParameter: SceneNodeParameters = { name: "camera1" };
  9.       // 创建相机
  10.       let camera: Promise<Camera> = sceneFactory.createCamera(sceneCameraParameter);
  11.       camera.then(async (cameraEntity: Camera) => {
  12.         // 使能相机节点
  13.         cameraEntity.enabled = true;
  14.         // 设置相机的位置
  15.         cameraEntity.position.z = 5;
  16.         // 设置相机Fov参数
  17.         cameraEntity.fov = 60 * Math.PI / 180;
  18.         // 可以参照此方式设置相机很多其他的参数
  19.         // ...
  20.       });
  21.       return camera;
  22.     });
  23.   });
  24. }
  25. <strong>ts</strong>
复制代码
光源的创建及管理

3D场景的光源是对于物理天下中光源的一种数据建模,模仿物理天下的光源对于3D场景中的物体产生影响。
光源具有很多的范例,比如平行光、锥形光。平行光即是用来模仿生存中的太阳光照,发出的光线处处平行且强度匀称。锥形光则像是我们使用的手电筒,以一个点向一个扇形地区发射光线,且发出的光线会随着隔断而衰减。光源的颜色也会对场景中的物体终极的着色产生影响,光源颜色与物体颜色相互作用的计算与真实物理天下保持一致。ArkGraphics 3D提供了创建光源,修改光源各种参数的能力,支持开发者通过对于光源属性的设置对于3D场景进行调解,得到期望的渲染效果。
光源相干控制的示例代码如下:
  1. import { Image, Shader, MaterialType, Material, ShaderMaterial, Animation, Environment, Container, SceneNodeParameters,
  2.   LightType, Light, Camera, SceneResourceParameters, SceneResourceFactory, Scene, Node } from '@kit.ArkGraphics3D';
  3. function createLightPromise() : Promise<Light> {
  4.   return new Promise(() => {
  5.     let scene: Promise<Scene> = Scene.load($rawfile("gltf/CubeWithFloor/glTF/AnimatedCube.gltf"));
  6.     scene.then(async (result: Scene) => {
  7.       let sceneFactory: SceneResourceFactory = result.getResourceFactory();
  8.       let sceneLightParameter: SceneNodeParameters = { name: "light" };
  9.       // 创建平行光
  10.       let light: Promise<Light> = sceneFactory.createLight(sceneLightParameter, LightType.DIRECTIONAL);
  11.       light.then(async (lightEntity: Light) => {
  12.         // 设置平行光的颜色属性
  13.         lightEntity.color = { r: 0.8, g: 0.1, b: 0.2, a: 1.0 };
  14.         // 可以参照此方式设置光源很多其他的参数
  15.         // ...
  16.       });
  17.       return light;
  18.     });
  19.   });
  20. }
复制代码






免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

大号在练葵花宝典

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表