1# Building and Managing ArkGraphics 3D Scenes 2<!--Kit: ArkGraphics 3D--> 3<!--Subsystem: Graphics--> 4<!--Owner: @zzhao0--> 5<!--SE: @zdustc--> 6<!--TSE: @zhangyue283--> 7 8A 3D scene consists of three essential parts: light, camera, and model. 9- 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. 10- 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. 11- 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. 12 13After 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. 14 15 16 17## Model Loading and Display 18Models come in a multitude of formats, but currently, ArkGraphics 3D supports only the loading of glTF models. glTF represents 3D scenes. For details about glTF, see [glTF-2.0](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html). 19 20A 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. 21 22You 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: 23```ts 24import { Image, Shader, MaterialType, Material, ShaderMaterial, Animation, Environment, Container, SceneNodeParameters, 25 LightType, Light, Camera, SceneResourceParameters, SceneResourceFactory, Scene, Node } from '@kit.ArkGraphics3D'; 26 27function loadModel() : void { 28 // Load scene resources, which supports .gltf and .glb formats. The path and file name can be customized based on the specific project resources. 29 let scene: Promise<Scene> = Scene.load($rawfile("gltf/DamagedHelmet/glTF/DamagedHelmet.glb")); 30 scene.then(async (result: Scene) => {}); 31} 32``` 33 34Once 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. 35 36Below is the comprehensive sample code for displaying a model. It is crucial to verify that the .gltf file's content and its path are correctly specified. 37 38```ts 39import { Image, Shader, MaterialType, Material, ShaderMaterial, Animation, Environment, Container, SceneNodeParameters, 40 LightType, Light, Camera, SceneResourceParameters, SceneResourceFactory, Scene, Node } from '@kit.ArkGraphics3D'; 41 42@Entry 43@Component 44struct Model { 45 scene: Scene | null = null; 46 @State sceneOpt: SceneOptions | null = null; 47 cam: Camera | null = null; 48 49 onPageShow(): void { 50 this.Init(); 51 } 52 53 Init(): void { 54 if (this.scene == null) { 55 // Load scene resources, which supports .gltf and .glb formats. The path and file name can be customized based on the specific project resources. 56 Scene.load($rawfile("gltf/DamagedHelmet/glTF/DamagedHelmet.glb")) 57 .then(async (result: Scene) => { 58 this.scene = result; 59 let rf:SceneResourceFactory = this.scene.getResourceFactory(); 60 // Create a camera. 61 this.cam = await rf.createCamera({ "name": "Camera" }); 62 // Set proper camera parameters. 63 this.cam.enabled = true; 64 this.cam.position.z = 5; 65 this.sceneOpt = { scene: this.scene, modelType: ModelType.SURFACE } as SceneOptions; 66 }) 67 .catch((reason: string) => { 68 console.log(reason); 69 }); 70 } 71 } 72 73 build() { 74 Row() { 75 Column() { 76 if (this.sceneOpt) { 77 // Use Component3D to display the 3D scenario. 78 Component3D(this.sceneOpt) 79 } else { 80 Text("Loading···") 81 } 82 }.width('100%') 83 }.height('60%') 84 } 85} 86``` 87 88## Creating and Managing a Camera 89 90As 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. 91 92The sample code for camera-related control is as follows: 93```ts 94import { Image, Shader, MaterialType, Material, ShaderMaterial, Animation, Environment, Container, SceneNodeParameters, 95 LightType, Light, Camera, SceneResourceParameters, SceneResourceFactory, Scene, Node } from '@kit.ArkGraphics3D'; 96 97function createCameraPromise() : Promise<Camera> { 98 return new Promise((resolve, reject) => { 99 // Load scene resources, which supports .gltf and .glb formats. The path and file name can be customized based on the specific project resources. 100 let scene: Promise<Scene> = Scene.load($rawfile("gltf/CubeWithFloor/glTF/AnimatedCube.glb")); 101 scene.then(async (result: Scene) => { 102 let sceneFactory: SceneResourceFactory = result.getResourceFactory(); 103 let sceneCameraParameter: SceneNodeParameters = { name: "camera" }; 104 // Create a camera. 105 let camera: Promise<Camera> = sceneFactory.createCamera(sceneCameraParameter); 106 camera.then(async (cameraEntity: Camera) => { 107 // Enable the camera node. 108 cameraEntity.enabled = true; 109 110 // Set the camera position. 111 cameraEntity.position.z = 5; 112 113 // Set the FoV. 114 cameraEntity.fov = 60 * Math.PI / 180; 115 116 // Set other camera parameters. 117 // ... 118 resolve(cameraEntity); 119 }); 120 }); 121 }); 122} 123``` 124 125 126## Creating and Managing Light 127 128Light 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. 129 130There are many types of lights, for example, directional light and spotlight. Directional light, similar to the sunlight, emits parallel light rays with uniform intensity. Spotlight is like a flashlight that produces cone-shaped light, which attenuates with distance. The color of the light impacts how objects are shaded in the scene. When rendering, the system calculates the interaction between the light and the object's surface color based on physical principles, resulting in a more realistic lighting effect. 131 132ArkGraphics 3D provides APIs for creating light and modifying light parameters. You can adjust the 3D scene by setting light properties to obtain the expected rendering effect. 133 134The sample code for controlling light is as follows: 135```ts 136import { Image, Shader, MaterialType, Material, ShaderMaterial, Animation, Environment, Container, SceneNodeParameters, 137 LightType, Light, Camera, SceneResourceParameters, SceneResourceFactory, Scene, Node } from '@kit.ArkGraphics3D'; 138 139function createLightPromise() : Promise<Light> { 140 return new Promise((resolve, reject) => { 141 // Load scene resources, which supports .gltf and .glb formats. The path and file name can be customized based on the specific project resources. 142 let scene: Promise<Scene> = Scene.load($rawfile("gltf/CubeWithFloor/glTF/AnimatedCube.glb")); 143 scene.then(async (result: Scene) => { 144 let sceneFactory: SceneResourceFactory = result.getResourceFactory(); 145 let sceneLightParameter: SceneNodeParameters = { name: "light" }; 146 // Create directional light. 147 let light: Promise<Light> = sceneFactory.createLight(sceneLightParameter, LightType.DIRECTIONAL); 148 light.then(async (lightEntity: Light) => { 149 // Set the color of the directional light. 150 lightEntity.color = { r: 0.8, g: 0.1, b: 0.2, a: 1.0 }; 151 152 // Set other light parameters. 153 // ... 154 resolve(lightEntity); 155 }); 156 }); 157 }); 158} 159``` 160 161