Problem getting a Tilemap Layer to render to a texture when using parent group

Datetime:2016-08-22 23:07:31          Topic: Game Development           Share

Hi all !

I'm having some issues with getting tilemap layers to render to textures if added to custom groups instead of the default game.world.

Context : I'm working on a top-down pixel-art a-rpg (think Zelda 3-like). I have a mix of tilemap layers and sprites. Nothing too fancy.

Goal : I want to implement a custom upscaling shader (e.g. hq4x). I'm changing my scene to draw layers and sprites to a texture, so that I can use that texture with my custom shader.

Progress : I can easily get sprites to render to my texture, and using my shader to display that texture also works well

Problem :  To avoid overhead of individual draw calls per sprite/layer, I use a top-level Group container ; but I can only get tilemap layers to appear if they are added to the game.world and not to my top-level container :-?

In my preload() : nothing exciting, just the tilemap (Tiled json), some images/spritesheets, and a shader/fragment

In my create() :

// The top-level container to hold display objects
this.m_group = new Phaser.Group(this.game, null);

// The render texture where I want all display objects to appear
this.m_renderTarget = this.game.add.renderTexture(g_screenWidth, g_screenHeight, "RenderTarget");

// The actual sprite using the render texture
let rtSprite : Phaser.Sprite = this.game.add.sprite(0, 0, this.m_renderTarget);

// Sprite test ; this works nicely
let sprite : Phaser.Sprite = this.game.make.sprite(0, 0, "Player");
this.m_group.add(sprite);

// Layer test ; this does NOT work
this.m_map = this.game.make.tilemap("Overworld");
this.m_map.addTilesetImage("Tileset", "Tileset");
this.m_layer = this.m_map.createLayer("Layer", g_gameWidth, g_gameHeight, this.m_group);

(I've excluded the shader/filter setup, not relevant for the problem)

In my Update() :

this.m_renderTarget.renderXY(this.m_group, 0, 0);

I was thinking using the 4th parameter "parent" of the createlayer method to add it to top-container would be sufficient. This is not the case.

The only way I found to get my layer to appear on my render texture is 1. add the layer to the default game.world, 2. turn off the layer.renderable (because I don't actually want it in the default scene), 3. create a sprite using the layer texture. 4. add the sprite to my container group. Which looks like :

this.m_layer = this.m_map.createLayer("Layer");
this.m_layer.renderable = false;
let sprite : Phaser.Sprite = this.game.make.sprite(0, 0, this.m_layer.texture);
this.m_group.add(sprite);

While this is functional, this sounds overly convoluted and non-intuitive, so surely I'm not using the whole thing correctly ! The layer should behave as a display object and I don't understand why it needs to be treated differently :-?

Additionally, I tried having a separate rendertexture.renderXY() call for the layer (this.m_renderTarget.renderXY(this.m_layer, 0, 0, true);) ; same problem, the layer only appears if added to the game.world and not to any other container.

Any idea what I'm missing or doing wrong ? Any help would be greatly appreciated !

Regards





About List