Search Unity

Question StructuredBuffer on Quest 2 with Vulkan and Single Pass Instanced not working?

Discussion in 'Shaders' started by AXGame5, Nov 25, 2022.

  1. AXGame5

    AXGame5

    Joined:
    Oct 1, 2019
    Posts:
    8
    Hey guys,
    I'm trying to use a compute shader on the quest 2 for some material changes. I got it to work on desktop but I have trouble when I use it on the quest, while using Vulkan and Single Pass Instanced as my settings. I could use Multipass to have it work but I would prefer not using the less performant setting if possible.
    Trying it from the editor make it run in the quest, just not when it's an APK build.

    I wasn't able to find other posts with the same issue, only similar cases that got fixed but not wiht fixes that I could apply here. Maybe I'm missing something as I'm still fairly new to shader coding.
    I think I was able to narrow it down to the StructuredBuffer not existing or not working when using it as a Standalone build. The object with the material is still there but not visible to me.

    Thanks for any help in advance

    Code (CSharp):
    1. SubShader
    2.     {
    3.         Tags { "RenderType"="Opaque" }
    4.         LOD 100
    5.  
    6.         Pass
    7.         {
    8.             CGPROGRAM
    9.             #pragma vertex vert
    10.             #pragma fragment frag
    11.          
    12.             #include "UnityCG.cginc"
    13.  
    14.             struct appdata
    15.             {
    16.                 float4 vertex : POSITION;
    17.                 uint id : SV_VertexID;
    18.                 UNITY_VERTEX_INPUT_INSTANCE_ID
    19.             };
    20.  
    21.             struct v2f
    22.             {
    23.                 float4 vertex : SV_POSITION;
    24.                 float4 color : COLOR;
    25.                 UNITY_VERTEX_OUTPUT_STEREO
    26.             };
    27.  
    28.             StructuredBuffer<float4> _ColorBuffer;
    29.  
    30.             v2f vert (appdata v)
    31.             {
    32.            
    33.                 v2f o;
    34.                 UNITY_SETUP_INSTANCE_ID(v);
    35.                 UNITY_INITIALIZE_OUTPUT(v2f, o);
    36.                 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
    37.                 // copy instance id in the appdata v to the v2g o
    38.               //  UNITY_TRANSFER_INSTANCE_ID(v, o);
    39.                 o.vertex = UnityObjectToClipPos(v.vertex);
    40.                
    41.                 o.color = _ColorBuffer[v.id];
    42.               //  o.color = _ColorBuffer[0]; // to test if the color buffer is the issue
    43.  
    44.                
    45.                 return o;
    46.             }
    47.  
    48.             fixed4 frag (v2f i) : SV_Target
    49.             {
    50.                 UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
    51.                 return i.color;
    52.             }
    53.             ENDCG
    54.         }
    55.     }
     
  2. AXGame5

    AXGame5

    Joined:
    Oct 1, 2019
    Posts:
    8
    I was only able to find other people using StructuredBuffer<> and it worked for them, though none were using it in single pass VR cases. I can otherwise only find references to using other compute buffer structures with vulkan but only c++ examples and the used structures aren't valid syntax when I try them. Still not quite sure how the buffer structure could break from changing rendering mode, and I doubt the issue would be in the compute shader since the setup works with opengl. But maybe I'm overlooking something?
    Code (CSharp):
    1. #pragma kernel CSMain
    2.  
    3. StructuredBuffer<float3> _VertexBuffer;
    4. RWStructuredBuffer<float4> _ColorBuffer;
    5. float4x4 _LocalToWorld;
    6. float4 _Sphere;
    7. uint _VertexCount;
    8. float _Intensity;
    9.  
    10. [numthreads(8,8,1)]
    11. void CSMain (uint id : SV_DispatchThreadID)
    12. {
    13.     if (id >= _VertexCount) {
    14.         return;
    15.     }
    16.  
    17.     float3 pos = mul(_LocalToWorld, float4(_VertexBuffer[id], 1.0)).xyz;
    18.     float mask = 1.0 - saturate(distance(pos, _Sphere.xyz) / _Sphere.w);
    19.  
    20.     _ColorBuffer[id] -= float4(mask *(_Intensity), 0, mask*(1- _Intensity), 1) ;
    21.    
    22. }