babylon加载高斯模型低端设备卡顿问题解决方案

性能模式高斯离屏 Pass 实现方案

本文说明告警中心 / STCM 编辑器在「性能」「均衡」档下,如何用 Babylon.js 做低分辨率离屏合成。主画布分辨率不降,只降低场景(含高斯点云)的填充率。

目标

近处拖镜头要流畅。不改 engine.setHardwareScalingLevel,画布仍按设备像素输出。

只把高斯缩小、墙留在主画布时,两边深度对不上,高斯会盖住近处模型或穿帮。因此约定:

  • 主画布全分辨率: 广场地面贴图、地面网格、地面装饰
  • 离屏低分辨率: 墙、楼板、GLB、高斯点云及其余场景物体
  • 同一相机、同一投影、同一张带深度的离屏缓冲,先写实体深度,再画高斯测深度

地面留在主画布,走动和俯视时地面不发糊;墙和高斯一起缩小,才能既省填充又不破遮挡。

启用条件

同时满足才走离屏,否则走普通 scene.render()

  1. 点云已有可见 splat
  2. 流式粗底图已铺完
  3. 离屏比例小于 1(性能约 0.55,均衡约 0.80)

底图未就绪就 blit,空高斯会把整屏涂黑。Pass 失败则复原分层,主场景直出。

渲染循环

使用 Engine.runRenderLoop 接管出图,不用默认的单次 scene.render() 包办全场景。

每帧顺序:

  1. 业务步进(机器人、标记、漫游等)
  2. 可选:镜头运动时冻结高斯按距离换档
  3. 若离屏 Pass 成功则 return,不再调用 Scene.render()
  4. 否则 scene.render() 走原路径

每帧开始调用 Engine.restoreDefaultFramebuffer(),避免上一帧还绑在 RTT 上。画布像素尺寸用 Engine.getRenderWidth(true) / getRenderHeight(true)

分层(layerMask)

Babylon 可见性规则:mesh.layerMask & camera.layerMask !== 0 才会被该相机渲染。不复制网格,只改 mask。

