Search Unity

Creating textures with compute shader not giving no results.

Discussion in 'General Graphics' started by Filtiarn_, Mar 30, 2022.

  1. Filtiarn_

    Filtiarn_

    Joined:
    Jan 24, 2013
    Posts:
    173
    I am trying to create 3 textures with each pixel having random color. I have it working on CPU but I am trying to port it to GPU using compute shader. Its not working and my textures are just not being created.

    C#
    Code (CSharp):
    1. //Create world map textures (GPU aka compute shader)
    2.         if (bUseComputeShader)
    3.         {
    4.                 //Create render texture X
    5.                 var rTextureX = new RenderTexture(worldMapTextureSize,worldMapTextureSize, 0, RenderTextureFormat.RFloat)
    6.                 {
    7.                     enableRandomWrite = true
    8.                 };
    9.                 rTextureX.Create();
    10.  
    11.                  //Create render texture Y
    12.                 var rTextureY = new RenderTexture(worldMapTextureSize,worldMapTextureSize, 0, RenderTextureFormat.RFloat)
    13.                 {
    14.                     enableRandomWrite = true
    15.                 };
    16.                 rTextureY.Create();
    17.  
    18.                  //Create render texture Z
    19.                 var rTextureZ = new RenderTexture(worldMapTextureSize,worldMapTextureSize, 0, RenderTextureFormat.RFloat)
    20.                 {
    21.                     enableRandomWrite = true
    22.                 };
    23.                 rTextureZ.Create();
    24.  
    25.                 //Do shader paramaters (0 is kernel index of world textures)(Make sure thread data is exact *8,1,1* as compute shader)
    26.                 computeShader.SetTexture(0, "entityWorldTextureX", rTextureX);
    27.                 computeShader.SetTexture(0, "entityWorldTextureY", rTextureY);
    28.                 computeShader.SetTexture(0, "entityWorldTextureZ", rTextureZ);
    29.                 computeShader.Dispatch(0, worldMapTextureSize / 8, worldMapTextureSize / 8, 1);
    30.  
    31.                 //Create world map texture X
    32.                 worldMapTextureX = new Texture2D(worldMapTextureSize,worldMapTextureSize, TextureFormat.RGB24, false);
    33.                 RenderTexture.active = rTextureX;
    34.                 worldMapTextureX.ReadPixels(new Rect(0, 0,rTextureX.width, rTextureX.height), 0, 0);
    35.                 worldMapTextureX.Apply();
    36.  
    37.                 //Create world map texture y
    38.                 worldMapTextureY = new Texture2D(worldMapTextureSize,worldMapTextureSize, TextureFormat.RGB24, false);
    39.                 RenderTexture.active = rTextureY;
    40.                 worldMapTextureY.ReadPixels(new Rect(0, 0,rTextureY.width, rTextureY.height), 0, 0);
    41.                 worldMapTextureY.Apply();
    42.  
    43.                 //Create world map texture z
    44.                 worldMapTextureZ = new Texture2D(worldMapTextureSize,worldMapTextureSize, TextureFormat.RGB24, false);
    45.                 RenderTexture.active = rTextureZ;
    46.                 worldMapTextureZ.ReadPixels(new Rect(0, 0,rTextureZ.width, rTextureZ.height), 0, 0);
    47.                 worldMapTextureZ.Apply();
    48.         }
    C# Draw Textures
    Code (CSharp):
    1. //Used to debug our world map texture
    2.     void OnGUI()
    3.     {
    4.         if (!bWorldMapGUIEnabled)
    5.             return;
    6.  
    7.         const float size = 128;
    8.         const float margin = 10;
    9.         GUI.DrawTexture(new Rect(0,0,size,size), worldMapTextureX);
    10.         GUI.DrawTexture(new Rect(0,size + margin,size,size), worldMapTextureY);
    11.         GUI.DrawTexture(new Rect(0, size + size + margin + margin,size,size), worldMapTextureZ);
    12.     }

    Compute shader

    Code (CSharp):
    1. RWTexture2D<float4> entityWorldTextureX;
    2. RWTexture2D<float4> entityWorldTextureY;
    3. RWTexture2D<float4> entityWorldTextureZ;
    4.  
    5. [numthreads(8,8,1)]
    6. void CSCreateEntityWorldTextures (uint3 id : SV_DispatchThreadID)
    7. {
    8.      //Set world texture X pixel
    9.     float r = frac(sin(dot(float2(0.1,1),float2(12.9898,78.233)))*43758.5453123);
    10.     float g = frac(sin(dot(float2(0.1,1),float2(12.9898,78.233)))*43758.5453123);
    11.     float b = frac(sin(dot(float2(0.1,1),float2(12.9898,78.233)))*43758.5453123);
    12.     entityWorldTextureX[id.xy] = float4(r,g,b,1);
    13.  
    14.     //Set world texture Y pixel
    15.     r = frac(sin(dot(float2(0.1,1),float2(12.9898,78.233)))*43758.5453123);
    16.     g = frac(sin(dot(float2(0.1,1),float2(12.9898,78.233)))*43758.5453123);
    17.     b = frac(sin(dot(float2(0.1,1),float2(12.9898,78.233)))*43758.5453123);
    18.     entityWorldTextureY[id.xy] = float4(r,g,b,1);
    19.  
    20.      //Set world texture Z pixel
    21.     r = frac(sin(dot(float2(0.1,1),float2(12.9898,78.233)))*43758.5453123);
    22.     g = frac(sin(dot(float2(0.1,1),float2(12.9898,78.233)))*43758.5453123);
    23.     b = frac(sin(dot(float2(0.1,1),float2(12.9898,78.233)))*43758.5453123);
    24.     entityWorldTextureZ[id.xy] = float4(r,g,b,1);
    25. }
     
    Last edited: Mar 30, 2022
  2. Filtiarn_

    Filtiarn_

    Joined:
    Jan 24, 2013
    Posts:
    173
    So I got some results on gpu but not what I want. First I will show cpu results which is what I want.
    you can see 3 random textures being generated on left side screen. Each pixel is just a random color.

    Screen Shot 2022-03-30 at 8.27.14 PM.png

    C#
    Code (CSharp):
    1. //create world map texture X
    2.             var worldMapTexture = new Texture2D(worldMapTextureSize,worldMapTextureSize);
    3.             for (int x = 0; x < worldMapTextureSize; x++)
    4.                 for (int y = 0; y < worldMapTextureSize; y++)
    5.                     worldMapTexture.SetPixel(x,y, UnityEngine.Random.ColorHSV(0.2f, 1f, 0.2f, 1f, 0.2f, 1f));
    6.             worldMapTexture.Apply();
    7.  
    8.             //create world map render texture x from above texture
    9.             worldMapRenderTextureX = new RenderTexture(worldMapTextureSize / 2 ,worldMapTextureSize / 2,0);
    10.             Graphics.Blit(worldMapTexture, worldMapRenderTextureX);
    11.  
    12.             //create world map texture y
    13.              for (int x = 0; x < worldMapTextureSize; x++)
    14.                 for (int y = 0; y < worldMapTextureSize; y++)
    15.                     worldMapTexture.SetPixel(x,y, UnityEngine.Random.ColorHSV(0.2f, 1f, 0.2f, 1f, 0.2f, 1f));
    16.             worldMapTexture.Apply();
    17.  
    18.             //create world map render texture x from above texture
    19.             worldMapRenderTextureY = new RenderTexture(worldMapTextureSize / 2 ,worldMapTextureSize / 2,0);
    20.             Graphics.Blit(worldMapTexture, worldMapRenderTextureY);
    21.  
    22.              //create world map texture y
    23.              for (int x = 0; x < worldMapTextureSize; x++)
    24.                 for (int y = 0; y < worldMapTextureSize; y++)
    25.                     worldMapTexture.SetPixel(x,y, UnityEngine.Random.ColorHSV(0.2f, 1f, 0.2f, 1f, 0.2f, 1f));
    26.             worldMapTexture.Apply();
    27.  
    28.             //create world map render texture x from above texture
    29.             worldMapRenderTextureZ = new RenderTexture(worldMapTextureSize / 2 ,worldMapTextureSize / 2,0);
    30.             Graphics.Blit(worldMapTexture, worldMapRenderTextureZ);
    Now here is gpu results. I am just getting red textures for some reason.

    Screen Shot 2022-03-30 at 8.27.33 PM.png

    Compute shader
    Code (CSharp):
    1. RWTexture2D<float4> entityWorldTextureX;
    2. RWTexture2D<float4> entityWorldTextureY;
    3. RWTexture2D<float4> entityWorldTextureZ;
    4.  
    5. [numthreads(8,1,1)]
    6. void CSCreateEntityWorldTextures (uint3 id : SV_DispatchThreadID)
    7. {
    8.     //rand (is range)
    9.     float2 rand = float2(0,1);
    10.  
    11.     //Set world texture X pixel
    12.     float r = frac(sin(dot(rand .xy, float2(12.9898, 78.233))) * 43758.5453);
    13.     float g = frac(sin(dot(rand .xy, float2(12.9898, 78.233))) * 43758.5453);
    14.     float b = frac(sin(dot(rand .xy, float2(12.9898, 78.233))) * 43758.5453);
    15.     float a = 1;
    16.     entityWorldTextureX[id.xy] = float4(r,g,b,a);
    17.  
    18.     //Set world texture Y pixel
    19.     r = frac(sin(dot(rand .xy, float2(12.9898, 78.233))) * 43758.5453);
    20.     g = frac(sin(dot(rand .xy, float2(12.9898, 78.233))) * 43758.5453);
    21.     b = frac(sin(dot(rand .xy, float2(12.9898, 78.233))) * 43758.5453);
    22.     a = 1;
    23.     entityWorldTextureY[id.xy] = float4(r,g,b,a);
    24.  
    25.     //Set world texture Y pixel
    26.     r = frac(sin(dot(rand .xy, float2(12.9898, 78.233))) * 43758.5453);
    27.     g = frac(sin(dot(rand .xy, float2(12.9898, 78.233))) * 43758.5453);
    28.     b = frac(sin(dot(rand .xy, float2(12.9898, 78.233))) * 43758.5453);
    29.     a = 1;
    30.     entityWorldTextureZ[id.xy] = float4(r,g,b,a);
    31. }
     
  3. Filtiarn_

    Filtiarn_

    Joined:
    Jan 24, 2013
    Posts:
    173
    So the function just does not seem to work at all. Its return all black textures. Not sure what I am doing wrong. Perhaps its numthreads or something?

    Code (CSharp):
    1.  
    2. Compute shader
    3. [numthreads(8,8,1)]
    4. void CSCreateEntityWorldTextures (uint3 id : SV_DispatchThreadID)
    5. {
    6.     //Should be gray
    7.     entityWorldTextureX[id.xy] = float4(0.5, 0.5, 0.5, 1);
    8.  
    9.     //Should be blue
    10.     entityWorldTextureY[id.xy] = float4(0,1,0,1);
    11.  
    12.     //Should be green
    13.     entityWorldTextureZ[id.xy] = float4(0,0,1,1);
    14. }
    C#
    Code (CSharp):
    1. computeShader.Dispatch(0, worldMapTextureSize / 8, worldMapTextureSize / 8, 1);
     
    Last edited: Mar 31, 2022
  4. Neto_Kokku

    Neto_Kokku

    Joined:
    Feb 15, 2018
    Posts:
    1,751
    At glance seems you are creating your render textures as RFloat, which only contain a single channel, but your compute shader expects a texture with four channels. Maybe that's the problem?
     
    Filtiarn_ likes this.
  5. Filtiarn_

    Filtiarn_

    Joined:
    Jan 24, 2013
    Posts:
    173
    Thanks. I got it working. I was creating render texts in C# wrong by typo.

    I had
    Code (CSharp):
    1.  worldMapRenderTextureX = new RenderTexture(worldMapTextureSize,0, worldMapTextureSize);
    Supposed to be
    Code (CSharp):
    1.  worldMapRenderTextureX = new RenderTexture(worldMapTextureSize,worldMapTextureSize,24);
    2.  
    3. Not sure how typo happened when I did it right in CPU version.
    4.  
    5. Thanks anyway.