I'm trying to make text have a fixed position in world space and be overlayed in screen space at the same time.

enter image description here

I have text in canvas with "Screen Space - Overlay" which covers my text located in canvas (world space).

What should I do?

  • \$\begingroup\$ you want a world space canvas that is always on top of everything I presume ? \$\endgroup\$
    – Uri Popov
    May 3, 2016 at 9:28
  • \$\begingroup\$ @UriPopov Exactly. \$\endgroup\$
    – Programmer
    May 3, 2016 at 9:29
  • \$\begingroup\$ I edited my answer to explain how to do exactly what you want. Please check it out. \$\endgroup\$
    – Uri Popov
    May 4, 2016 at 8:03

2 Answers 2


You're going to need a custom shader for your World Space UI objects that has it's Render Order to Overlay and has ZTest turned off. Also your World Space ui does not have to be a child of a screen overlay canvas( that's not how it works)

This is a copy of the Default UI shader with the necessary changes. Should do the trick. Just make a material with this shader, and apply it to everything you want drawn over the top of geometry in your WorldSpace UI.

Shader "UI/Default_OverlayNoZTest"
         [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
         _Color ("Tint", Color) = (1,1,1,1)

         _StencilComp ("Stencil Comparison", Float) = 8
         _Stencil ("Stencil ID", Float) = 0
         _StencilOp ("Stencil Operation", Float) = 0
         _StencilWriteMask ("Stencil Write Mask", Float) = 255
         _StencilReadMask ("Stencil Read Mask", Float) = 255

         _ColorMask ("Color Mask", Float) = 15


             Ref [_Stencil]
             Comp [_StencilComp]
             Pass [_StencilOp] 
             ReadMask [_StencilReadMask]
             WriteMask [_StencilWriteMask]

         Cull Off
         Lighting Off
         ZWrite Off
         ZTest Off
         Blend SrcAlpha OneMinusSrcAlpha
         ColorMask [_ColorMask]

             #pragma vertex vert
             #pragma fragment frag
             #include "UnityCG.cginc"

             struct appdata_t
                 float4 vertex   : POSITION;
                 float4 color    : COLOR;
                 float2 texcoord : TEXCOORD0;

             struct v2f
                 float4 vertex   : SV_POSITION;
                 fixed4 color    : COLOR;
                 half2 texcoord  : TEXCOORD0;

             fixed4 _Color;

             v2f vert(appdata_t IN)
                 v2f OUT;
                 OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
                 OUT.texcoord = IN.texcoord;
                 OUT.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);
                 OUT.color = IN.color * _Color;
                 return OUT;

             sampler2D _MainTex;

             fixed4 frag(v2f IN) : SV_Target
                 half4 color = tex2D(_MainTex, IN.texcoord) * IN.color;
                 clip (color.a - 0.01);
                 return color;

credit goes to http://answers.unity3d.com/questions/878667/world-space-canvas-on-top-of-everything.html

Edit: Ok so I managed to replicate what the OP wants using my shader and a screen-space camera canvas. Here is a screenshot: enter image description here

The red square is a world canvas image that has a material with the shader. The button is a screenspace camera button with the same material. Both canvases are set to the UI layer. The world space canvas has its sorting order set to 1 and the camera canvas order in layer is 0. Now both the world space canvas and the camera one are over all other geometry and the world canvas is on top of everything.


A world-space canvas is rendered as a 3d plane-mesh in the game-world, which means it is overlapped by other 3d objects. But to solve this problem you don't need a custom shader. You can do it with multiple cameras with different culling masks.

When you have multiple cameras in your scene, each camera will be rendered separately. The culling mask decides what will be rendered by the camera. Then the output of all the cameras get drawn on top of each other in order of their "Depth" value.

  • Click on "Layers -> Edit Layers" and create a new user layer "Over".
  • Assign that layer to the world-space canvas.
  • Make sure everything else has the "Default" layer assigned to it.
  • Create a second camera which is identical to the first. Make sure it also maintains the same position, rotation and other settings so both cameras always show the exact same view frustum.
  • On the first camera (the "default"-camera) set:
    • Clear Flags: "Skybox" / "Solid color" (whatever you want to be the background)
    • Culling mask: "Default"
    • Depth: 0
  • On the second camera (the "over" camera) set:
    • Clear Flags: "Depth Only"
    • Culling mask: "Over"
    • Depth: 1
  • \$\begingroup\$ I have a question. Isn't this doing the exact same thing as the shader in my answer, but just internally ? \$\endgroup\$
    – Uri Popov
    May 3, 2016 at 9:55
  • \$\begingroup\$ I have tried this, and it only makes world space canvas elements be in front of default non-canvas gameobjects. Canvas overlay is still in front of world space canvas. where did i go wrong? \$\endgroup\$
    – Programmer
    May 3, 2016 at 10:18
  • \$\begingroup\$ @Gog65 I don't understand. Isn't that what you wanted? \$\endgroup\$
    – Philipp
    May 3, 2016 at 10:53
  • \$\begingroup\$ @UriPopov Shader programming is not my area of expertise. \$\endgroup\$
    – Philipp
    May 3, 2016 at 10:54
  • \$\begingroup\$ @Philipp i want my world space canvas to be on top everything, even my Screen Space - Overlay canvas. \$\endgroup\$
    – Programmer
    May 3, 2016 at 10:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .