CommandBuffers (presumably) not executed

Hi everyone!

we are using multiple render targets for great effect in our project, and after some time we got it to work with rendertextures and OnPostRender() magic (see for a working sample http://forum.unity3d.com/threads/mrt-multiple-render-target-in-unity5-how-to-best-practice.383644/#post-2693022)

We are now trying to get it to work with command buffers. But no success so far. It all fails silently (is it supposed to fail silently?) and the command buffers don’t show up in the frame debugger.

Here’s a few snippets:

       var setMRT = new CommandBuffer();
 setMRT.name = "CB:setMRT";
 setMRT.GetTemporaryRT(Shader.PropertyToID("color0"), Screen.width, Screen.height, 0);
 setMRT.GetTemporaryRT(Shader.PropertyToID("color1"), Screen.width, Screen.height, 0);
 setMRT.GetTemporaryRT(Shader.PropertyToID("depth"), Screen.width, Screen.height, 32, FilterMode.Point, RenderTextureFormat.Depth);
 RenderTargetIdentifier[] colors = {
 new RenderTargetIdentifier(Shader.PropertyToID("color0")),
 new RenderTargetIdentifier(Shader.PropertyToID("color1"))
 };

 setMRT.SetRenderTarget(colors, new RenderTargetIdentifier(Shader.PropertyToID("depth")));
 camera.AddCommandBuffer(CameraEvent.BeforeForwardOpaque, setMRT);
 
 var releaseTemp = new CommandBuffer();
 releaseTemp.name = "CB:releasetempbuffers";
 releaseTemp.ReleaseTemporaryRT(Shader.PropertyToID("color0"));
 releaseTemp.ReleaseTemporaryRT(Shader.PropertyToID("color1"));
 camera.AddCommandBuffer(CameraEvent.AfterEverything, releaseTemp);


 var resolve = new CommandBuffer();
 resolve.name = "CB:resolveMRT";
 var props = new MaterialPropertyBlock();
 props.SetTexture("bars", TestTexture);
 resolve.DrawMesh(Quad, Matrix4x4.identity, MrtResolveMaterial, 0, 0, props);
 camera.AddCommandBuffer(CameraEvent.AfterForwardAlpha, resolve);

The only command buffer that is executed is the last one (“CB:resolveMRT”). The other two don’t show up nowhere, and the the draw calls in the frame debugger don’t show the MRT.

Any hints on what I am doing wrong are greatly appreciated.

PS: Is ‘fail silently’ a bug or intended behaviour. should we file a bug report? In a related direction: does anyone read the documentation bugs we file from time to time?

Thanks in advance!

  • Simon

I trimmed it down to the command buffer to set the MRT for the moment. When I add the drawMesh command to the buffer, then it is also displayed in the frame debugger and draws the mesh. However it still does not set the rendertarget.

It does something however: When I remove the getTemporary calls from the buffer, unity complains about not finding the named render textures. On the other hand however, It does not look like I am leaking resources even though I never release the temps in this case.

Here’s the current code in all its glory:

        var setMRT = new CommandBuffer();
        setMRT.name = "CB: set MRT";
//        setMRT.GetTemporaryRT(Shader.PropertyToID("color0"), Screen.width, Screen.height, 0);
//        setMRT.GetTemporaryRT(Shader.PropertyToID("color1"), Screen.width, Screen.height, 0);
//        setMRT.GetTemporaryRT(Shader.PropertyToID("depth"), Screen.width, Screen.height, 32, FilterMode.Point, RenderTextureFormat.Depth);
        RenderTargetIdentifier[] colors = {
            new RenderTargetIdentifier(Shader.PropertyToID("color0")),
            new RenderTargetIdentifier(Shader.PropertyToID("color1"))
        };
        setMRT.SetRenderTarget(colors, new RenderTargetIdentifier(Shader.PropertyToID("depth")));
        myCamera.AddCommandBuffer(CameraEvent.BeforeForwardOpaque, setMRT);

edit: ok, the docs hint that the temps are released after rendering each frame. one mystery solved…

I’ll keep talking to myself here…

Setting the buffers with Camera.setTargetBuffers(…) works fine, using Graphics.setRenderTarget(…) has no effect at all. Creating a buffer with the setRenderTarget() call and executing it directly also has no effect, same as attaching it to a camera.

If CommandBuffer.setRenderTarget() maps to Graphics.SetRenderTarget(), what would be the corresponding CommandBuffer call to Camera.setTargetBuffers()?

Should there be a semantic difference between Camera.setTargetBuffers(), Graphics.SetRenderTarget(), CommandBuffer.SetRenderTarget (executed through Graphics.ExecuteCommandBuffer()) and and the same command buffer attached to a camera?

Here is the bug report: https://fogbugz.unity3d.com/default.asp?813115_s4fci6a3cp5atgll
and a link to the minimal repro: https://drive.google.com/open?id=0B-NQQxq4JO8AQ0FtUGpJN1F0T1E