Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Compute shader - assigning data to be processed.

Discussion in 'Shaders' started by _OskaR, Sep 1, 2013.

  1. _OskaR

    _OskaR

    Joined:
    Aug 9, 2013
    Posts:
    1
    I have read:
    http://forum.unity3d.com/threads/148874-Compute-Shaders
    http://docs.unity3d.com/Documentation/Manual/ComputeShaders.html
    and I have some questions:
    1. Will it work for non-Pro version? I can create CS but for example OnRenderImage func is not available.
    2. How to assign texture (or mesh data etc.) to compute shader? I see that we have creating new texture - so also new data in the memory. Is it needed? Do I have to use string related to texture name in my assets browser or sth different?
    3. If I have multiple compute shaders and meshes, how often per frame will be switched context GPGPU/rendering? Will be executed all compute shaders then rendered all data or not?

    ________________________________________________

    Looks like it doesn't work a little bit better - I forgot to drag and drop the script. Now it has been executed but not evertything is good.

    Well known kernel:
    Code (csharp):
    1. #pragma kernel FillWithRed
    2.  
    3. RWTexture2D<float4> Result;
    4.  
    5. [numthreads(4,4,1)]
    6.  
    7. void FillWithRed(uint3 dtid : SV_DispatchThreadID)
    8. {
    9.     Result[dtid.xy] = float4(1.0,0.0,0.0,1.0);
    10. }
    The script:
    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class FillWithRed : MonoBehaviour
    5. {
    6.     public int width = 128;
    7.     public int height = 128;   
    8.     public ComputeShader compute;
    9.     private bool created = false;
    10.     private RenderTexture output;
    11.    
    12.     private void Init()
    13.     {
    14.         if(created)
    15.         {
    16.             return;
    17.         }
    18.         else
    19.         {
    20.             if (!SystemInfo.supportsComputeShaders)
    21.             {
    22.                 Debug.LogWarning ("supportsComputeShaders fail");
    23.                 return;
    24.             }
    25.             Debug.Log("init FillWithRed");
    26.             output = new RenderTexture (width, height, 0, RenderTextureFormat.ARGB32);
    27.             output.enableRandomWrite = true;
    28.             output.Create();
    29.             created = true;
    30.         }
    31.     }
    32.    
    33.     void Start ()
    34.     {
    35.         Debug.Log("start FillWithRed");
    36.         Init ();       
    37.     }
    38.    
    39.     void Update ()
    40.     {
    41.         if(created)
    42.         {
    43.             compute.SetTexture (0, "Result", output);
    44.             compute.Dispatch(0,4,4,1);
    45.             renderer.material.SetTexture("_MainTex",output);
    46.         }
    47.         else
    48.         {
    49.             Debug.Log("texture not created");
    50.         }
    51.     }  
    52. }
    If I remove the line
    Code (csharp):
    1. renderer.material.SetTexture("_MainTex",output);
    I will see no changes (textured and shader mesh) - sounds "ok" because I will change separate data only which will be not in use by renderer. But if I leave it - my mesh is grey (shaded only). :x
     
    Last edited: Sep 1, 2013
  2. FurryFur

    FurryFur

    Joined:
    Jun 30, 2013
    Posts:
    7
    The RenderTexture class is also not available in the non-Pro version. You could probably work around this by using a compute buffer instead which, as far as I can tell from the doc, will work in the free version. There are a lot of alternatives to the OnRenderImage event handler, have a look at the rendering section of this docs page http://docs.unity3d.com/Documentation/Manual/ExecutionOrder.html

    You can use compute.SetTexture or compute.SetBuffer to set texture data and generic data (using compute buffers) on the compute shader. You can use Resources.Load to load textures into your script, check the docs for details on how to use it. I'm not sure what you mean by the second part of this question.. . Any textures need to be created once only so the memory impact shouldn't be a problem.

    They will probably be interleaved, something like foreach gameObject call Update then render stuff. All shaders including compute shaders use the same hardware shader units so I don't think this will be a problem. What you really want to limit is the total number of draw/GPGPU calls.

    I'm not an expert on compute shaders but it seems to me that in your code you have a RenderTexture which is 128x128 but your compute shader is only executing 4x4 threads and only filling the top 4x4 pixels of the RenderTexture. Still, I would expect it to at least change the rest of the texture to black so I'm not sure.