Blending Textures in an OpenGL Shader

Hold on there! This blog article is taken from my previous website and quite old. It may be not as interesting or relevant as it used to be, a lot of information may be deprecated.

For my assignment I wanted to get more familiar with the use of OpenGL shaders and the used language (GLSL). I started by searching the openFrameworks forums, and found that the GLSL tutorial over at Lighthouse3D was much appreciated. Also the ofxShader examples topic is a must read, but you need to do some puzzling in order to get things working with the latest version of OF.

Going trough different tutorials on the web isn't as easy as you might think, OpenGL has been around for quite some time, and has evolved over the years, rendering some tutorials seriously out of date. An other difficulty I found is there are different ways to achieve the same goal, without it being clear if something is depreciated, or bad practice. Using openFrameworks is great, it takes a lot of the hard work away, but this has the downside that it's user may not know what's happening behind the scenes, which in my case has caused a lot of trouble and confusion when trying out these shader techniques. (Luckily you can browse the source and learn a lot from that, but still it can be a head scratcher some times).

After getting the examples running from the above mentioned forum thread I tried to create a simple program and shader from scratch, I left the FBO (Frame Buffer Object) out of it to simplify things.  The program would allow you to change the brightness and contrast of a load image by using a (fragment) shader.

shaderTest02b

Downloads: source code (code::blocks), binaries (win32)

For this program and the next one I've used the most up to date version of ofxShader that I could find. It's located at Kyle McDonald's Google Code page: http://code.google.com/p/kyle/source/browse/trunk/openframeworks/addons/ofxShader/ (At the time of this writing the latest version is from revision 81, Aug 08, 2010).

This version is a bit different from the one used in the examples by Theo Watson, mainly being the following: [cpp light="true"]// loading the shader, usually done in app::setup() ofxShader::loadShader() -> ofxShader::setup() // enabling the shader, usually done in app::draw() ofxShader::setShaderActive(true) -> ofxShader::begin() // setting an uniform, to set a shader parameter, usually done in app::draw() ofxShader::setUniformVariable*type*() -> ofxShader::setUniform(*type*) // disabling the shader, usually done in app::draw() ofxShader::setShaderActive(false) -> ofxShader::end()[/cpp] This version by Kyle McDonald also includes an easy way (ofxShader::setTexture()) to bind an image or texture to the shader. This gets me to my second program.

In this topic someone suggests to use a GLSL shader to blend textures like done in Adobe Photoshop. Romain Dura has created a glsl file containing a lot of blend modes used in Photoshop which you can find in his blog post, I tried to combine theses thing together. After quite some struggling (see rant at the start of this post) I've managed  to get things working which I turned into a app.

This was also a nice opportunity to try out the ofxControlPanel GUI add-on by Theo Watson, which is a nice alternative for Memo's ofxSimpleGuiToo.

ShaderTextureBlendingGui

In the control panel you can set a (different) Base or Blend image by double-clicking on a file listed in the appropriate file lister just below the preview. In the right column of the control panel you find sliders and a dropdown list that will allow you to change the shader parameters. The contrast and brightness is applied after blending the Base and Blend image. The Blend Mix parameter allows you to dim the effect of the blending where a 0.0 value represents the original Base image and 1.0 value the blended Base + Blend image.

The result of above settings is displayed here below.

Downloads: source code (code::blocks), binaries (win32)

ShaderTextureBlendingResult

More images on Flickr