2020.06.16
還是棄用Shader
的方式了茫叭,用Graphics
镊掖。Github
游戲開發(fā)中或多或少都有接觸過Tilemap
,在Tiled
編輯器里編輯好地圖之后钮蛛,導出數(shù)據(jù)仅颇,然后在游戲引擎(Cocos...)里就可以直接使用了,確實很方便。
由于Pixi.js
自身并不支持Tilemap
的解析渲染茎匠,所以我一直在嘗試了解背后的機制格仲。最初能想到的實現(xiàn)就是,在一個Container
里放一堆Sprite
把地圖拼出來汽抚,Pixi.js
的Texture
支持以一個BaseTexture
為基礎(chǔ)抓狭,分塊讀取,所以實現(xiàn)一個也還可以造烁。代碼差不多就是這樣:
const rect = new PIXI.Rectangle(0, 0, this.square, this.square)
for (let i = 0, sn = 0; i < this.size.height; i++) {
for (let j = 0; j < this.size.width; j++) {
sn = this.data[i * this.size.width + j]
if (!sn) continue
sn--
rect.x = (sn % this.tilesets.columns) * this.square
rect.y = (~~(sn / this.tilesets.columns)) * this.square
// 分塊讀取
const tile = new PIXI.Sprite(new PIXI.Texture(this.tilesheet, rect))
tile.position.set(j * this.square, i * this.square)
tile.anchor.set(.5)
this.addChild(tile)
}
}
一天看到Pixi.js
的作者在Codepen
上的代碼后否过,于是有了今天這篇文章。
實現(xiàn)思路
上面是v5的實現(xiàn)惭蟋,v4實現(xiàn)起來略麻煩苗桂。
利用shader去渲染Tilemap。我們從Tilemap
導出的JSON
數(shù)據(jù)可以知道告组,主要的數(shù)據(jù)其實就是地圖元素(瓦片)在圖集中的索引煤伟。如何在著色器里拿到索引數(shù)據(jù)呢?
如果你看了上面Codepen
的代碼木缝,或許你就知道了:
const bitmap = new PIXI.Graphics()
for (let i = 0; i < layer.height; i++) {
for (let j = 0; j < layer.width; j++) {
const
index = layer.data[i * layer.width + j] - 1,
column = this.mapData.tilesets[0].columns,
x = index % column,
y = Math.floor(index / column)
bitmap.beginFill((x << 16) + (y << 8), index !== -1 ? 1 : 0)
bitmap.drawRect(j, i, 1, 1)
bitmap.endFill()
}
}
// 生成紋理后面會傳入紋理單元 一定要設(shè)置:PIXI.SCALE_MODES.NEAREST
core.renderer.generateTexture(bitmap, PIXI.SCALE_MODES.NEAREST)
創(chuàng)建一個bitmap
便锨,把地圖的索引數(shù)據(jù)變成顏色值儲存在這個bitmap
里。
還需要一段著色器代碼:
precision mediump float;
uniform sampler2D tilesheet, bitmap;
uniform float tileSize, tileColumn;
uniform vec2 tilesheetSize;
varying vec2 vTextureCoord, vVertexPosition;
void main() {
vec4 color = floor(texture2D(bitmap, vTextureCoord) * 255.0);
if (color.a == 0.0) discard;
vec2 coord = (vec2(color.r, color.g) * tileSize
+ mod(vVertexPosition, tileSize)) / tilesheetSize;
gl_FragColor = texture2D(tilesheet, coord);
}
這里還有一些Pixi.js
的操作我碟,我就不寫出來了放案。弄明白原理,就行矫俺。感覺和法線貼圖是一個道理吱殉,雖然我并沒有研究過。主要就是把索引數(shù)據(jù)變成紋理上傳到GPU
厘托,然后在著色器代碼里讀取出來友雳。