Search Unity

Issue writing to RenderTexture from Computer Shader (Metal)

Discussion in 'Shaders' started by MaxisJames, Dec 28, 2019.

  1. MaxisJames

    MaxisJames

    Joined:
    Jun 14, 2015
    Posts:
    2
    Hello!

    I've been attempting to dig into compute shaders and have been getting some weird results when trying to write to render textures via compute shader. I've stripped everything back to what seems like its simplest possible form, a compute shader that just copies an input texture to a render texture, but I'm still running into the same issue.

    Input on the left, output on the right.
    Output image is a 2048x2048 render texture (see below), but the compute shader only seems to be able to write to the first 4x4 pixels regardless of anything that I do. It's almost as if its writing to a 4x4 target which is then being blit to my output render texture.
    Screenshot 2019-12-28 at 13.49.26.png

    Screenshot 2019-12-28 at 13.50.55.png

    Code below, as you can see there's really not very much going on here (the compute buffer is just there to double check that the shader is executing more than 16 times), so I'm sure I'm just missing something incredibly obvious, but any help would be greatly appreciated.

    Running Unity 2019.2.16f1 on Mac OS Mojave using Metal.

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class CopyTextureWithComputerShader : MonoBehaviour
    4. {
    5.     public Texture2D inputTexture;
    6.     public RenderTexture outputRenderTexture;
    7.     public ComputeShader computeShader;
    8.     public void Start()
    9.     {
    10.         var tempOutputTexture = RenderTexture.GetTemporary(2048, 2048);
    11.         tempOutputTexture.enableRandomWrite = true;
    12.  
    13.         var kernelID = computeShader.FindKernel("CopyTexture");
    14.         var buffer = new ComputeBuffer(1024, 4);
    15.        
    16.         computeShader.SetTexture(kernelID,"InputTexture", inputTexture);
    17.         computeShader.SetTexture(kernelID,"OutputRenderTexture", tempOutputTexture);
    18.         computeShader.SetBuffer(kernelID,"OutputBuffer", buffer);
    19.         computeShader.Dispatch(kernelID, tempOutputTexture.width/32,tempOutputTexture.height/32,1);
    20.        
    21.         var results = new float[1024];
    22.         buffer.GetData(results);
    23.         foreach ( var item in results)
    24.         {
    25.             Debug.Log(item);
    26.         }
    27.         buffer.Release();
    28.        
    29.         Graphics.Blit(tempOutputTexture,outputRenderTexture);
    30.     }
    31. }
    Code (HLSL):
    1. #pragma kernel CopyTexture
    2.  
    3. Texture2D<float4> InputTexture;
    4. RWTexture2D<float4> OutputRenderTexture;
    5. RWStructuredBuffer<float> OutputBuffer;
    6.  
    7. [numthreads(32,32,1)]
    8. void CopyTexture (uint3 id : SV_DispatchThreadID)
    9. {
    10.     OutputBuffer[id.x] = InputTexture[id.xy].r;
    11.     OutputRenderTexture[id.xy] = InputTexture[id.xy];
    12. }
     
  2. MaxisJames

    MaxisJames

    Joined:
    Jun 14, 2015
    Posts:
    2
    Well, problem appears to be solved by calling '.Create' on the temporary render textures.
    Caught me off guard as calling it doesn't seem to be necessary for Blit operations and unity didn't throw any errors or warnings but either way the issue is gone for now!
    Screenshot 2019-12-29 at 01.05.52.png
     
    ArtemKonyshev and FS_adam like this.