How do you implement perspective correct Gouraud shading across a triangle? What's the algorithm for doing so?

I have flat shading working and I have perspective correct texture mapping working.  Is the way your raster Gouraud shading much different from the perspective correct texture mapping?  (Is gouraud shading even supposed to be perspective correct?)

It is my understanding that you interpolate the lighting color/value down the edges, then interpolate across each scanline.  However,  I think I'm stuck on how to properly divide by Z for each pixel to get the correct light/color value for each pixel.

Any algorithm/article/tutorial would be of great help as I've searched everywhere but can only find high level, abstract descriptions of it.

Thanks in advance!
(Is gouraud shading even supposed to be perspective correct?)


Originally, it wouldn't have been perspective correct, but on (hardware) systems these days it will be. FWIW Dreamcast had perspective correct Gouraud shading because, once you are doing perspective correct texturing, it is relatively little additional cost to do Gouraud "correctly".


  I have flat shading working and I have perspective correct texture mapping working. Is the way your raster Gouraud shading much different from the perspective correct texture mapping?


I'm assuming that you've started with homogeneous 'world space' vertices, i.e. something like, 

$[x,y,z, 1, u,v, R,G,B]$,

applied a projection matrix to get

$[X_p, Y_p, Z_p, 1, u, v, R, G, B, w]$,

and then, after clipping, divided through by w to obtain screen coordinates

$[X_p/w, Y_p/w, Z_p/w, 1/w, u/w, v/w, R/w,... ]$.  

For convenience, let's rename $u/w$ and $v/w$ as $u'$ &amp; $v'$, $1/w$ as $w'$, $R/w$ as $R'$ etc.

To do perspective correct texturing I assume you are linearly interpolating, per pixel, the $u'$, $v'$, and $w'$ values, computing the reciprocal of the interpolated  $w'$ and multiplying that by $u'$ and $v'$ to obtain the per-pixel U &amp; V coordinates.

To do perspective correct Gouraud, simply use the same approach with the interpolated $R'$ , $G'$ and $B'$ values. The most expensive part is typically the division (i.e. reciprocal) but that can be shared with the texturing.