Inspired by Angelo Pesce’s comment here, I decided this morning I’d have a go at generating a Normal Map from a live video input, using a CIFilter patch. The code is surprisingly simple.
///////////////////////////
//// FUNCTIONS ////
///////////////////////////
/*
Function to calculate the luminosity of a pixel
*/
float luminosity(vec4 color)
{
vec4 lumcoeff = vec4(0.299,0.587,0.114,0.0);
return dot(color, lumcoeff);
}
/*
Creates Normal Map for use in Displacement Map / Height Map GLSL shaders
*/
vec4 tb_normalMap(sampler inPix)
{
// Sampler dimensions
vec2 dims = samplerSize(inPix);
// Working pixel coordinates
vec2 xy = samplerCoord(inPix);
// Normalised coordinates of working pixel (used to calculate Normal Z component)
vec2 xyNorm = xy / dims;
// Normal grid size (in pixels)
float offset = 1.0;
// Working pixel luminosity
vec4 pix = sample(inPix, samplerTransform(inPix, xy));
float lumCurrent = luminosity(pix);
// Derivitive X
float lumdx = luminosity(sample(inPix, samplerTransform(inPix, vec2(xy.x+offset, xy.y))));
float dx = lumCurrent - lumdx;
// Derivitive Y
float lumdy = luminosity(sample(inPix, samplerTransform(inPix, vec2(xy.x, xy.y+offset))));
float dy = lumCurrent - lumdy;
// Normal Z. I'm not sure if this is strictly-speaking correct, but it seems to work!
float dz = 1.0;
// Output Normal Map
return vec4(dx,dy,dz,1.0);
}
///////////////////////////
//// MAIN LOOP ////
///////////////////////////
kernel vec4 normalMap(sampler Image)
{
// Output Normal Map
return tb_normalMap(Image);
}
The idea is that this map can be used to aid lighting of meshes created with Vertex Displacement Mapping / Heightmap techniques.
May or may not be useful…
Here’s what the effect looks like (I actually think it’s quite a nice effect in it’s own right).
EDIT:
Corrected mistake in function name in main loop.

0 Responses to “Normal Map”
Leave a Reply