跳到主要内容

按需渲染

产品查看器、配置器、检查工具等经常静止的场景无需每帧重绘。将 app.autoRender 设为 false,仅在变化时设置 app.renderNextFrame,即可按需渲染,让空闲场景的 GPU 也空闲。通用方式参见优化指南。

大型流式场景还会在后台加载和调整细节。这些工作与渲染解耦,无论是否绘制,每帧都会进行,因此空闲时也持续加载。产生值得绘制的新结果时,系统通过 frame:request 通知。

基本模式​

关闭自动渲染,系统请求时绘制:

app.autoRender = false;

app.systems.gsplat.on('frame:request', () => {
app.renderNextFrame = true;
});

当流式加载产生新细节,或异步排序结果就绪时,frame:request 在渲染前每帧触发一次。处理它可让场景逐渐达到完整细节,无需中间每帧都绘制。

frame:request 的触发范围与自行请求​

frame:request 覆盖数据本身的变化,引擎自动触发。只影响当前场景显示方式的变化不触发,需自行请求:

变化是否触发 frame:request
LOD 细节加载进度是,自动处理
预算、LOD 距离或范围是,自动处理
相机移动否,自行请求
画布或视口尺寸变化否,自行请求
材质参数,例如 alpha 裁剪否,自行请求
着色器动画,例如渐显否,自行请求
增删 gsplat、相机或图层否,自行请求

自行请求时,变化后设置 app.renderNextFrame = true。例如相机移动时渲染:

const lastPos = new pc.Vec3();
const lastRot = new pc.Quat();

app.on('update', () => {
const pos = camera.getPosition();
const rot = camera.getRotation();
if (!pos.equals(lastPos) || !rot.equals(lastRot)) {
app.renderNextFrame = true;
lastPos.copy(pos);
lastRot.copy(rot);
}
});
备注

相机、图层和 gsplat 组件的增删只有在实际渲染帧中才注册,因此变化后至少绘制一帧。这也是首次加载期间应正常连续渲染、运行就绪后再转按需的原因。

结合快速首帧​

可与快速首帧结合。加载及入场动画期间逐帧绘制,完成后切换:

  1. 首帧加载时保持 autoRender = true。
  2. 等待 frame:ready 报告场景加载、排序和绘制完成。
  3. 切换 autoRender = false,由 frame:request 及相机、尺寸、设置变化驱动。
const gsplatSystem = app.systems.gsplat;

const onFrameReady = (camera, layer, ready, loadingCount) => {
if (ready && loadingCount === 0) {
gsplatSystem.off('frame:ready', onFrameReady);

// the scene is fully shown — switch to on-demand rendering from here
app.autoRender = false;
}
};
gsplatSystem.on('frame:ready', onFrameReady);

gsplatSystem.on('frame:request', () => {
app.renderNextFrame = true;
});

两个事件互补:frame:ready 表示某个已渲染帧完整且排序完成,适合首次显示和截图;frame:request 表示有新流式数据值得绘制。

实时示例​

单个非流式数据按需渲染:显示后停止,仅在相机移动、窗口变化或设置更改时重绘。

基础按需渲染

另请参见​