1# Creating and Using ArkGraphics 3D Resources
2The following types of resources are used in a 3D scene:
3- Material: mathematical modeling of optical properties of an object in a scene. During rendering calculation, these physical properties are used to calculate the interaction with light to obtain the final color rendered. ArkGraphics 3D provides physically based rendering (PBR) materials. You can create material resources based on these PBR materials so as to obtain the desired rendering result.
4- Image: essentially a two-dimensional buffer for storing information required for 3D rendering calculation, such as basic colors and normals. ArkGraphics 3D provides the capability of creating image resources in PNG, JPG, and KTX formats and customizing image resources.
5- Shader: a program executed on a GPU to tell the GPU which parallel computing operations can be performed. The default shader provided by the Ark Graphics Platform (AGP) engine implements PBR. You only need to specify parameters to get different PBR effects. ArkGraphics 3D allows you to create custom shaders and customize the rendering calculation process, for example, to prevent an object from being affected by light.
6- Environment: a description of the 3D scene background, which can be created based on images. To simulate a real-world environment in a 3D scene, you can map a square or sphere onto an image and wrap the image around the square or sphere. ArkGraphics 3D allows you to create environment resources and define the background of 3D scenes.
7- Animation: used to create virtual objects that can move in a 3D scene, for example, people, animals, and vehicles. They are one of the essential elements that make up a 3D scene, and provide rich content for cartoons, games, virtual reality, and similar scenes.
8
9## Creating and Using Materials
10
11Key attributes of a material include the name and type, which can be used as inputs to create a material. The sample code is as follows:
12```ts
13import { Image, Shader, MaterialType, Material, ShaderMaterial, Animation, Environment, Container, SceneNodeParameters,
14  LightType, Light, Camera, SceneResourceParameters, SceneResourceFactory, Scene, Node } from '@kit.ArkGraphics3D';
15
16function createMaterialPromise() : Promise<Material> {
17  return new Promise(() => {
18    let scene: Promise<Scene> = Scene.load($rawfile("gltf/CubeWithFloor/glTF/AnimatedCube.gltf"));
19    scene.then(async (result: Scene) => {
20      let sceneFactory: SceneResourceFactory = result.getResourceFactory();
21      let sceneMaterialParameter: SceneResourceParameters = { name: "material" };
22      // Create a material.
23      let material: Promise<Material> = sceneFactory.createMaterial(sceneMaterialParameter, MaterialType.SHADER);
24      return material;
25    });
26  });
27}
28```
29## Creating and Using a Shader
30Shaders are mainly used to control GPU computing. You can customize rendering capabilities for more flexibility in 3D rendering control. To create a shader resource, you must specify its name and path in the application sandbox. A shader resource is mainly used to replace the shader attribute of a material so as to customize the rendering algorithm for the material. The sample code is as follows:
31```ts
32import { Image, Shader, MaterialType, Material, ShaderMaterial, Animation, Environment, Container, SceneNodeParameters,
33  LightType, Light, Camera, SceneResourceParameters, SceneResourceFactory, Scene, Node } from '@kit.ArkGraphics3D';
34
35function createShaderPromise() : Promise<Shader> {
36  return new Promise(() => {
37    let scene: Promise<Scene> = Scene.load($rawfile("gltf/CubeWithFloor/glTF/AnimatedCube.gltf"));
38    scene.then(async (result: Scene) => {
39      let sceneFactory: SceneResourceFactory = result.getResourceFactory();
40
41      // Create a variable of the SceneResourceParameters type and use it to create a shader.
42      let sceneResourceParameter: SceneResourceParameters = { name: "shaderResource",
43        uri: $rawfile("shaders/custom_shader/custom_material_sample.shader") };
44      let shader: Promise<Shader> = sceneFactory.createShader(sceneResourceParameter);
45      shader.then(async (shaderEntity: Shader) => {
46        let sceneMaterialParameter: SceneResourceParameters = { name: "material" };
47        // Create a material.
48        let material: Promise<Material> = sceneFactory.createMaterial(sceneMaterialParameter, MaterialType.SHADER);
49        material.then(async (materialEntity: ShaderMaterial) => {
50          // Bind the material to the shader.
51          materialEntity.colorShader = shaderEntity;
52        });
53      });
54      return shader;
55    });
56  });
57}
58```
59
60## Creating and Using an Image
61An image resource in a 3D scene can be directly used by the GPU. Key parameters for creating an image resource include the name and path of the image resource. It is a common operation to apply an image resource to a material as one of the material attributes. The sample code is as follows:
62```ts
63import { Image, Shader, MaterialType, Material, ShaderMaterial, Animation, Environment, Container, SceneNodeParameters,
64  LightType, Light, Camera, SceneResourceParameters, SceneResourceFactory, Scene, Node } from '@kit.ArkGraphics3D';
65
66function createImagePromise() : Promise<Image> {
67  return new Promise(() => {
68    let scene: Promise<Scene> = Scene.load($rawfile("gltf/CubeWithFloor/glTF/AnimatedCube.gltf"));
69    scene.then(async (result: Scene) => {
70      let sceneFactory: SceneResourceFactory = result.getResourceFactory();
71      let sceneImageParameter: SceneResourceParameters = { name: "image", uri: $rawfile("bricks.jpg") };
72      // Create an image.
73      let image: Promise<Image> = sceneFactory.createImage(sceneImageParameter);
74      image.then(async (imageEntity: Image) => {
75        let sceneMaterialParameter: SceneResourceParameters = { name: "material" };
76        // Create a material.
77        let material: Promise<Material> = sceneFactory.createMaterial(sceneMaterialParameter, MaterialType.SHADER);
78        material.then(async (materialEntity: ShaderMaterial) => {
79          // Use the created image resource to set the texture attribute.
80          if (materialEntity && materialEntity.colorShader) {
81            materialEntity.colorShader.inputs["BASE_COLOR_Image"] = imageEntity;
82          }
83        });
84      });
85      return image;
86    });
87  });
88}
89```
90## Creating and Using an Environment
91To create an environment resource, you need to specify the name and path of the image or glTF model in the application sandbox, and set the environment resource as an environment attribute of the 3D scene. In this way, the created environment resource is set as the background environment of the 3D scene. Environment resources also provide attributes such as **diffuseFactor** and **specularFactor**. The sample code is as follows:
92```ts
93import { Image, Shader, MaterialType, Material, ShaderMaterial, Animation, Environment, Container, SceneNodeParameters,
94  LightType, Light, Camera, SceneResourceParameters, SceneResourceFactory, Scene, Node } from '@kit.ArkGraphics3D';
95
96function createEnvironmentPromise() : Promise<Environment> {
97  return new Promise(() => {
98    let scene: Promise<Scene> = Scene.load($rawfile("gltf/CubeWithFloor/glTF/AnimatedCube.gltf"));
99    scene.then(async (result: Scene) => {
100      let sceneFactory: SceneResourceFactory = result.getResourceFactory();
101      let sceneEnvironmentParameter: SceneResourceParameters = { name: "env", uri: $rawfile("bricks.ktx") };
102      // Create an environment.
103      let env: Promise<Environment> = sceneFactory.createEnvironment(sceneEnvironmentParameter);
104      env.then(async (envEntity: Environment) => {
105        // Set environment-related attributes.
106        envEntity.indirectDiffuseFactor.x = 1;
107        envEntity.indirectDiffuseFactor.y = 1;
108        envEntity.indirectDiffuseFactor.z = 1;
109        envEntity.indirectDiffuseFactor.w = 1;
110      });
111      return env;
112    });
113  });
114}
115```
116