# 资源系统

资源是一类特殊的对象，其存储着框架需要使用的数据，比如纹理、几何数据、材质等等。资源系统管理着整个场景的资源，其包括自身和资源注册、[资源加载器](loader)、[资源元素](elements)三部分。

资源系统在运行时可以通过`scene.assets`获取，可在手动使用中看到具体的用法。

## 推荐用法

推荐的用法是在`xml`中用对应的几个标签定义资源，然后在特定的组件中使用资源的`asset-id`引用：

```xml
<xr-assets>
  <xr-asset-load type="texture" asset-id="waifu" src="/assets/textures/waifu.jpg" />
  <xr-asset-material asset-id="standard-mat" effect="standard" />
</xr-assets>

<xr-mesh node-id="waifu" geometry="plane" uniforms="u_baseColorMap: waifu" />
```

> 注意这种用法有一定的限制，具体标签和组件的说明，可见[资源元素](elements)。

> 需要注意资源加载都是异步的，组件引用资源时会根据资源加载的时机来执行`onAdd`或者`onUpdate`周期，所以可能存在资源尚未准备好就开始渲染之类的状况，需要开发者用**资源元素**中介绍的`XRAssets`元素的事件回调酌情自行处理。

## 手动使用

对于高级用户，有时候会想手动加载、获取或者释放资源，资源系统暴露了一系列接口来满足这样的需求：

```ts
// 加载资源
const {value: tex1} = await scene.assets.loadAsset({type: 'texture', assetId: 'tex1', src: texUrl1});
scene.assets.loadAsset({type: 'texture', assetId: 'tex2', src: texUrl2});

// 手动获取加载过的资源，最后一个参数是`fallback`资源，作为候补
const tex2 = scene.assets.getAsset('texture', 'tex1', 'white');

// 手动获取加载过的资源和状态
const {value: tex2, state, promise} = scene.assets.getAssetWithState('texture', 'tex1', 'white');

// 手动添加一个资源
scene.assets.addAsset('texture', 'tex3', tex3);

// 取消加载资源
scene.assets.cancelAsset('texture', 'tex2');

// 释放加载过的资源
scene.assets.releaseAsset('texture', 'tex1');
```

## 资源注册

除了使用加载机制来添加资源，还有一套额外的机制，就是**资源注册**。资源注册允许我们为某个`id`的资源提供创建其实例的一个回调，当有组件引用到这个资源时，便会执行回调去创建它，这个方法只会执行一次：

```ts
registerTexture('white', (scene: Scene) => scene.createTexture({
  source: [new Uint8Array([255, 255, 255, 255])],
  width: 1,
  height: 1
}));
```

这个例子就是注册了一个`white`的纹理资源。目前框架提供的可用资源注册方法会在**各个资源**的文档（比如[纹理](/miniprogram/dev/reference/xr-frame/component/render/texture)）中单独论述。
