以下内容转载自totoro的文章《WebGL-Y轴翻转踩坑实录》

作者:totoro

链接:blog.totoroxiao.com/webgl-flipY…

来源:blog.totoroxiao.com/

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

前言

自定义栅格图层 是指用户可以通过特定软件,将自定义的图像按照上文所述的方式切割为瓦片,并生成图片,然后按照瓦片坐标拼接形成地图的图层。常用于手绘地图、卫星图、地形图等。

案例背景

基于 WebGL 的地图渲染API,实现自定义栅格图层(将地图切分为等大的正方形,并以图片进行拼接渲染)时,为了节省纹理上传的开销,将栅格瓦片集中绘制到一张纹理上,然后绘制时根据瓦片各自的纹理坐标取各自的纹理,大概示意图如下:

瓦片根据加载的先后顺序依次排列绘制到大纹理上,占位宽度一致,竖向排列。比如若瓦片大小为256px,那么瓦片1的位置为{x:0, y:0}, 瓦片2的位置为{x:0, y:256}。

然后出现了一系列问题:

瓦片错乱:瓦片1的位置显示了瓦片4的内容;

瓦片内容倒置。

问题分析

根据调试定位,发现问题的根源在于Y轴翻转。

问题1: Y轴翻转是什么?为什么要翻转?

先看看没有任何处理的情况下如何绘制纹理,我们绘制瓦片的基本顶点模型是一个中心在原点的正方形,对于每个顶点坐标,需要映射到一个纹理坐标(下图左),传给片元着色器,再使用 texture2D() 取纹理像素,这种情况下左上角顶点(-1,1)对应的纹理坐标为(0,0)。

纹理坐标系与顶点坐标系的Y轴方向不同,进行坐标映射的时候会不方便,所以如果将纹理坐标系的Y轴翻转则能使坐标映射更容易(上图右)。

WebGL 也提供了相应接口实现该功能, WebGLRenderingContext.pixelStorei() 是 WebGL 中用于描述像素存储模式的函数,其中 UNPACK_FLIP_Y_WEBGL 可以用于设置Y轴是否翻转:

// 1表示翻转,0表示不翻转

gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);

复制代码

问题2: 为什么Y轴翻转会导致瓦片错乱呢?

如上文所述,首先需要通过 texImage2D 创建一个大纹理,然后使用 texSubImage2D 将瓦片绘制到大纹理上:

// x, y 表示偏移量

gl.texSubImage2D(gl.TEXTURE_2D, 0, x, y, gl.RGBA, gl.UNSIGNED_BYTE, image);

复制代码

这个接口用于改变纹理中指定子区域的数据,可以类比于 CanvasRenderingContext2D.drawImage() ,我们平常使用drawImage 时都是以左上角为原点进行偏移,所以想象中的大纹理是如下图所示的那样,瓦片1的左上角对应纹理坐标(0, 1),左下角为(0, 0.75),以此类推。

但实际上Y轴翻转并不只作用在片元着色器的纹理中,使用 texImage2D 创建大纹理时其像素存储模式就已经确定了,当执行texSubImage2D时也会对image的像素存储位置进行反转,其执行过程是这样:

所以实际上大纹理应该长如下这样:

所以当使用纹理坐标左上角(0, 1)+左下角(0, 0.75)时,我们取到的是瓦片4的纹理,最终导致了瓦片错乱。

问题3: 为什么瓦片会倒置?

正确取得纹理坐标后,又出现了新的问题:

瓦片在屏幕上显示出来是上下颠倒的,且这种情况只出现在chrome/firefox里,因为在这两个浏览器中我们使用了 createImageBitmap 将blob格式的图片转为了位图,而在safari浏览器(不支持 createImageBitmap)中我们将blob格式转为了Image 对象,最终导致了这种差异,所以我们从ImageBitmap 着手去定位问题原因。

