LBS 开发微课堂|Polyline绘制优化:效果更丰富,性能更佳!

为了让广大的开发者

更深入地了解

百度地图开放平台的技术能力

轻松掌握满满的技术干货

更加简单地接入

开放平台的服务

我们特别推出了

“位置服务(LBS)开发微课堂”

系列技术案例

第一期的主题是

《Polyline 绘制优化升级》

你还想了解哪些技术内容?

快来评论区留言告诉我们吧!

cut-off

Polyline(线段)绘制,作为地图绘制的基础,凝聚着工程师们的巧思与智慧。百度地图开放平台持续对地图 SDK 的 Polyline 绘制技术进行优化,努力为开发者提供更好的开发体验。

百度地图最新版本的地图 SDK 在基础性能、渲染效果以及场景化应用等方面都有了明显的突破,让地图绘制更流畅,绘制效果更丰富。

(向上发光效果呈现出的围栏视觉效果)

(司乘同显:乘客端小车平滑移动效果)

今天,让我们一起来看看这些技术提升背后的秘密,体验一下百度地图在 Polyline 绘制方面的过人之处吧!


1 Polyline渲染优化

新版地图 SDK 的 Polyline 绘制功能采用了记录法向量的方式,有效解决了线宽变化导致的顶点数据重复计算的问题,使得开发者在调用相关功能进行开发时,能够显著降低CPU的占用率。

1.1 顶点数据优化方案

旧版 SDK:在线的每一段的顶点处,垂直当前线段做垂线,再沿垂线各取二分为一线宽长度计算出上下两个顶点的位置坐标。

新版 SDK:在线的每一段的顶点处,垂直当前线段做两个相反方向的射线,记录顶点位置点及射线的方向向量,绘制时传入线宽。

以两个点的线段为例:

旧版本(图 1)在 CPU 阶段根据线宽计算顶点位置 a1、a2、b1、b2 和纹理坐标 st 。

新版本(图 2)中直接记录原始 A、B 和 an1、an2、bn1、bn2 方向信息。

顶点偏移量计算 delta= an1*lineWidth*线宽缩放比例,等同于 shader 中的 vec4 delta= vec4(a_normal.xy * u_line_width * v_direction, 0, 0) 。

线宽缩放比例在正常直线时为 1,拐角连接处根据拐角类型(jointype)计算需要的缩放比例。比如:圆角为 1,尖角为向量 AB 的法向量与 AB、BC 法向量相加的向量的点乘结果(有最大值限制)。

1.2 顶点数据差异对比

图 3(旧版本)

图 4(新版本)

旧版中(图 3):a_position 中 xyz 代表位置,a_texCoord 中 st 代表纹理坐标。

新版中(图 4):a_position 中 xyz 代表位置,w 代表累计长度(纹理坐标及 Track 动画时使用);射线方向向量在 a_nomal 中,xy 代表法向量,z 的正负代表法向量的正逆,用于纹理计算;z 的绝对值代表线宽缩放比例,用于顶点偏移量计算。

1.3 Shader数据处理实现

图 5( 旧版本)

图 6( 新版本)

旧版中(图 5):gl_Position 数据由传入的顶点数据经过 MVP 矩阵转化后得到;纹理坐标直接传递给片段着色器。

新版中(图 6):gl_Position 数据由传入的顶点数据+线宽对应的顶点偏移量计算后再经过 MVP 矩阵转化后得到;纹理坐标也在顶点着色器 Shader 中计算后传递给片段着色器。

gl_Position 根据线宽在顶点着色器 Shader 中计算:

// 线宽缩放比例,直线时为1,拐角处根据拐角类型计算得出
float v_direction = abs(a_normal.z);
// 线宽对应的顶点偏移
vec4 delta= vec4(a_normal.xy * u_line_width * v_direction, 0, 0);
gl_Position = u_MVPMatrix * vec4(a_position.xyz, 1) + u_MVPMatrix * delta;

纹理坐标在顶点着色器 Shader 中计算(以repeat方式为例):

float s = 0.5 + a_normal.z * 0.5;
// u_gl_to_pixel不同地图缩放层级的坐标像素比例
// u_tex_height0为纹理高度
float t = a_position.w * u_gl_to_pixel / u_tex_height0;
v_tex_coord0 = vec2(s, t);
另外还内置其他纹理坐标计算方式:拉伸中间部分,纹理整数倍平铺、0~0.5 部分拉伸、单纹理拉伸、纹理等比缩放等。

路线走过擦除、置灰场景,走过和未走过路线样式的处理,是根据顶点着色器 Shader 中传递的累计长度(v_acculength)在片段着色器 Shader 中控制并渲染。

v_accuLength = a_position.w;
if (v_accuLength >= u_progressLength) { // progress forward
   gl_FragColor = u_color1;
} else { // progress backward
   gl_FragColor = u_color0;
}

1.4 性能对比

同等 26,050 个点数据路线绘制(乌鲁木齐-深圳),新旧版本性能对比,可以看到 CPU 占用率下降超 50%,GPU 性能没有明显改变。

图 7(旧版本)

图 8(新版本)

2 发光效果优化

2.1 性能优化

得益于顶点数据优化方案,新版的Polyline绘制实现了发光与非发光效果的顶点数据共享同一份数据Buffer,开发者在调用相关功能的过程中,可以显著降低内存的占用量。

2.2 模糊发光

旧版的发光效果逻辑中,需要用到离屏渲染,绘制比原polyline宽度更宽的线,然后进行多次模糊处理,生成一张模糊图片绘制到原来的Polyline下方,实现发光效果。所以旧版SDK的发光效果就需要两倍的时间、空间去计算和储存点信息,还要离屏渲染,不仅要申请额外的帧缓冲空间,多次模糊的处理还增加了GPU的耗时时间。

针对模糊效果的离屏渲染问题,我们在新版SDK的Shader中采用了模糊函数进行替代,避免了相关问题。模糊程度可通过系数灵活控制。

代码片段:

if (uniforms.u_bloom == 1) {
  // 透明度渐变发光
    // uniforms.u_speed衰减速度
    weight = pow(weight, uniforms.u_speed);
} else if (uniforms.u_bloom == 2) {
    // 模糊发光
    // uniforms.u_times代表模糊程度
    // r = 根号2 = 1.414,σ为 r/3 = 0.471
    // 2.0*σ方 = 2.0 * 0.471 * 0.471 =  0.443682
    weight = 1.0 - exp( - (weight * weight ) / float(uniforms.u_times) * 0.443682);
}

新、旧版模糊发光效果对比:

2.3 发光方向

通过记录方向向量的方案,发光效果拥有了更多的自由度:新版SDK的发光效果不仅可以实现正常的向两侧发光,还支持单侧发光和向上发光。Polygon边线、Circle的边线、弧线、大地曲线也采用了类似Polyline的处理技术。

多方向发光效果:

图 11 线段

图 12 圆边线

图 13 Polygon 边线

2.4 参数接口

Polyline的发光效果功能为开发者提供了高度灵活且可配置的参数接口,从而可以实现更加丰富和吸引人的用户体验,助力开发者打造出更具竞争力的应用。

渐变线多方向不同发光参数动态更新效果:

3 Track 动画

3.1 场景分析

在司乘同显场景中,旧版 SDK 在司乘同显组件中对路线和小车数据进行绑路计算,每次动画结束需要更新 Polyline 的点数据集,每次更新变化就会产生大量的计算。然而大部分的情况下整体路线信息是没有变化的,只是随着行程进度进行路线擦除或置灰。类似的还有轨迹回放,小车平滑移动等场景。为了解决以上问题,Polyline绘制引入了Track 动画。

3.2 Track 动画

在新版 SDK 中,Polyline 新增的 Track 动画能力,可以根据行程进度对路线进行动画处理;除了按进度进行动画,还内置了绑路逻辑,开发者可以直接传入小车行进的位置和方向信息,由 SDK 自动绑路后进行动画;另外除了正常(Nomal)样式,还新增了走过和未走过路线样式,实现 Polyline 走过和未走过路线的自定义绘制。对比旧版的 BMKTraceOverlay,在性能、效果、易用性和灵活性方面都有较大提升。

历史轨迹回放:

图 15

走过路线擦除:

图 16

新旧版本特性对照:

新版效果将于 9 月份在官网发布的 Android 地图 SDK V7.6.3 和 iOS 地图 SDK V6.6.3 版本中呈现,敬请期待!

  • 18
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值