Search Unity

Shader is not supported on this GPU (none of subshaders/fallbacks are suitable)

Discussion in 'Shaders' started by stephenl_unity, Nov 8, 2018.

  1. stephenl_unity

    stephenl_unity

    Joined:
    Jun 11, 2018
    Posts:
    8
    Hi guys,
    I'm working on a VR project that uses a custom shader to achieve the effect shown in the attached image. This works perfectly on the Vive and Oculus Rift, however when I do an Android build for the Vive Focus, I am getting a "Shader is not supported on this GPU (none of subshaders/fallbacks are suitable)" warning.

    Im unsure as to what part of the shader is causing this issue and any help would be appreciated.

    Android build
    Graphics API - OPENGLES3



    Code (CSharp):
    1.  
    2.  
    3. Shader "DepthKit/VestigeLines"
    4. {
    5.     Properties
    6.     {
    7.         _Sprite     ("Texture", 2D) = "white" {}
    8.         _UseSprite     ("Use Sprite", Float) = 0.0
    9.         _Width         ("Width", Float) = 1.0
    10.         _Opacity     ("Opacity", Range(0,1)) = 1.0
    11.  
    12.         //NOTE: These are set per material, not per layer, as they cannot be controlled by the MaterialPropertyBlock
    13.         _SrcMode      ("Blend Src Mode", Float) = 0.0
    14.         _DstMode      ("Blend Dst Mode", Float) = 0.0
    15.         _ZTest ("Depth Compare Mode", Int) = 0
    16.  
    17.         _BlendEnum("Blend Enum", Float) = 0.0
    18.  
    19.         // Distortion settings
    20.         _Frequency("Frequency", Float) = 0
    21.         _FrequencyX("FrequencyX", Float) = 0
    22.         _FrequencyY("FrequencyY", Float) = 0
    23.         _FrequencyZ("FrequencyZ", Float) = 0
    24.         _Amplitude("Amplitude", Float) = 0
    25.         _AmplitudeX("AmplitudeX", Float) = 0
    26.         _AmplitudeY("AmplitudeY", Float) = 0
    27.         _AmplitudeZ("AmplitudeZ", Float) = 0
    28.         _DistortionAmount("Distortion Amount", Range(0.0,1.0)) = 1
    29.         [Toggle]_EnableDistortionRange("Enable Distortion Range", Float) = 0.0
    30.         _DistortionRange("Distortion Range", Range(0.0, 1000.0)) = 10
    31.         _DistortionCenter("Distortion Center", Vector) = (0.0,0.0,0.0,1.0)
    32.  
    33.         // Explode settings
    34.         _ExplodeDistance("Explode Distance", Range(0.0,1000.0)) = 10
    35.         _ExplodeRange("Explode Range", Range(0.0, 1000.0)) = 10
    36.         _ExplodeAmount("Explode Amount", Range(0.0,1.0)) = 1
    37.         _ExplodeCenter("Explode Center", Vector) = (0.0,0.0,0.0,1.0)
    38.  
    39.         // Dissolve settings
    40.         _DissolveTexture("Dissolve Texture (RGB)", 2D) = "white" {}
    41.         _DissolveAmount("Dissolve Amount", Range(0.0, 1.0)) = 0.5
    42.  
    43.         // Burn settings
    44.         _BurnSize("Burn Size", Range(0.0, 1.0)) = 0.15
    45.         _BurnTexture("Burn Texture (RGB)", 2D) = "white" {}
    46.     }
    47.  
    48.     SubShader
    49.     {
    50.         // All hologram shaders are rendered in the transparency pass, with no shadowing
    51.         Tags { "Queue"="Transparent+1" "RenderType"="Transparent" "IgnoreProjector"="True" "ForceNoShadowCasting" ="True" }
    52.         LOD 100
    53.  
    54.         Blend [_SrcMode] [_DstMode]
    55.         ZWrite Off
    56.         Cull Off
    57.         ZTest [_ZTest]  // self occlusion if ztest is set to LEQUAL
    58.         Offset -128, -1 // large bias to camera to ensure our lines do not fail depth test when co-planar with depth
    59.  
    60.         Pass
    61.         {
    62.             CGPROGRAM
    63.  
    64.             #pragma exclude_renderers d3d11_9x
    65.             #pragma vertex vert
    66.             #pragma fragment frag
    67.             #pragma geometry geom
    68.             #pragma multi_compile_fog
    69.             #pragma glsl
    70.  
    71.             #include "UnityCG.cginc"
    72.             #include "../../../DepthKit/Renderers/Resources/DepthKit.cginc"
    73.  
    74.             struct appdata
    75.             {
    76.                 float4 vertex : POSITION;
    77.                 float2 uv : TEXCOORD0;
    78.             };
    79.  
    80.             struct v2g
    81.             {
    82.                 float2 uv : TEXCOORD0;
    83.                 float4 vertex : SV_POSITION;
    84.                 DEPTHKIT_TEX_COORDS(1, 2, 3)    // reserve texcoords/interpolants 1-3 for depthkit use
    85.                 UNITY_FOG_COORDS(4)                // if Unity distance fogging enabled
    86.                 float2 uv_DissolveTexCoords : TEXCOORD5;
    87.             };
    88.  
    89.             sampler2D _Sprite;
    90.             float4 _Sprite_ST;
    91.  
    92.             //Creates the necessary declarations for DK textures
    93.             DEPTHKIT_TEX_ST
    94.  
    95.             float _UseSprite;
    96.             float _Width;
    97.             float _Opacity;
    98.             float _BlendEnum;
    99.  
    100.             float _Frequency;
    101.             float _FrequencyX;
    102.             float _FrequencyY;
    103.             float _FrequencyZ;
    104.             float _Amplitude;
    105.             float _AmplitudeX;
    106.             float _AmplitudeY;
    107.             float _AmplitudeZ;
    108.             float _DistortionAmount;
    109.             float _EnableDistortionRange;
    110.             float _DistortionRange;
    111.             float4 _DistortionCenter;
    112.  
    113.             float _ExplodeDistance;
    114.             float _ExplodeRange;
    115.             float _ExplodeAmount;
    116.             float4 _ExplodeCenter;
    117.  
    118.             sampler2D _DissolveTexture;
    119.             float _DissolveAmount;
    120.  
    121.             sampler2D _BurnTexture;
    122.             float _BurnSize;
    123.  
    124.  
    125.             bool IsVertexWithinDistortionRange(float4 vertex) {
    126.                 float4 worldSpaceVertexPosition = mul(unity_ObjectToWorld, vertex);
    127.  
    128.                 float3 direction = worldSpaceVertexPosition.xyz - _DistortionCenter.xyz;
    129.                 float distanceFromEpicenter = length(direction);
    130.  
    131.                 return (distanceFromEpicenter <= _DistortionRange);
    132.             }
    133.  
    134.             v2g vert (appdata v)
    135.             {
    136.                 v2g o;
    137.                 UNITY_INITIALIZE_OUTPUT(v2g,o);
    138.  
    139.                 float2 colorTexCoord;
    140.                 float2 depthTexCoord;
    141.                 float4 vertOut;
    142.  
    143.                 dkVertexPass(v.vertex, colorTexCoord, depthTexCoord, vertOut, o.valid);
    144.  
    145.                 bool applyDistortion = (_EnableDistortionRange == 0.0f ? true : IsVertexWithinDistortionRange(vertOut));
    146.  
    147.                 float distortionOffsetX = (applyDistortion ? (_DistortionAmount * (sin(_Time.y * _Frequency + vertOut.y * _FrequencyX) * _AmplitudeX * _Amplitude)) : 0.0f);
    148.                 float distortionOffsetY = (applyDistortion ? (_DistortionAmount * (sin(_Time.y * _Frequency + vertOut.z * _FrequencyY) * _AmplitudeY * _Amplitude)) : 0.0f);
    149.                 float distortionOffsetZ = (applyDistortion ? (_DistortionAmount * (sin(_Time.y * _Frequency + vertOut.x * _FrequencyZ) * _AmplitudeZ * _Amplitude)) : 0.0f);
    150.  
    151.                 vertOut.x += distortionOffsetX;
    152.                 vertOut.y += distortionOffsetY;
    153.                 vertOut.z += distortionOffsetZ;
    154.  
    155.                 o.vertex = mul(unity_ObjectToWorld, vertOut);
    156.                 o.uv = v.uv;
    157.                 o.uv_MainTex   = colorTexCoord;
    158.                 o.uv2_MainTex2 = depthTexCoord;
    159.  
    160.                 UNITY_TRANSFER_FOG(o, vertOut);
    161.                 o.uv_DissolveTexCoords = colorTexCoord;
    162.  
    163.                 return o;
    164.             }
    165.  
    166.             [maxvertexcount(4)]
    167.             void geom(line v2g input[2], inout TriangleStream<v2g> OutputStream)
    168.             {
    169.                 // remove connector lines between line segments in linestrip
    170.                 if(input[0].uv.x == 1.0 && input[1].uv.x == 1.0){
    171.                     return;
    172.                 }
    173.  
    174.                 v2g output;
    175.                 UNITY_INITIALIZE_OUTPUT(v2g, output);
    176.  
    177.                 // get the worldspace direction down the line
    178.                 float3 lineLook = input[1].vertex.xyz - input[0].vertex.xyz;
    179.                 float4 explodeOffset;
    180.                 float3 lineMidPoint = input[0].vertex.xyz + (lineLook * 0.5f);
    181.                 float3 direction = lineMidPoint - _ExplodeCenter.xyz;
    182.                 float3 explodeDirection = normalize(direction);
    183.                 float distanceFromEpicenter = length(direction);
    184.                 //float rangeScale = saturate(distanceFromEpicenter / );
    185.                 float rangeTime = (distanceFromEpicenter <= _ExplodeRange ? 1.0f : 0.0f);
    186.                 float3 explodeScale = ((explodeDirection * _ExplodeDistance) * _ExplodeAmount);
    187.  
    188.                 // output a stretched quad as the line segment, 2 x 2 verts, orientated towards the camera
    189.                 for(int i = 0; i < 2; i++)
    190.                 {
    191.                     //direction from camera to this object
    192.                     float3 cameraLook = _WorldSpaceCameraPos.xyz - input[i].vertex.xyz;
    193.  
    194.                     //billboard direction is orthogonal to both line & camera
    195.                     float3 up = normalize(cross(cameraLook, lineLook));
    196.  
    197.                     output.valid = input[i].valid;
    198.  
    199.                     float4 vert0 = float4(input[i].vertex.xyz + (up * _Width), 1.0);
    200.  
    201.                     //explodeDirection = normalize(input[i].vertex.xyz - _ExplodeCenter.xyz);
    202.                     //explodeOffset = float4((input[i].vertex.xyz + explodeScale), 1.0f);
    203.                     //explodeOffset = float4(lerp(float3(0.0f, 0.0f, 0.0f), float3(input[i].vertex.xyz + explodeScale), 0.0f), 1.0f);
    204.                     explodeOffset = float4(lerp(input[i].vertex.xyz, float3(input[i].vertex.xyz + explodeScale), rangeTime), 1.0f);
    205.                     vert0 += explodeOffset;
    206.  
    207.                     output.vertex = mul(UNITY_MATRIX_VP, vert0);
    208.  
    209.  
    210.                     output.uv = float2(i == 0 ? 1.0 : 0.0, 1.0);
    211.                     output.uv_MainTex   = input[i].uv_MainTex;
    212.                     output.uv2_MainTex2 = input[i].uv2_MainTex2;
    213.                     output.uv_DissolveTexCoords = input[i].uv_DissolveTexCoords;
    214.  
    215.                     OutputStream.Append(output);
    216.  
    217.                     float4 vert1 = float4(input[i].vertex.xyz - (up * _Width), 1.0);
    218.  
    219.                     //explodeDirection = normalize(input[i].vertex.xyz - _ExplodeCenter.xyz);
    220.                     //explodeOffset = float4((input[i].vertex.xyz + explodeScale), 1.0f);
    221.                     //explodeOffset = float4(lerp(float3(0.0f,0.0f,0.0f), float3(input[i].vertex.xyz + explodeScale), 0.0f), 1.0f);
    222.                     explodeOffset = float4(lerp(input[i].vertex.xyz, float3(input[i].vertex.xyz + explodeScale), rangeTime), 1.0f);
    223.                     vert1 += explodeOffset;
    224.  
    225.                     output.vertex = mul(UNITY_MATRIX_VP, vert1);
    226.                     output.uv = float2(i == 0 ? 1.0 : 0.0, 0.0);
    227.                     output.uv_MainTex   = input[i].uv_MainTex;
    228.                     output.uv2_MainTex2 = input[i].uv2_MainTex2;
    229.                     output.uv_DissolveTexCoords = input[i].uv_DissolveTexCoords;
    230.  
    231.                     OutputStream.Append(output);
    232.                 }
    233.             }
    234.  
    235.             fixed4 frag (v2g i) : SV_Target
    236.             {
    237.                 float4 dkColor;
    238.                 dkFragmentPass(i.uv2_MainTex2, i.uv_MainTex, dkColor, i.valid);
    239.  
    240.                 clip(i.valid > 0.0 ? 0 : -1);
    241.  
    242.                 // Do dissolve clipping
    243.                 clip(tex2D(_DissolveTexture, i.uv_DissolveTexCoords).rgb - _DissolveAmount);
    244.  
    245.                 // sample the texture
    246.                 float4 spriteCol = lerp(fixed4(1.0,1.0,1.0,1.0), tex2D(_Sprite, i.uv), _UseSprite);
    247.  
    248.                 float4 finalCol;
    249.                 finalCol.rgb = spriteCol.rgb * dkColor.rgb;
    250.                 finalCol.a = 1.0;
    251.  
    252.                 if (_DissolveAmount > 0.0f &&
    253.                     _DissolveAmount < 1.0f) {
    254.                     // Apply burn effect to dissolve edge
    255.                     half test = tex2D(_DissolveTexture, i.uv_DissolveTexCoords).rgb - _DissolveAmount;
    256.                     if (test < _BurnSize) {
    257.                         float4 burnColour = tex2D(_BurnTexture, float2(test *(1 / _BurnSize), 0));
    258.                         finalCol = burnColour;
    259.                     }
    260.                 }
    261.  
    262.  
    263.                 // note; BLEND_MULTIPLY has a known issue with respecting transparency on sprites.
    264.                 if (_BlendEnum == BLEND_ALPHA || _BlendEnum == BLEND_MULTIPLY)
    265.                 {
    266.                     finalCol.a *= spriteCol.a * _Opacity;
    267.                 }
    268.                 else if (_BlendEnum == BLEND_ADD || _BlendEnum == BLEND_SCREEN)
    269.                 {
    270.                     finalCol.rgb *= spriteCol.a * _Opacity;
    271.                 }
    272.  
    273.                 // apply fog
    274.                 UNITY_APPLY_FOG(i.fogCoord, finalCol);
    275.  
    276.                 return finalCol;
    277.             }
    278.             ENDCG
    279.         }
    280.     }
    281. }
    282.  
     

    Attached Files:

  2. LennartJohansen

    LennartJohansen

    Joined:
    Dec 1, 2014
    Posts:
    2,394
    Hi.

    I think your #pragma geometry geom will force the shader model to 4.0 and that is not supported by OpenGL ES3.

    You need OpenGL ES 3.1+AEP to support shader model 4.0

    Have a look here

    Lennart
     
  3. stephenl_unity

    stephenl_unity

    Joined:
    Jun 11, 2018
    Posts:
    8
    Hi Lenanrt,
    Thanks for the response. I've read the documentation you've linked and have tried to solve the issue, but I don't know if I am approaching it wrong. In my Player Settings, under the Graphics API heading, I have OPENGLES3 selected. When I try and add additional graphics API's my only other options are OPENGLES2 and Vulkan.

    Can I add OPENGLES3.1 + AEP or are these options pre-determined by my selected build platform? Is ticking the "Require AES 3.1" tickbox all I need to do?

    Apologies if this is a stupid question. I understand that you are saying by having OPENGLES3 selected, the target 4.0 (set by the use of #pragma geometry) is not supported, I just don't know how to actually change my graphics api to use the 3.1 AES version that supports the 4.0 target.

    Any direction you can provide would be fantastic.
     
  4. LennartJohansen

    LennartJohansen

    Joined:
    Dec 1, 2014
    Posts:
    2,394
    I am not really sure. I think the checkbox should be enough, but I do not do any mobile development and have not tested.

    Lennart
     
  5. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    https://docs.unity3d.com/Manual/class-PlayerSettingsAndroid.html
    Alternatively, try removing OpenGL entirely and just use Vulkan.
     
  6. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,014
    That'll work if the driver implements geometry shaders, which is not guaranteed.
     
  7. stephenl_unity

    stephenl_unity

    Joined:
    Jun 11, 2018
    Posts:
    8
    Hi, thanks for the reply. I didn't realize that having the Auto Select API tickbox checked automatically tries for GLES3.1.
    I have tried with Vulkan only and the build doesn't run. It crashes instanty and never launches from the Vive Focus.
     
  8. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,014
    I don't know about Vive Focus, but usually there's a possibility to get some logs from Android devices :)
    You should check those.

    When you have Auto Graphics API, it will try in sequence OpenGL ES 3.2 (since 2018.3, I think), 3.1 AEP, 3.1, 3.0 and 2.0. If any os those succeeds, it stops and says "this is the one I'm going to use".
    If Vive Focus doesn't have OpenGL ES 3.1 AEP or 3.2 support, geometry shaders will not work.