Search Unity

How StructuredBuffer can be used in shaders for Android?

Discussion in 'Shaders' started by kraihd, May 20, 2018.

  1. kraihd

    kraihd

    Joined:
    Sep 10, 2015
    Posts:
    9
    When I use StructuredBuffer in shaders for Android, they always draw objects purple, and their Shader.isSupported return false.
    My Android device supports OpenGL ES 3.2, and SystemInfo.supportsComputeShaders returns true, though.
    Of course it passes target 4.5. Drawing fails only if the shader contains StructuredBuffer.
    I tried to turn on Requires ES 3.1 check at player settings, which had no effect.
    What is the way to make them work?

    These are the codes:
    Code (CSharp):
    1. Shader "TestShader" {
    2.     Properties{
    3.         _MainTex("Texture", 2D) = "white" {}
    4.     }
    5.  
    6.     Category{
    7.         Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" }
    8.         Blend SrcAlpha OneMinusSrcAlpha
    9.         Cull Off
    10.         Lighting Off
    11.         ZWrite On
    12.         ZTest On
    13.      
    14.         SubShader{
    15.             Pass{
    16.                 CGPROGRAM
    17.                 #pragma vertex vert
    18.                 #pragma fragment frag
    19.                 #pragma target 4.5
    20.  
    21.                 #include "UnityCG.cginc"
    22.  
    23.                 sampler2D _MainTex;
    24.                 StructuredBuffer<float> _Colors;
    25.  
    26.                 struct appdata_t {
    27.                     float4 vertex : POSITION;
    28.                     float2 texcoord : TEXCOORD0;
    29.                 };
    30.  
    31.                 struct v2f {
    32.                     float4 vertex : SV_POSITION;
    33.                     float2 texcoord : TEXCOORD0;
    34.                     float4 color : TEXCOORD1;
    35.                 };
    36.  
    37.                 v2f vert(appdata_t v) {
    38.                     v2f o;
    39.                     o.vertex = UnityObjectToClipPos(v.vertex);
    40.                     o.texcoord = v.texcoord;
    41.                     o.color = float4(_Colors[0], _Colors[1], _Colors[2], 1);
    42.                     return o;
    43.                 }
    44.  
    45.                 fixed4 frag(v2f i) : SV_Target {
    46.                     float4 color = tex2D(_MainTex, i.texcoord) * i.color;
    47.                     clip(color.a - 0.001);
    48.                     return color;
    49.                 }
    50.  
    51.                 ENDCG
    52.             }
    53.         }
    54.     }
    55. }
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class TestComponent : MonoBehaviour {
    4.     ComputeBuffer buffer;
    5.     float[] array;
    6.     float time;
    7.  
    8.     void Start() {
    9.         buffer = new ComputeBuffer(4, sizeof(float));
    10.  
    11.         var mr = GetComponent<MeshRenderer>();
    12.         mr.material.SetBuffer("_Colors", buffer);
    13.  
    14.         array = new float[3];
    15.     }
    16.  
    17.     void Update() {
    18.         time += Time.deltaTime;
    19.         if (time > 0.1f) {
    20.             array[0] = Random.Range(0.5f, 1f);
    21.             array[1] = Random.Range(0.5f, 1f);
    22.             array[2] = Random.Range(0.5f, 1f);
    23.             buffer.SetData(array);
    24.             time -= 0.1f;
    25.         }
    26.     }
    27.  
    28.     void OnDestroy() {
    29.         buffer.Release();
    30.     }
    31.  
    32.     void OnGUI() {
    33.         var mr = GetComponent<MeshRenderer>();
    34.         GUILayout.Label("ComputeShader is supported: " + SystemInfo.supportsComputeShaders.ToString());
    35.         GUILayout.Label("This shader is supported: " + mr.sharedMaterial.shader.isSupported.ToString());
    36.     }
    37. }
     
    Last edited: May 20, 2018
  2. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    755
    Hi!
    Most likely your device doesn't support StructuredBuffers in vertex shaders. It's not a requirement for OpenGL ES 3.1+ to have it.
    Using them in fragment shaders would be fine, though.
     
    pcysl5edgo, ecidevilin and kraihd like this.
  3. kraihd

    kraihd

    Joined:
    Sep 10, 2015
    Posts:
    9
    Thanks for the information!
     
  4. DocTatur

    DocTatur

    Joined:
    Aug 13, 2015
    Posts:
    1
    Hello , I have a similar issue and I want to be sure it's not a player setting probleme or else :
    I am working on android note 8, OpenGL ES3.2, I use computebuffers in a shader for DrawMeshInstancedIndirect to draw several colored spheres.
    and I have the following error read in adb shell:
    "GLSL link error: The number of vertex shader storage blocks is greater than the maximum number allowed
    and of course nothing of what I want to show appears on the screen"

    Is it my device which lack computebuffer support or a software pb ?
    What can I do to replace my current solution to adapt for Android devices to draw many spheres without the DrawMeshInstancedIndirect and vertex shader , which works great on pc?
    thanks for you help !
     
  5. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    755
    @DocTatur yes, this is the same thing. Basically, many devices support 0 SSBOs in VS.