Tags

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

Arkwood’s eyes were burnt out. Two smoldering holes in the front of his skull. Not quite.

‘But your virtual room is a health hazard,’ he said, slipping off the Oculus Rift virtual reality headset, ‘can’t you turn the lights down low?’

Yes. You only had to ask. I will dim the ambient light in the room.

Basic OpenGL lighting requires more than ambient light though. For example, as Learn OpenGL points out, the Phong lighting model incorporates diffuse and specular lighting too. But for now, let’s get started with just the ambient part.

Here’s the fragment shader for our virtual room, with the ambient light set to pure white:

static const char* FragmentShaderSrc =
	"#version 150\n"
	"uniform sampler2D Texture0;\n"
	"in      vec4      oColor;\n"
	"in      vec2      oTexCoord;\n"
	"out     vec4      FragColor;\n"
	"void main()\n"
	"{\n"
	"	float ambientStrength = 1.0f;\n"
	"	vec3 lightColor = vec3(1.0f, 1.0f, 1.0f);\n"
	"	vec3 ambient = ambientStrength * lightColor;\n"
	"	vec3 result = ambient * oColor.xyz * texture2D(Texture0, oTexCoord).xyz;\n"
	"   FragColor = vec4(result, 1.0f);\n"
	"}\n";

And with an ambient strength of 1.0, the ambient light is having no effect on the overall textured colour of the room.

Note that the ambient light and strength are defined in the shader – we could pass these values to the shader as uniforms instead. Oh, and note also that we are using a bit of swizzling, to get at the colour and texture .xyz values.

But what if we change the ambient light to pure green instead:

static const char* FragmentShaderSrc =
	"#version 150\n"
	"uniform sampler2D Texture0;\n"
	"in      vec4      oColor;\n"
	"in      vec2      oTexCoord;\n"
	"out     vec4      FragColor;\n"
	"void main()\n"
	"{\n"
	"	float ambientStrength = 1.0f;\n"
	"	vec3 lightColor = vec3(0.0f, 1.0f, 0.0f);\n"
	"	vec3 ambient = ambientStrength * lightColor;\n"
	"	vec3 result = ambient * oColor.xyz * texture2D(Texture0, oTexCoord).xyz;\n"
	"   FragColor = vec4(result, 1.0f);\n"
	"}\n";

Nice. Learn OpenGL explains how the light’s colour is affecting the walls, ceiling and floor of our room – discarding the red and blue colours and reflecting only the green.

But when it comes to using ambient for real, we want to drop its strength to a low value, say 0.1. It provides the overall room with just a bit of light, ready for the diffuse and specular parts to add their lighting contribution.

static const char* FragmentShaderSrc =
	"#version 150\n"
	"uniform sampler2D Texture0;\n"
	"in      vec4      oColor;\n"
	"in      vec2      oTexCoord;\n"
	"out     vec4      FragColor;\n"
	"void main()\n"
	"{\n"
	"	float ambientStrength = 0.1f;\n"
	"	vec3 lightColor = vec3(1.0f, 1.0f, 1.0f);\n"
	"	vec3 ambient = ambientStrength * lightColor;\n"
	"	vec3 result = ambient * oColor.xyz * texture2D(Texture0, oTexCoord).xyz;\n"
	"   FragColor = vec4(result, 1.0f);\n"
	"}\n";

Arkwood relaxed his weedy, ugly bones. ‘That’s better,’ he said, as I ran the Microsoft Visual Studio C++ application, making use of the Oculus SDK for Windows. ‘It’s all dim and sensual.’

Wait until I add a lamp to the room, to provide some directional rays – diffuse lighting will tip him into sordid ecstasy. And the bright spot of specular will be his end.

Ciao!

P.S.

With a nice dim room, ambient strength at 0.05, I add a cube without any ambient treatment (it has its own shaders). Enjoy the unnatural vibrancy!