ImageBitmap表示位图图像,用于在canvas中绘制图像,相比较于Image 其延迟较低,因为在执行texSubImage2D 将Image 绘制到纹理上时也会先将其转为ImageBitmap:

不论是在 canvas 里绘制2d图像,还是在 WebGL 中创建纹理,当使用图像时浏览器会把图像做一次解码(decode)处理。这个解码也就是把图像的原始格式(比如 jpeg、png 等)统一转换为位图,即每个像素使用 RGB 或 RGBA 来描述。当图片尺寸比较大的时候,解码也会有一定的消耗,而且这个耗时是同步的。——《高性能 WebGL —— 使用 ImageBitmap 提升纹理性能》(http://www.jiazhengblog.com/blog/2019/03/24/3407/)

同时 WebGL 规范里对 ImageBitmap 有一些特殊的描述,当介绍 pixelStorei 的三个参数:UNPACK_FLIP_Y_WEBGL、UNPACK_PREMULTIPLY_ALPHA_WEBGL、UNPACK_COLORSPACE_CONVERSION_WEBGL时,明确说明了其对ImageBitmap 无效,只能在创建 ImageBitmap 的时候就进行相应设置:

If the TexImageSource is an ImageBitmap, then these three parameters will be ignored. Instead the equivalent ImageBitmapOptions should be used to create an ImageBitmap with the desired format.

所以可以大胆猜测,pixelStorei 所指定的像素存储模式其实作用于将图像解码转为位图的预处理过程。当我们直接将位图绘制到纹理上时就没有这个预处理过程了,所以UNPACK_FLIP_Y_WEBGL 参数失效了。

小结

UNPACK_FLIP_Y_WEBGL 参数用于设置纹理像素存储模式中是否将Y轴翻转,翻不翻取决于你的顶点模型的坐标系方向,适合自己就好。在我们的应用场景里,顶点模型和图像坐标系是反的,所以需要将该参数设为1。

使用 texSubImage2D 上传图片时同样受到UNPACK_FLIP_Y_WEBGL 参数的影响。

如果上传的图像是ImageBitmap对象,则在其创建时可通过 ImageBitmapOptions中的 imageOrientation、premultiplyAlpha、colorSpaceConversion 三个参数让其与pixelStorei 中所设置的参数保持一致。

最终使用自定义栅格图层实现手绘图叠加到地图上,完成效果如下:

产品推广

目前我们腾讯位置服务已经支持个性化图层使用,如需接入请查看:个性化图层编辑平台,更多示例与开发文档,您也可以官网搜索个性化图层查看!!!

关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。

本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。

[基于 WebGL实现自定义栅格图层踩坑实录]http://www.zyiz.net/tech/detail-142172.html

JAVA发布栅格图层_基于 WebGL实现自定义栅格图层踩坑实录相关推荐

  1. java项目----教务管理系统_基于Java的教务管理系统

    java项目----教务管理系统_基于Java的教务管理系统 2022-04-22 18:18·java基础 最近为客户开发了一套学校用教务管理系统,主要实现学生.课程.老师.选课等相关的信息化管理功 ...

  2. 「Java」基于Mirai的qq机器人开发踩坑笔记(其一)

    目录 0. 前置操作 I. 安装MCL II. MCL自动登录配置 III. 安装IDEA插件 1. 新建Mirai项目 2. 编写主类 3. 添加外部依赖 4. IDEA运行 5. 插件打包 6. ...

  3. 「Java」基于Mirai的qq机器人开发踩坑笔记(其二)

    目录 0. 配置机器人 1. onLoad方法 2. onEnable方法 3. 消息属性 4. 消息监听 I. 好友消息 II. 群聊消息 III. 无差别消息 5. 发送消息 I. 文本消息 II ...

  4. java写新闻模板_基于java新闻发布及管理系统

    基于java新闻发布及管理系统 java 2020-10-18 下载地址 https://www.codedown123.com/44681.html Java新闻发布系统新闻发布及管理系统就是一个能 ...

  5. three.js加载3d模型_基于WebGL的3D技术在网页中的运用 ThingJS 前端开发

    Three.js.ThingJS这些引擎库可以加载3D制作软件的模型,大幅度提高了制作效率,改变WebGL开发困难的局面,让Web开发者享受便捷的3D开发服务.三者的难度对比如下: ThingJS(框 ...

  6. sonar覆盖率怎么统计的_实战|Java 测试覆盖率 Jacoco插桩的不同形式总结和踩坑记录(上)...

    本文为霍格沃兹测试学院优秀学员关于 Jacoco 的小结和踩坑记录.测试开发进阶学习,文末加群. 一.概述 测试覆盖率是老生常谈的话题.因为我测试理论基础不是很好,这里就不提需求.覆盖率等内容,直奔主 ...

  7. arcgis把jpg转成栅格图像_土地利用JPG数据转栅格

    一.课程简介 本套视频以栅格数据处理.矢量数据处理与制图综合.空间分析.自动矢量化和ArcScene三维可视化为主,课程内容见目录标题,视频时长12小时. 购买本课程后将免费获取下列资料: ①11G视 ...

  8. 【机器人栅格地图】基于灰狼算法求解栅格地图路径规划及避障含Matlab源码

    1 简介 1.1 灰狼算法介绍 1.2 栅格地图介绍 栅格地图有两种表示方法,直角坐标系法和序号法,序号法比直角坐标法节省内存 室内环境栅格法建模步骤 1.栅格粒大小的选取 栅格的大小是个关键因素,栅 ...

  9. Java在MVC开发模式中使用try-catch以及throws避免踩坑

    场景 1.throws是在方法上抛出异常,throw是在语句上抛出异常. 2.try-catch是在catch里处理try捕获异常并处理. 3.一般try-catch是在上层Controller中使用 ...

最新文章

  1. Unity中sharedMaterials 和 materials
  2. [转]Java 关闭线程的安全方法
  3. Android camera 开发(10)---Camera 硬件介绍
  4. TCP/UDP通信解疑
  5. 下一个十年:练好内功被集成的弹性计算
  6. 华为回应关于“获政府巨额补贴”报道;最高法:微信微博聊天记录可作为证据;GoLand 2020.1 路线图公布 | 极客头条...
  7. github可以刷星吗_GitHub 没有 star,该写进简历里吗?
  8. Physical Plausible Shading
  9. 关羽卖枣,张飞杀猪,二人何以有“盖世武功”?
  10. 屏幕录制 gif android,分享 Android 手机屏幕录制并制玉成 GIF 演示图片
  11. html如何生成条形码,前端使用JsBarcode生成条形码
  12. 泛微云桥任意文件读取漏洞复现[09/18]
  13. 一根网线让两台笔记本对拷文件
  14. python3实用小工具--商品库存查看工具(附源码)
  15. Github代码复现-IVIX中国波指计算
  16. P4556 [Vani有约会]雨天的尾巴(树上的差分+线段树的启发式合并)
  17. Xshell快速命令集解放生产力
  18. 《那些年啊,那些事——一个程序员的奋斗史》——36
  19. Android Scroller
  20. 笔记:光场相机能否用于SLAM?

热门文章

  1. pandas拉长dataframe
  2. php闪屏程序,节日闪屏的两种构成方式
  3. Xavier上的第一个I2C驱动
  4. spring Boot环境下dubbo+zookeeper的一个基础讲解与示例
  5. VXLAN 概念(Part II)- 每天5分钟玩转 OpenStack(109)
  6. 从偶然的机会发现一个mysql特性到wooyun waf绕过题
  7. BZOJ 2763: [JLOI2011]飞行路线 【SPFA】
  8. Hadoop: The Definitive Guide (3rd Edition)
  9. 电脑安装系统出错蓝屏报错为 STOP 0xc0000020 ,什么原因?
  10. 终于过了。。。。。。。。。。。