OpenGL – A Modified Phong-Blinn Light Model For Shadowed Areas

I was looking through the book Graphics Programming Methods (2003) the other day when I came across a paper titled “A Modified Phong-Blinn Light Model for Shadowed Areas” and thought it was pretty good, so I implemented it. It’s a really short paper, but what’s it’s basically saying is that by not allowing ambient light to be modified by geometry normals, any characteristics of the geometry are lost because we calculate the diffuse intensity as the dot product of the light location and the surface normal and limit the result between 0 and 1 (i.e. we only take diffuse lighting into consideration for surfaces facing our light source).

What the paper proposes instead is that we allow the dot product to run as -1.0 to +1.0, and when the value is within the range 0.0 to 1.0 (i.e. facing the light) we shade as usual, but when it’s -1.0 to 0.0 (facing away from the light) we calculate the lighting as the ambient light plus the negative diffuse intensity multiplied by the ambient light multiplied by q, where q is a value between 0.0 and 1.0. When q is 0.0, it’s like we’re using a traditional Phong-Blinn model, when it’s 1.0 we’re using the fully modified version, and any value in between is a sliding-scale combination of them.

To put that another way, if our surface is facing away from the light source, we use: Lighting = Ambient + (Diffuse * Ambient * q)

In the following images, the light source is roughly in line with the geometry on the Y and Z axis’, and is a way over on the positive X axis (i.e. to the right). Check out the difference…

Standard lighting with q = 0.0
Standard lighting with q = 0.0 - notice that the inside right area of the torus is getting no diffuse lighting, and all detail is lost to the ambient lighting.
Improved lighting with q = 0.5
Improved lighting with q = 0.5 - there's now some detail in the shadowed area on the inside-right of the torus
Improved lighting with q = 1.0
Improved lighting with q = 1.0 - there's now significantly more detail in the shadowed area on the inside-right of the torus

To create this effect, I used the following fragment shader:

Modified Phong-Blinn Light Model Fragment Shader

Credits for this method go to Anders Hast, Tony Barrera, and Ewer Bengtsson – good work, fellas! =D

Simple OpenGL FBO Textures

I was playing around with FBOs and rendering to textures the other week and came up with this. A spinning yellow torus is rendered to a texture, then a second spinning torus is textured using the texture we just created of the first spinning torus… Yeah, I need to stop using donuts as my test objects.

Full source code & shaders after the jump…

Continue reading Simple OpenGL FBO Textures

Anaglyphic 3D in GLSL

I’ve been playing around with getting some red/cyan stereoscopic 3D working of late, and it’s all turned out rather well – take a look… (Red/Blue or Red/Cyan glasses are required for the effect to work):

Anaglyphic 3D in GLSL
Click for bigger version.

If you’ve got suitable glasses you should definitely see a 3D effect, although I don’t think me rescaling the image has done it any favours – so click the image to see the full sized version for the full effect.

The trick to this has been to render the scene twice to two separate FBO textures, then sample from the left and right textures to draw a fullscreen quad with a combined version as follows:

In the code itself, the torus’ spin around on the spot and look pretty good, although there’s no anti-aliasing as yet as I need to create some multisample buffers instead of straight/normal buffers for the FBO, but it’s not decided to play ball just yet – not to worry though, the hard part’s done and I’m sure multisampling will be sorted in a day or so. After that, I might give ColorCode3D (TM)(R)(C)(Blah) a go, as it seems to give a better colour representation whilst still allowing the same amount of depth as traditional anaglyphic techniques. Also, I’ve got to start using asymmetric frustums for the projection to minimise the likelihood of eye-strain, but I don’t see that as being too much of a problem.

Good times! =D

How To: Syntax highlight GLSL shaders in Gedit

GLSL shaders share a lot in common with the C language, and Gedit can syntax highlight C/C++ and a host of other languages – so why not GLSL shaders? Here’s a simple way to make it happen…

1.) Gedit uses gtksourceview for its syntax highlighting rules – so find out where that’s located on your distro with the following:

Once you’ve got the location of the c.lang file, navigate there in the bash (on Ubuntu it’s in /usr/share/gtksourceview-2.0/language-specs).

2.) Make a copy of the c.lang file in case you accidentally stuff it up (optional, but better safe than sorry):

3.) Open the file with your text editor of choice and modify the c.lang file to add in additional file extensions which should be syntax highlighted as per the c.lang definitions:

A couple of lines into the file (after the comments at the top) you’ll see the following:

Assuming you’re ending your vertex shaders with .vp and your fragment shaders with .fp (if you’re using .vert and .frag or such just substitute appropriately), change the line to read:

Save it, close gedit, and open a .vp or .fp file with Gedit – syntax highlighty goodness is rightfully yours. Of course, this is normal C highlighting, not true GLSL highlighting – but it’s a good start.

If you wanted to add things like vec3, uniform etc. then you can find the following sections in the c.lang file and add ’em in yourself:


C++/OpenGL/GLSL Texture Manipulation

Just learning some GLSL and playing about with vertex and fragment shaders – not a bad first start, but it’s going to take a significant amount of time and effort to get to really writing some descent shaders – it’s just very, very different from fixed-pipeline stuff… What you’re looking at is a texture where I’ve drawn some stuff on it in bright red, and then in the fragment shader anything found in the texture to be bright red gets discarded, effectively leaving in empty, like a cut-out =D

All in, the project’s around 500 lines of source, with the shaders being merely:

Vertex Shader

Fragment Shader

The Linux Code::Blocks project will all source & image can be found below, but you’ll need to have or install libGL, libGLEW, libglfw, libIL, libILU, libILUT for it to work right out of the box. The linkage details are all in the Code::Blocks project file (and also in the .depend file if you don’t use C::B) so you can see what you need if there’s anything missing.


Update: Ha! Hadn’t thought of this before, but I guess what I’m really doing is Chroma-Keying (or Colour-Keying, whatever you prefer)… And you can do the same thing in SDL/OpenGL without using any shaders like this.