侧栏导航

热血传奇 - 超大地图渲染



本篇文章记录了:

  1. 热血传奇 的地图解析
  2. 将地图数据文件转化成可编辑的Tile地图格式
  3. 在H5客户端上进行超大地图的渲染
  4. 实现人物角色在超大地图的移动和瞬移

demo

热血传奇中的地图

热血传奇中的地图渲染是比较典型超大地图渲染.

土城为例,xy坐标轴达到了 1000 x 800, 加上每格坐标需要渲染一张48 x 32大小的贴图,地板,草皮,建筑物3层地图.

如果完整渲染整个地图, 总共3686400000个像素,30亿,恐怖如斯,PC上渲染一次要数十秒.

但实际上, 我们只需要渲染2倍玩家视角范围大小就足够了.为什么是2倍呢, 1倍用来看, 4周再额外绘制半屏, 用于缓冲角色移动时的范围计算和资源加载造成的渲染延迟 .

接下来看看具体步骤.

转化成可编辑的Tile地图格式

将wil中的位图文件提取为.png (如何提取?)

将wil中的地图数据提取为.tmx和.tsx文件.(需要了解tmx的数据结构)

一张超大地图用到的png文件大概会有5万张左右, 如果在H5游戏中用http去下载的话,在5G商用之前,玩一次游戏得等到天荒地老, 所以这里我们需要对png分类,再做成图集, 同时为了兼容tile地图编辑器.我们也需要保留png图片.

也就是:

  1. 在地图编辑中用零碎的png小图
  2. 在游戏渲染时用texture图集

在Tile编辑器上的渲染效果图

比奇

比奇

土城

土城

在H5客户端上进行超大地图的渲染

在游戏渲染时用texture图集,这个图集怎么做呢?

我用 Egret TextureMerger 生成texture图集和相应的索引配置文件, 用node.js写js脚本来修改.tsx文件中的png引用路径名为textrure中的路径, 并重命名为.tsxi,

修改游戏中tilemap渲染库源代码. 使其使用.tsxi中的路径加载图片.

实现人物角色在超大地图的移动和瞬移效果

还是修改tilemap渲染库源代码. 增加move方法.

其实现原理是:

  1. 移动时角色是不动,只调用move(newX,newY) ,
  2. 在move方法中修改TileMap的渲染原点的x,y坐标
  3. 根据TileMap的原点坐标查找范围内的图片,贴图渲染.

预期效果图如下:move

渲染优化

如果渲染超大地图上每一格贴图.存在几个问题
  1. 首先是内存吃不消.(比奇省涉及几万张平均大小3k的图片)
  2. 再个就是效率跟不上(Unity和Egret渲染一次要几十分钟,时间花在磁盘IO上)
  3. 即使换成图集.也受限与浏览器的单个图集大小限制(8192),而wil图集大小平均9000x9000,超过限制

这些问题会造玩家进入地图时一片黑.

针对上述问题 , 有几个思路
  1. 仅渲染除视图范围之外+额外1/2(针对玩家移动时作为缓冲)大小的地图.
  2. 只追加渲染新增的格子的贴图,排除已渲染的格子.

假设 视图大小 800(宽,px) x 600(高,px) , 实际渲染的范围是 1600 x 1200 . (800x(1+0.5) = 1600)

假设每格的tile大小为 48x32. 玩家可视范围内 17 x 19格, 实际渲染 34 x 36 格

首次渲染优化

换算成地图坐标系

假设玩家的坐标为比奇省的 (322,256), 即安全区,那么首次渲染的贴图坐标就应该为

[322-17,326-19] 到 [ 322+17,326+19]之间, 每层34x36格,3层(base/mid/obj)共3672格,

理论上需要渲染3672张图片,但实际上tile.wil中的图片单张大小是96*48.可以占4格.

obj和mid层仅有少数几张图片, 所以实际首次渲染的贴图平均大概1000张左右.

浏览器的 webgl效率应该是可以跟上的.

移动渲染优化

横向 or 纵向移动一格,仅仅需追加远小于 (36 or 34) x 3 张贴图

效果图

实际效果中, 以比奇省安全区(有树木,有水,有桥,房子等间建筑物体), 这样较为复杂的场景下

  1. draw call 400左右
  2. fps 有3~5帧的抖动,稳定在59左右,
  3. 首次渲染由于需要网络下载400张的小图片,视觉效果上会逐渐显示(可优化)
  4. 移动过程顺滑如丝.

再看看实际效果图:demo

以上就是 热血传奇 - 超大地图渲染

下一篇 <热血传奇 - 角色和怪物的渲染>

最后更新于 13th Jun 2019
微信二维码
在微信上关注我