How do I calculate the intersection between a ray and a plane?
This produces the wrong results.
float denom = normal.dot(ray.direction
First consider the math of the ray-plane intersection:
In general one intersects the parametric form of the ray, with the implicit form of the geometry.
So given a ray of the form x = a * t + a0, y = b * t + b0, z = c * t + c0;
and a plane of the form: A x * B y * C z + D = 0;
now substitute the x, y and z ray equations into the plane equation and you will get a polynomial in t. you then solve that polynomial for the real values of t. With those values of t you can back substitute into the ray equation to get the real values of x, y and z. Here it is in Maxima:

Note that the answer looks like the quotient of two dot products! The normal to a plane is the first three coefficients of the plane equation A, B, and C. You still need D to uniquely determine the plane. Then you code that up in the language of your choice like so:
Point3D intersectRayPlane(Ray ray, Plane plane)
{
Point3D point3D;
// Do the dot products and find t > epsilon that provides intersection.
return (point3D);
}