So I’ve got a rather convoluted system setup where I need to capture a set of objects on an offscreen camera, render it all out to a render texture, and then assign a bunch of other objects specific rects of that render texture to display. Basically, real-time pre-rendering of 3D models to make them appear like sprites. The details aren’t super important but I noticed something super odd while building this system and I’m not sure why it would be the case.
For the sake of simplicity I decided to leave the offscreen camera disabled and instead manually call Render() on it at the very end of a controlling monobehaviour’s LateUpdate(). At the time it seemed to make more sense but I guess in retrospect it was completely unnecessary. Anyway, while testing out some non-interpolated animations I had created in blender I was finding a very strange behavior that I couldn’t explain. The objects being rendered by the offscreen camera would twitch in odd directions for no apparent reason. It was happening with a very high frequency but it would only affect certain characters. The characters affected were always consistent as long as I didn’t move around and change which models were being culled. When investigating the models in the editor view they seemed to be animating just fine. On a hunch I decided to enable my offscreen camera and stop calling Render() manually. And just like that the problem was solved!
I can’t for the life of me understand why this would be the case. The timing shouldn’t affect anything since afaik calling Render() basically just queues up a command buffer to execute during the normal drawing phase. Neither the models nor the camera move at all so I don’t think it would be a syncing issue affecting any matrices. Could this be a bug? Or is something else going on under the hood that I’m just not aware of?
Interesting. I’ll keep that in mind. For now I don’t see any impact from it but it’s good to know.
Nope. And I initially thought the same thing so I tried playing with the near and gar planes as well as moving both the camera and objects around a bit just to see if it had to do with world space placement and rounding errors. No effect.
Yep. All objects are exactly half of their bounding volume.z plus 1 away from the camera. The camera is set to have a near plane of 0.1 and a far plane of the largest bounding volume.z it will be rendering plus 2. At the moment that means everything I am rendering is about than 3 units away and the camera’s far plane is about 6.
I’ll give that a shot just for curiosity’s sake but at this point I’m leaning towards bug. Wouldn’t be the first one I’ve confirmed in Unity 2022. Not even the first one I’ve confirmed today.
I don’t know what you’re talking about. In this case you just reload camera visibility.
Unity will render this camera using rendering queue. So you can’t override that using “enabled” property. (without frame delay)
So I made another interesting discovery, switching to calling Render() during Update rather than LateUpdate DID also fix the problem. But again I’m not sure why it would have an affect like that. Going by this frame update cycle chart you can see that the internals of the animator would be processed after Update and before LateUpdate. So it seems that is having some kind of effect that I wouldn’t expect. Part of the reason I was calling it in LateUpdate was BECAUSE it was after all internal animations were processed. For the heck of it I tried disabling Graphics Jobs and GPU skinning but it had no effect. The twitching continued.
For now I’m just going to cut out the manual call and leave the camera enabled since it works and perhaps is even slightly better according to DevDunk.
I took what they wrote to mean ‘enable the camera for rendering and disable when not needed’ since it was in the context of a camera that would never render unless I told it to. Perhaps I misunderstood though.
To clarify, I attended a talk a bit ago where they render cameras to a render texture (like security footage).
They said they enable cam1 on frame 1 (and the cam updates), disable cam 1 on frame 2 and enable cam 2, disable cam 2 on frame 3, etc.
Said to improve performance a lot on quest 2 since Render() stalled the main thread. Might already be fixed or changer, so thought to pass on the info
Hello again! Yes, they results look decent enough for my work. They don’t look perfect and certainly not as good as if I crafted sprite art by hand but I really have no doubt that a much more skilled 3D artist and a much more clever programmer using shaders couldn’t get an effect that would fool most people into thinking they were looking at high quality handcrafted pixel art. I ended up taking the easy way out and just lining up all of my objects in front of a few camera so I loose some nicer features like real worldspace lighting and motion data for cloth physics. But it still works exactly the way I need it to in a performant and most importantly, scalable fashion. I really don’t know why this trick hasn’t been more wide spread for indie devs in the past but I see some evidence that it is starting to catch on more recently though.