I’m trying to manually control the order in which a number of objects are rendered. This will be an environment which plays out in a 2D manner, but is rendered with 3D objects. The order in which these objects must render could change on the fly, frame by frame.
According to the documentation, and a lot of forum posts regarding this same concept, the best way of doing this is to edit the Material.renderQueue value of an object. I have done this, but I am yet to see this produce any results at all. I have also tried using a custom shader and set the Queue tag, but this doesn’t work either.
I’m trying it in this manner:
void Awake () {
GetComponent<MeshRenderer>().material.renderQueue = GetComponent<MeshRenderer>().material.renderQueue + 1;
}
I have tried printing the renderQueue value to confirm that it’s updating, and it is.
I’ve also tried running it in the Start event, and heck, even the Update event. No matter what I try, meshes are rendered in the standard depth based order. I don’t think I’ve changed any manner of default setting, except for trying to manipulate the renderQueue value.
Any idea as to what I’m doing wrong?
After some looking around, I think I might understand this a little better. I think that I had confused renderQueue with manipulating the z buffer. I thought that an object with a higher renderQueue value would always be rendered on top of an object with a lower renderQueue value, regardless of whether one was in front of or behind the other. However, this doesn’t appear to be the case. The objects still respect the z buffer. I was simply changing the order in which they were rendered, not the order in which they were displayed.
With that said, how would I go about implementing this? I’d rather not have to shuffle the actual z position of each object. In fact, I’d rather keep them all on the same plane for collision handling purposes. If two objects overlap, how can I make sure that one is rendered on top of the other?
If I understand you correctly, you could get the effect you want by having a separate camera for each level of overlapping objects you need. All the cameras should be kept at the same position and rotation, essentially all seeing the same view of the scene. Set each camera’s depth property to a different value and set the culling mask so that the camera only renders one layer. For the camera with the lowest depth value, keep the clear flags set to Skybox, but for the others, select Depth Only. The cameras will now render in order of the depth property, those with higher depth rendering over those with lower depth. You can choose which overlap level an object will have by changing its layer.
Yes, I’m familiar with that concept, and I’ve done it as well. It works fine for a few layers, but I’m going to have a lot of objects entering and leaving the scene frequently. The only way that this would work would be to instantiate and manage the culling mask of a camera for every single object at runtime. That’s a little extreme. This really seems like there should be a simpler way.