したがって、Threejs と Brandon Jone の tilemap メソッド (ここにあります) を使用してタイルマップを実装するにはTHREE.Plane
、各レイヤーにジオメトリを使用し、次のカスタム シェーダーで顔をペイントします。
頂点シェーダー:
var tilemapVS = [
"varying vec2 pixelCoord;",
"varying vec2 texCoord;",
"uniform vec2 mapSize;",
"uniform vec2 inverseTileTextureSize;",
"uniform float inverseTileSize;",
"void main(void) {",
" pixelCoord = (uv * mapSize);",
" texCoord = pixelCoord * inverseTileTextureSize * inverseTileSize;",
" gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);",
"}"
].join("\n");
フラグメント シェーダー:
var tilemapFS = [
"varying vec2 pixelCoord;",
"varying vec2 texCoord;",
"uniform sampler2D tiles;",
"uniform sampler2D sprites;",
"uniform vec2 inverseTileTextureSize;",
"uniform vec2 inverseSpriteTextureSize;",
"uniform float tileSize;",
"uniform int repeatTiles;",
"void main(void) {",
" vec4 tile = texture2D(tiles, texCoord);", //load this pixel of the tilemap
" if(tile.x == 1.0 && tile.y == 1.0) { discard; }", //discard if R is 255 and G is 255
" vec2 spriteOffset = floor(tile.xy * 256.0) * tileSize;", //generate the offset in the tileset this pixel represents
" vec2 spriteCoord = mod(pixelCoord, tileSize);",
" vec4 texture = texture2D(sprites, (spriteOffset + spriteCoord) * inverseSpriteTextureSize);",
" gl_FragColor = texture;",
"}"
].join("\n");
各テクスチャは次のようにセットアップされます。
//Setup Tilemap
this.tilemap.magFilter = THREE.NearestFilter;
this.tilemap.minFilter = THREE.NearestMipMapNearestFilter;
//tilemap.flipY = false;
if(this.repeat) {
this.tilemap.wrapS = this.tilemap.wrapT = THREE.RepeatWrapping;
} else {
this.tilemap.wrapS = this.tilemap.wrapT = THREE.ClampToEdgeWrapping;
}
//Setup Tileset
this.tileset.wrapS = this.tileset.wrapT = THREE.ClampToEdgeWrapping;
this.tileset.flipY = false;
if(this.filtered) {
this.tileset.magFilter = THREE.LinearFilter;
this.tileset.minFilter = THREE.LinearMipMapLinearFilter;
} else {
this.tileset.magFilter = THREE.NearestFilter;
this.tileset.minFilter = THREE.NearestMipMapNearestFilter;
}
そして、ユニフォームは次のとおりです。
//setup shader uniforms
this._uniforms = {
mapSize: { type: 'v2', value: new THREE.Vector2(this.tilemap.image.width * this.tileSize, this.tilemap.image.height * this.tileSize) },
inverseSpriteTextureSize: { type: 'v2', value: new THREE.Vector2(1/this.tileset.image.width, 1/this.tileset.image.height) },
tileSize: { type: 'f', value: this.tileSize },
inverseTileSize: { type: 'f', value: 1/this.tileSize },
tiles: { type: 't', value: this.tilemap },
sprites: { type: 't', value: this.tileset },
inverseTileTextureSize: { type: 'v2', value: new THREE.Vector2(1/this.tilemap.image.width, 1/this.tilemap.image.height) },
repeatTiles: { type: 'i', value: this.repeat ? 1 : 0 }
};
そして、実際のジオメトリとメッシュ:
//create the shader material
this._material = new THREE.ShaderMaterial({
uniforms: this._uniforms,
vertexShader: tilemapVS,
fragmentShader: tilemapFS,
transparent: false
});
this._plane = new THREE.PlaneGeometry(
this.tilemap.image.width * this.tileSize * this.tileScale,
this.tilemap.image.height * this.tileSize * this.tileScale
);
this._mesh = new THREE.Mesh(this._plane, this._material);
this._mesh.z = this.zIndex;
this.tileSize
です。16
_ this.tileScale
_ 4
私が抱えている問題は、16x16 タイルの端の周りに破れがあることです。
奇妙な部分は、常に発生するわけではなく、y 軸に沿って移動するときに散発的にのみ発生することです (ただし、私の Linux ボックスでは、問題はさらに悪化し、x 軸にも影響します)。
頂点シェーダーで配置すると、16x16 のタイルがわずかにずれているようです。しかし、何が原因なのかわかりません。どんな助けでも大歓迎です、ありがとう!
編集
これは引き裂きのより良い画像です。草地でより目立ちます。
ご覧のとおり、16x16 タイルのエッジに沿っています ( でスケーリングされているため4
)。