Vertex Fragment Shader Structure
By: Ahmed Schrute
Tags: Learning To Code, Game Development, Graphics, Education, Unity3d

This article is a continuum of shader coding articles using Shader lab in Unity, I highly recommend you visit my two articles Understanding Mesh Anatomy in Unity and Shader Variables Datatypes for better understanding of this article.

In Unity, using shader lab, we can create surface shaders or vertex-fragment shaders.

Vertex-Fragment shaders provide more control over the geometry of the objects and the pixel view more than Surface shaders.

Vertex Shaders can be used for coloring vertices or manipulate vertices positions.

Fragment Shaders control per pixel colors and manipulate pixel (relative to the world) position.

The combination of Vertex and Fragment shaders enable a wide spectrum of morphing and manipulating the rendered view of 3d objects.

Vertex Fragment Shader Structure

Shader "VFShader/UnlitTextureShader" {

Properties

{

_MainTex ("Texture", 2D) = "white" {}

} SubShader

{

Pass

{

CGPROGRAM #pragma vertex vert

#pragma fragment frag struct appdata

{

float4 vertex : POSITION; // vertex position

float2 uv : TEXCOORD0; // texture coordinate

}; struct v2f

{

float4 vertex : SV_POSITION; // clip space position

float2 uv : TEXCOORD0; // texture coordinate

};



v2f vert (appdata v)

{

v2f o;

o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);

o.uv = v.uv;

return o;

}



sampler2D _MainTex;

fixed4 frag (v2f i) : SV_Target

{

fixed4 col = tex2D(_MainTex, i.uv);

return col;

}

ENDCG

}

}

}

Properties block (used to define properties you can set in the inspector)

Properties {

SubShader Block (defines the rendering pass)

SubShader {

Pass Block (contains the rendering configuration)

Pass{

CG PROGRAM (directive to compile code in between into low-level shader assembly)

Every CG program starts with

CGPROGRAM

and ends with

ENDCG

Compiler directives

#pragma type name

These directives define the functions that are needed to run before the program startup, In our case, we will have two functions (vertex and fragment) therefore we need two compiler directives.

for vertex function

#pragma vertex vert

for fragment function

#pragma fragment frag

Including Unity Builtin Library makes life easier

#include “UnityCG.cginc”

Data Structures for holding our data

//used for the vertex function

struct appdata {} //used for fragment shader

struct v2f {}

Vertex Function

v2f vert (appdata v)

{

v2f o;

o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);

o.uv = v.uv;

return o;

}

This function returns v2f (data type) and takes input v of data type appdata and the name of the function as mentioned in the vertex compiler directive vert.

In this function, we start by declaring a variable of type v2f with the name o as a return variable.

Then, we start assigning values to the two attributes of v2f (vertex and uv).

For the vertex attribute, the main objective is to transform the position to clip space (3d to 2d), we are approaching this by multiplying the vertex position with the model*view*projection matrix.

For the uv attribute, we are passing down the uv mapping data from the mesh data to our v2f data structure. (Understanding Mesh Anatomy in Unity)

Before we move to the fragment function we declare a variable with the data type sampler2D with the name _MainTex same as _MainTex mentioned in the Properties which will hold the Texture we sat in the inspector.

sampler2D _MainTex;

Fragment Function

fixed4 frag (v2f i) : SV_Target

{

fixed4 col = tex2D(_MainTex, i.uv);

return col;

}

The fragment function returns a fixed4 which represents the color of the pixel (r,g,b, a). (Shader Variables Datatypes)

frag, the fragment function takes an argument of type v2f which our vertex function returned. (SV_Target is a semantic signifier check the notes below)

In the fragment function, we are using the tex2D to map the texture(_MainTex) to the uv map passed from the v2f i.