内容
离屏层0x10000000墙、模型、高斯等
地面层相机原 mask 去掉离屏位(常见 0x0FFFFFFF广场地面、网格、地面装饰
  • 离屏那趟:camera.layerMask = 离屏层,再渲 RTT
  • 主画布那趟:camera.layerMask = 原 mask & ~离屏层,再 scene.render(),只出地面

高斯 renderingGroupId = 1,墙/模型默认 group 0,保证离屏内先实体后高斯。

离屏缓冲

使用 RenderTargetTexture,不要用 PostProcess,也不要第二台相机复制场景。

创建参数:

  • new RenderTargetTexture(name, { width, height }, scene, options)
  • generateMipMaps: false
  • generateDepthBuffer: true(墙和高斯必须同一套深度)
  • samplingMode: Texture.BILINEAR_SAMPLINGMODE
  • doNotChangeAspectRatio: true
  • ignoreCameraViewport = true(按 RTT 自身宽高画)
  • wrapU / wrapV = Texture.CLAMP_ADDRESSMODE
  • clearColor = new Color4(0, 0, 0, 0)(透明底,贴回时才能丢掉空像素)

分辨率:高度 ≈ 画布高 × 比例,宽度按画布宽高比,最小边 16。窗口变化时 rtt.resize({ width, height })

必须从 scene.customRenderTargets 中移除该 RTT。 否则 scene.render() 会再自动渲一遍,与手动画的冲突。

绑定:

  • rtt.activeCamera = 当前场景相机(同一套 view / projection)
  • rtt.renderList = 本趟进入离屏的 mesh
  • 调用 rtt.render() 只画这张小图

深度

高斯在 rendering group 1。默认组切换会清深度,高斯就看不到墙,会整片盖上去。

离屏 rtt.render() 之前:

scene.setRenderingAutoClearDepthStencil(1, false, false, false)

三个 false:不清 color / depth / stencil。

高斯材质:forceDepthWrite = falsedisableDepthWrite = true(只测不写)。

主画布 scene.render() 时:

  • scene.autoClear = true
  • scene.autoClearDepthAndStencil = true

地面要在干净的 depth 上画;随后 blit 不再测深度,直接盖在地面之上。

切回画布

rtt.render() 之后:

  1. Engine.restoreDefaultFramebuffer()
  2. Engine.setViewport(camera.viewport, canvasW, canvasH) 恢复全画布 viewport
  3. camera.getProjectionMatrix(true)
  4. scene.updateTransformMatrix(true)

后两步纠正离屏小尺寸带来的投影,避免主画面和拾取变形。

贴回全屏

不用场景里再挂一张平面 mesh,用全屏 effect:

  • new EffectRenderer(engine)
  • new EffectWrapper({ engine, vertexShader, fragmentShader, attributeNames: ['position'], samplerNames: ['textureSampler'] })
  • wrapper.onApplyObservableeffect.setTexture('textureSampler', rtt)

片元逻辑:颜色和 alpha 都接近 0 则 discard,否则输出不透明 RGB,避免透明黑底糊一层。

贴回时机:订阅 scene.onAfterRenderingGroupObservable,在 renderingGroupId === 0(地面画完)时立刻 effectRenderer.render(wrapper)。若观察者未触发,scene.render() 返回后再补一次 blit。

一帧流程

Engine.runRenderLoop
  restoreDefaultFramebuffer
  按比例准备 / resize RTT
  地面 → 地面层,其余 + 高斯 → 离屏层
  camera.layerMask = 离屏层
  setRenderingAutoClearDepthStencil(1, false, false, false)
  rtt.render()                    // 小图:墙写深度 → 高斯测深度
  camera.layerMask = 仅地面
  restoreDefaultFramebuffer
  setViewport + 刷新投影矩阵
  autoClear / autoClearDepthAndStencil = true
  scene.render()                  // 全分辨率只画地面
  onAfterRenderingGroup(0)
    EffectRenderer 贴 RTT         // 空像素 discard

Babylon API 一览

环节API
自定义帧Engine.runRenderLoop / stopRenderLoop
画布尺寸getRenderWidth(true) / getRenderHeight(true)
离屏目标RenderTargetTextureresizerenderListactiveCamerarender()
采样 / 环绕Texture.BILINEAR_SAMPLINGMODECLAMP_ADDRESSMODE
清色Color4rtt.clearColor
分层AbstractMesh.layerMaskCamera.layerMask
绘制顺序renderingGroupId
组间深度Scene.setRenderingAutoClearDepthStencil
主场景清屏scene.autoClearautoClearDepthAndStencil
回画布restoreDefaultFramebuffersetViewportupdateTransformMatrix
全屏贴图EffectRendererEffectWrapperEffect.setTexture
贴回时机onAfterRenderingGroupObservable
禁止自动渲 RTTscene.customRenderTargets 移除

未使用 PostProcess、未使用 hardwareScaling、未使用第二台相机复制场景。

约束

  • 高斯与墙必须同缓冲、同深度,禁止只缩小高斯
  • 底图未就绪禁止离屏
  • 离屏内实体组与高斯组之间禁止清深度
  • 主画布贴回前要清屏,只留地面
  • 贴图时丢掉空像素,避免全屏黑雾
  • Pass 失败则主场景直出,不要继续用坏掉的离屏结果

调参

意图调整风险
更流畅、更糊降低离屏比例(如 0.4)墙沿、文字更锯
接近原清晰度比例靠近 1几乎不省填充,可直接关 Pass
近处仍卡优先再降比例,而不是再拆一层深度

档位保存在本机。切到性能/均衡且参数变化时,按新策略重新加载点云流。

已知问题

  • 最小像素过大,或点云未 ready 就关深度排序 → 场景空(属显示调参,不是 Pass 本身)
  • 底图未铺完就 blit → 黑屏或高斯消失
  • 高斯与墙不在同一张深度图 → 高斯盖住近处模型
  • 只降 LOD、不降填充 → 近处仍然卡;应用离屏比例解决
内容概要:本文研究永磁同步电机(PMSM)在全速域范围内的无传感器复合控制策略,提出了一种基于高频信号注入法与自适应滑模观测器(SMO)相结合的加权融合方法,并通过Simulink进行仿真实现。该方法针对低速、零速与中高速不同工况下的转子位置及速度估算难题,分别采用高频注入法(适用于低速及零速运行)和改进型自适应滑模观测器(适用于中高速运行),并通过设计动态加权切换机制实现两类观测器输出的无缝融合,有效克服了单一观测器在全速域内性能下降的问题。研究深入分析了两种观测器的工作原理,提出了工况分区策略与平滑过渡的加权融合算法,提升了系统在全速范围内的稳定性、鲁棒性与动态响应精度。通过Simulink平台构建完整的闭环控制系统,仿真实验验证了该复合策略在稳态运行、突加负载、速度切换等工况下的优异性能。; 适合人群:具备电机控制理论、现代控制理论基础以及Simulink/MATLAB仿真能力的电气工程、自动化、控制科学与工程等专业的硕士及以上学历研究人员,从事高性能电机驱动系统开发的工程师或科研人员。; 使用场景及目标:① 解决永磁同步电机在无机械传感器条件下实现全速域(尤其是零速启动与低速运行)精确转子位置与速度估计的技术难题;② 学习异构状态观测器(高频注入与滑模观测器)的融合思想与柔性切换控制策略的设计方法;③ 掌握高频信号注入、滑模观测器设计、动态加权融合等关键技术在Simulink中的建模、仿真与参数整定技巧。; 阅读建议:此资源以Simulink仿真实现为核心,强调理论分析与工程实践深度融合,建议读者在理解高频注入与滑模观测器数学模型的基础上,动手搭建完整的控制系统模型,重点调试高频注入信号频率与幅值、滑模观测器增益、边界层参数以及加权切换函数的阈值与平滑因子,以深入掌握复合观测器的优化设计与抗干扰性能提升方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值