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 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