Hello.
Because AnyPortrait uses Mesh Renderer, I assumed the Mask component will work fine. So I have added the panel as the children of my canvas and add Mask component to that panel, then I have made AnyPortrait object and Image object as the children of the panel.
As the result the mask is working fine for the child image, but it is not applied to the child AnyPortrait object.
Could you please explain why the Mask component does not work for AP objects.
Thank you.
PS
I know about the way to do masking with "Sprite Mask" component. But using of the UI panels looks much simplest for me.
Hello.
Thank you for that very detailed answer.
Hi!
This problem is not specific to AnyPortrait, but is a common problem for Mesh Renderers, especially in most cases where Custom Shaders are used.
Canvas, Image, and Mask in Unity UI are not actually compatible with Mesh Renderer (a.k.a 3D Mesh).
There are two reasons:
The first is "the Limitation of Render Mode".
If the Render Mode of the Canvas is "Screen Space - Overlay", it will not be rendered properly.
So you need to change the Render Mode to "Screen Space - Camera" or "World Space".
This issue is covered in our manual.
https://rainyrizzle.github.io/en/AdvancedManual/AD_2DCanvas.html
The second reason is “the Rendering order”.
The general rules for determining rendering order do not apply to objects under Canvas.
Mesh Renderers are rendered before or after other UI elements in a batch.
To solve this problem, you or our team need to write rendering code that references the Canvas.
In addition to compatibility issues, the Mask component uses Stencil.
Therefore, if you want to mask meshes using a custom shader, you must write stencil code.
Our manual for creating a Shader with a Stencil for a Sprite Mask (not a Mask) is as follows.
( https://rainyrizzle.github.io/en/AdvancedManual/AD_SpriteMask.html )
However, in order to mask with Stencil, the “Rendering order” must work properly.
As a result, to solve this problem you have to pass three hurdles.
(1) The Render Mode of Canvas must be changed to match 3D Mesh.
(2) You must write a script that controls the rendering order of 3D Meshes in the Canvas.
(3) You must create a shader containing a stencil and apply it through AnyPortrait's Material Library.
Placing a 3D Mesh on Canvas and applying a Mask should all resolve (1), (2), and (3) above.
Especially, the problem is that solving (2), is very difficult and inefficient, so it is actually very difficult to implement this.
(A method of arbitrarily rendering by inserting a Mesh Renderer into a Canvas Renderer is sometimes used, but we are not sure whether this method is appropriate to apply to an object composed of a set of numerous meshes, such as AnyPortrait.)
The easiest way to solve this problem is to use "Render Texture" and "Raw Image" in Unity UI.
(1) Add a new camera that renders the 3D meshes, including AnyPortrait Characters, you want to add to the UI, and set the rendering results to be saved in Render Texture.
(Explanation of AnyPortrait and Render Texture: https://rainyrizzle.github.io/en/AdvancedManual/AD_RenderTexture.html )
(2) Set the Culling Mask so that existing cameras do not render the 3D meshes.
(3) Add a "Raw Image" object under the Mask of the Canvas, and apply the "Render Texture" with the results of rendering the 3D meshes as the source of the raw image.
Through the above method, you can easily insert a 3D Mesh into Canvas and apply a Mask.
The above answer was written based on comments from Unity documentation and forums.
Since we do not know the internal code related to Unity UI's shader or rendering, we just got limited information through forums.
So there may be other solutions that we don't know about.
What we found was that the majority of developers do not recommend putting 3D meshes in Canvas.
This issue requires a lot of discussion among Unity users, and if an appropriate method exists, we will consider whether it can be applied to AnyPortrait.
If you have any opinion, please leave a comment!
Thank you.