My team has a custom rendering pipeline based loosely on LWRP. We’re seeing an issue with two of the rendering passes interacting in a strange way which seems related to SetRenderTarget.
This issue does not repro in Unity editor, but repros on iOS devices.
The former pass renders to a texture, and the latter renders the transparent objects in the scene. If the former pass executes, no transparent objects are visible. If the former pass is disabled, transparent objects are rendered correctly.
This is a simplified version of the code that results in the bad state. Commenting out the call to “cmd.SetRenderTarget(renderTexture)” fixes the problem, but is necessary for the Render To Texture pass to function correctly.
RenderTargetHandle colorHandle = RenderTargetHandle.CameraTarget;
RenderTargetHandle depthHandle = RenderTargetHandle.CameraTarget;
RenderBufferLoadAction loadOp = RenderBufferLoadAction.Load;
RenderBufferStoreAction storeOp = RenderBufferStoreAction.Store;
// Render to a texture in one pass
var cmd = CommandBufferPool.Get("Render To Texture");
var orthoMatrix = Matrix4x4.Ortho(-1f, 1f, -1f, 1f, -1f, 1f);
cmd.SetGlobalMatrix(Shader.PropertyToID("_renderVP"), GL.GetGPUProjectionMatrix(orthoMatrix, true));
cmd.SetRenderTarget(renderTexture);
cmd.DrawRenderer(renderer, material);
context.ExecuteCommandBuffer(cmd);
cmd.Clear();
CommandBufferPool.Release(cmd);
// Render transparent objects in the next pass
CommandBuffer cmd = CommandBufferPool.Get("Render Transparents");
CoreUtils.SetRenderTarget(cmd, colorHandle.Identifier(), loadOp, storeOp, depthHandle.Identifier(), loadOp, storeOp, ClearFlag.None, Color.black);
context.ExecuteCommandBuffer(cmd);
cmd.Clear();
Camera camera = renderingData.cameraData.camera;
var drawSettings = CreateDrawRendererSettings(camera, SortFlags.CommonTransparent, rendererConfiguration, renderingData.supportsDynamicBatching);
context.DrawRenderers(renderingData.cullResults.visibleRenderers, ref drawSettings, m_TransparentFilterSettings);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
According to the documentation for SetRenderTarget, “You do not explicitly need to preserve active render targets during command buffer execution (current render targets are saved & restored afterwards).” Not only does this not seem to be the case, but the subsequent call to SetRenderTarget should correctly restore the render target to its previous state.