- Home /
Render a camera multiple times in a single frame?
I have several groups of 3D objects, I want to render them as if they were in "layers" - no matter what their Z depth is.
So I render "Group 1" in front of "Group 2", I render "Group 2" in front of "Group 3" and so on. Because they aren't single meshes I can't unfortunately do this by turning culling off because the objects within each group need to cull with each other, just not with other groups! (e.g. Group 1 objects cull with each other but not with Group 2).
The way I thought it doing this is by rendering a single camera multiple times whilst switching the layers of the objects. So I have a script attached to each of the groups which does the following:
public void Update()
{
SetLayerRecursively( mRenderBatch.gameObject, 8);
mCamera.Render();
SetLayerRecursively( mRenderBatch.gameObject, 0);
}
void SetLayerRecursively(GameObject obj, int newLayer)
{
obj.layer = newLayer;
foreach (Transform child in obj.transform)
{
if (null == child)
{
continue;
}
SetLayerRecursively(child.gameObject, newLayer);
}
}
This switches the object onto a renderable layer (8), renders it and then switches it back onto a non renderable layer. The camera is then set to depth only so I hoped that this would render the layers nicely on top of each other and it does - in Free Aspect mode. The second I switch the mode to anything else it just renders a blank screen.
What am I doing wrong? I feel like I'm incredibly close - given it works in free aspect! - but just a little bit away.
Note: I have considered using multiple cameras but I wanted to use one camera for cleanliness and because I read that it's a more optimal solution (and appears to be in my limited testing!).
Answer by callen · Nov 25, 2015 at 09:26 PM
I'm not sure why you say multiple cameras are not 'optimal' but that's the approach I'd suggest. I don't see any reason in your description for calling Camera.Render() rather than letting Unity handle it, but according to this page is your camera.enabled=false as the docs say it must be?
But if you used multiple cameras you could make each camera render just the subset of objects (or specific layer) you need, and you can control their order by using the Camera.depth property. No scripting required.
I think possibly in your testing, you were trying to call Camera.Render on multiple cameras, in one frame? This sounds like it would be very inefficient.
Hey! Thanks for the reply! As far as I understand it multiple cameras do additional processing - alongside the actual render cycle - making their usage more expensive. In my own tests I got around a 30% performance increase by swapping to the method I've detailed in the above post.
When using the multiple cameras I was letting them render "automatically" - it's only in the above code that I wanted to render them in a custom way given that I needed a single camera to do multiple 'passes'.
Cheers!
What "additional processing" are you talking about? A camera is just a virtual object all it defines is a viewpoint / direction and the projection parameters. So it specifies the View- and Projectionmatrix, that's all. When you call Render() on the camera it does exactly the same thing as when it's rendered automatically.
On the other hand your SetLayerRecursively method can be quite costy if you have many objects.