Render order of primitives attached to UI canvas

I have a situation which is quite hard to explain. Firstly I have a scene which consist of a Screen Space -Camera canvas set at plane distance = 10. Attached to the canvas is a UGUI Raw Image element which is displaying a render target, and a Pie Chart which is a filled-circle created using procedural mesh. Each object are position of top of each other but with different Z-order.(ie textui is place in front of the circle which is place in front of the rawimage). The hierarchy of the objects are as follow:

  • ScreenSpaceCanvas
    ++ RawImage
    ++ Panel
    +++ PieChart(emptyObject)
    ++++ TextLabel
    ++++ ProceduralCircleMesh

The camera is at world position (0,1, -10) with lookAt in the direction of (0,0,1).
The local position of each of the element are as follow:

  • ScreenSpaceCanvas
    ++ RawImage = (0,0,10)
    ++ Panel = (0,0, -1)
    +++ PieChart = (0,0,-1)
    ++++ TextLabel = (0,0,-2)
    ++++ ProceduralCircleMesh = (0,0,0)

So this is the problem I am facing, when the RawImage is active, the UIText in TextLabel does not draw(or maybe is drawn behind the piechart), but then I disabled the rawImage, the text object rendered correctly in front of the circle.

To help isolating the problem, the ProceduralCircleMesh has a custom shader attached to it

Shader "Custom/PieChart" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)
    }
    SubShader
    {
   
        Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
        Blend SrcAlpha OneMinusSrcAlpha

        Pass
        {
            Cull off
            Zwrite off
           
            CGPROGRAM
            #include "UnityCG.cginc"
           
            #pragma target 4.0
            #pragma vertex vert
            #pragma fragment frag
           
           
            half4 _Color;
           
           
            struct VertIn
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float4  pos : SV_POSITION;   
            };
                           

            v2f vert(VertIn v)
            {
                v2f OUT;
               
                OUT.pos = mul(UNITY_MATRIX_MVP, v.vertex);
       
                return OUT;
            }
           
            half4 frag(v2f i) : SV_TARGET
            {           
                return _Color;   
            }
           
            ENDCG

        }
    }
    FallBack "Diffuse"
}

When i change the shader to a opaque shader by modifying the shader to

       Tags { "RenderType"="Opaque" }

        Pass
        {
            Cull off
            Zwrite On
            .
            .
            .

The text is rendered correctly in front of the circle.
Hence i suspect that the problem is caused by the conflicting draw order of the circle with the rest of the transparent UI element, but i have no idea how to resolve this.

Sorry for the long post, hope you guys can point me to the right direction

We render the UI as a separate ‘thing’ to the pie chart if it’s a mesh. You need to write a custom CanvasRenderer that renders your pie chart. In 5.2 (released soon) you can just set the mesh on the CanvasRenderer and you’ll be able to render the pie chart.

Thanks Tim for the info. For the past days, I have been messing around with canvasRenderer and manage to get my piechart to render using the canvasRenderer instead of a mesh renderer. However I am now unable to customize the color of my pie chart like I used to. Previously I am modifying the color properties of my custom shader by:

pieSlice.GetComponent<Renderer>().material.SetColor("_Color", color[i]);

Now converting to canvas shader, I am unable to do so. I am aware, from your previous posts, about canvasRenderer not being a renderer but something that pump vertex to the canvas to create a UI mesh. Currently canvasRender have a setColor function but its not working with the custom material that I am using.

So how do I modify the color of the mesh(and in such a way that it works with canvasgroup’s alpha) and if it is possible to assign texture to it too?

Hi all, I’d like to share with you my plugin to create 2D Primitives.
You can create these primitives

  • Circle
  • Star
  • Rounded square
  • Arrow
  • Spiral
  • N-Sides Polygon
  • Gradient Quad
  • 4 Corner Gradient Quad

All primitives types are inherited from default Graphic class so it’s behave as any canvas element.
The main pros to use those primitives are:

  • They are resolution independent;

  • Fully animable;

  • Lightweight;

  • Fully configurable;

  • Source code included;

  • You can use the shapes included in the pack (as a static class Shape2DHelper) for many implementations: spawn objects, emit particles, draw, animation etc.

  • Fast and easy to prototype or create UI / UX;

To next version I’m adding support to create 2D Sprite Primitives as well.

Here is the link to the plugin on Asset Store
2D Primitives