RenderTexture is active but still get a black image after using a compute shader

Hello,

I’m not sure it is here I should post this.

I have a compute shader that does computation on textures and stores the result into a RenderTexture. I then retrieve the renderTexture into a Texture2D.
I’m doing the same process several times in a loop with different input but the same output RenderTexture.

My problem is that I have to do RenderTexture.active = destRenderTexture; after every use of the compute shader or the output image is black. The profiler tells me that setting the active renderTexture takes a lot of time so I would like to set it once at the beginning and get the output after every computation of the compute shader.

Here are somes parts of the code

RenderTexture destRenderTexture = new RenderTexture(2048, 2048, 0, RenderTextureFormat.ARGBHalf);
destRenderTexture.enableRandomWrite = true;
destRenderTexture.Create();
destRenderTexture.name = "outputRenderTexture";
RenderTexture.active = destRenderTexture;

for(...)
{
   // set Input data
  // set  compute shader parameters
  shader..SetFloats("scale", _intensityArray);
  ...
  shader.SetTexture(shader.FindKernel("ComputeShader"), "dstTex", destRenderTexture);

   shader.Dispatch(0, 2048 / 8, 2048 / 8, 1);

  if(RenderTexture.active !=null)
  {
    // RenderTexture.active.name is outputRenderTexture
    Debug.Log("RenderTexture " + RenderTexture.active.name + " size " + RenderTexture.active.width + " " + RenderTexture.active.height);
  }

  // If I uncomment this it works correctly, otherwise I get a black image
  // RenderTexture.active = destRenderTexture;

  Texture2D resultTexture = new Texture2D(destRenderTexture.width, destRenderTexture.height, TextureFormat.RGBAHalf, true);
                           
   resultTexture.ReadPixels(new Rect(0, 0, destRenderTexture.width, destRenderTexture.height), 0, 0);
   resultTexture.Apply();
}

I don’t understand the reason to set everytime the active RenterTexture. Especially, that RenderTexture.active is already equal to my RenderTexture.

Did you figure it out?

I haven’t yet. So I set the active texture every time.

Actually, I have an error when I don’t set the active texture every time:

[d3d11] attempting to ReadPixels outside of RenderTexture bounds! Reading (0, 0, 2048, 2048) from (1065, 691)

I don’t know where (1065, 691) comes from.
I check the RenderTexture.active and it is not null and its size is (2048, 2048).

I don’t use ReadPixel anymore. I use Graphics.CopyTexture to copy the RenderTexture to the Texture2D. It seems to be faster but I don’t know if it is correct to use it that way. But I don’t need to set active render texture anymore.
I also use a temporary renderTexture instead of creating a new one. It still not super fast but it is faster than before.

here is the code.

  RenderTextureDescriptor renderTextureDescriptor = new RenderTextureDescriptor(2048, 2048, RenderTextureFormat.ARGBHalf);,
  renderTextureDescriptor.enableRandomWrite = true;
  RenderTexture destRenderTexture = RenderTexture.GetTemporary(renderTextureDescriptor);
   
    for(...)
    {
       // set Input data
      // set  compute shader parameters
      shader..SetFloats("scale", _intensityArray);
      ...
      shader.SetTexture(shader.FindKernel("ComputeShader"), "dstTex", destRenderTexture);
   
       shader.Dispatch(0, 2048 / 8, 2048 / 8, 1);
   
      Texture2D resultTexture = new Texture2D(destRenderTexture.width, destRenderTexture.height, TextureFormat.RGBAHalf, true);
      Graphics.CopyTexture(destRenderTexture, resultTexture);                           
    }                              
RenderTexture.ReleaseTemporary(destRenderTexture);

Hi!

Would it be possible to file a bug report? It sounds like something internally is setting its own active RenderTexture and not restoring it to the original (yours) afterwards.

I have submitting a bug using the bug report from the editor.
ticket: 1277899_8dsku3fska9d9p63