FMX填充大量3D形状时ViewPort3D性能下降 如何不删除元素优化性能
ViewPort3D大量TRectangle3D场景渲染卡顿优化方案
以下优化方案均不需要删除现有矩形元素,可以根据你的场景需求组合使用:
- 合并DrawCall,降低渲染批次开销
你当前的卡顿核心原因是每一个TRectangle3D都是独立的渲染单元,10000个元素就会产生至少10000次DrawCall,GPU负载会随元素数量线性上升。最优解决方案是将所有静态/半静态的矩形数据合并到单个TMesh组件中,全局仅产生1次DrawCall,性能可以提升数十倍。如果需要动态修改矩形属性,只要锁定TMesh的顶点缓冲区修改对应偏移的顶点数据即可,开销远低于修改独立3D组件。 - 全局共享材质实例
不要为每个TRectangle3D单独创建LightMaterialSource实例,所有视觉样式一致的矩形共用同一个材质实例,可大幅减少材质切换的状态开销。示例代码:// 全局只初始化一次共用材质 var SharedMat: TLightMaterialSource; SharedMat := TLightMaterialSource.Create(Self); SharedMat.Diffuse := TAlphaColorRec.Red; // 所有矩形都绑定同一个材质 for var I := 0 to RectList.Count - 1 do TRectangle3D(RectList[I]).MaterialSource := SharedMat; - 开启性能优先渲染配置
除了已经关闭的多重采样,还可以修改以下配置:- 将
Viewport3D1.Quality设为Viewport3DQuality.Performance - 关闭全局3D特效:
Viewport3D1.Context.DisableEffect([TEffectType.Shadow, TEffectType.Reflection]) - 所有不需要交互的
TRectangle3D关闭HitTest属性,避免鼠标移动时触发大量命中检测
- 将
- 视锥体裁剪优化
相机旋转时,实时判断每个矩形是否在相机的可视范围内,将视野外的矩形Visible属性设为False,不需要渲染不可见元素。如果你的矩形分布有规律,还可以增加空间八叉树裁剪,进一步降低判断开销。 - 相机旋转操作防抖优化
你当前的MouseMove事件每触发一次就会更新一次相机角度,触发重绘,高频移动鼠标时会产生大量冗余重绘。可以增加移动阈值,仅当鼠标累计移动超过2~3像素时再更新相机角度,降低重绘频率:private FLastX, FLastY: Single; procedure TForm3.Viewport3D1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single); var I: IViewport3D; DeltaX, DeltaY: Single; begin if ssRight in shift then begin DeltaX := X - FLastX; DeltaY := Y - FLastY; // 累计移动超过2像素再更新 if Abs(DeltaX) < 2 and Abs(DeltaY) < 2 then Exit; I:=ViewPort3D1; with tdummy(I.CurrentCamera.Parent) do RotationAngle.X:=RotationAngle.X - DeltaY; with tdummy(I.CurrentCamera.Parent.Parent) do RotationAngle.Y:=RotationAngle.Y + DeltaX; FLastX := X; FLastY := Y; end; end;
内容的提问来源于stack exchange,提问作者Crockinline
相关产品推荐
相关产品推荐

