Phong shading can be done manually. You just calculate the phong lighting per pixel with normals interpolated accross the face of each polygon. (of course this very expensive and isnt the best choice for real time rendering as Bubba pointed out)
Here's an excerpt from my raytracer, ive tried to clean up the code a bit for clarity and generalization (hopefully i didnt mess it up too much!). This function is called to calculate the phong lighting for every pixel in the resulting frame (ie. Phong Shading)
ray is the current vector from the eye to the point on the polygon.
face The vertices of the current polygon.
u and v are the interpolation coefficients of the current polygon.
t is the scalar factor of the ray representing the distance from the eye to the point on the polygon.
c is where the resulting color of the pixel will be stored.
information about lights and objects in the scene is found in the scene member variable.
Code:
void RayTracer::calcPhongLighting(const Ray& ray, VertexList* face, float u, float v, float t, Color& c) {
/* the coefficients for each type of lighting */
float kambient = 0.8f;
float kdiffuse = 0.75f;
float kspecular = 0.25f;
float shine = 50.0f;
Point3f point = ray.start + (ray.dir * t);
Vector3f norm = scene->currentObject.normals[(face->vertex) - 1] * u +
scene->currentObject.normals[(face->next->vertex) - 1] * (1.0f - (u + v)) +
scene->currentObject.normals[(face->next->next->vertex) - 1] * v;
norm.normailze();
Ray reflect;
reflect.start = point;
reflect.dir = norm * (2 * norm.dot(ray.dir * -1)) + ray.dir;
reflect.dir.normalize();
// recursive ray trace call for reflection
castRay(scene->objects, reflect, c);
/* after the recursive 'castRay' function returns, 'c' will have the ambient term of the lighting */
c.r = (unsigned char)(c.r * kambient);
c.g = (unsigned char)(c.g * kambient);
c.b = (unsigned char)(c.b * kambient);
for (int i = 0; i < scene->numLights; i++) {
Vector3f lightDir = -(scene->lights[i].pos - point);
Vector3f reflect = norm * (2 * norm.dot(lightDir)) - lightDir;
lightDir.normalize();
reflect.normalize();
float l = norm.dot(lightDir * -1) * kdiffuse + pow((-ray.dir).dot(reflect), shine) * kspecular;
Color light = scene->lights[i].color;
c.r += (int)((float)light.r * l); c.g += (int)((float)light.g * l); c.b += (int)((float)light.b * l);
}
}
(Magos, i know your post was more related to DX support so this may not be of interest to you. I posted this more for the sake of search bait in case anyone else comes wandering in curious about Phong Shading )