The vertex shader corresponds to a rendering pipeline’s programmable stage, where the vertices are transformed from a 3D space to a two-dimensional projection on the screen. Its smallest unit of calculation corresponds to an independent vertex.

Inside the USB_simple_color shader, there is a function called “**vert**” which corresponds to our **vertex shader stage**. The reason why we know that it is our *vertex shader* is that it was declared as such in the #pragma vertex.

```
#pragma vertex vert
...
v2f vert (appdata v)
{
...
}
```

Before continuing with the explanation of this stage, we must remember that our shader **USB_simple_color **is an **Unlit** type (it does not have light) that’s why it includes a function for the **vertex shader** and another for the **fragment shader** (#pragma fragment frag). It is essential to mention this since Unity provides a quick way to write shaders in the form of “Surface Shader” (surf) that generates Cg code automatically, exclusively for materials that are affected by lighting. This allows optimization of development time but does not help us understand it because many functions and calculations occur internally in the program. This is why we created an *Unlit* shader at the beginning of this book; to understand its operation in detail.

We are going to analyze the structure of the *vertex shader stage*. Our function begins with the word “*v2f*” which means “*vertex to fragment*”. This name makes a lot of sense when we understand the internal process that is happening inside the program. V2f will be used later as an argument in the **fragment shader stage**, hence its name. So, as our function starts with *v2f* that means it is a *vertex output* type, therefore, we will have to return a value associated with this data type.

Continue with “**vert**” which is the **name** of our **vertex shader stage** and then the arguments in parentheses where *appdata* fulfils the function of *vertex input*.

`v2f vert (appdata v) {} ...`

This function can transform and connect **appdata** properties with **v2f** properties. If we continue our analysis, we will notice that inside the function, the struct *v2f* has been initialized with the letter “o”, so “o” would be our pointer, therefore, all the properties that were declared in *struct v2f* will be found inside this variable.

v2f o;

o.vertex …

o.uv …

return o;

SSo the first operation that occurs within the *vertex shader stage* is the transformation of the object vertices from *object-space* to *clip-space* through the “UnityObjectToClipPos” method. Let’s remember that our objects are within a three-dimensional space in the scene, and we must transform those coordinates into a two-dimensional projection of pixels on the screen. That transformation occurs precisely within the “UnityObjectToClipPos” function. What this function does is multiply the matrix of the current model (unity_ObjectToWorld) by the factor of the multiplication between the current view and the projection matrix (UNITY_MATRIX_VP).

```
UnityObjectToClipPos( float3 pos).
{
return mul(
UNITY_MATRIX_VP,
mul(unity_ObjectToWorld, float4(pos , 1.0)));
}
```

This operation is declared in the “**UnityShaderUtilities.cginc**” file which has been included as a dependency in *UnityCG.cginc* and that is why we can use it inside our shader. So, we take the vertex input from our object (v.vertex), transform the matrix from *object-space* to *clip-space* (UnityObjectToClipPos) and save the result in the vertices output (o.vertex).

```
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
}
```

A factor that we must consider when working with inputs or outputs is that both properties must have the same number of dimensions, e.g., if we go to the *vertex input appdata* we will see that the vector “**float4** vertex” has the same number of dimensions as “**float4** vertex” in the vertex output (v2f).

If one property is of type float4 and the other float3 then Unity may return an error because in most cases you cannot transform from a four-dimensional vector to a three-dimensional vector or less.

Then we can find the TRANSFORM_TEX function. This function asks for two arguments which are: 1. the input UV coordinates of the object (v.uv) and 2. the texture that we are going to position over those coordinates (_MainTex). It fulfils the function of controlling the “tiling and offset” in the UV coordinates of the texture.

Finally, we pass these values to the UV output (o.uv) since later they will be used in the *fragment shader stage*.