- Home /
2.5D perspective rendering order challenges
I'm createing a 2.5D game, with a 3/4 perspective. Here is a shot of the scene layout. The camera is perspective, and the characters are leaning back so they are flat against the camera view.
My characters are made up of 10 parts each, and although the z-depths of all the parts are correctly layered, I learned that Unity decides which one to render first based on the centerpoint of the object, and not the object itself like you would think. Depending on the camera angle, this makes for some strange results ( I read that somewhere, could be corrected)
I thought I could fix the problem with Shaders and RenderQueue so I created custom shaders for all 10 parts of the character. (Lower leg, upper leg) I set each shader to Transparent + (1,2 or 3) depending on which level I wanted it to be on. As expected, this works great for one character. However, when there are multiple characters on the screen, the legs and arms always render on-top of the torso, because the Shader tells them to, even if they are behind the other character.
Can anyone help? Is there such thing as selective renderQu? It would be awesome if the z-depth could just handle this so I don't have to manage it manually.
Also, excuse the art, its temporary :)
transparent cutout soft edge unlit shaders render depths well, maybe looking at the shading code will help,
Answer by Wolfram · Feb 03, 2013 at 06:44 PM
No special shaders required, and no individual layers.
You can modify the shader's render queue for transparent objects directly:
var queueOffset = 1;
function Start(){
var allRenderer=GetComponentsInChildren();
foreach (Renderer r in allRenderer) {
foreach (Material m in r.materials) {
m.renderQueue = m.shader.renderQueue + queueOffset;
}
}
}
Attach this script to each (hierarchy) of objects, and select a unique offset for each "layer" you need. Larger offsets mean in front of other object.
Note this might lead to additional drawcalls, as each queue number needs to be processed individually.
EDIT: @joeyaaaaa has a point that all "cutout" shaders don't do/need transparency sorting, they use standard z-Buffer occlusion. But they only work if you have/want only 100% transparent and 100% opaque pixels, not half-transparent objects.
EDIT2: woops, my code is a mixture of UnityScript and C#. But I guess you get the point.
Thanks, I didn't know you could modify this from script. Pretty cool. However, it is essentially doing the exact same thing I was doing with the renderQueue,, just using a different method.
For example I want the Arm to be ontop of the Torso for each individual character, but I don't want ALL arms to be ontop of ALL torsos in the scene when there are multiple characters. Does that make sense?
Yes. So if the shaders you created solve your problem for one individual object, use the script I posted on each "layer" you need, and just change the offset accordingly. For example, if your shaders use the offsets "standard", "+1", "+2", then set the offset of the script of your row that's farthest away to 0, the next one in front of that to at least 3, the next one to at least 6, and so on.
Got it, so I think this would make sense if the characters stayed at static depths. But I don't think I'm understanding how this will work for my particular setup. I should mention the characters move up and down, left and right, and can go infront and behind one another, which creates the problem
So in my head It would seem like I would need to live update the overall queueOffset of the object based on the depth from the camera. Sounds like an expensive operation, but maybe its worth a shot?
Hm, O$$anonymous$$, this new information changes just about everything... -.-
Indeed, in this case you won't get far with shader queues or layers. With Cutout shaders, the problem will still solve itself, but maybe they don't help you, for example if you rely on semi-transparent pictures in your objects?
There was a detailed topic about the transparency sorting queue depending on direction to the camera (which changes when your object moves to the corner of the screen and therefore messes with your sorting, but that seems to be how Unity currently does it), as opposed to sorting by parallel distance from the camera plane. But I can't seem to find that question again.
Ah, found it! And I didn't see that accepted answer before, but it sounds as if that solution should work for you (remember to remove the specialized arms/legs shaders that have modivied queues).
Answer by Harry64 · Feb 03, 2013 at 05:09 PM
I am a noob in Unity so maybe this doesnt help but I have a Idea.
make the parts of the body on separate unity layers and make for each layer a own camera. set the cameras to only render there layer and then you could maybe decide which part of the body is rendered first.
Thanks Harry64. Good idea. I think I'm going to try to exhaust the custom shader route first, but if that doesn't work out, I will probably end up using this technique. Thanks.