# 5.3 Phong Fragment Shader

The different between Phong and Blinn-Phong lies only in the specular component.

## Phong Vertex Shader

In this Lab, we are sharing the vertex shader between Phong and Blinn-Phong.

Accordingly, we are going to directly use **blinn.vert** for our Phong model.

## Create Phong Fragment Shader

Create phong.frag in folder **shaders**.

## Write the Specular Component

In Phone model, we need to use the cosine of the angle between the view direction and the reflection vector. Accordingly, we need to replace the half vector in Blinn-Phong model with the reflection vector. Fortunately, we can use the GLSL reflect() function to calculate the reflection vector.

Remeber, you need to guarantee the reflection vector to be normalised.

In this example, we set the shininess coefficient alpha to 8.0.

```glsl
    // 3. specular
    vec3 viewDir = normalize(viewPos - fragPos);
    // reflectDir = -lightDir - 2( (-lightDir) dot norm)norm
    // you need to make reflectDir normalised
    vec3 reflectDir = reflect(-lightDir, norm);

    // set the shininess coefficient alpha to 8.0 
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), 8.0);

    // assuming a light source with a bright white colour
    vec3 specular = vec3(0.3) * spec;
```

## Result

Set the initshader in main() to use **blinn.vert** and **phong.frag**,&#x20;

```cpp
initShader( "shaders/blinn.vert", "shaders/phong.frag");
```

With the following light source position of glm::vec3(5.0f, 5.0f, 10.0f) and  eye position of  glm::vec3(0.0f, 0.0f, 5.0f) in main.cpp, you will see something similar to the following:

<figure><img src="https://3464970502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3JUKGJZ67JX02QZdPhsy%2Fuploads%2FgemMkG9PqGnQUedev5pR%2Fimage.png?alt=media&#x26;token=e7669941-9cab-4994-ab7c-a1ac9f910fcb" alt="" width="483"><figcaption></figcaption></figure>

which is very similar to Blinn-Phong:

<figure><img src="https://3464970502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3JUKGJZ67JX02QZdPhsy%2Fuploads%2FJgnfBBss744CKI7bLP0w%2Fimage.png?alt=media&#x26;token=93235037-6a6a-49cc-9017-c8bab9bbbcbc" alt="" width="483"><figcaption></figcaption></figure>

## Full Source Code

```glsl
// phong.frag
#version 410

// for lighting
in vec3 fragPos;
in vec3 normal;

uniform vec3 lightPos;
uniform vec3 viewPos;

out vec4 colour_out;

void main()
{
    // manually set the vertex colour
    vec3 color = vec3(1.0, 0.0, 0.0);

    // 1. ambient
    vec3 ambient = 0.05 * color;

    // 2. diffuse
    vec3 lightDir = normalize(lightPos - fragPos);
    vec3 norm = normalize(normal);
    float diff = max(dot(lightDir, norm), 0.0);
    vec3 diffuse = diff * color;
    
    // 3. specular
    vec3 viewDir = normalize(viewPos - fragPos);
    // reflectDir = -lightDir - 2( (-lightDir) dot norm)norm
    // you need to make reflectDir normalised
    vec3 reflectDir = reflect(-lightDir, norm);

    // the shininess coefficient alpha = 8.0 
    float spec = pow(max(dot(norm, reflectDir), 0.0), 8.0);

    // assuming a light source with a bright white colour
    vec3 specular = vec3(0.3) * spec;

    // The final combined colour
    colour_out = vec4(ambient + diffuse + specular, 1.0);
}
```
