Search Unity

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

Discussion in 'General Graphics' started by AudrasC, Aug 19, 2020.

  1. AudrasC

    AudrasC

    Joined:
    Feb 19, 2016
    Posts:
    19
    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

    Code (CSharp):
    1. RenderTexture destRenderTexture = new RenderTexture(2048, 2048, 0, RenderTextureFormat.ARGBHalf);
    2. destRenderTexture.enableRandomWrite = true;
    3. destRenderTexture.Create();
    4. destRenderTexture.name = "outputRenderTexture";
    5. RenderTexture.active = destRenderTexture;
    6.  
    7. for(...)
    8. {
    9.    // set Input data
    10.   // set  compute shader parameters
    11.   shader..SetFloats("scale", _intensityArray);
    12.   ...
    13.   shader.SetTexture(shader.FindKernel("ComputeShader"), "dstTex", destRenderTexture);
    14.  
    15.    shader.Dispatch(0, 2048 / 8, 2048 / 8, 1);
    16.  
    17.   if(RenderTexture.active !=null)
    18.   {
    19.     // RenderTexture.active.name is outputRenderTexture
    20.     Debug.Log("RenderTexture " + RenderTexture.active.name + " size " + RenderTexture.active.width + " " + RenderTexture.active.height);
    21.   }
    22.  
    23.   // If I uncomment this it works correctly, otherwise I get a black image
    24.   // RenderTexture.active = destRenderTexture;
    25.  
    26.   Texture2D resultTexture = new Texture2D(destRenderTexture.width, destRenderTexture.height, TextureFormat.RGBAHalf, true);
    27.                            
    28.    resultTexture.ReadPixels(new Rect(0, 0, destRenderTexture.width, destRenderTexture.height), 0, 0);
    29.    resultTexture.Apply();
    30. }

    I don't understand the reason to set everytime the active RenterTexture. Especially, that RenderTexture.active is already equal to my RenderTexture.
     
    Last edited: Aug 28, 2020
  2. BrandyStarbrite

    BrandyStarbrite

    Joined:
    Aug 4, 2013
    Posts:
    2,076
    Did you figure it out?
     
  3. AudrasC

    AudrasC

    Joined:
    Feb 19, 2016
    Posts:
    19
    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).
     
  4. AudrasC

    AudrasC

    Joined:
    Feb 19, 2016
    Posts:
    19
    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.

    Code (CSharp):
    1.   RenderTextureDescriptor renderTextureDescriptor = new RenderTextureDescriptor(2048, 2048, RenderTextureFormat.ARGBHalf);,
    2.   renderTextureDescriptor.enableRandomWrite = true;
    3.   RenderTexture destRenderTexture = RenderTexture.GetTemporary(renderTextureDescriptor);
    4.    
    5.     for(...)
    6.     {
    7.        // set Input data
    8.       // set  compute shader parameters
    9.       shader..SetFloats("scale", _intensityArray);
    10.       ...
    11.       shader.SetTexture(shader.FindKernel("ComputeShader"), "dstTex", destRenderTexture);
    12.    
    13.        shader.Dispatch(0, 2048 / 8, 2048 / 8, 1);
    14.    
    15.       Texture2D resultTexture = new Texture2D(destRenderTexture.width, destRenderTexture.height, TextureFormat.RGBAHalf, true);
    16.       Graphics.CopyTexture(destRenderTexture, resultTexture);                          
    17.     }                              
    18. RenderTexture.ReleaseTemporary(destRenderTexture);
    19.  
     
  5. BartPieters

    BartPieters

    Unity Technologies

    Joined:
    Apr 12, 2019
    Posts:
    25
    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.
     
  6. AudrasC

    AudrasC

    Joined:
    Feb 19, 2016
    Posts:
    19
    I have submitting a bug using the bug report from the editor.
    ticket: 1277899_8dsku3fska9d9p63