In black, a patch at level N, and in orange and green, the two right adjacent patches to the black one, in orange and green, both at level N+1.
Now, to generate the normal map of a patch, i'm using the most simple technique ever: differencing the heightfield. For a given texel, i just take the 4 adjacent heights ( left, right, top, bottom ), and generate a normal from that.
The seams problem occurs for all the texels that are on the boundary: for example, all the texels that are at coordinate x = 0 in the patch. The left adjacent height is undefined for those. So, before, i was simply taking the current height, rather than the adjacent one.
You can see in the following shot, the typical problem when showing off the normal map. In red, the horizontal seams. In blue, the vertical ones.
How to fix that ? I choose the most logical solution: taking the height directly from the adjacent patch. Since i've got the links to the adjacent patches, you're probably thinking it's surely only a matter of sampling the heightfield from the adjacent patch, isn't it ? Well, unfortunately, no, it isn't so easy. You have to remember that the adjacent patches can be at a different tesselation level. You have to list all of the possible situations ( left = level - 1, left = level, left = level + 1), and also handle the case where the sampled height doesn't exist.. yet. Just think about it: if the current patch is at level N and the left one is at level N-1, half the height values in the left patch are "missing", and have to be generated on-the-fly when computing the normal. I'll save the details here, but believe me: sometimes it's mind-boggling.
Anyway, i've finished to fix the horizontal seams. Fixing the vertical seams is only a matter of hours now ( hopefully it should be finished tomorrow ). Here is a screenshot after the fix. If you compare with the previous screen, notice that the horizontal seams ( red arrows ) have disappeared, and that the transition for these normals is now smooth: