By transparent you mean that the haze texture is rendered on top of the surface, without regard for terrain features?
Yes, Exactly.
Do you have any ideas? Does DX9 offer any additional solutions for this?
Well, In DX9 we have a multiple options available. I suppose the easiest one would limit the changes for the surfaces rendering alone. In a "post rendering" stage the final color is computed:
cFinal.rgb = cFragment.rgb * cAttennuate.rgb + cInScatter.rgb;
Currently, parameters cAttennuate and cIncatter are computed so that the result is equal to DX7 fixed function fog.
Of course, we can compute the optical depth of an atmosphere between the camera and a vertex located in a surface mesh, resulting a scalar value. But since the optical depth is a wave-length dependent the scalar is multiplied with a wave length dependency vector and the result would be cAttennuate.
It might be possible to compute the cInScatter: cInScatter = HazeColor * optical depth. Of course, the exact equation would require a scaling factors for the optical depth, some clamping and a few factors to match-it with the current sky-dome. But I am not exactly sure about that. We can do some experimentations after implementing the 3D terrain in DX9.
I have never programmed DX7 so I can't really say anything about it. It's possible to do the math via CPU but I don't know how to feed the data into the fixed function pipeline in DX7.
You may find this interesting:
http://etd.dtu.dk/thesis/58645/imm2554.pdf