Dynamically rendering circle mask

Hi!

I’m creating a circle progress bar. For this kind of effect I normally use a full circle image and then apply a mask to it rendering part of a circle in an offscreen canvas element.

However I have never done this in PlayCanvas, and I’m not sure what would be the process to assign the bitmap of the canvas to a masking sprite on runtime, and I don’t think there is any example on how to do this.

Has anyone done this before or could you give me any hint? Thanks! :slight_smile:

Hi @mariogarranz,

Masks are supported in Playcanvas UI element components, though for the moment I think only 1-bit precision is available. That means only yes/no (transparent or not), no nice fading out pixels based on the alpha texture.

https://developer.playcanvas.com/en/user-manual/user-interface/image-elements/

For a progress bar you can take a look at this tutorial project, it uses a scaled up element to fill the bar, of course not sure how that would work in your case (with a circle progress bar):

https://developer.playcanvas.com/en/tutorials/ui-elements-progress/

Thanks Leonidas, I’m aware of all of that.

What I want to do is generate the mask dynamically to have a circle progress bar, not a rectangle one. I have done this several times in other engines by rendering the pie section that I want masked on a canvas context, and then using that as the mask.

So, my question in this case is if someone know how could I use that canvas context bitmap as a mask in Play Canvas.

Basically I want to use this feature:

And then use the resulting image as a mask.

Ah right, so you can do that relatively easily by grabbing the canvas draw surface (pixels) and creating or updating a pc.Texture.

This Playcanvas take a screenshot example does exactly that:

https://playcanvas.com/project/605131/overview/capturing-screenshot-from-camera

So, basically the steps are:

  • Use a Canvas2D to draw on it. You can find several examples on the web about it.
  • Grab the pixels from that canvas.
  • Use the pixels to populate a pc.Texture which you can use in your UI elements.

Though if you plan in doing that per frame, it’s going to be quite slow, not recommended. Take a look at this post:

1 Like

I see what you mean but, according to what you are saying and what the link mentions, that seems indeed like a ver performance expensive operation.

I have done this several times by using structures like Phaser’s BitmapData:

https://photonstorm.github.io/phaser-ce/Phaser.BitmapData.html

Which can act then like a texture for a sprite, and it doesn’t have a big cost, just as much as rendering a few more pixels offscreen, no noticeable impact on the game performance.

I’ll give this method a try to see how it performs, but I’m sure there must be a not very expensive way, I just can’t figure out which one yet :confused:

Thanks for your help!

Oh yeah, normally you will just use a pixel shader directly on the Playcanvas material.

That would be super fast since it will be rendered using the GPU.

Though I can’t think an example right now that uses custom shaders to produce masks.

If you are comfortable in using GLSL this shouldn’t be hard. A good starting point is this tutorial on how to add some custom GLSL on a material slot:

https://developer.playcanvas.com/en/tutorials/warp-a-sprite-with-glsl/

1 Like

Thanks! That does indeed look like a promising solution I hadn’t thought of :slight_smile:

1 Like

Hey there, have you ever figured out a straight forward solution for this? Looking for a quick one and don’t really have the resources to spend time on playing with fragment shaders (unfortunately).

Something like this? https://developer.playcanvas.com/en/tutorials/loading-circle-ui/

Thank you, I was thinking too fancy when googling :wink: