engine.rendering 是mapvthree的渲染管理中枢,掌握它的核心API,你就能精确控制3D场景的每一帧渲染!
不知道大家有没有遇到过这样的场景:
如果你有这些需求,那今天这篇文章就是为你准备的!
Rendering(渲染管理器)是mapvthree引擎的核心组件之一,它随着Engine初始化自动创建,通过engine.rendering访问。
在介绍具体API之前,我们先来理解一下渲染的生命周期。每一帧的渲染大致分为这几个阶段:
准备阶段(Prepare) → 更新阶段(Update) → 渲染阶段(Render)mapvthree为我们提供了两个关键的钩子函数,让我们能在不同阶段插入自己的逻辑:
// 添加监听器
engine.addPrepareRenderListener((engine, renderState) => {
// 在这里执行准备工作
// 比如根据相机状态更新数据、计算可见性等
console.log('准备渲染,当前帧数:', renderState.frameCount);
});
// 移除监听器
engine.removePrepareRenderListener(myCallback);什么时候用?
// 添加监听器
engine.addBeforeRenderListener((engine, renderState) => {
// 在这里执行渲染前的最后准备
// 此时场景物体已经完成了位置更新
console.log('即将渲染...');
});
// 移除监听器
engine.removeBeforeRenderListener(myCallback);什么时候用?
特性 | PrepareRenderListener | BeforeRenderListener |
|---|---|---|
执行时机 | 场景物体更新之前 | 场景物体更新之后 |
适用场景 | 数据准备、可见性判断 | 最终调整、状态获取 |
回调参数 | engine, renderState | engine, renderState |
当你修改了场景中的某些数据,需要立即看到效果时,可以调用这个方法:
// 修改了一些数据后...
myPoint.color = '#ff0000';
// 请求渲染更新
engine.requestRender();💡:如果你已经开启了enableAnimationLoop,通常不需要手动调用requestRender(),因为引擎会自动在每帧进行渲染。
// 开启循环渲染(适合动态场景)
engine.rendering.enableAnimationLoop = true;
// 关闭循环渲染(适合静态场景,节省性能)
engine.rendering.enableAnimationLoop = false;// 设置渲染间隔为40ms(约25fps)
engine.rendering.animationLoopFrameTime = 40;
// 设置为16ms(约60fps)
engine.rendering.animationLoopFrameTime = 16;使用场景:
enableAnimationLooprequestRender()按需渲染animationLoopFrameTime降低帧率有时候我们需要暂停渲染,比如进行截图、调试或者节省资源:
// 暂停渲染
engine.rendering.freezeUpdate = true;
// 恢复渲染
engine.rendering.freezeUpdate = false;典型应用:截图前暂停动画,保证画面稳定。
// 获取当前像素比
console.log(engine.rendering.pixelRatio);
// 设置像素比(影响清晰度和性能)
engine.rendering.pixelRatio = 2; // 高清
engine.rendering.pixelRatio = 1; // 标准(更好的性能)// 获取当前分辨率
const res = engine.rendering.resolution;
console.log(`宽度: ${res.x}, 高度: ${res.y}`);Rendering还提供了对天空和天气实例的访问:
// 获取天空实例
const sky = engine.rendering.sky;
if (sky) {
sky.time = 3600 * 15; // 设置为下午3点
}
// 获取天气实例
const weather = engine.rendering.weather;
if (weather) {
weather.weather = 'rainy'; // 设置为下雨
}// 获取Three.js渲染器
const renderer = engine.rendering.renderer;
// 获取相机
const camera = engine.rendering.camera;
// 获取场景
const scene = engine.rendering.scene;
// 获取渲染状态(包含视图矩阵、帧数等信息)
const renderState = engine.rendering.renderState;现在来看一个实际的应用场景:当地图缩放到特定层级时,动态加载或卸载矢量图层。
这在地球级别的应用中非常常见——远距离看地球时不需要显示详细的矢量数据,只有放大到一定程度才需要加载。
import * as mapvthree from '@baidu/mapv-three';
// 创建引擎(使用地球投影)
const engine = new mapvthree.Engine(document.getElementById('map_container'), {
map: {
projection: 'ecef',
},
});
// 添加天空
const sky = engine.add(new mapvthree.DynamicSky());
// 创建地图视图(初始不带矢量图层)
const mapView = window.mapview = engine.add(new mapvthree.MapView({
terrainProvider: null,
vectorSurfaceOptions: {
restrictViewportLevel: true,
},
}));
// 用于跟踪当前 vectorProvider 的状态
let currentVectorProvider = null;
let lastZoomState = null; // 记录上一次的状态,避免重复操作
// 使用 PrepareRenderListener 实现层级控制
engine.addPrepareRenderListener(() => {
const currentZoom = engine.map.getZoom();
const shouldShowVector = currentZoom > 15;
// 只在状态变化时才操作,避免每帧都执行
if (lastZoomState !== shouldShowVector) {
if (shouldShowVector && !currentVectorProvider) {
// zoom > 15 且当前没有 vectorProvider,添加它
console.log('添加 BaiduVectorTileProvider,zoom:', currentZoom);
currentVectorProvider = new mapvthree.BaiduVectorTileProvider({
// 配置选项
});
mapView.setVectorProvider(currentVectorProvider);
}
else if (!shouldShowVector && currentVectorProvider) {
// zoom <= 15 且当前有 vectorProvider,删除它
console.log('删除 BaiduVectorTileProvider,zoom:', currentZoom);
mapView.setVectorProvider(null);
currentVectorProvider = null;
}
lastZoomState = shouldShowVector;
}
});addPrepareRenderListener:在每帧渲染前检查地图缩放层级lastZoomState:避免每帧都执行添加/移除操作,只在状态真正变化时才操作方式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 动态控制矢量图层显隐 | 轻量、快速 | 只能控制vectorProvider |
删除重建MapView | 切换整个地图风格 | 彻底、干净 | 开销较大,会重新加载所有数据 |
因为我们需要在场景物体更新之前就做出决策——是否需要加载新的图层。如果用 BeforeRenderListener,可能会导致一帧的延迟。
让我们用一张表来总结今天学到的内容:
API | 作用 | 常用场景 |
|---|---|---|
| 在渲染准备阶段执行回调 | LOD、动态加载、可见性判断 |
| 在渲染前执行回调 | 最终状态调整、数据同步 |
| 手动请求渲染 | 静态场景数据更新后 |
| 开启循环渲染 | 动态场景、动画效果 |
| 设置渲染间隔 | 性能优化、帧率控制 |
| 暂停/恢复渲染 | 截图、调试 |
| 设备像素比 | 清晰度与性能平衡 |
你可以思考一下:
如果这篇文章对你有帮助,别忘了点个赞支持一下!👍
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。