Skip to content

资源加载

引擎通常需要加载不同的资源文件,为了统一管理所有文件的加载和读取,我们在 Engine3D 里封装了统一的 res 资源管理器,可以方便用户加载,存储和读取各种文件资源。

基本用法

ts
// 加载 2D贴图
let texture = await Engine3D.res.loadTexture('path/to/image.png');
// 加载 GLTF/GLB 模型
let gltf = await Engine3D.res.loadGltf('path/to/model.gltf');
let glb = await Engine3D.res.loadGltf('path/to/model.glb');

下载进度回调

res 支持下载进度回调,我们可以配置 LoaderFunctions 用来监听文件加载事件回调,常用于 UI 加载进度提示:

ts

let parser = await Engine3D.res.loadGltf('/sample.gltf',{
  // 可以自定义 fetch 请求头,例如加入 Authorization
  headers: {
    'Authorization': 'Bearer xxxx',
    // ...
  },
  onProgress: (receivedLength:number, contentLength:number, url:string) => {
    // 监听下载进度
  },
  onComplete: (url:string) => {
    // 文件下载完成
  },
  onError: (e) => {
    // 文件加载错误
  },
  onUrl: (url:string) =>{
    // 可以根据需求,修改原始url,返回自定义路径
  }
});

贴图管理器

我们可以将加载的贴图统一储存在 res 资源池中,使用时直接读取即可,方便集中下载和管理贴图

ts
// 提前下载贴图
let brdfLUTTexture = new BitmapTexture2D();
await brdfLUTTexture.load('PBR/BRDFLUT.png');
// 统一存储
Engine3D.res.addTexture('BRDFLUT', brdfLUTTexture);
// 需要时取出
let brdfLUTTexture = Engine3D.res.getTexture('BRDFLUT');

材质球管理器

同理,统一将各类材质球添加到材质球管理器,方便后续使用

ts
let floorMat = new LitMaterial();
Engine3D.res.addMat('floorMat', floorMat );
// 需要时取出
let floorMat = Engine3D.res.getMat('floorMat');

预设体管理器

也可以将 Object3D 节点添加到资源管理内,方便查找和调用

ts
let box = new Object3D();
res.addPrefab('box', box);
// 需要时取出
let box = res.getPrefab('box');

示例

WebGPU is not supported in your browser
Please upgrade to latest Chrome/Edge

<
ts
import { Engine3D, Scene3D, Object3D, Camera3D, View3D, DirectLight, HoverCameraController, Color, AtmosphericComponent } from '@orillusion/core';

// initializa engine
await Engine3D.init();
// create new scene as root node
let scene3D: Scene3D = new Scene3D();
scene3D.addComponent(AtmosphericComponent);
// create camera
let cameraObj: Object3D = new Object3D();
let camera = cameraObj.addComponent(Camera3D);
// adjust camera view
camera.perspective(60, Engine3D.aspect, 1, 5000.0);
// set camera controller
let controller = cameraObj.addComponent(HoverCameraController);
controller.setCamera(0, -20, 15);
// add camera node
scene3D.addChild(cameraObj);
// create light
let light: Object3D = new Object3D();
// add direct light component
let component: DirectLight = light.addComponent(DirectLight);
// adjust lighting
light.rotationX = 45;
light.rotationY = 30;
component.lightColor = new Color(1.0, 1.0, 1.0, 1.0);
component.intensity = 1;
// add light object
scene3D.addChild(light);

let button = document.createElement('button');
button.setAttribute('style', 'position:fixed;top:calc(50% - 20px);left:0;right:0;width:150px;padding:10px;font-size:16px;margin:auto;');
button.innerHTML = 'Load Model';
document.body.appendChild(button);

button.onclick = async () => {
    button.onclick = null;
    // load model
    let dragon = await Engine3D.res.loadGltf('https://cdn.orillusion.com/PBR/DragonAttenuation/DragonAttenuation.gltf', {
        onProgress: (receivedLength: number, contentLength: number, url: string) => {
            if (!url.match(/\.bin$/)) return;
            button.innerHTML = 'Loading ' + ((receivedLength / contentLength) * 100).toFixed(0) + '%';
        },
        onComplete: (url: string) => {
            if (!url.match(/\.bin$/)) return;
            button.innerHTML = 'Model Loaded!';
            setTimeout(() => {
                button.remove();
            }, 1000);
        }
    });
    scene3D.addChild(dragon);
};

let view = new View3D();
view.scene = scene3D;
view.camera = camera;
// start render
Engine3D.startRenderView(view);