1e41f4b71Sopenharmony_ci# Building and Managing ArkGraphics 3D Scenes
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ciA 3D scene consists of three essential parts: light, camera, and model.
4e41f4b71Sopenharmony_ci- Light provides illumination for a 3D scene so that the models in the 3D scene become visible. Without light, the rendering result is all black.
5e41f4b71Sopenharmony_ci- The camera acts as a viewer of the 3D scene. In essence, 3D rendering is to observe a 3D scene from a perspective and project it to a 2D image. Without a camera, no rendering result is obtained.
6e41f4b71Sopenharmony_ci- A model in a 3D scene is used to describe a shape, structure, and appearance of an object, and generally has attributes such as meshes, materials, textures, and animations. Popular 3D model formats are OBJ, FBX, and glTF.
7e41f4b71Sopenharmony_ci
8e41f4b71Sopenharmony_ciAfter a model is loaded, it can be rendered using the ArkUI component [Component3D](../reference/apis-arkui/arkui-ts/ts-basic-components-component3d.md). You can also call ArkTS APIs to modify the camera and light settings, which will help you achieve the desired perspective and lighting conditions. The ArkTS APIs can use NAPIs to call the capabilities implemented by C++ APIs in AGP.
9e41f4b71Sopenharmony_ci
10e41f4b71Sopenharmony_ci![3D scene display process](./figures/scene.PNG)
11e41f4b71Sopenharmony_ci
12e41f4b71Sopenharmony_ci## Model Loading and Display
13e41f4b71Sopenharmony_ciModels come in a multitude of formats, but currently, ArkGraphics 3D supports only the loading of glTF models. glTF represents 3D scenes, just like the PNG format that represents a type of image. For details about glTF, see [glTF-2.0](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html).
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ciA glTF model can contain key elements of a 3D scene, including the light, camera, and model. If a glTF model contains a camera, you can use the APIs provided by ArkGraphics 3D to load the glTF model to render the 3D scene in the camera view. If the model does not contain a camera, you can use the ArkGraphics 3D APIs to create a camera for rendering. Due to the large size, a 3D model is usually loaded in asynchronous mode. After a model is loaded, a scene object is returned, based on which you can edit the 3D scene.
16e41f4b71Sopenharmony_ci
17e41f4b71Sopenharmony_ciYou can call the [load](../reference/apis-arkgraphics3d/js-apis-inner-scene.md#load) API provided by **Scene** to load a glTF model. The sample code is as follows:
18e41f4b71Sopenharmony_ci```ts
19e41f4b71Sopenharmony_ciimport { Image, Shader, MaterialType, Material, ShaderMaterial, Animation, Environment, Container, SceneNodeParameters,
20e41f4b71Sopenharmony_ci  LightType, Light, Camera, SceneResourceParameters, SceneResourceFactory, Scene, Node } from '@kit.ArkGraphics3D';
21e41f4b71Sopenharmony_ci
22e41f4b71Sopenharmony_cifunction loadModel() : void {
23e41f4b71Sopenharmony_ci  // Load the model.
24e41f4b71Sopenharmony_ci  let scene: Promise<Scene> = Scene.load($rawfile("gltf/DamagedHelmet/glTF/DamagedHelmet.gltf"));
25e41f4b71Sopenharmony_ci  scene.then(async (result: Scene) => {});
26e41f4b71Sopenharmony_ci}
27e41f4b71Sopenharmony_ci```
28e41f4b71Sopenharmony_ci
29e41f4b71Sopenharmony_ciOnce the model is loaded, you can use the **SceneResourceFactory** instance to create a camera and light source, and modify the camera and light settings to adjust the viewing angle and illumination effect. Finally, you can pass the **Scene** instance and **ModelType** as **SceneOptions** to the **Component3D** component to display them on the screen.
30e41f4b71Sopenharmony_ci
31e41f4b71Sopenharmony_ciThe sample code for displaying a model is as follows:
32e41f4b71Sopenharmony_ci```ts
33e41f4b71Sopenharmony_ciimport { Image, Shader, MaterialType, Material, ShaderMaterial, Animation, Environment, Container, SceneNodeParameters,
34e41f4b71Sopenharmony_ci  LightType, Light, Camera, SceneResourceParameters, SceneResourceFactory, Scene, Node } from '@kit.ArkGraphics3D';
35e41f4b71Sopenharmony_ci
36e41f4b71Sopenharmony_ci@Entry
37e41f4b71Sopenharmony_ci@Component
38e41f4b71Sopenharmony_cistruct Model {
39e41f4b71Sopenharmony_ci  scene: Scene | null = null;
40e41f4b71Sopenharmony_ci  @State sceneOpt: SceneOptions | null = null;
41e41f4b71Sopenharmony_ci  cam: Camera | null = null;
42e41f4b71Sopenharmony_ci
43e41f4b71Sopenharmony_ci  onPageShow(): void {
44e41f4b71Sopenharmony_ci    this.Init();
45e41f4b71Sopenharmony_ci  }
46e41f4b71Sopenharmony_ci
47e41f4b71Sopenharmony_ci  Init(): void {
48e41f4b71Sopenharmony_ci    if (this.scene == null) {
49e41f4b71Sopenharmony_ci      // Load the model and place the gltf file in the related path. Use the actual path during loading.
50e41f4b71Sopenharmony_ci      Scene.load($rawfile('gltf/DamagedHelmet/glTF/DamagedHelmet.gltf'))
51e41f4b71Sopenharmony_ci      .then(async (result: Scene) => {
52e41f4b71Sopenharmony_ci        this.scene = result;
53e41f4b71Sopenharmony_ci        let rf:SceneResourceFactory = this.scene.getResourceFactory();
54e41f4b71Sopenharmony_ci        // Create a camera.
55e41f4b71Sopenharmony_ci        this.cam = await rf.createCamera({ "name": "Camera" });
56e41f4b71Sopenharmony_ci        // Set proper camera parameters.
57e41f4b71Sopenharmony_ci        this.cam.enabled = true;
58e41f4b71Sopenharmony_ci        this.cam.position.z = 5;
59e41f4b71Sopenharmony_ci        this.sceneOpt = { scene: this.scene, modelType: ModelType.SURFACE } as SceneOptions;
60e41f4b71Sopenharmony_ci      })
61e41f4b71Sopenharmony_ci      .catch((reason: string) => {
62e41f4b71Sopenharmony_ci        console.log(reason);
63e41f4b71Sopenharmony_ci      });
64e41f4b71Sopenharmony_ci    }
65e41f4b71Sopenharmony_ci  }
66e41f4b71Sopenharmony_ci
67e41f4b71Sopenharmony_ci  build() {
68e41f4b71Sopenharmony_ci    Row() {
69e41f4b71Sopenharmony_ci      Column() {
70e41f4b71Sopenharmony_ci        if (this.sceneOpt) {
71e41f4b71Sopenharmony_ci          // Use Component3D to display the 3D scenario.
72e41f4b71Sopenharmony_ci          Component3D(this.sceneOpt)
73e41f4b71Sopenharmony_ci        } else {
74e41f4b71Sopenharmony_ci          Text("loading ...")
75e41f4b71Sopenharmony_ci        }
76e41f4b71Sopenharmony_ci      }.width('100%')
77e41f4b71Sopenharmony_ci    }.height('60%')
78e41f4b71Sopenharmony_ci  }
79e41f4b71Sopenharmony_ci}
80e41f4b71Sopenharmony_ci```
81e41f4b71Sopenharmony_ci
82e41f4b71Sopenharmony_ci## Creating and Managing a Camera
83e41f4b71Sopenharmony_ci
84e41f4b71Sopenharmony_ciAs an important part of a 3D scene, a camera determines the projection process from the 3D scene to a 2D image. Key camera parameters, such as the near plane, far plane, and FoV, also pose an important impact on 3D rendering. You can set these camera parameters to control the rendering process, thereby achieving the desired rendering effect.
85e41f4b71Sopenharmony_ci
86e41f4b71Sopenharmony_ciThe sample code for camera-related control is as follows:
87e41f4b71Sopenharmony_ci```ts
88e41f4b71Sopenharmony_ciimport { Image, Shader, MaterialType, Material, ShaderMaterial, Animation, Environment, Container, SceneNodeParameters,
89e41f4b71Sopenharmony_ci  LightType, Light, Camera, SceneResourceParameters, SceneResourceFactory, Scene, Node } from '@kit.ArkGraphics3D';
90e41f4b71Sopenharmony_ci
91e41f4b71Sopenharmony_cifunction createCameraPromise() : Promise<Camera> {
92e41f4b71Sopenharmony_ci  return new Promise(() => {
93e41f4b71Sopenharmony_ci    let scene: Promise<Scene> = Scene.load($rawfile("gltf/CubeWithFloor/glTF/AnimatedCube.gltf"));
94e41f4b71Sopenharmony_ci    scene.then(async (result: Scene) => {
95e41f4b71Sopenharmony_ci      let sceneFactory: SceneResourceFactory = result.getResourceFactory();
96e41f4b71Sopenharmony_ci      let sceneCameraParameter: SceneNodeParameters = { name: "camera1" };
97e41f4b71Sopenharmony_ci      // Create a camera.
98e41f4b71Sopenharmony_ci      let camera: Promise<Camera> = sceneFactory.createCamera(sceneCameraParameter);
99e41f4b71Sopenharmony_ci      camera.then(async (cameraEntity: Camera) => {
100e41f4b71Sopenharmony_ci        // Enable the camera node.
101e41f4b71Sopenharmony_ci        cameraEntity.enabled = true;
102e41f4b71Sopenharmony_ci
103e41f4b71Sopenharmony_ci        // Set the camera position.
104e41f4b71Sopenharmony_ci        cameraEntity.position.z = 5;
105e41f4b71Sopenharmony_ci
106e41f4b71Sopenharmony_ci        // Set the FoV.
107e41f4b71Sopenharmony_ci        cameraEntity.fov = 60 * Math.PI / 180;
108e41f4b71Sopenharmony_ci
109e41f4b71Sopenharmony_ci        // Set other camera parameters.
110e41f4b71Sopenharmony_ci        // ...
111e41f4b71Sopenharmony_ci      });
112e41f4b71Sopenharmony_ci      return camera;
113e41f4b71Sopenharmony_ci    });
114e41f4b71Sopenharmony_ci  });
115e41f4b71Sopenharmony_ci}
116e41f4b71Sopenharmony_ci```
117e41f4b71Sopenharmony_ci
118e41f4b71Sopenharmony_ci
119e41f4b71Sopenharmony_ci## Creating and Managing Light
120e41f4b71Sopenharmony_ci
121e41f4b71Sopenharmony_ciLight in a 3D scene is a data model that simulates the impact of the light in the physical world on an object in the 3D scene.
122e41f4b71Sopenharmony_ci
123e41f4b71Sopenharmony_ciThere are many types of lights, for example, directional light and spot light. Directional light, similar to the sunlight, emits parallel light rays with uniform intensity. Spot light is like a flashlight that produces cone-shaped light, which attenuates with distance. The light color also affects the color of the object in the scene. The interaction between the light color and the object color should be consistent with that in the physical world. ArkGraphics 3D provides APIs for creating light and modifying light parameters. You can adjust the 3D scene by setting light attributes to obtain the expected rendering effect.
124e41f4b71Sopenharmony_ci
125e41f4b71Sopenharmony_ciThe sample code for controlling light is as follows:
126e41f4b71Sopenharmony_ci```ts
127e41f4b71Sopenharmony_ciimport { Image, Shader, MaterialType, Material, ShaderMaterial, Animation, Environment, Container, SceneNodeParameters,
128e41f4b71Sopenharmony_ci  LightType, Light, Camera, SceneResourceParameters, SceneResourceFactory, Scene, Node } from '@kit.ArkGraphics3D';
129e41f4b71Sopenharmony_ci
130e41f4b71Sopenharmony_cifunction createLightPromise() : Promise<Light> {
131e41f4b71Sopenharmony_ci  return new Promise(() => {
132e41f4b71Sopenharmony_ci    let scene: Promise<Scene> = Scene.load($rawfile("gltf/CubeWithFloor/glTF/AnimatedCube.gltf"));
133e41f4b71Sopenharmony_ci    scene.then(async (result: Scene) => {
134e41f4b71Sopenharmony_ci      let sceneFactory: SceneResourceFactory = result.getResourceFactory();
135e41f4b71Sopenharmony_ci      let sceneLightParameter: SceneNodeParameters = { name: "light" };
136e41f4b71Sopenharmony_ci      // Create directional light.
137e41f4b71Sopenharmony_ci      let light: Promise<Light> = sceneFactory.createLight(sceneLightParameter, LightType.DIRECTIONAL);
138e41f4b71Sopenharmony_ci      light.then(async (lightEntity: Light) => {
139e41f4b71Sopenharmony_ci        // Set the color of the directional light.
140e41f4b71Sopenharmony_ci        lightEntity.color = { r: 0.8, g: 0.1, b: 0.2, a: 1.0 };
141e41f4b71Sopenharmony_ci
142e41f4b71Sopenharmony_ci        // Set other light parameters.
143e41f4b71Sopenharmony_ci        // ...
144e41f4b71Sopenharmony_ci      });
145e41f4b71Sopenharmony_ci      return light;
146e41f4b71Sopenharmony_ci    });
147e41f4b71Sopenharmony_ci  });
148e41f4b71Sopenharmony_ci}
149e41f4b71Sopenharmony_ci```
150