fragment vertex/vertex fragment shaders in unity

Fragment Vertex shaders are a different beast to surface shaders. We are able to access vertex data and control pixels in much finer detail.

Below is a simple frag/vert shader. The framework is similar to the surface shaders we've been looking at, only the usual CGPROGRAM block now sits within a Pass block, that lives in the SubShader. I haven't included a Properties block, but that remains unchanged.

The first thing is we now have #pragmas for the frag and vert functions and also #include the UnityCG.cginc file, that contains lots of handy shader functions There are other files we can include when we are working with lighting and shadows.

Next up in the framework is the "appdata" struct - it essentially has all the vertex data that our 3d model holds. Here we've go the vertex variable as a float4 type, and we use the POSITION attribute. The "vertex" name can be arbitrary. You can also list other data, such as normals, color (multiple) and UVs & they will have they're own attribute tags.

After that we have a "v2f" struct, which defines the struct for the vertices that are being converted to screenspace fragments. Again there are attribute tags for them.

v2f vert uses both of the structs - it makes "o" of type v2f, and uses the UnityObjectToClipPos function to convert the vertex coordinates into clipping space -or 2d space if you like. There are two commented out lines which assign the processed vertex's colour to use the model's x and z position data to set the red and green colours. If you wish to create some sort of effect/pattern that follows the object if it moves/rotates or your camera moves/rotates - then you will want to do it here in the vert function.

 the frag function is up next - taking the return value from vert function and calling it "i". Here we use the now-screen-space-converted-vertex's x and y values to set the red and green. NOTE - we are now in screenspace, which only uses X and Y values. Also, the values will be large, as they will refer to screen pixel numbers, which is why I'm multiplying them by 0.001. Also, because we are in screenspace, any patterns/effects will not stick to the object and will also change if you move the camera.

Shader "Dave/Unlit/vf_colour"
{
    SubShader
    {
        Pass
        {
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag

        #include "UnityCG.cginc"
       
        struct appdata
        {
        float4 vertex : POSITION;
    
        };
        struct v2f //vertex to fragment
        {
            float4 vertex: SV_POSITION; //vertices in screenspace
            float4 color: COLOR;
        };

        v2f vert(appdata v)
        {
            v2f o;
            o.vertex = UnityObjectToClipPos(v.vertex); //converts world space data to clipping space
            //o.color.r = (v.vertex.x +5)*0.1;//assign world x coord to red
            //o.color.g = (v.vertex.z + 5)*0.1;
           
            return o; //returns to fragment shader
        }

        fixed4 frag(v2f i) :SV_TARGET
        {
            fixed4 col;
        col.r = i.vertex.x*0.001;
        col.g = i.vertex.y*0.001;
        return col;
        }

        ENDCG
        }




   }





}

Comments

Popular posts from this blog

setting VFX graph properties using C#

scripting custom render texture creation, assignment, shaders