By “artifact” you mean the abrupt terminator on specular ?
DirectionalLight is the standard function from the Orange Book
You should post it too for completeness.
I am pretty sure it abruptly sets the specular to 0 when normal is perpendicular to light, whereas the Blinn specular should be smoothed slowly.
In tutorials this artifact is usually disregarded. Even the lit built-in CG function works this way. The problem could be visualized easily:
When dot(N,L) is 0, then dot(N,H) is not close to 0. Moreover, as dot(N,L) leads to 0, dot(N,H) is not leads to 0. This will cause the hard edge of the specular term.
A common workaround is to multiply the specular term with the diffuse term:
The problem with this is that the specular will be too weak for large (N,V) angles (close to 90 deg).
Another solution is to use a 1D lookup texture for the range [0,1] that is smoothly starts from 0 and rise quickly to 1 like this one:
spec = f(diff) * pow(max(0.0, dot(N, H)), Sn);
Another possibility is to use the smoothstep function for f.
You could use smoothstep(diff) for the diffuse term too. This will smoothly mix the “edges” of the lights.