Search Unity

Compute shader in GLSL?

Discussion in 'Shaders' started by RyuK, Jul 13, 2015.

  1. RyuK

    RyuK

    Joined:
    Feb 12, 2014
    Posts:
    55
    Hello, http://docs.unity3d.com/Manual/ComputeShaders.html says "However, it is also possible to write compute shaders in GLSL by inserting your code between GLSLPROGRAM / ENDGLSL tags." but doesn't exactly tell how to do that. For vertex shaders I add "#ifdef VERTEX", for fragment shaders I add "#ifdef FRAGMENT" but what about compute shaders? I appreciate it too if there's a simple example for a compute shader program in GLSL :)
     
  2. RyuK

    RyuK

    Joined:
    Feb 12, 2014
    Posts:
    55
    Anyone? On Unity 5.1.2f1 I wrote Compute Shader code in HLSL and it ran fine on an Android 5 device, then I put
    #pragma kernel main
    at the top of the .compute file and placed compiled GLSL of the HLSL I used above (Compiled Code you get in the inspector of the compute shader) between GLSLPROGRAM / ENDGLSL tags. Then I built the app, and it's not working though I just used the translated GLSL (#version 310 es at the top) from the working HLSL.
     
  3. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    328
    I am also interested how to write directly GLSL compute shaders in Unity :)
     
  4. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,025
    Hi!
    It should work. Please submit a bugreport if it doesn't.
     
  5. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    328
    Unity Editor set <OpenGL 4.5> and API in Player Settings OpenGLCore.

    *.compute file content:

    Code (CSharp):
    1. GLSLPROGRAM
    2. #pragma kernel main
    3. #version 420
    4. #extension GL_ARB_shading_language_420pack : require
    5. #ifdef GL_ARB_compute_shader
    6. #extension GL_ARB_compute_shader : enable
    7. #endif
    8.  
    9. #ifdef COMPUTE
    10. layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
    11. void main()
    12. {
    13.     return;
    14. }
    15. #endif
    16.  
    17. ENDGLSL
    which should be equivalent to:

    Code (CSharp):
    1. #pragma kernel CSMain
    2.  
    3. [numthreads(8,8,1)]
    4. void CSMain (uint2 id : SV_DispatchThreadID)
    5. {
    6. }
    Error:
    "Compute shader compilation had a problem, your compute shader was not compiled correctly (on glcore)".
     
  6. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,025
    Please submit a bugreport :)
    If you post the bug number here, it will be easier to follow up on it
    Bugreports also contain additional information that might be helpful.
    Thanks!
     
    MadeFromPolygons likes this.
  7. bobozzz

    bobozzz

    Joined:
    May 27, 2015
    Posts:
    38
    It's still not working.. Did anyone file the bug report already?
     
  8. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    328
    Minimal working example with Unity 2022 (code is not optimized, I just show language syntax and setup):

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class ShaderStorageBufferObject : MonoBehaviour
    5. {
    6.     [SerializeField] ComputeShader _ComputeShader;
    7.     [SerializeField] int _Resolution = 1024;
    8.     [SerializeField] FilterMode _FilterMode = FilterMode.Bilinear;
    9.     ComputeBuffer _RWStructuredBuffer, _ConstantBuffer;
    10.     byte[] _Bytes;
    11.     Texture2D _Texture;
    12.  
    13.     void Start()
    14.     {
    15.         _RWStructuredBuffer = new ComputeBuffer(_Resolution * _Resolution, sizeof(float), ComputeBufferType.Structured);
    16.         _ConstantBuffer = new ComputeBuffer(2, sizeof(float), ComputeBufferType.Constant);
    17.         _Bytes = new byte[_Resolution * _Resolution * sizeof(float)];
    18.         _Texture = new Texture2D(_Resolution, _Resolution, TextureFormat.RGBA32, false, false);
    19.         GameObject plane = GameObject.CreatePrimitive(PrimitiveType.Plane);
    20.         Material material = plane.GetComponent<Renderer>().material;
    21.         material.shader = Shader.Find("Sprites/Default");
    22.         material.mainTexture = _Texture;
    23.         _Texture.filterMode = _FilterMode;
    24.     }
    25.  
    26.     void Update()
    27.     {
    28.         _ConstantBuffer.SetData(new float[]{Time.time, (float)_Resolution});
    29.         _ComputeShader.SetConstantBuffer("_UniformBuffer", _ConstantBuffer, 0, 2 * sizeof(float));
    30.         _ComputeShader.SetBuffer(0, "_StorageBuffer", _RWStructuredBuffer);
    31.         _ComputeShader.Dispatch(0, _Resolution / 8, _Resolution / 8, 1);
    32.         _RWStructuredBuffer.GetData(_Bytes);
    33.         _Texture.LoadRawTextureData(_Bytes);
    34.         _Texture.Apply();
    35.     }
    36.  
    37.     void OnDestroy()
    38.     {
    39.         Destroy(_Texture);
    40.         _RWStructuredBuffer.Release();
    41.         _ConstantBuffer.Release();
    42.     }
    43. }
    44.  
    Code (CSharp):
    1. #pragma kernel main
    2.  
    3. GLSLPROGRAM
    4. #version 430
    5. layout (std430, binding = 0) writeonly buffer _StorageBuffer {float mainImage[];};
    6. layout (std140, binding = 0) uniform _UniformBuffer {float iTime; float iResolution;};
    7. layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
    8.  
    9. float RGBAToFloat(vec4 c)
    10. {
    11.     int rgba = (int(c.w * 255.0) << 24) + (int(c.z * 255.0) << 16) + (int(c.y * 255.0) << 8) + int(c.x * 255.0);
    12.     return intBitsToFloat(rgba);
    13. }
    14.  
    15. vec3 Hash(vec2 p )
    16. {
    17.     vec3 q = vec3(dot(p,vec2(127.1,311.7)), dot(p,vec2(269.5,183.3)), dot(p,vec2(419.2,371.9)));
    18.     return fract(sin(q)*43758.5453);
    19. }
    20.  
    21. vec3 Noise(vec2 p)
    22. {
    23.     vec2 i = floor(p);
    24.     vec2 u = p - floor(p);
    25.     u = vec2(u.x*u.x*(3.0-2.0*u.x), u.y*u.y*(3.0-2.0*u.y));
    26.     vec3 res = mix(mix(Hash(i),Hash(vec2(i.x+1.0,i.y)),u.x),mix(Hash(vec2(i.x,i.y+1.0)),Hash(vec2(i.x+1.0,i.y+1.0)),u.x),u.y);
    27.     return res * res;
    28. }
    29.  
    30. vec3 Fbm(vec2 p)
    31. {
    32.     vec3 v = vec3(0.0);
    33.     vec3 a = vec3(0.5);
    34.     for (int i = 0; i < 5; ++i)
    35.     {
    36.         v = v + a * Noise(p);
    37.         p = vec2((0.87 * p.x - 0.48 * p.y),(0.48 * p.x + 0.87 * p.y)) * 2.0;
    38.         a = a * vec3(0.5);
    39.     }
    40.     return v;
    41. }
    42.  
    43. vec3 Pattern (vec2 p, float time)
    44. {
    45.     vec3 q = Fbm(vec2(p.x + 5.0, p.y + 1.0));
    46.     vec3 r = Fbm(vec2(p.x + 4.0 * q.x - time * 0.5, p.y + 4.0 * q.y + time * 0.3));
    47.     return Fbm(vec2(p.x + 8.0 * r.x, p.y + 8.0 * r.z));
    48. }
    49.  
    50. void main()
    51. {
    52.     vec2 fragCoord = gl_GlobalInvocationID.xy;
    53.     vec2 uv = fragCoord.xy / vec2(iResolution);
    54.     vec4 fragColor = vec4(Pattern(uv, iTime), 1.0);
    55.     mainImage[int(iResolution) * gl_GlobalInvocationID.y + gl_GlobalInvocationID.x] = RGBAToFloat(clamp(vec4(fragColor.rgb, 1.0), vec4(0.0), vec4(1.0)));
    56. }
    57. ENDGLSL
     
    Last edited: Oct 10, 2022
    xiaofanlinus likes this.
  9. ScetticoBlu

    ScetticoBlu

    Joined:
    Nov 26, 2020
    Posts:
    21
    For those who care (that post is the only one where I found GLSL example):
    I lost a day around vec3 buffer that, returned to CPU in Vector3 array, got filled with "random" 0.
    I knew it was something related to byte size, in fact here they say vec3s are treated as 16-bytes.
    Solved creating in my compute shader:
    Code (CSharp):
    1. struct MyVec3
    2. {
    3.     float x;
    4.     float y;
    5.     float z;
    6. };
    And using it in my return buffer.
     
    Last edited: Apr 3, 2023