How to apply a mask to a whole UMG widget

I have a square UMG widget which I show as a 3d widget in world space in my level. I want the square to have rounded corners. And these rounded corners, should clip any content inside the widget.

i.e.: If the widget has a border and inside the border an image, the image edges should clip with rounded corners too, since the widget as a whole should have rounded corners.

So far the only way I am able to achieve this is by modifying the widget rendering material as a whole (the material applied to the widget within an actor within the level). I modify the material by applying a sampler2d with a rounded rect texture and using that as an opacity mask.

This works fine but if I try to render the widget to a separate render target (with FWidgetRenderer, to use with stereo layers), the rounded corners are not rendered (since they are part of the material which displays the widget and not of the widget itself).

If instead I apply the rounded rect texture to the UMG border component in the widget, any child components (i.e. the image inside the widget) render on top of the border and the rounded corners are covered by the image’s straight edges.

So how should I go about this?

Unfortunately, this site seems dead…

So I’ll answer my own question with the one approach I figured out so far.

  1. Create your widget inside UMG as usual, with straight edges.
  2. Create an Actor in the level, with a widget component, whose class is set to the UMG widget created in step 1.
  3. The widget component of the actor will have a material assigned to it. This is an engine material used for all widgets. Create a copy of this material and set it to masked mode.
  4. Add a sampler2d node to the material and hook it up to the opacity mask pin in the material.
  5. Load a texture of a square with rounded corners in the sampler node. The area extending from each rounded corner should be black in the texture. The rest of the texture should be white.

The result will be that the widget will be rendered in the level masking out the black areas in the texture, resulting in the widget having rounded corners.

I was able to achieve this in a fairly straightforward manner using the Retainer Box Widget. Simply put, the Retainer Box has two functions. One, it allows you to set a custom tick for a widget, forcing it to update less than other widgets. Two, it allows you to force a widget through a material, allowing you to do all sorts of effects.

Simply set up your material in the “Effect” Category of the RetainerBox

Note the name of the “Texture Parameter” field in this case, it’s unhelpfully called “Texture”. Once you have added the material to the Retainer Box, make sure it’s a UI material with its blend mode set to “masked.” Then, make your material as per usual.

I wanted mine to just be a circular mask for a Diablo style health bar, so I did a little trick I know to get a circular mask, but as you can see, you could easily put any alpha masked texture in. NB: The name of the Texture Sample Parameter 2D is also “Texture.” In order to get the underlying texture of your widget, you need those two parameter names to match. Also, keep in mind that if your widget is non-square, you may have to do some warping to get it to look just right.

Here’s how mine looked in-game (just a plain ol’ progress bar)

138093-retainerboxdemo2.png

2 Likes

I gave up on this a while back so I did not try out your solution, but the issue with my solution was that, in the end, I wanted to then use stereo layers to render the widget (to mitigate antialiasing in vr). With my approach works for the widget itself but the stereo layer still captures it as a straight square. Your approach however might actually work with stereo layers. I should try it out someday.