Jump to content

Massive Sprite optimization


relativistic
 Share

Recommended Posts

I have the specific requirement of using a Sprite to provide a mask for an entire tile-less terrain. So it can't be segmented into smaller pieces - container.mask will only accept 1 sprite as its mask.

So what I'm doing is a 4096x2048 texture sprite with a sprite.scale = 8. Only a small part of the sprite is shown on the screen because with that scale it is massive.

From what I understand, PIXI is creating a 32768x16384 quad behind the scenes and using the sprite as its texture. Performance is surprisingly pretty good I'm guessing because WebGL is smart about not drawing off-screen texels. But some overhead is bound to be there.

So I'd like to have a screen sized sprite and instead change the UV coordinates of the texture on the fly in order to control what is shown. It also has to work as a mask. Is there a way to do that in PIXI?

Edit: This is WebGL only. I have no interest in canvas.

Link to comment
Share on other sites

Hello! Yes, that's possible but not through masks. You need another layer! please look at https://pixijs.github.io/examples/#/layers/lighting.js , and look at 

 

You dont have to use pixi-layers plugin, its just a handy shortcut. Also , please look at https://github.com/pixijs/pixi-tilemap , that's for tiles. Also, https://github.com/Alan01252/pixi-tilemap-tutorial - good tutorial for tiles.

 

Link to comment
Share on other sites

5 hours ago, ivan.popelyshev said:

...

Thank you for your reply.

I don't think that applies to my use case because I'm using a Sprite to mask a fullscreen TileSprite, not to do lighting. Then each TileSprite/Spritemask combo is stacked on top of each other. I'm smooth-blending together different terrain textures, exactly as you would blend terrain in a normal 3D game. Apart from the inefficiency I mentioned it looks great.

I also tried a TileSprite as a mask, which sort of works statically, but it won't update when tileScale or tilePosition is changed.

Correct me if I'm wrong but screen-sized TileSprite masks is exactly what I need: a quad with screen width/height and the ability to change texture coordinates through tileScale/tilePosition. Texture wrap won't be used in this case because tilePosition won't ever get past the wrap point.

Are there plans in pixijs to allow TileSprites as a mask?

Link to comment
Share on other sites

Mask and lighting are the same effect implemented with different techniques. First is the shader, second is just MULTIPLY blendMode.

You can make full-screen TilingSprite and set its blendMode to multiply, that'll work ;) 

If you want to mask only one container and not the entire stage - add them both (container + tilingpsrite) to some parent container with VoidFilter. The idea is it creates a layer, renders container there, multiplies it to tilingsprite, then renders that container onto stage. That's how I make lighting, and that's the way you can do your stuff too.

I hope that in pixi-v5 we'll have better way to do that kind of things. I'm actually researching it ^_^

Link to comment
Share on other sites

Hey Ivan.

Due to the fact that I have 5 of these layers, the multiply blend method creates an extra offscreen buffer and 5 extra full screen draws. I did some limited testing and performance is way worse.

Really, all I want is to be able to set the following in realtime:

sprite_texture = new PIXI.Texture(base, new PIXI.Rectangle(x, y, width, height));

at the moment I can only set that when initializing the sprite.

Link to comment
Share on other sites

multiply blend method creates an extra offscreen buffer and 5 extra full screen draw.

Mask does that too. But blendMode can work without offscreen buffer, if you want to mask everything that was rendered before your big thingy.

at the moment I can only set that when initializing the sprite.

You can do that in runtime. Just set "sprite.texture" to a new one, or change both "texture.orig" and "texture.frame" and then call "sprite.onTextureUpdate()".

Ok, I re-read what you asked, and I think you wont get more performance from it. PIXI clips the mask area, because its actually done through a SpriteMaskFilter.

Link to comment
Share on other sites

On 5/13/2017 at 3:26 PM, ivan.popelyshev said:

Ok, I re-read what you asked, and I think you wont get more performance from it. PIXI clips the mask area, because its actually done through a SpriteMaskFilter.

You're right. Tried with pre-cut small masks and performance is the same. Same goes for Sprites.

Only thing that would help at this point is multitexturing.

Is this still being targetted for v5? https://github.com/pixijs/pixi.js/projects?query=sort%3Acreated-asc Particularly the "support multitexture sprite rendering with alphaMasks" part.

Link to comment
Share on other sites

6 hours ago, relativistic said:

You're right. Tried with pre-cut small masks and performance is the same. Same goes for Sprites.

Only thing that would help at this point is multitexturing.

Is this still being targetted for v5? https://github.com/pixijs/pixi.js/projects?query=sort%3Acreated-asc Particularly the "support multitexture sprite rendering with alphaMasks" part.

That's my WIP project, and its different alpha masks, they are per-sprite.

When we remove extra offscreen buffers, fillrate will be the problem. Multitexturing will only make it worse.

Did you try to just use tilingsprite with multiply blendmode?

Link to comment
Share on other sites

On 5/15/2017 at 0:38 AM, ivan.popelyshev said:

Did you try to just use tilingsprite with multiply blendmode?

I gave it a proper try this time and on my lower end device (iPad Air) FPS drops to 36 from 40 (masks). I am using 3 containers with VoidFilter. Shader masking is faster.

It also doesn't work with greyscale masks with no alpha channel. All of my masks are JPEGs since they compress 10 times better than PNGs. These are terrain masks with big soft features so PNG doesn't do well.

Code is a mess so no codepen for now, maybe in the weekend if I can find time.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...