Geometry Shader Input: GL_TRIANGLES_ADJACENCY

Hello,

I wondering if we can use other geometry input than point and triangle.
In my case, I try to implementate a technic that I read in order to extrude vertices depending on the silhouette. It has to use GL_TRIANGLES_ADJACENCY, in order to determine the normal of adjacent faces. I tried with several different semantics but it has been a failed each time.
If anyone could give me a clue, I thank you in advance.

I searched a lot on internet, but it seems that there are not a lot of informations about geometry shaders used on unity.

Here is my last try (Shader warning in ‘Custom/Billboard’: Program ‘VS_Main’, unrecognized identifier ‘triangles_adjacency’ (compiling for d3d11) at line 35):

// Geometry Shader -----------------------------------------------------
[maxvertexcount(4)]
void GS_Main(triangles_adjacency GS_INPUT p[6], inout TriangleStream<FS_INPUT> triStream)
{
...
}

Geometry shaders in Unity are currently only HLSL style Geometry shaders, as far as I’m aware, so their input might be different than what you expect.

You can choose from the following primitive types:

  • point
  • line
  • triangle
  • lineadj
  • triangleadj
    DataType is a regular input struct that you might also see for fragment and vertex shaders.

Hello RC-1290

Thank you for your fast answer, it’s very interesting, because since I started to program shaders on unity, I’ve always believed that the #CG shaders in unity was based more on CgFX than HLSL, although in all cases, it’s still very different from the two.
I’ll try what you suggested tonight and I’ll let you updated about the result :slight_smile:

Thank you.

Hello,

I investigate tonight about what RC-1290 wrote, but I’m deceipt because after debbugging, the triangleadj seems to feed data only in the vertices 0, 1 and 2. The other vertices are just 0; therefore, it doesn’t send adjacency information.
Here is my shader code to verify what I say, and I attached a screen shot of the result (vertices 0, 2 and 4 should be the main triangle of the triangleadj):

Shader "Custom/ShaderTest02" 
{
	Properties 
	{
		_MainTex ("Base (RGB)", 2D) = "white" {}
	}

	SubShader 
	{
		Pass
		{
			Tags { "RenderType"="Opaque" }
			LOD 200
		
			CGPROGRAM
				#pragma target 5.0
				#pragma vertex VS_Main
				#pragma fragment FS_Main
				#pragma geometry GS_Main
				#include "UnityCG.cginc" 

				// **************************************************************
				// Data structures												*
				// **************************************************************
				struct appdata 
				{
				    float4 vertex : POSITION;
				    float2 texcoord1 : TEXCOORD0;
				    float3 normal : NORMAL;
				};

				struct GS_INPUT
				{
					float4	pos	: POSITION;
					float3	normal : NORMAL;
					float2 texcoord1 : TEXCOORD0;
				};

				struct FS_INPUT
				{
					float4 pos : POSITION;
					float2 uv1 : TEXCOORD0;
				};


				// **************************************************************
				// Vars
				// **************************************************************
				sampler2D _MainTex;
				
				// **************************************************************
				// Shader Programs
				// **************************************************************

				// Vertex Shader ------------------------------------------------
				GS_INPUT VS_Main(appdata_base v)
				{
					GS_INPUT output = (GS_INPUT)0;

					output.pos =  mul(_Object2World, v.vertex);
					output.normal = v.normal;
					output.texcoord1 = v.texcoord;

					return output;
				}
				
				// Geometry Shader -----------------------------------------------------
				[maxvertexcount(3)]
				void GS_Main(triangleadj GS_INPUT p[6], inout TriangleStream<FS_INPUT> triStream)
				{
					FS_INPUT pIn;
					
					float4x4 vp = mul(UNITY_MATRIX_MVP, _World2Object);
					pIn.pos = mul(vp, p[0].pos);
					pIn.uv1 = p[0].texcoord1;
					triStream.Append(pIn);
					
					pIn.pos = mul(vp, p[2].pos);
					pIn.uv1 = p[1].texcoord1;
					triStream.Append(pIn);
					
					pIn.pos = mul(vp, p[4].pos);
					pIn.uv1 = p[2].texcoord1;
					triStream.Append(pIn);
					triStream.RestartStrip();
				}



				// Fragment Shader -----------------------------------------------
				float4 FS_Main(FS_INPUT i) : COLOR
				{
					float4 c = tex2D (_MainTex, i.uv1);
				    return c;
				}

			ENDCG
		}
	} 
}

Oh… apparently it’s NOT possible. :frowning:

Well… I mean, it’s not supported by default. I guess you could always go deeper.

Thanks RC-1290. I’ll investigate for a way to build myself the data, it’s a bit sad because it’ll take a bit of process while it shouldn’t because it could be taken in charge by the pipeline. However, it shouldn’t be so difficult to build my own data by using a script C#.
I guess that it’ll be one of improvements for the next versions, but in the mean time, the Geometry Shaders aren’t yet assumed as a default feature on all graphic cards and all different supports as cell phones, therefore, I guess that it’s not a priority.

Thanks for your time :slight_smile:

Yeah, I believe they’re still looking for a way to make these ‘new’ features work on both DirectX and OpenGL using the same shader, because most solutions really only handle DX9-level stuff. Aras recently posted another blog post about this.