Share this Page

CS525 Project 1 - Kodachrome

The objective for this project was to process a stream of images captured from the webcam, and apply a set of vertex, fragment and geometry shaders to achieve different visual effects. The shaders had to be written using the OpenGL Shading Language (GLSL). My application made use of the OpenCV library for the webcam capture part. OpenCV has also been used to integrate face recognition support into one of the shaders.

How To Use The Application

The application presenta a total of 12 shader programs, organized into 3 pages of 4 programs each. Most of the shaders expose a configurable parameter that can be modified using the keyboard as the following section explains.

Here is a quick reference of the keys used by the application:

Shaders

Saturation

Main techniques: fragment shader saturation adjustment (saturation.frag)

This shader simply displays the current webcam feed, allowing the user to control the saturation level of the image. The fragment shader computes a black - and white value for each fragment, and mixes that value with the original color for each color channel, depending on an external, user customizable parameter.


Posterize

Main techniques: fragment shader color quantization (posterize1.frag)

The fragment shader used in this view limits the number of color shades for each color channel depending on the external shader parameter. The quantization is done by multiplying, rounding and then dividing each fragment color by the user parameter:

color.r = round(color.r * param) / param;

Color Threshold

Main techniques: fragment shader single channel threshold (colorThreshold.frag)

This view uses a fragment shader that computes the difference between one of the fragment colors (red in this case) and the average of the other two channels. If the difference is bigger than a user specified threshold, the fragment passes through the shader as it is. Otherwise, it is rendered black and white.


Hologram

Main techniques: background subtraction, scanline simulation (hologram.frag)

This view simulates a 'hologram' effect by subtracting the current webcam feed from a fixed background (press [n] to capture a background image from the webcam). The subtraction result is colored using a bluish palette and modulated by a low and high frequency sine function, to simulate scanlines and flicker.


Emboss

Main techniques: Embossing (emboss.frag)

This view simply applies an emboss convolution filter to a black and white version of the camera image. Image embossing is explained in more detail Here.


Funny Mirror

Main techniques: Polar coordinate distortion, face detection (funmirror.frag)

This view uses a fragment shader that smulates a funny mirror effect by distorting the image texture coordinates after converting them into polar form. A brief explanation of some of the effects implemented by this shader can be found here. When face detection is turned on, the shader gets the face rectangle identified by OpenCV as a uniform vec4. The shader then re-centers the effect using some simple math on te texture coordinate conversion.


Live Environment Mapping

Main techniques: Vertex-based spherical environment mapping (envMap.vert, EnvMap.frag)

This view implements a basic environment mapping shader, using the webcam feed as a sphere map. Since the webcam image does not map very well on a sphere, a simple technique has been used to avoid mapping artifacts at the texture boundaries. When the reflection vector gets close to the boundaries, the texture result is increasily mixed with a constant color.


Main techniques: Image difference, Gaussian blur, accumulation texture (smoke2.frag)

Motion Accumulator

The fragment shader used in this view makes use of three separate inputs to generate its result: the current webcam frame, the previous frame and The previous rendering result by the shader itself. The shader computes the black and white difference between the current and previous frame, adds is to the previous rendering result and finally blurs it. After being written to the frame buffer, the output is copied to a texture so it can be passed back to this shader during the next rendering.


Bump Mapped Coin

Main techniques: Environment-mapped bump mapping (envMap.vert coin.frag)

This view uses the embossed image generated for one of the previous views to build a bump map and apply it to the surface of a short cylinder in order to make it look like a coin. For each fragment of the emboss image we compute the x and y gradients and normalize their cross product to get the surface normal at that point. The normal is the used to compute a reflection vector to lookup into a sperical environment map, generated again from the webcam feed (as it was for the Live Environment Mapping view).


Comic book

Main techniques: Fixed palette posterize, embossing (envMap.vert coin.frag)

This view implements a fixed-palette posterization technique: Instead of simply quantizing the color channels, we decide a priori which colors we want to use (in this case light shades of blue, red and white). For each fragment we then compute the distance to each one of the colors, and we choose the one closest to the original. The 'comic book' effect is enhanced by adding contours to the result using an embossing filter.


Ghost

Main techniques: Texture deformation (ghost.frag)

This fragment shader uses the output of the Motion Accumulator view to deform a fixed image (i.e. a background image captured from the webcam using [n]). The motion accumulator output itself is slightly blended with the result inside the fragment shader to give a subtle, ghosthy presence effect on the image.


Geometry Shader Tessellation

Main techniques: Polygon tessellation, environment mapping, vertex shader displacement mapping (heightmap.vert envMap.frag)

This view uses a geometry shader to tessellate a quad in order to form a grid with any desired level of detail. The grid vertices are fed to a vertex shader that used the Motion Accumulator result as a lookup texture to modify the vertex y coordinate. Its worth noting how the vertex normals are not valid anymore at this point so we need to recompute them inside the shader through the same technique used for the Bump Mapped Coin. The resulting deformed surface is then shaded using an environment mapping fragment shader.

Downloads

>>> DOWNLOAD SOURCE AND WIN32 BINARIES <<<

 

myMigthyStats