- Home /
How to clear multiple render buffers (MRT)
Hi, I'm trying to use multiple render targets for a game I'm working on. Since I haven't done that before I created a small project to try it. I have several questions :
what are the differences between :
void Camera.SetTargetBuffers(RenderBuffer[] colorBuffer, RenderBuffer depthBuffer);
and
static void Graphics.SetRenderTarget(RenderBuffer[] colorBuffers, RenderBuffer depthBuffer);
Camera.SetTargetBuffers doesn't seem to work well : if I call it the buffers are not filled (they are black), they don't cover the "render quad" and are placed on the bottom left of the screen. Am I missing something ?
where/when should I call those methods : OnPreRender (it seems to work) ? OnRenderImage ? ...
The second buffer is not cleared each frames. Is there a way to clear a buffer manually (ask for it to be cleared) ?
Here is the small example project so you can see what I did. The project only render a sphere, the red channel of the sphere is rendered in the first target, the green channel of the sphere is rendered in the second target. They are then combine with the first target being on the left side of the screen and the second target being on the right side (they are squeezed and thats intended). MRT example
And screenshots of what I get :
As you can see the right side (second target) the buffer is not cleared.
Thanks !
Answer by kebrus · Aug 14, 2014 at 01:56 PM
Dude i got tell you thx for your example project, i was hammering my head trying to put MRT working and your example seems to work for the most part, i still get some weird results sometimes because the render texture leaks when developing and you can only get it to work again by closing and reopening unity.
Anyway, regarding your question it seems to work differently with dx11 and without it but one thing that worked with me was to use the GL command "Clear", the way you do it is by switching to the second target and clear it and then return to the first.
here's a simple code example, probably not really elegant but it works, put it in the beginning of PreRender
RenderTexture lastActive = RenderTexture.active;
RenderTexture.active = m_target2;
GL.Clear(false, true, Color.clear);
RenderTexture.active = lastActive;
You could probably don't use the lastActive RT and simply point to the first target, it's up to you
Thanks a lot. I forgot about the GL class. Still some questions about how the $$anonymous$$RT functions work in Unity but that will do for now.
For the sake of being complete here is my OnPreRender function :
void OnPreRender( ) {
if ( SystemInfo.supportedRenderTargetCount >= 2 ) {
//camera.SetTargetBuffers( m_buffers, m_target1.depthBuffer );
RenderTexture.active = m_target2;
GL.Clear( false, true, camera.backgroundColor );
RenderTexture.active = m_target1;
Graphics.SetRenderTarget( m_buffers, m_target1.depthBuffer );
}
}
A few notes :
the profiler tells me that there are 3 RenderTexture, and 2 used. So I think we could spare creating the first RenderTexture by getting the one that the camera use ( RenderTexture.active ).
the profiler shows me spikes of about 8ms every few frames with 96% of the frame time spent on RenderTexture.SetActive.
To be honest, there's still stuff i don't get it with $$anonymous$$RT, the documentation and the lack of example don't give any ideas why some things don't work or work poorly
In a very similar example as yours going on and i'm getting 4 render textures being used. From my previous experience the numbers are not to be trusted because unity reserves and uses render textures as it needs them so sometimes is hard to tell if we are doing anything wrong or not, most of the times i just close unity and open in again, this usually clears everything
HDR, forward/deferred, depth buffer, gamma/linear space, dx11 are all things that can influence the outcome of a particular render texture and it's performance
i'm not getting any spikes on that call, in fact i'm not getting any spikes at all so i'm not really sure what that could be, could it be some setting in the quality settings?
for some reason my own example now doesn't let me paint the background of the second target it always uses the same color as the first target, along with that, my draw calls are most of the times increased by one with the script running (ex: from 10 to 11), which is okay but i don't really know why the extra draw call, so i'm still trying to figure out most of these stuff with $$anonymous$$RT, i'll definitely post something on the forums as soon as i get a good grasp of how things work, i even made a post yesterday on shaderlab about $$anonymous$$RT since i'm currently trying to improve my own glow shader effect into using $$anonymous$$RT to save draw calls
New problem : it works in the editor but doesn't work in builds. In builds unity crash after 1 or 2 seconds (both debug and release). Plus in debug the display isn't good : what should be on the right is on the left and what should be on the left is on the right; and the second buffer isn't cleared. I think I'll report a bug.