# Bitmap alpha bevel algorithm?

I am looking to create an algorithm which adds a bevel effect to a bitmap using it's alpha as a bump map.

How would I go doing something like this? I have tried specular lighting but I only get the highlight and not the shade.

All of these were done using size: 30px(The depth of the bevel from the contour of the bitmap), angle 130, altitude 50.

From left to right, top to bottom:

1. Chisel Hard bevel
2. Chisel Soft Bevel
3. Smooth Bevel
4. Chisel Hard with soften: 16px - a blurred bevel?

I am trying to create each of these effects, how would I go about creating the basic bevel? and what do I need to get to each of these from that bevel

This can be accomplished with a convolution of the distance transform.

Use a distance transform on the edge of the mask. Then threshold this distance transform to remove values beyond some distance. I think the secret to getting the shading is to convolve the distance transform result with a kernel that looks something like this:

[ -1.0  -1.0  -1.0
-1.0   0.0   0.0
-1.0   0.0   1.0 ]


This should get you started in the right direction:

#include "opencv/cv.h"
#include "opencv/highgui.h"

using namespace cv;
using namespace std;

int main() {


    //find edges and invert image for distance transform
dist = 255-dist;
threshold(dist, dist, 20, 20, CV_THRESH_TRUNC);
blur(dist, dist, Size(3,3));
dist.convertTo(bevel, CV_8U);
equalizeHist(bevel, bevel);
imshow("2",bevel);


    //convolve with secret sauce
float d[] = {-1,-2,-3,
-2, 0, 0,
-3, 0, 1 };
Mat kernel(3, 3, CV_32F, d);
kernel = kernel - mean(kernel)[0];
filter2D(dist, dist, CV_32F, kernel);

//normalize filtering result to [-1, 1]
double maxVal;
minMaxLoc(dist, NULL, &maxVal);
dist = 128 * dist / maxVal;

//convert and display result
dist.convertTo(bevel, CV_8U, 1, 128);
imshow("3", bevel);


    waitKey(0);
}

• Those look awesome! The one with soften looks like a blur, but how would I go making the "Smooth Bevel" from them? – Shedokan Oct 29 '11 at 10:36
• I believe Smooth Bevel blurs the distance mask before convolution, and Soften blurs the result after convolution. – Matt M. Oct 30 '11 at 0:51

Photoshop's Bevel and Emboss works predictably:

1) Compute a distance transform in a temporary 8-bit single channel image

• Chisel uses the Euclidean Distance Transform with a Chamfer metric (3x3, 5x5, or 7x7 depending on size). You can use an exact euclidean distance transform if you'd like, I prefer the one from Meijster since it can be made anti-aliased ("A General Algorithm for Computing Distance Transforms in Linear Time", MEIJSTER).

• Smooth Bevel uses a Chamfer 5-7-11 distance transform followed by two applications of a box blur, to produce the bump map.

2) Apply bump mapping to the intermediate distance transform image. Blinn's original technique is suitable.

3) For softening you can perform a convolution on the surface normals or you can filter them using a kernel.

4) Using the bump map the surface normals are combined with the global light source to compute the lighting intensity as a value from -1 to 1 where negative values are shadows, positive values are highlights, and the absolute value is the magnitude of the light source.

5) Two 8-bit single channel temporary images are calculated, one from the highlight intensities and the other from the shadows. From there it is is trivial matter to use each masks to tint the layer using a colour, blend mode, and opacity - one mask for the highlights and the other for the shadows.

Visual Basic source code for implementing some of this can be found here:

http://www.Planet-Source-Code.com/vb/scripts/ShowCode.asp?txtCodeId=51640&lngWId=1