# 资源系统

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

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

# 推荐用法

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

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

注意这种用法有一定的限制,具体标签和组件的说明,可见资源元素

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

# 手动使用

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

// 加载资源
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的资源提供创建其实例的一个回调,当有组件引用到这个资源时,便会执行回调去创建它,这个方法只会执行一次:

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

这个例子就是注册了一个white的纹理资源。目前框架提供的可用资源注册方法会在各个资源的文档(比如纹理)中单独论述。