I'm implementing a line-of-sight calculation shader in which I have an observer which can be dragged about on a map, and the areas visible to the observer are visualized. This is done by traditional shadow mapping where I render the 3D terrain surface in 4 directions with 90 degree frustums to produce depth maps, and then render everything from above, using the four depth maps and frustums for lookup.
This works fairly well as long as there is some variation in the terrain. However, on flat surfaces, the depth map doesn't have enough precision to separate the z values as they get close to the horizon. I have tried to illustrate the problem in the following figure:
This is one of the camera frustums as viewed from the side. When the camera, C gets close to the ground, the two depth values, Z1 and Z2 will map to the same pixel in the depth map, and only the closest one is used, causing the surface beyond this point to be visualized as invisible.
I know that this method will have its limitations, and that the range can't be too far, but does anyone have any ideas about how I could reduce this problem and increase the useful range of this method?
I have tried increasing the number of frustums up to 8 frustums with 45 degree FOV, and it helps a little bit, but not very much.