Hi, I'm doing a geometry shader to be able to perform grass. I have a problem (which I think it is) with the transformation of the vertecies.

I’m doing a shader following a tutorial, this is the link

http://ellenack.com/2016/11/05/grass-geometry-shader/

In this, they only do the explanation and development of the geometry shader (which does not bother me). I have been in the middle, since when it is supposed that the first strands of the grass should appear, these are not seen. Playing with the transformations of the vertices that leave the GS I have managed to visualize different things, but I can not do it correctly.
Regarding the fragment shader, I have used a lambert shading which is taken from another forum like this.

Enter the code:

Shader "Custom/Pasto"
{
	Properties
	{
		_Length ("Cantidad", Float) = 10
		_Width ("Ancho", Float) = 1
		_Gravity ("Gravedad", Float) = 0
		_Steps ("Pasos", Int) = 20
		_shadercolor ("supersimple color", Color) = (1,1,1,1)
    	_ObjectSpaceLightPos("Some Vector", Vector) = (0,0,0,0)

	}
	SubShader
	{
		Tags { "RenderType"="Opaque" }
		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma geometry geom
			#pragma fragment frag

			#include "UnityCG.cginc"

			//Structura de entrada al vertex
			struct appdata
			{
				float4 vertex : POSITION;
				float3 normal : NORMAL;
			};
			//Structura de entra al geometry
			struct geomInput
			{
				float4 pos : POSITION;
				float3 normal: NORMAL;
			};
			//Structura de entrada al fragment
			struct v2f
			{
				float4 vertex : SV_POSITION;
				float3 normal: NORMAL;
			};

			//Vertex shader
			geomInput vert (appdata v)
			{
				geomInput o;
				//o.pos = v.vertex;
				o.pos = UnityObjectToClipPos(v.vertex);
				o.normal = v.normal;
				return o;
			}
			float _Length;
			float _Width;
			float _Gravity;
			float _Steps;

			//Geometry shader
			[maxvertexcount(80)]
			void geom(triangle geomInput i[3], inout TriangleStream<v2f> stream)
			{
				float4 P1 = i[0].pos;
				float4 P2 = i[1].pos;
				float4 P3 = i[2].pos;

				float3 N1 = i[0].normal;
				float3 N2 = i[1].normal;
				float3 N3 = i[2].normal;

				float4 P = (P1 + P2 + P3) / 3.0;
				float3 N = (N1 + N2 + N3) / 3.0;
				float4 T = float4 (normalize((P2.xyz-P1.xyz)), 0.0);

				for( int i = 0; i < _Steps; i++ )
				{
    
    				float t0 = (float)i / _Steps;
    				float t1 = (float)(i+1) / _Steps;
 
 				   float4 p0 = normalize(float4(N, 0) - (float4(0, _Length * t0, 0, 0) * _Gravity * t0)) * (_Length * t0);
    				float4 p1 = normalize(float4(N, 0) - (float4(0, _Length * t1, 0, 0) * _Gravity * t1)) * (_Length * t1);
 

				    float4 w0 = T * lerp(_Width, 0, t0);
    				float4 w1 = T * lerp(_Width, 0, t1);

    				v2f ot;

					float4x4 vp = mul(UNITY_MATRIX_MVP, unity_WorldToObject);

					ot.vertex = p0 - w0;
					//ot.vertex = mul(UNITY_MATRIX_MVP, p0 - w0);
					ot.normal = cross(T, p0);
					stream.Append(ot);

					ot.vertex = p0 + w0;
					//ot.vertex = mul(UNITY_MATRIX_MVP, p0 + w0);
					ot.normal = cross(T, p0);
					stream.Append(ot);

					ot.vertex = p1 - w1;
					//ot.vertex = mul(UNITY_MATRIX_MVP, p1 - w1);
					ot.normal = cross(T, p1);
					stream.Append(ot);

					ot.vertex = p1 + w1;
					//ot.vertex = mul(UNITY_MATRIX_MVP, p1 + w1);
					ot.normal = cross(T, p1);
					stream.Append(ot);

				}		
			}

			//Fragment shader
			float4 _shadercolor;
            float4 _ObjectSpaceLightPos; //position vector of light source

			fixed4 frag (v2f i) : SV_Target
			{
				float3 lightdirWRTvertes=((i.vertex)-(_ObjectSpaceLightPos)); 
            	float3 worldnormal = normalize(i.normal);
            	float3 lightdir = normalize(lightdirWRTvertes);
            	float3 lambert = saturate(dot(lightdir,worldnormal));
				fixed4 col;
				col.rgb = lambert*_shadercolor;
            	        col.a=1;//a for transperency or alpha.
				return col;
			}
			ENDCG
		}
	}
}

They could help me with this. Sorry for the inconvenience, I’m fairly new to the GS and I have no exact idea how it works. Thank you :slight_smile:

I actually just figured this out myself. In the tutorial you and I used, they don’t mention anything about using the P variable in the beginning.

I simply added that onto the position that I’m passing into the triStream and that fixed my issue!

Instead of ot.vertex = p0 - w0; it’d be ot.vertex = UnityObjectToClipPos((p0 - w0) + P);