Search Unity

Global shader variables in compute shaders

Discussion in 'Shaders' started by Atutahi, May 16, 2017.

  1. Atutahi

    Atutahi

    Joined:
    Oct 10, 2016
    Posts:
    4
    Hi there,

    I'm trying to access a global variable (set from C# with Shader.SetGlobal) from inside a Compute Shader.
    Is there any reason this might not work, or am I doing something wrong ?

    Thanks in advance !
     
  2. LukasCh

    LukasCh

    Unity Technologies

    Joined:
    Mar 9, 2015
    Posts:
    102
    Short Answer: No, it should no work with compute.
    Long Answer: Global variables + some of our built-in variables in graphics are actually batched into buffers and bind across all render calls (Of course specifics differs across graphics API), so it means it will have graphics variables in it. As compute shader has nothing common in rendering pipeline there is not actual benefit binding global variables in compute. Also keep in mind that binding buffers is not performance free.

    However what you want to achieve can be easily done with ComputeBuffers (https://docs.unity3d.com/ScriptReference/ComputeBuffer.html).
    So basically how it would look like:
    - Create ComputeBuffer and add there all global variables you might need.
    - Update ComputeBuffer at given time with new values.
    - Every time ComputeShader.Dispatch is used, before that you bind your global buffer with ComputeShader.SetBuffer.

    Also I recommend creating a compute shader include file that will have a signature of you global computebuffer, so you wouldn't need to duplicate it for every compute shader.
    etc.
    MyGlobalVariablesSignature.cginc
    Code (csharp):
    1.  
    2. struct MyGlobalVariables
    3. {
    4. ...
    5. };
    6. RWStructuredData<MyGlobalVariables> _MyGlobalVeriables;
    7.  
     
    Lyrcaxis and AverageCG like this.
  3. Nihil688

    Nihil688

    Joined:
    Mar 12, 2013
    Posts:
    503
    I actually had a similar question which ties to your answer @LukasCh Im using a global variable in a shader but it doesn't seem to work on Samsung S6 but works fine on S7 and PC, etc. Both support Shader model 3.0 right so is there anything else I should check for specifics in graphics API to find the root of the issue?
     
  4. Atutahi

    Atutahi

    Joined:
    Oct 10, 2016
    Posts:
    4
    Thanks @LukasCh for clearing this up !
     
  5. Johannski

    Johannski

    Joined:
    Jan 25, 2014
    Posts:
    826
    Uh awesome to get a bit more information about global shader variables! I'm wondering if it is possbile to profile them in any way (Or if they show up in the profiler). I'm using them quite a lot and I'm wondering how to see its performance overhead. Or is there a resource you can point me at @LukasCh ?
     
  6. LukasCh

    LukasCh

    Unity Technologies

    Joined:
    Mar 9, 2015
    Posts:
    102
    Yea I checked so the only difference is gpu generation (Only compared GPUs), so there shouldn't be any obvious limitations. Its a bit hard for me to guess the issue with this little information, so basically if this only s6 issue, I really recommend reporting the bug for it (Also it always healthy to check for regression - easiest way to identify bug without any technical information).

    I think your best bet is to use third party GPU debug tools (As you will get all the information). However keep in mind that it will depend from your platform:
    - On windows its kind a easy as its embedded in visual studio.
    - Same ^ for apple platforms.
    - With android its a bit tricky, because of vast variation of GPU vendors and as far as I know there is no universal tool for them.
     
  7. strich

    strich

    Joined:
    Aug 14, 2012
    Posts:
    375
    For anyone who might have been wondering - You can share global textures between shaders and compute shaders. Which means you can pass around any arbitrarily large amounts of data you want.

    Code (CSharp):
    1.  
    2.         control1= new RenderTexture(2048, 2048, 0,
    3.         RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear);
    4.         control1.enableRandomWrite = true;
    5.         control1.Create();
    6.         control1.SetGlobalShaderProperty("_MyGlobalControlMap");
    7.  
    8.         myComputeShader.SetTextureFromGlobal(_kernelHandle, "ControlMap", "_MyGlobalControlMap");
    9.  
     
  8. Nihil688

    Nihil688

    Joined:
    Mar 12, 2013
    Posts:
    503
    After lot's of checking, it wasn't the phone that wasn't working it was the operating system. Marshmallow didn't work ok with global variables in shaders whereas Nougat was ok
     
  9. wechat_os_Qy06eaOhICF9NcZoMWMLtv5cI

    wechat_os_Qy06eaOhICF9NcZoMWMLtv5cI

    Joined:
    Feb 1, 2018
    Posts:
    33
    Any documents on those built-in variables and cbuffer?I think UNITY_MATRIX_M or P or VP ,those variables are all in CBUFFER.But who is who ?for example cbuffer 0 means which variable?Where can I found documents ?