Search Unity

Inverse Mask

Discussion in 'UI Toolkit' started by TomTheMan59, Dec 6, 2021.

  1. TomTheMan59

    TomTheMan59

    Joined:
    Mar 8, 2021
    Posts:
    356
  2. AlexandreT-unity

    AlexandreT-unity

    Unity Technologies

    Joined:
    Feb 1, 2018
    Posts:
    377
    Short term, you will get the ability to create a hole in a geometry generated with the upcoming vector API (which can be used as a mask). But there are no plans regarding cancelling the masking provided by an ancestor. I'll bring this idea to the attention of our product manager though. Thanks.
     
    Last edited: Dec 7, 2021
  3. TomTheMan59

    TomTheMan59

    Joined:
    Mar 8, 2021
    Posts:
    356
    Would it work for this animation? The circle is the mask that is masking out the black square. This way you can do an animation where that shape shrinks to 0.

    https://imgur.com/e39PxNn

    Cool! This would be a great feature if it was implemented and usable like in the video above!
     
  4. AlexandreT-unity

    AlexandreT-unity

    Unity Technologies

    Joined:
    Feb 1, 2018
    Posts:
    377
    So if I understand correctly, as your circle shrinks, it reveals what's behind it. In this case, why not just draw the circle after the rectangle instead of using masking?
     
  5. TomTheMan59

    TomTheMan59

    Joined:
    Mar 8, 2021
    Posts:
    356
    That probably wasn't a good video explaining it. Here is the setup that I have using sprites. The circle has to be the mask so that it any gameplay elements behind the UI is reveled.

     
  6. SimonDufour

    SimonDufour

    Unity Technologies

    Joined:
    Jun 30, 2020
    Posts:
    578
    I am going to start from the beginning. Please let me know if any assumption are wrong.

    I understand that you want to hide some elements when they are outside the circle. Do these elements are UI, meshes? both? This may affect the overall strategy. The UI may be rendered last, on top of the regular camera rendering for most default configuration.

    If you want to fill the outside of a circle with a color, then there is multiple way to do it. You already found one, and you can use the same sprite in UI toolkit. You could also use a mesh in game with a sorting order telling unity to draw it after the other 3d elements. Another strategy would be to use the UI Toolkit Vector API to draw a large rectangle (larger than the screen) with a hole in it and scale that visual element. The mesh would be generated once, but it may be harder to find what size is visible and where it will be placed. Check the transform-origin if you are using this as you could set the origin of the scaling to be at the center of your circle. You could also regenerate the mesh at each frame with an exact shape. Overall, the render an object with a hole on top approach would work without masking: you are just filling pixels outside the circle after that something else rendered previously. This is not masking, as you are not preventing the rendering in some section.

    So if you want to prevent the rendering on some pixels, (aka use real masking) then the mask is applied first and the shader use to render after will consider that information and ignore some areas. UI Tookit uses that when the overflow is hidden. This prevents text in a child element, for example, to appear outside an element, even if the element has rounded corners. But for this to work, the elements that need to be masked need to have that specific shader. You will not be able to mask the camera rendering, as UI toolkit will be rendered after that camera.

    One third option, that would leave even more control, would be to use an intermediate render texture and do a copy, pixel by pixel, like you want it to happen. This has the disadvantage of being slower than any other method described above.
     
    Last edited: Dec 10, 2021
  7. TomTheMan59

    TomTheMan59

    Joined:
    Mar 8, 2021
    Posts:
    356
    The elements are just gameplay elements. It's a transition that hides the gameplay elements (sprites/particle systems) so I can reset or transition to another area in the game.

    This seems exactly what I need! I just make a massive black rectangle and cutout a circle that is larger than the screen. Then I just scale the entire visual element down.

    This part is an area I would have no idea how to determine.

    It seems easier to just regenerate the mesh every frame and shrink the size down. Can you generate the hole based on a sprite png or svg and then simply set the size of it every frame? Is this a lot of processing or is it pretty cheap?

    Thanks for the information! I hope this will help others doing similar transitions with UIToolkit. Awesome API!
     
    Last edited: Dec 10, 2021