#What the hell is a pop material on a CanvasRenderer?

1 messages · Page 1 of 1 (latest)

ocean jay
#

Talking about the old UI system here, but since #📲┃ui-ux is under artist tools now I think it's best to ask here.

I'm trying to create an inverse mask component that would work similar to a normal mask component. To do this, I've copied the code of the Mask component, and I'm trying to modify it, but it's pretty difficult.

While reading its code, I'm seeing references to pop materials. I'm really struggling with making it work like I want it to work, so I'm trying to understand everything in that script one by one - and I can find barely any info about pop materials online.

So - what is it, how does it work, and can it help me with making an inverse mask? Either an explanation here, or just a link to a resource would be very helpful.

silk karma
#

hmm not sure what pop material is referring to, but when i researched an adjacent topic i found a way of getting a negative mask by modifying the stencil property of the shader

#

i should be able to get more info to you in like, 15 minutes

ocean jay
#

sadly, I'm using a custom ShaderGraph shader, which does not allow for modifying stencel properties 😭 my only hope (it seems) is to create a custom component similar to mask

silk karma
#

could you link the script where you're finding "pop materials"

#

although fwiw if it's really a material thing then one of the artist channels would be more likely to be able to help

ocean jay
#

the Mask component in unityengine.ui

lofty flower
#

If you want to do masking, you can use the ui default shader on a material and set the stencil values yourself to do masking without the mask component

ocean jay
#

is referencing the pop materials on canvas renderer

#

it has pop materials here and it can get and set them and it can have multiple it seems

lofty flower
#

masking via that all happens with the stencil buffer anyway so it will re create the same effect
rect mask is different as that will modify the graphic meshes that are within it.

#

read what i said above and ignore this (pop material)

#

you are confused

ocean jay
#

I cannot set the stencil values on it

lofty flower
#

good for you but you can

ocean jay
#

I cannot use the default ui shader

#

How

lofty flower
#

does it not have those options exposed or modifyable in the shader?

ocean jay
#

that's the issue

#

that's all the things that are present on this (set to canvas) shader

lofty flower
#

Well you can still do masking with images and materials as I said. Masking happens by:

  • mask writes to stencil buffer
  • things rendered after read and either draw or do not based on stencil values
  • (optional) buffer values are cleared by drawing something over the whole area
ocean jay
#

yeah, I'm trying to do that right now

lofty flower
#

when you edit the shader can you modify them in the main options bit?

lofty flower
#

They probably are "maskable" but they decided not to expose the options

ocean jay
lofty flower
#

This is why you either need to use a different stencil ID OR "clear" it after to restore the stencil state

silk karma
#

the method i found did it in code

ocean jay
#

that's why I was looking into those pop materials maybe they have some clue, or so I thought

lofty flower
#

you can have a blank image that draws after that writes 0 for the id over that area

#

that "resets it" for later things

#

or as i said, a different stencil id can be used to not conflict with the normal masking

ocean jay
#

but how can I decide which stencil ID is used by the graphics that are being masked?

#

I can try clearing it out, that sounds like a potentially good idea

#

but I'm confused how the normal mask works without doing that

lofty flower
#

should be an exposed option on ui/default

#

so means you need to assign your own material with these things set

#

is also how you can do the masking without the mask component
Ive used this system to do inverse masking before

ocean jay
#

so - what I need to do, is render my inverse mask object, then render the thing I want masked, and then render a transparent object in that place afterward that will clear the stencil?

#

That smells like a hack but I could try

lofty flower
#

yep it kinda is but it works because the draw order of things in the UI is controlled by hierarchy order

ocean jay
#

how does the mask component not have to do that, and it just magically works, by being contained within the children of the mask object?

#

because by this logic everything that is rendered after the mask should be masked

#

right? or what am I missing

lofty flower
#

Im not sure tbh but this is how me/a collegue made it work in the past

ocean jay
#

well, I'll try it, thanks so much

ocean jay
silk karma
#

@ocean jay i see you've already gotten an answer but may as well leave this here
this is what i used

using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UI;

public class NegativeMask : Image {
    public override Material materialForRendering {
        get {
            Material material = new(base.materialForRendering);
            material.SetFloat("_StencilComp", (int)CompareFunction.NotEqual);
            return material;
        }
    }
}
ocean jay
#

but thanks

urban lotus
#

invert the mask

#

that's it

ocean jay
urban lotus