- Home /
Rendering Order
How would I go about changing the order an object is rendered to the screen? I have a crosshair sprite that is drawn -120 units down the Z axis of the player ship, but I'd like it to be rendered after everything else on the scene so it is always on top.
Note that, due to the camera following the ship smoothly and not exactly, I cannot put the crosshair on the GUI as it will be very inaccurate.
Answer by Kuba · Nov 24, 2009 at 10:13 AM
In your shader use the appriopriate tag that defines the rendering order (subshader tags):
Tags {"Queue" = "Overlay" }
Thanks. I shall have to look into shaders a little more.
Could someone post an example, how was this resolved? I have tried both setting the objects: renderer.material.renderQueue = 4000; and also creating a custom shader that uses: Tags { "Queue" = "Overlay" } and neither of these methods worked on their own nor in concert. I got no compile errors but the item continues to be rendered behind other geometry.
Changing the rendering order does not necessarily mean that geometry won't occlude later render passes. In fact, it may actually lead to the opposite. Geometry drawn earlier will block areas of the screen if it writes to the depth buffer and the later passes do a depth test (ZTest) to deter$$anonymous$$e if it should draw or not.
To make sure that an object always draws, use a shader which has ZTest turned off.
Answer by yoyo · Jan 06, 2011 at 07:49 PM
No need to modify the shader, you can set Material.renderQueue instead.
[EDIT] In my project, I've added a render queue enum that I use to manage queues project-wide. Various bits of code around the project use this enum to set material.renderQueue. I use the convention of indenting my in-between layers. (A lot of materials stay at their defaults, this is just when I need procedural control.)
// RenderQueue provides ID's for Unity render queues. These can be applied to sub-shader tags, // but it's easier to just set material.renderQueue. Static class instead of enum because these // are int's, so this way client code doesn't need to use typecasting. // // From the documentation: // For special uses in-between queues can be used. Internally each queue is represented // by integer index; Background is 1000, Geometry is 2000, Transparent is 3000 and // Overlay is 4000. // // NOTE: Keep these in numerical order for ease of understanding. Use plurals for start of // a group of layers. public static class RenderQueue { public const int Background = 1000;
// Mid-ground.
public const int ParallaxLayers = Background + 100; // +1, 2, 3, ... for additional layers
// Lines on the ground.
public const int GroundLines = Background + 200;
public const int Tracks = GroundLines + 0;
public const int Routes = GroundLines + 1;
public const int IndicatorRings = GroundLines + 2;
public const int Geometry = 2000;
public const int Transparent = 3000;
// Lines on the screen. (Over world, but under GUI.)
public const int ScreenLines = Transparent + 100;
public const int Overlay = 4000;
}
What sort of number would I need to make something on top of all other objects in the scene? A really large number? Would 1024 be sufficient or is it much more than necessary? Cheers, this looks like an interesting prospect.
Click through to this link and it explains where things go by default, which should help you figure out where to insert your stuff. Bigger numbers are on top. http://unity3d.com/support/documentation/Components/SL-SubshaderTags.html
Answer by Jaap Kreijkamp · Nov 24, 2009 at 11:40 PM
Although you already got a good answer, I was wondering why you dismiss placing the crosshair using the GUI layer (or a sprite manager on a orthographic camera). With:
Camera.WorldToScreenPoint(position : Vector3) : Vector3
you could get the screen coordinates of your target and get pinpoint precision placing it on screen without worrying about scaling and lighting effects you could get when placing a mesh in the scene (although both are solvable).
I did also consider linepicking afterward, although it seemed a lot more complex in my head and this actually makes it look very simple. I will experiment with both methods, I think! Cheers.
Answer by KevinBKnaus · Jan 16, 2015 at 05:38 PM
If you can create a new layer in the Cross Hair Inspector's Sprite Renderer you can then assign the Crosshair the new layer and it should render "last", and that means in the foreground.
Your answer
Follow this Question
Related Questions
Strange Render Order Issue 0 Answers
Problem with rendering? 0 Answers
Sun-shaft camera glitch 0 Answers
Small line appearing under my 2D pixel sprite - 2D Graphics not rendering properly 2 Answers