当前位置: 首页 > news >正文

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 版本中呈现,敬请期待!

相关文章:

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

为了让广大的开发者 更深入地了解 百度地图开放平台的技术能力 轻松掌握满满的技术干货 更加简单地接入 开放平台的服务 我们特别推出了 “位置服务(LBS)开发微课堂” 系列技术案例 第一期的主题是 《Polyline 绘制优化升级》 你还想了解哪些…...

VS Code设置C++编译器路径

C_Cpp.default.compilerPath是C/C编译器路径; python.condaPath是conda路径....

laravel项目配置

创建laravel项目 composer create-project --prefer-dist laravel/laravel 项目名称生成项目key php artisan key:generate.清理配置缓存 php artisan config:clearlaravel生成代码 官网链接 php artisan make:model Flight --all生成Flight类相关的文件,对应数…...

Python试讲

Python试讲 导语Python简介Python及其特点如何使用Python Python与计算计算变量 导语 本次试讲内容如下:Python简介与使用,Python与基本运算 辅助教材为 《趣学Python编程》和《Python编程从入门到实践》 Python简介 Python是目前入门最简单最好学的…...

RESTful API

RESTful API是一种基于REST (Representational State Transfer) 架构风格的应用程序编程接口。它通过使用HTTP协议的不同方法(如GET、POST、PUT、DELETE等)来对资源进行操作和传输数据。 使用RESTful API构建web应用程序需要遵循以下几个步骤&#xff1…...

NEEP-EN2-2020-Text1

英二-2020-Text 1 摘自新科学家(New scientist)2018年11月的文章《Rats can make friends with robot rats and will rescue them when stuck》。 以下为个人解析,非官方公开标准资料,可能有误,仅供参考。(…...

摩托罗拉E6系统研究

这是很久以前研究摩托罗拉E6刷机包时总结的一些经验,不一定准确但留个纪念,希望会制作刷机包的高手交流学习。 ------------------------------------------------------------------------------------------------------------------------------- 摩…...

Spring中,ApplicationContext主要的实现类型包括?

Spring中,‌ApplicationContext主要的实现类型包括FileSystemXmlApplicationContext、‌ClassPathXmlApplicationContext、‌XmlWebApplicationContext、‌AnnotationConfigWebApplicationContext。‌ FileSystemXmlApplicationContext:‌这个实现从一个…...

JavaScript青少年简明教程:事件及处理

JavaScript青少年简明教程:事件及处理 在编程语言中,事件(Event)是一种使程序能够响应特定操作或条件发生的机制。它允许程序中的不同部分(比如对象、类或模块)在发生某些特定情况时互相通信或协作。事件驱…...

node_exporter

目录 指标详解常用指标 指标详解 指标描述node_arp_entriesARP(Address Resolution Protocol)表中的条目数量,用于将IP地址映射到MAC地址。node_boot_time_seconds系统启动时间的Unix时间戳,表示从1970年1月1日以来的秒数。node…...

近期在看

1. C Primer 2. 深入理解 FFmpeg 3. 鸿蒙 sdk 开发...

C++篇:C++入门基础(1)

C前言: C 的发展历史可以追溯到1979年,当时C语言以其效率和灵活性成为广泛使用的系统编程语言,但它也有一些限制,例如缺乏直接支持面向对象编程(OOP)的特性。 之后Bjarne Stroustrup(也就是C之父)是C的创始…...

【Linux】网络编程_3

文章目录 十、网络基础5. socket编程socket 常见APIsockaddr结构简单的UDP网络程序 未完待续 十、网络基础 5. socket编程 socket 常见API // 创建 socket 文件描述符 (TCP/UDP, 客户端 服务器) int socket(int domain, int type, int protocol);// 绑定端口号 (TCP/UDP, 服…...

Kafka设计与原理详解

RocketMQ 是一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。同时,广泛应用于多个领域,包括异步通信解耦、企业解决方案、金融支付、电信、电子商务、快递物流、广告营销、社交、即…...

IPV6公网暴露下的OPENWRT防火墙安全设置(只允许访问局域网中指定服务器指定端口其余拒绝)

首先是防火墙的常规配置和区域配置 标的有点乱但是选项含义都做了解释,看不懂可以直接按图抄作业。 其次是对需要访问的端口做访问放通 情况1 DDNS位于openwrt网关上,外网访问openwrt,通过端口转发访问内部服务器。此情况需要设置端口转发。 …...

单调栈② | Java | LeetCode 接雨水 最大的矩形

42. 接雨水 暴力法 for循环遍历每一个柱子,内层for循环找到左边和右边比它高的柱子 时间复杂度 n^2 优化:添加一个预处理 定义一个数组,存放该柱子右边比他高的柱子是哪一个 再用一个数组,存放该柱子左边比他高的柱子是哪一个 …...

2024年全国青少年信息素养大赛总决赛日赛程表

2024全国青少年信息素养大赛赛程表分赛场(浙江传媒学院桐乡校区、桐乡技师学院)日期地点时间赛项16日传媒学院8:00-9:00检录 9:00-10:30开赛图形化编程挑战赛(小学1-3年级)A组12:00-13:00检录 13:00-14:30开赛图形化编程挑战赛&am…...

PHP:连接钉钉接口-钉钉回调事件,本地测试数据

前置数据参考 数据说明:参见官方文档回调事件消息体加解密 - 钉钉开放平台 (dingtalk.com) URL后面带的参数: signature5a65ceeef9aab2d149439f82dc191dd6c5cbe2c0&timestamp1445827045067&noncenEXhMP4r Post参数: { &quo…...

【C++标准模版库】vector的介绍及使用

vector 一.vector的介绍二.vector的使用1.vector 构造函数2.vector 空间增长3.vector 增删查改4.vector 迭代器的使用1.正向迭代器2.反向迭代器 5.victor 迭代器失效问题(重点) 三.vector不支持 流提取与流插入四.vector存储自定义类型1.存储string2.存储…...

数说故事|引爆社媒的森贝儿IP,品牌如何实现流量变现?

以可爱、雅痞、贱萌......的外表加魔性舞姿出圈的可爱小狗——森贝儿贵宾犬Milo,用“可爱微怒”的表情演绎着当代打工人的“疯态”,并迅速晋升成不少打工人高频使用的表情包。 最近几年,“萌系”爆款IP频出,用小动物的形象、可爱…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看

文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...

[特殊字符] Spring Boot底层原理深度解析与高级面试题精析

一、Spring Boot底层原理详解 Spring Boot的核心设计哲学是约定优于配置和自动装配,通过简化传统Spring应用的初始化和配置流程,显著提升开发效率。其底层原理可拆解为以下核心机制: 自动装配(Auto-Configuration) 核…...

Oracle实用参考(13)——Oracle for Linux物理DG环境搭建(2)

13.2. Oracle for Linux物理DG环境搭建 Oracle 数据库的DataGuard技术方案,业界也称为DG,其在数据库高可用、容灾及负载分离等方面,都有着非常广泛的应用,对此,前面相关章节已做过较为详尽的讲解,此处不再赘述。 需要说明的是, DG方案又分为物理DG和逻辑DG,两者的搭建…...

触发DMA传输错误中断问题排查

在STM32项目中,集成BLE模块后触发DMA传输错误中断(DMA2_Stream1_IRQHandler进入错误流程),但单独运行BLE模块时正常,表明问题可能源于原有线程与BLE模块的交互冲突。以下是逐步排查与解决方案: 一、问题根源…...