Wednesday 21 January 2015

Simple Shaders

Disclaimer: This is not a tutorial website!

Of late, I have been learning GLSL programming creating simple shaders!
I have been following many online tutorials that are free and I am thankful to them :)

Here goes my first take on Shaders!

A Simple Toon Shader of a Teapot.


Vertex Shader

varying vec3 normal,lightDir;
   
    void main()
    {
        normal = normalize(gl_NormalMatrix * gl_Normal);
        lightDir=normalize(vec3(gl_LightSource[0].position));
        gl_Position = ftransform();
    }

Fragment Shader

varying vec3 normal,lightDir;
  
    void main()
    {
  
        float intensity;
        vec4 color;
      
        intensity = dot(lightDir,normal);
      
        if (intensity > 0.95)
            color = vec4(0.5,0.5,1.0,1.0);
        else if (intensity > 0.5)
            color = vec4(0.3,0.3,0.6,1.0);
        else if (intensity > 0.25)
            color = vec4(0.2,0.2,0.4,1.0);
        else
            color = vec4(0.1,0.1,0.2,1.0);
      
        gl_FragColor = color;
    }

And here's the output!
Tada!


Diffuse Shading

Here are the shaders of the teapot with just the diffuse component calculating the color and intensity using the diffuse component formula. This is also known as Lambertian Shader.

Vertex Shader

void main()
{
vec3 normal,lightDir;
vec4 diffuse;
float dotProd;
normal=normalize(gl_NormalMatrix * gl_Normal);
lightDir = normalize(vec3(gl_LightSource[0].position));
dotProd=max(dot(normal,lightDir),0.0);
diffuse=gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
gl_FrontColor=dotProd * diffuse;
gl_Position = ftransform();
}

Fragment Shader

void main()
{
gl_FragColor=gl_Color;
}

Here goes the teapot with only Diffuse(without ambient light).



It looks like this coz I have a light set at the position (1,0.5,1).

Adding Ambient Component to this!


void main()
{
vec3 normal,lightDir;
vec4 diffuse,ambient,globalAmbient;
float dotProd;
normal=normalize(gl_NormalMatrix * gl_Normal);
lightDir = normalize(vec3(gl_LightSource[0].position));
dotProd=max(dot(normal,lightDir),0.0);
diffuse=gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
ambient=gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
globalAmbient=gl_LightModel.ambient * gl_FrontMaterial.ambient;
gl_FrontColor=dotProd * diffuse + ambient + globalAmbient;

gl_Position = ftransform();
}


The fragment Shader remains the same!

Alright! Now adding ambient light we get this!


It looks like this with just global Illumination without a user specified light.