Search Unity

Geometry shader examples for OpenGL

Discussion in 'Shaders' started by ellioman, Dec 9, 2015.

  1. ellioman

    ellioman

    Joined:
    Mar 14, 2013
    Posts:
    19
    Howdy,
    So with the 5.3 update, Mac GPUs that support OpenGL 4.1 should be able to use geometry shaders in Unity.

    I want to start playing with this but having difficulty trying to find me some examples to get me started. I'm constantly getting a "Shader is not supported on this GPU (none of subshaders/fallbacks are suitable)" errors in the shaders that I've found online (I have a mid 2014 Macbook Pro so I've got OpenGL 4.1 which should be able to run geometry shaders).

    Does someone have any simple shader examples that could help me out? Don't need anything fancy, just something that uses the geometry shader.
     
  2. ellioman

    ellioman

    Joined:
    Mar 14, 2013
    Posts:
    19
    Anybody?
     
  3. Michal_

    Michal_

    Joined:
    Jan 14, 2015
    Posts:
    365
    Hey,
    first of all, geometry shaders don't work with surface shaders. You have to use standard combination of vertex, geometry, pixel shaders and handle everything yourself. So getting it to interact with lights can be a bit tricky for example. Also, the cross-compilation from HLSL to GLSL seems to be buggy at the moment, so not every valid code will compile and you have to try to rewrite it somehow. With that being said, here is a simple working shader (a bit hacky to get over compiler issues). The geometry shader computes common normal vector for every triangle.

    Code (CSharp):
    1. Shader "test/MyShader"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Texture", 2D) = "white" {}
    6.     }
    7.     SubShader
    8.     {
    9.         Tags { "RenderType"="Opaque" }
    10.         LOD 100
    11.  
    12.         Pass
    13.         {
    14.             CGPROGRAM
    15.             #pragma vertex vert
    16.             #pragma fragment frag
    17.             #pragma geometry geom
    18.            
    19.             #include "UnityCG.cginc"
    20.  
    21.             struct appdata
    22.             {
    23.                 float4 vertex : POSITION;
    24.                 float3 normal : NORMAL;
    25.                 float2 uv : TEXCOORD0;
    26.             };
    27.  
    28.             struct v2f
    29.             {
    30.                 float4 vertex : SV_POSITION;
    31.                 float3 normal : NORMAL;
    32.                 float2 uv : TEXCOORD0;
    33.                 float3 worldPosition : TEXCOORD1;
    34.             };
    35.  
    36.             sampler2D _MainTex;
    37.             float4 _MainTex_ST;
    38.            
    39.             v2f vert (appdata v)
    40.             {
    41.                 v2f o;
    42.                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    43.                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    44.                 o.normal = v.normal;
    45.                 o.worldPosition = mul(_Object2World, v.vertex).xyz;
    46.                 return o;
    47.             }
    48.  
    49.             [maxvertexcount(3)]
    50.             void geom(triangle v2f input[3], inout TriangleStream<v2f> OutputStream)
    51.             {
    52.                 v2f test = (v2f)0;
    53.                 float3 normal = normalize(cross(input[1].worldPosition.xyz - input[0].worldPosition.xyz, input[2].worldPosition.xyz - input[0].worldPosition.xyz));
    54.                 for(int i = 0; i < 3; i++)
    55.                 {
    56.                     test.normal = normal;
    57.                     test.vertex = input[i].vertex;
    58.                     test.uv = input[i].uv;
    59.                     OutputStream.Append(test);
    60.                 }
    61.             }
    62.            
    63.             fixed4 frag (v2f i) : SV_Target
    64.             {
    65.                 // sample the texture
    66.                 fixed4 col = tex2D(_MainTex, i.uv);
    67.  
    68.                 float3 lightDir = float3(1, 1, 0);
    69.                 float ndotl = dot(i.normal, normalize(lightDir));
    70.  
    71.                 return col * ndotl;
    72.             }
    73.             ENDCG
    74.         }
    75.     }
    76. }
    77.  
     
    AFrisby likes this.
  4. ellioman

    ellioman

    Joined:
    Mar 14, 2013
    Posts:
    19
    You my friend are a gentleman and a scholar! That's exactly what I looking for.

    I wasn't sure what the input to the geometry shader should be, how to output the vertices etc.
     
  5. jister

    jister

    Joined:
    Oct 9, 2009
    Posts:
    1,749
    @Michal_ desperately trying to get any geometry shader working on mac, but keep running into 2 things:
    Shader is not supported on this GPU, and Metal: Error creating pipeline state (Custom/Geom_Grass): Vertex attribute POSITION0(0) is missing from the vertex descriptor.
    I tried running this one and got the Shader not supported... any advice?
    EDIT: ok so after adding a fallback to yours it compiled. but still not for metal :(
    my specs are:
    MacBook Pro (Retina, 15-inch, Early 2013)
    2,7 GHz Intel Core i7
    16 GB 1600 MHz DDR3
    NVIDIA GeForce GT 650M 1024 MB
    Intel HD Graphics 4000 1536 MB
    i wouldn't thing my macbook is the problem.

    example of shader where i get the pipeline error:
    Code (CSharp):
    1. Shader "Custom/Geom_Grass" {
    2.     Properties {
    3.         _MainTex ("Main Texture", 2D) = "white"{}
    4.         _Color ("Color", Color) = (1,1,1,1)
    5.         _GrassHeight ("Grass Height", float) = 3
    6.         _GrassWidth ("Grass Width", float) = 0.1
    7.         _Glossiness ("Smoothness", Range(0,1)) = 0.5
    8.         _Metallic ("Metallic", Range(0,1)) = 0.0
    9.     }
    10.     SubShader {
    11.         Tags { "RenderType"="Opaque" }
    12.         LOD 200
    13.         Cull off
    14.         ZWrite off
    15.  
    16.         Pass
    17.         {
    18.             CGPROGRAM
    19.             // Physically based Standard lighting model, and enable shadows on all light types
    20.             #pragma vertex vert
    21.             #pragma geometry geom
    22.             #pragma fragment frag
    23.             #pragma target 5.0
    24.             #pragma multi_compile_fog
    25.  
    26.             #include "UnityCG.cginc"
    27.  
    28.             float4 _Color;
    29.             float3 _worldPos;
    30.             float _GrassHeight;
    31.             float _GrassWidth;
    32.  
    33.             struct data{
    34.                 float3 pos;
    35.             };
    36.  
    37.             StructuredBuffer<data> buff_Points;
    38.  
    39.             struct input {
    40.                 float4 pos:SV_POSITION;
    41.                 float2 uv:TEXCOORD0;
    42.                 UNITY_FOG_COORDS(1)
    43.             };
    44.  
    45.             sampler2D _MainTex;
    46.             half _Glossiness;
    47.             half _Metallic;
    48.  
    49.             input vert(uint id : SV_VertexID)
    50.             {
    51.                 input o;
    52.                 o.pos = float4(buff_Points[id].pos +_worldPos, 1);
    53.                 return o;
    54.             }
    55.             [maxvertexcount(3)]
    56.             void geom(point input p[1], inout TriangleStream<input> triStream)
    57.             {
    58.                 float4 p1 = p[0].pos.xyzw + float4(0,_GrassHeight,0,0);
    59.                 float4 p2 = p[0].pos.xyzw + float4(-_GrassWidth,0,0,0);
    60.                 float4 p3 = p[0].pos.xyzw + float4(_GrassWidth,0,0,0);
    61.                 input pIN;
    62.                 pIN.pos = mul(UNITY_MATRIX_VP, p1);
    63.                 pIN.uv = float2(0,0);
    64.                 UNITY_TRANSFER_FOG(pIN,pIN.pos);
    65.                 triStream.Append(pIN);
    66.  
    67.                 pIN.pos = mul(UNITY_MATRIX_VP, p2);
    68.                 pIN.uv = float2(0,1);
    69.                 UNITY_TRANSFER_FOG(pIN,pIN.pos);
    70.                 triStream.Append(pIN);
    71.  
    72.                 pIN.pos = mul(UNITY_MATRIX_VP, p3);
    73.                 pIN.uv = float2(1,0);
    74.                 UNITY_TRANSFER_FOG(pIN,pIN.pos);
    75.                 triStream.Append(pIN);
    76.             }
    77.  
    78.             float4 frag(input i):COLOR
    79.             {
    80.                 fixed4 col = tex2D(_MainTex, i.uv)*_Color;
    81.                 UNITY_APPLY_FOG(i.foCoord, col);
    82.                 return col;
    83.             }
    84.             ENDCG
    85.         }
    86.     }
    87.     FallBack "Diffuse"
    88. }
    89.  
     
    Last edited: Jul 18, 2017
  6. sam-perisentient

    sam-perisentient

    Joined:
    Aug 11, 2013
    Posts:
    31
    Regarding "Shader is not supported on this GPU". That graphics card reports a SystemInfo.graphicsShaderLevel of 45 (Metal / OpenGL ES 3.1 capabilities (Shader Model 3.5 + compute shaders)) when the editor is running Metal, and 46 (OpenGL 4.1 capabilities (Shader Model 4.0 + tessellation)) when the editor is running OpenGL.

    Geometry shaders do work when running under OpenGL, but not under Metal (because shader model 3.5 doesn't support them). Ironically the reverse is true for compute shaders.

    I know this is an old post, but I found it so someone else might too...
     
    GeorgeMays, sonofbryce and waken like this.