资讯动态

UE5+SuperMap SDK三维模型选中高亮颜色修改实战

发布时间:2026/9/14 18:26:13 来源:尧图企业网站定制
年初接了一个三维规划审查项目技术栈是UE5加SuperMap Hi-Fi 3D SDK for Unreal负责把城市级的三维GIS场景接进来做量测、剖切和业务对象选中。功能做到一半客户提了个看起来很小的需求默认的模型选中高亮颜色不够醒目想把选中建筑改成橙色选中管线改成荧光绿最好还能按业务类型区分方便评审汇报时一眼看清对象归属。我一开始以为这不就是个颜色属性改个RGB值就行。结果真正动手才发现SuperMap Hi-Fi 3D SDK for Unreal这套东西虽然跑在Unreal里但底层渲染路径和原生的Editor Selection完全不是一回事。直接改EditorPreferences里的选中色根本不生效因为模型根本不是你摆在地图里的静态Mesh而是SDK动态生成的场景内容和分块网格体。断断续续折腾了两天才把整条链路摸清楚。这篇就把我实际验证过的改法、排查思路和踩过的坑完整写出来给后面用同一套SDK做业务选中的朋友当个参考。1. 先从源头看清SuperMap Hi-Fi 3D SDK的高亮到底是怎么画出来的1.1 我遇到的场景默认高亮颜色为什么不够用最初跑通示例工程的时候选中一个建筑默认高亮是偏青蓝的半透明色。这个颜色在白天阳光底图上还算清楚可一旦切到夜景底图或者深色卫星影像背景辨识度就急剧下降。客户原话是蓝不蓝绿不绿的堆在一起根本分不清哪个是选中的楼。需求本身不复杂但给了三个条件第一颜色要按对象类型区分比如建筑、管线、道路分别用不同色第二选中状态要能叠加呼吸效果第三不能影响未选中对象的原始显示效果。这就意味着不能简单用一个全局颜色覆盖所有必须在上层做对象分类再逐个下发高亮色。搞清楚这个前提后我开始倒查SDK到底是怎么实现选中高亮的因为只有知道颜色从哪里来才知道该去哪里改。1.2 SDK选中高亮的底层渲染路径在传统Unreal开发里想让一个Actor高亮通常有三条路修改Actor-SetActorEnableCollision配合原生高亮通过CustomDepthStencil给模型描边动态替换模型材质或调节Emissive自发光参数。但对于SuperMap Hi-Fi 3D SDK for Unreal加载出来的场景这三条路都不完全适用。SDK在运行时拿到的是iServer发布的三维服务数据场景里的建筑、道路、管线不是一个个关卡里摆好的Actor而是通过地形分块、LOD动态加载生成的Mesh。你和某个模型交互本质上是SDK在维护一个拾取/选中管理模块它会根据命中到的模型ID去找对应的Mesh分区然后给这个分区里的SubMesh换上一套高亮用的材质或者叠加一个半透明叠加Pass。我验证了一下SDK的高亮整体上是材质替换透明度混合的思路而不是纯后处理描边。证据有两个一是修改高亮材质的颜色参数能直接影响高亮显示的最终颜色二是选中对象之后用SceneCapture截图选中区域的Mesh颜色是整体被混合覆盖的并不是只有边缘轮廓线。如果把这一层关系理清楚就能明白一个关键结论你要改的颜色实际上是SDK内部那张高亮材质或者材质实例的参数而不是Unreal编辑器里的SelectionColor也不是引擎默认的SelectionOutlineColor。这也是很多人改了半天空不掉颜色的根本原因。1.3 高亮颜色的来源与优先级结合SDK的公开接口和实际行为我把高亮颜色的来源分成四个层级优先级从高到低排优先级颜色来源作用范围灵活度1运行时按对象/图层调用的高亮接口单独对象或图层最高可任意控制2高亮材质实例中的颜色参数全局所有选中对象共用中可做复杂材质效果3SDK初始化配置文件中的默认高亮参数全局插件加载时生效低影响所有场景4SDK内置默认高亮材质兜底最低记住这个优先级很重要。很多项目出现改了配置没生效的情况十有八九是因为SDK某处代码已经以更高优先级设置了颜色配置值根本没机会展示出来。我后来在项目里定的策略是整体色系用材质实例控制业务选中颜色用运行时接口单独下发配置文件只做兜底。这样无论SDK怎么更新版本颜色表现都能保持稳定。2. 修改高亮颜色的三条实操路径2.1 路径一通过SDK运行时接口直接设置颜色这是最推荐的一条路适合需要根据业务动态切换颜色的场景。以我用的SuperMap Hi-Fi 3D SDK for Unreal 11i版本为例在场景初始化完成后拿到场景Actor中的选中管理模块调用类似下面这样的接口// 获取场景加载时生成的Actor ASuperMapSceneActor* SceneActor ...; // 方式1设置所有选中对象的统一高亮颜色 FLinearColor HighlightColor FLinearColor(0.0f, 0.5f, 1.0f, 1.0f); SceneActor-GetSelectionManager()-SetHighlightColor(HighlightColor); // 方式2按图层分别设置11i版本多数支持 SceneActor-GetSelectionManager()-SetLayerHighlightColor(TEXT(建筑), FColor::FromHex(TEXT(#FF8C00))); SceneActor-GetSelectionManager()-SetLayerHighlightColor(TEXT(管线), FLinearColor(0.0f, 1.0f, 0.2f));注意不同小版本之间方法命名可能有差异。我见过老一点的SDK用的是SetSelectionColor新版本改成了SetHighlightColor还有的版本需要先拿到USelectionLayer再调用。所以拿到SDK之后不要凭记忆敲先打开Plugins/SuperMap/Source目录下的头文件搜索Highlight或Selection关键字确认当前版本真实暴露了哪些接口。接口调用完了如果颜色没变先检查两件事一是是否在SDK完成场景加载后调用二是选中对象的那一层是否已经设置了独立颜色。单独的SetHighlightColor优先级低于按图层的SetLayerHighlightColor这点和1.3里列的优先级是对应的。2.2 路径二通过替换高亮材质实例来做深度定制如果你希望高亮不只是一个变个颜色这么简单而是想要描边、边线变色、呼吸闪烁、透明度渐变等复合效果那就得直接动材质。SDK的插件目录下面材质命名通常是M_SuperMap_Highlight或MI_SuperMap_HighlightColor可以在Unreal的Content Browser里搜索SuperMap关键词找到它。千万不要直接改这个原始材质否则SDK一旦重新加载或覆盖文件你的改动就没了。正确做法是创建一个材质实例在Content Browser中右键 - Create Material Instance 父材质选择 M_SuperMap_Highlight 生成的实例命名为 MI_Highlight_Orange然后在材质实例的细节面板里把HighlightColor具体参数名以材质实际为准改成你要的橙色HighlightIntensity控制强度Opacity控制透明度。保存之后如果你要走全局统一风格这条路可以在SDK的初始化配置里把高亮材质替换成这个实例如果只想对部分对象生效甚至可以运行时动态设置材质实例参数。这段实操下来我觉得材质实例这条路是最可控的因为它本质上是利用Unreal原生的材质系统在做事所有材质相关的调试工具、性能分析和后期处理都能用上。缺点也很明显它对不熟悉材质编辑器的朋友有门槛而且一旦SDK内部在特定帧率下频繁重置材质参数你设置的值可能被覆盖需要在SDK注册的回调事件里面重新设置。2.3 路径三通过初始化配置/配置文件预设高亮颜色有的项目不打算写代码只想在SDK初始化阶段把默认高亮色调好不想每次运行都手动调接口。这种情况可以找SDK插件目录下的配置文件通常是这样的路径[ProjectRoot]/Plugins/SuperMap/Config/SuperMapSDK.ini或者是带XML格式的全局配置Scene Highlight Color R255 G140 B0 A180 / /Highlight /Scene具体是ini还是xml看版本。改完之后重启Unreal编辑器或者重新打包项目才会生效。这里有个容易踩的坑如果你用的是从SuperMap iServer动态加载的三维服务服务端图层的状态有时会覆盖客户端配置。比如数据在iServer发布时带有自己的默认样式SDK加载后优先认服务端样式你的配置文件颜色反而成了没有生效的那个。碰到这种情况要么把服务端图层样式一并改掉要么在客户端初始化完成后主动调用一遍运行时接口用路径一的方式强制覆盖。2.4 三条路径怎么选拿我自己的项目举例子如果你的目标只是把默认高亮色从青色改成橙色且没有复杂的业务逻辑直接用路径三改配置文件最快。如果高亮颜色需要根据用户点击、图层开关、权限角色变化而动态改变用路径一。如果要做建筑橙色选中边缘发光半透明呼吸这种复合效果用路径二在材质实例里做全套。我实际生产中把路径一和路径二做了组合材质实例负责整体的风格表现运行时接口负责具体给哪个图层哪个对象下发什么颜色。配置文件那层几乎没再用主要是怕之后SDK升级覆盖掉自定义配置。3. 环境坑位引擎版本、注册表路径与插件识别改颜色的坑解决之后还有个更前置的问题经常卡住人SDK插件能在项目里正常加载和运行本身就需要环境清干净。这一章把我在UE5环境里遇到的和引擎路径、插件识别的相关问题做个汇总。3.1 UE引擎安装路径与注册表的关联SuperMap Hi-Fi 3D SDK for Unreal的安装器在安装插件时需要自动探测Unreal引擎的安装位置。这个探测动作在Windows上主要依赖注册表。Epic的Unreal引擎安装时会在注册表写入类似这样的键HKEY_LOCAL_MACHINE\SOFTWARE\EpicGames\Unreal Engine\4.0注意这里面的4.0并不是特指UE 4.0版本它更像是Epic保留的一个固定入口很多插件的安装器都会去这个键下面读BuildDirectory字符串值拿到引擎实际所在路径比如D:\Program Files\Epic Games\UE_5.3。如果你是用Epic Games Launcher正常安装的引擎这个键一般不会丢。如果你用的是从源码编译的引擎或从别人那里拷贝的绿色版引擎这个键就经常缺失结果就是安装器提示Unable to find Unreal Engine插件装不进去或者装进去了在Editor里显示Disabled。解决方法是检查注册表缺了就手动补打开注册表编辑器 regedit 定位到 HKEY_LOCAL_MACHINE\SOFTWARE\EpicGames\Unreal Engine\4.0 如果没有BuildDirectory字符串值新建一个数值数据填引擎根目录例如 D:\Program Files\Epic Games\UE_5.3还有一点要注意有些32位的安装器读不到64位注册表视图导致明明装了引擎还找不到。这时在64位系统上要让安装器以64位模式运行否则就得在WOW6432Node分支下检查一遍注册表项。这个坑特别隐蔽因为表面上看注册表路径一模一样但32位和64位视图是两个独立空间。3.2 UE5下高亮接口不生效的排查链路我刚开始在UE5.3上运行时遇到过选中对象后高亮颜色变了但过几帧又变回去的现象。排查过程比较典型也很有代表性第一步确认SDK版本与引擎匹配。很多GIS SDK的发布周期滞后于Unreal官方版本当时我手里那个SDK插件明确标注支持UE 5.1/5.2在UE5.3上虽然能编译通过但内部渲染行为已经出现偏差。后来升级到对应SDK版本才正常。检查方法很简单打开.uplugin文件看EngineVersion兼容范围。第二步排查高亮接口的调用时机。SDK的场景Actor在BeginPlay之后还需要一段时间做数据加载和Mesh生成如果你在BeginPlay里立刻调用SetHighlightColor这时内部高亮材质可能还没初始化完成设置被吞掉。改法是在SDK的OnSceneInitialized或者OnLayerAdded事件回调后再设置。第三步检查是否被后处理干扰。如果场景里有PostProcessVolume且启用了Bloom高亮材质的自发光部分会被泛光放大颜色看起来饱和度不对。这不算接口失效只是颜色被后期效果改了。我当时把Bloom强度临时调到0颜色偏灰的问题立刻就暴露出来了。3.3 一个容易混淆的问题版权提示和选中高亮无关在GIS类插件混用的项目里经常有人问UE5里Cesium for Unreal场景右下角一直显示Cesium的版权标识能不能通过设置隐藏掉。这个问题和SuperMap SDK的高亮修改本质无关但既然做三维GIS集成迟早会遇到。我的观点是SDK和数据的版权标识是合规要求修改选中高亮颜色不应该也不需要去动版权显示。SuperMap Hi-Fi 3D SDK for Unreal本身在加载服务数据时也可能出现数据来源标识这是正常现象。如果你为了截图好看想临时隐藏那是另一回事但绝不能把隐藏版权当成常规功能写进交付文档。渲染层面版权一般是UI层和选中高亮的材质通道互不干扰你改高亮颜色完全不需要管它。3.4 iServer 11i的数据组织方式对选中高亮有直接影响数据从SuperMap iServer 11i发布出来到了SDK这边怎么被组织成可拾取对象这点特别影响高亮效果。如果你的数据是模型数据集、白模建筑、管线这类带有明确对象边界的矢量模型选中高亮是按对象来算的选中一个楼就是一个楼变高亮效果干净利落。如果你的数据是倾斜摄影模型、点云或者BIM整体烘焙那SDK拿到的更多是分层Mesh而不是独立业务对象这个时候选中高亮可能退化成整层高亮或瓦片级高亮颜色切换非常生硬。在SuperMap iDesktop里处理数据时可以提前把需要做对象级选中的模型单独抽出为模型数据集或者给数据集设置独立的图层风格。这个习惯会让你在后面做高亮业务时省掉一大半力气。iServer 11i发布时尽量使用S3M格式它对对象标识的保留比传统切片格式完整得多。4. 进阶玩法按模型分类分配不同高亮色与动态效果基础色改完之后我们项目的业务场景需要把选中对象和业务类型绑定起来。比如同一个场景里同时存在建筑、绿地和地下管线客户要求选中的建筑显示成橙色、绿地显示成绿色、管线显示成荧光黄。这就需要给每个选中对象单独下发颜色。4.1 按模型属性字段分类下发高亮颜色SuperMap数据集里的模型一般会带业务字段比如在iDesktop里给建筑数据集加了类型字段分为住宅、办公楼、学校那么SDK拾取到对象之后我们可以通过SDK的查询属性接口拿到这条记录的字段值再决定用什么颜色。基本逻辑长这样// 伪代码接口名以当前SDK版本为准 TArrayFSuperMapObjectInfo SelectedInfos SelectionManager-GetSelectedObjectInfos(); for (const auto Info : SelectedInfos) { FString ObjectType Info.GetFieldValue(TEXT(Type)); FLinearColor TargetColor; if (ObjectType TEXT(住宅)) TargetColor FLinearColor(1.0f, 0.5f, 0.0f); else if (ObjectType TEXT(办公楼)) TargetColor FLinearColor(0.8f, 0.2f, 0.8f); else if (ObjectType TEXT(学校)) TargetColor FLinearColor(0.0f, 0.8f, 1.0f); SelectionManager-SetObjectHighlightColor(Info.ObjectID, TargetColor); }这段代码看起来简单但要注意一个性能点如果选中了上百个对象循环里逐个调SetObjectHighlightColor底层可能会对Mesh材质参数做多次广播帧率会有明显掉帧。我的做法是把同一颜色的对象ID收集起来按颜色批量设置减少SDK内部的材质参数更新次数。4.2 叠加呼吸和闪烁效果为了让评审汇报时重点对象更抢眼可以在高亮颜色基础上加呼吸效果。呼吸的本质是让透明度或自发光强度随时间周期性变化。用Unreal自带的Timeline组件就能实现。先给需要呼吸的对象设置高亮材质实例然后在Tick里修改材质参数// 通过Dynamic Material Instance控制呼吸 UMaterialInstanceDynamic* DynMat MeshComp-CreateAndSetMaterialInstanceDynamic(0); float BreathPhase FMath::Sin(GetWorld()-GetTimeSeconds() * 2.0f) * 0.5f 0.5f; DynMat-SetScalarParameterValue(TEXT(HighlightIntensity), BreathPhase);这里有个小坑如果直接在SDK的对象上强行创建动态材质实例SDK下一次高亮状态切换可能会把材质还原成它自己管理的材质。我最终的稳妥方案是把呼吸效果做成一个独立的材质函数利用World Position Offset或者Vertex Color通道叠加同时让SDK在设置高亮时不要覆盖材质参数。具体的不覆盖设置有的SDK版本叫bOverrideMaterialParams有的叫KeepCustomMaterial翻头文件找一下即可。4.3 同屏多对象选中的颜色区分多选模式下默认高亮会让所有对象变成同一种颜色视觉上分不清当前主选中和其他选中。参考CAD的夹点设计可以把主选中对象设置成高饱和度颜色把次要选中对象设置成低透明度、低饱和度的同色系颜色。这样用户一眼就能看出哪个是当前操作的焦点对象。SDK通常会在选中集合里提供当前焦点对象或者最后选中对象的标识。如果版本没有直接暴露你可以自己在业务层记录最后一次点击的对象ID然后单独给它下发一个更亮的颜色其余对象用统一色。5. 改完之后我踩过的坑与验证建议5.1 颜色改了不生效的几个常见原因这部分是最有实用价值的我按实际踩坑频率排个序SDK重置材质参数SDK在某些状态下取消选中、重新加载图层、镜头切换会重置对象材质到默认状态。对策是监听SDK的场景更新事件在事件回调里重新设置颜色。LOD切换导致材质丢失高LOD和低LOD的Mesh可能使用不同的材质槽你只在其中一个LOD上改了颜色镜头拉远切到低LOD时颜色又变回去了。对策是确认你的高亮设置在All LODs上都生效或者临时锁定LOD层级排查。色彩空间不一致导致颜色偏灰Unreal默认是sRGB管线但部分SDK内部处理颜色时走的是线性空间。你填的FLinearColor(1.0f, 0.5f, 0.0f)和材质面板里看到的颜色不一定一致建议用FColor::FromHex配合sRGB转换。PostProcess Volume里的Color Grading把颜色带偏了我在夜景项目中遇到过后处理里把全局饱和度调低后高亮颜色也跟着变灰。这不是SDK问题检查后处理即可。配置文件和代码重复设置如果配置里写了一种颜色代码里又调了另一种以代码为准但容易造成改了配置为什么没反应的错觉。5.2 性能与效果平衡的几个参数建议高亮材质如果用了半透明混合会显著增加OverDraw尤其是城市级场景里同时选中多个建筑时。我的建议高亮区域能不用全模型透明就不要全模型透明优先用边缘发光或描边降低OverDraw压力。半透明高亮时Opacity控制在0.6到0.85之间太低的话背后物体透出来会显得脏太高又遮住模型本身纹理。呼吸效果的频率控制在1~2Hz超过2Hz容易让用户视觉疲劳。如果一帧内要更新大量高亮颜色先合并对象再批量提交避免逐个触发材质参数更新。5.3 从iDesktop到iServer再到UE的一致性验证高亮颜色虽然主要靠客户端控制但如果数据在SuperMap iDesktop里设置了特殊的图层风格发布到iServer 11i之后再被SDK加载默认高亮层的表现可能和iDesktop预览时不一样。我的建议是在项目启动阶段做一个高亮一致性检查选一个已知对象分别在iDesktop、WebGL端、UE端各选中一次把颜色的十六进制值记录下来对比。如果差距大优先在iServer服务端把图层样式统一再回到客户端处理业务高亮。这样可以避免同一个场景在不同端颜色不一致的验收问题。5.4 我的几个调试技巧最后分享几个平时调试高亮问题的技巧都很简单但能省很多时间用SceneCapture做一个角落小窗口实时预览选中对象方便在不打断主视图操作的情况下检查颜色效果。在SDK日志级别里开启LogSuperMapSDK Verbose高亮切换时会输出对象的Mesh更新信息能直接看到材质被覆盖的时机。改颜色之前先用Unreal的Visual Logger或者DrawDebugLine在选中对象周围画一个包围盒先确认SDK是否真的拾取到了目标对象。很多高亮颜色不对其实是因为拾取ID错位对象都选错了颜色自然不对。如果是打包后的程序里颜色不对先在编辑器PIE模式里跑一遍如果编辑器正常、打包异常优先检查配置文件的打包规则确保Config目录被包含进Pak。改选中高亮这个事看着是个小功能实际上牵扯到SDK渲染机制、数据组织方式、引擎环境配置和后处理合成好几层。我现在再遇到类似需求已经习惯了按先确认拾取对象、再分优先级设置颜色、最后验证LOD和后处理的流程走几乎不会再被改了半天不生效卡住。如果看完这篇你还是没找到自己项目里的问题建议直接从5.1的五个原因清单开始排查大概率是其中之一。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价