, , , , , , , , , , , , ,

Arkwood disrobed, tossing his T-shirt onto the BBQ. ‘Oh, it is sooo hot outside!’ he lamented. Keen for the neighbours not to spy his scrawny bones and faint, I suggested he leave the back garden for the house.

‘But I love the light,’ he continued, crying.

‘Dont worry,’ I empathised, ‘Put on the Oculus Rift virtual reality headset and I will pipe in all the light you desire.’

After all, I had already filled a virtual room with ambient and diffuse lighting in my previous post. All that remained of the Phong lighting model was some specular lighting, so let’s get to it!

Learn OpenGL show us how to add specular lighting. I cranked open my C++ Microsoft Visual Studio application – which makes use of the Oculus SDK for Windows and OpenGL graphics library – and passed a uniform to the fragment shader:

const float position_x = view.M[0][3];
const float position_y = view.M[1][3];
const float position_z = view.M[2][3];

glUniform3f(glGetUniformLocation(Fill->program, "viewPos"), position_x, position_y, position_z);

We are providing the fragment shader with our viewing position in the virtual room. But remember that we are doing our lighting calculations in world space, so I invert the view matrix first before fetching the x, y and z position.

Here’s how we add specular lighting to the ambient and diffuse calculations from said previous post:

"float specularStrength = 1.0f;\n"
"vec3 viewDir = normalize(viewPos - FragPos);\n"
"vec3 reflectDir = reflect(-lightDir, norm);\n"
"float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);\n"
"vec3 specular = specularStrength * spec * lightColor;\n"

First, we get the view direction from our viewing position and fragment position. Then we use the light direction and normal to work out the reflection. Lastly we use the angle between the reflection and view direction to produce our specular component.

Note that I am using a specular strength of 1.0 to really emphasise the effect of specular lighting.

Specular can be added to ambient and diffuse, to apply the Phong lighting model to the virtual room:

"vec3 result = (ambient + diffuse + specular);\n"
"if (uIsTexture == true) {\n"
"	result = result * texture2D(Texture0, oTexCoord).xyz;\n"
"} else {\n"
"	result = result * oColor.xyz;\n"
"FragColor = vec4(result, 1.0f);\n"

Great. For the ceiling, walls and floor in our virtual room we apply lighting to their textures. For the coral cube we apply lighting to its colour.

Here’s the virtual room with specular lighting set to a power of 32 shininess:

See how the white light source at the far end of the room is casting a specular spot on the carpet.

Let’s crank the shininess to a power of 256:

We can really see the intensity of the specular spot now, on the wooden panel ceiling, wallpaper and carpet.

Arkwood gasped. ‘Hurray! Now I can bask in the light of a virtual world, without having to endure the scorching BBQ and sunshine heat of the real world.’

And, more importantly, the neighbours don’t have to endure the vulgar sight of his sweaty nipples.



Here’s a video of Arkwood putting on the Rift headset and strolling about a virtual room with the ambient, diffuse and specular of the Phong lighting model: