Geometry shader not working on Debian10 GL3.3 SM5

Hi all !

I got pain with geometry shaders.
When targetting my app to linux, they simply do nothing.

For example this one:

Shader "My_shaders/MyStdLitmap_transition"
{
    Properties {
        [NoScaleOffset] _MainTex ("Diffuse Texture", 2D) = "white" {}
      [NoScaleOffset] _DirtLMTex ("Dirt/AO-LM (RGB-A)", 2D) = "(RGBA: .98,.98,.98,1)" {} // bidouille: presque 1 pour eviter les effets de bord....
      _NightLightColor ("Lightmap color", Color) = (1,1,1,1)
        [NoScaleOffset] _BumpMap ("Normal Texture", 2D) = "bump" {}

        _TransitionDist("Transition dist", Float) = 100
    }
    SubShader {
        Pass{
            Tags { "LightMode" = "ForwardBase" }
            CGPROGRAM
        
         #pragma require geometry

         // my variants....
         #pragma multi_compile_local ___ WITH_CITY_NIGHTLIGHTS

            #pragma vertex vertex_program
         #pragma geometry geometry_program
         #pragma fragment fragment_program

         #pragma multi_compile_fog

         #pragma multi_compile_fwdbase nolightmap nodirlightmap nodynlightmap novertexlight


         #include "Lighting.cginc"
         #include "AutoLight.cginc"
           
            // My vars
            sampler2D _MainTex;
            sampler2D _BumpMap;
            sampler2D _DirtLMTex;
         static const half _BumpDistFade=20;
         static const half _BumpLengthFade=5;
         static const half _TransitionColorSpread=4;
         static const half _TransitionMessFactor=10;
         half _TransitionDist;
        
#if defined(WITH_CITY_NIGHTLIGHTS)
         fixed4 _NightLightColor;
#endif


            // Base Input Structs
            struct APP2V {
                float4 vertex: POSITION;
                half3 normal: NORMAL;
                half4 UV0: TEXCOORD0;
                half4 UV1: TEXCOORD1;
                half4 tangent: TANGENT;
            };
        
            struct V2G {
                float4 pos: SV_POSITION;
                half4 UV0: TEXCOORD0;
                half4 UV1: TEXCOORD1;
                half4 posWorld: TEXCOORD2;
                half3 normalWorld: TEXCOORD3;
                half3 tangentWorld: TEXCOORD4;
                half3 binormalWorld: TEXCOORD5;
            UNITY_FOG_COORDS(6) // fog in 6
//#if defined (SHADOWS_SCREEN)
//            SHADOW_COORDS(7) // shadows data into TEXCOORD7
            unityShadowCoord4 _ShadowCoord : TEXCOORD7;
//#endif   
   
            };

            struct G2F {
                float4 pos: SV_POSITION;
                half4 UV0: TEXCOORD0;
                half4 UV1: TEXCOORD1;
                half4 posWorld: TEXCOORD2;
                half3 normalWorld: TEXCOORD3;
                half3 tangentWorld: TEXCOORD4;
                half3 binormalWorld: TEXCOORD5;
            UNITY_FOG_COORDS(6) // fog in 6
            unityShadowCoord4 _ShadowCoord : TEXCOORD7;
            half fade_factor: COLOR0; // transition IN/OUT fade to ambient factor
            };




   
         inline float random11(float p)
         {
             p = frac(p * .1031);
             p *= p + 33.33;
             p *= p + p;
             return((frac(p)-0.5)*2); //-1 to +1
         }
         inline half2 random21(float p)
         {
            half3 p3 = frac(float3(p,p,p) * half3(.1031, .1030, .0973));
            p3 += dot(p3, p3.yzx + 33.33);
            return frac((p3.xx+p3.yz)*p3.zy);
         } 
         //========================================================================

           
            // Vertex program
            V2G vertex_program( APP2V v )
         {
                V2G o;
               
                o.normalWorld = normalize( mul( float4( v.normal, 0.0 ), unity_WorldToObject ).xyz );       
                o.tangentWorld = normalize( mul( unity_ObjectToWorld, v.tangent ).xyz );
                o.binormalWorld = normalize( cross( o.normalWorld, o.tangentWorld )* v.tangent.w);
                       

                o.posWorld = mul( unity_ObjectToWorld, v.vertex);
                o.pos = v.vertex;//UnityObjectToClipPos( v.vertex);
                o.UV0 = v.UV0;
                o.UV1 = v.UV1;

#if defined (UNITY_NO_SCREENSPACE_SHADOWS)
            TRANSFER_SHADOW(o)
#else
            o._ShadowCoord = ComputeScreenPos(UnityObjectToClipPos( v.vertex));
#endif

            UNITY_TRANSFER_FOG(o,o.pos);

                return o;
            }
        
        
         [maxvertexcount(3)]
         void geometry_program(triangle V2G IN[3], inout TriangleStream<G2F> triStream)
         {
            G2F o;
            half4 displace_effect;

            half3 a= half3(random11(IN[0].posWorld),random11(IN[1].posWorld),random11(IN[2].posWorld));
  
            float3 tri_in_cam = _WorldSpaceCameraPos.xyz - (IN[0].posWorld.xyz+IN[1].posWorld.xyz+IN[2].posWorld.xyz)/3;
            half tri_dist = length(tri_in_cam);
           


            // quand TransitionDist < 0 on inverse le mess far/near
            // idem plus bas pour le fade au blanc....
            if(_TransitionDist >= 0.0)
               displace_effect = half4(a.xyz*_TransitionMessFactor*clamp(sqrt(tri_dist)-_TransitionDist,0,10),0);
            else
               displace_effect = half4(a.xyz*_TransitionMessFactor*clamp(-_TransitionDist-sqrt(tri_dist),0,10),0);

            for(int i = 0; i < 3; i++)
            {
               o.posWorld=IN[i].posWorld;
               o.normalWorld=IN[i].normalWorld;
               o.tangentWorld=IN[i].tangentWorld;
               o.binormalWorld=IN[i].binormalWorld;

               o.pos = UnityObjectToClipPos(IN[i].pos+displace_effect);

               o._ShadowCoord = IN[i]._ShadowCoord; // transfer as is shadows coming from vertex program
              
               UNITY_TRANSFER_FOG(o,o.pos);
              
               o.UV0 = IN[i].UV0;
               o.UV1 = IN[i].UV1;
              
               if(_TransitionDist >= 0.0)
                  o.fade_factor = saturate(length(_TransitionMessFactor*sqrt(tri_dist)-_TransitionDist)/30-(_TransitionDist/_TransitionColorSpread));
               else
                  o.fade_factor = saturate(length(-_TransitionMessFactor*_TransitionDist-sqrt(tri_dist))/30-(_TransitionDist/_TransitionColorSpread));
              
               triStream.Append(o);
            }

            triStream.RestartStrip();
         }        
        
           
            // Fragment program
            float4 fragment_program( G2F i ): SV_Target
         {
            half3 pixel_in_cam = _WorldSpaceCameraPos.xyz - i.posWorld.xyz;
            half pixel_dist = length(pixel_in_cam);

//                float3 viewDirection = normalize( pixel_dist );
                half3 lightDirection = normalize( _WorldSpaceLightPos0.xyz );

                // Texture Maps
            //--------------
            // diffuse
                fixed4 diffuse = tex2D( _MainTex, i.UV0);

            // if diffuse texture have some alpha then clip under 0.5
            clip(diffuse.a-0.5);
        
            // dirt-AO
                fixed4 dirt = tex2D( _DirtLMTex, i.UV1);// dirt and AO texture
           
            fixed3 diff = diffuse * dirt.rgb * 1.5; // *1.5 for less dark walls

            fixed3 normalDirection;
           
           
            // fading bumps with distance ( far walls do not need bumpmaps )
            //---------------------------------------------------------------
            if(pixel_dist < _BumpDistFade)
            {
               // bump
               fixed3 bump =  UnpackNormal (tex2D (_BumpMap,  i.UV0));
              
               // a revoir sur un vecteur plutot que sur des valeurs X et Y independantes
               fixed delta=saturate((pixel_dist-(_BumpDistFade-_BumpLengthFade))/_BumpLengthFade);
              
               // small interpolation to make bump coming less visible...
               bump = fixed3(lerp(bump.x,0,delta),lerp(bump.y,0,delta),1);

               // Normal Transpose Matrix ( i still do not get why this is here 8*(  )
               half3x3 local2WorldTranspose = half3x3(
                  i.tangentWorld,
                  i.binormalWorld,
                  i.normalWorld
               );
              
               // Calculate Normal Direction from normal and bumpies
               normalDirection = normalize( mul( bump, local2WorldTranspose ) );
            }
            else
            {
               normalDirection = i.normalWorld; // with no bumps
            }
              
              
            fixed3 outputColor;
              
              
#if defined(WITH_CITY_NIGHTLIGHTS)
            // Night lightmap and its color and its intensity
            fixed lm =  dirt.a;
            fixed3 emiss = lm * _NightLightColor.rgb;// * _NightLightFactor;
           
            // night city wall lightings with less dirt/AO....
            outputColor = diff * UNITY_LIGHTMODEL_AMBIENT.rgb + diffuse*(1-(dirt.rgb*lm-(lm-1)))*emiss*2;
#else
            // Lighting
            fixed3 diffuseReflection = _LightColor0.rgb * saturate( dot( normalDirection, lightDirection ) );
           
                outputColor = diff * (diffuseReflection * SHADOW_ATTENUATION(i) + UNITY_LIGHTMODEL_AMBIENT.rgb);
               
#endif              

            // coming IN and OUT color setting
            outputColor = lerp(outputColor,UNITY_LIGHTMODEL_AMBIENT.rgb,i.fade_factor);
        
           
            UNITY_APPLY_FOG(i.fogCoord,outputColor);
           
                return half4(outputColor, 1.0);
           
            // show grey normals+bumps
//                return half4(saturate( dot( normalDirection, lightDirection )),saturate( dot( normalDirection, lightDirection )),saturate( dot( normalDirection, lightDirection )), 1.0);
           
            }
           
            ENDCG
        }
     
      // shadow caster rendering pass, implemented manually
      // using macros from UnityCG.cginc
      Pass
      {
         Tags {"LightMode"="ShadowCaster"}

         CGPROGRAM
         #pragma vertex vert
         #pragma fragment frag
         #pragma multi_compile_shadowcaster
         #include "UnityCG.cginc"

         struct v2f {
             V2F_SHADOW_CASTER;
         };

         v2f vert(appdata_base v)
         {
             v2f o;
             TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
             return o;
         }

         float4 frag(v2f i) : SV_Target
         {
             SHADOW_CASTER_FRAGMENT(i)
         }
         ENDCG
      }
   }
}

Draws nothing in linux.
However, it works like a charm in ( windows ) editor and windows target.

Could anyone please give it a try on a simple project targetted to linux and ran on a debian10 ?
My OpenGL is 3.3 and SM5…

Thanks a bunch !

Happy unitying ! :slight_smile:

bumpies ? :slight_smile:

noone targets to linux ? :frowning:

please @bgolus , if you are still here, can you maybe help me on this case ? :slight_smile:

No idea.

You might try running the Linux version of the editor and see if that shader gives you any useful errors. But my guess is you’re running into a driver issue, and not something on Unity’s side.

okay. i think this is the best option :slight_smile:
Moreover as my linux runs on VMWARE^^

Strange thing though is that the bug also appears on a non virtual linux.
I just don’t know enough about this problem for having a clue on its causes. Thanks @bgolus !
Sorry i bothered you on this but i thought you could find one of my misuses of shaders :wink:

Have nice day and happy unitying ! :slight_smile: