Page 1 of 6
Dynamic Cloud Shadows
Posted: 22.12.2007, 01:49
by chris
For people who are building Celestia from sources, here is a patch to enable dynamic cloud shadows in Celestia:
http://www.celestiaproject.net/~claurel/celest ... hadows.zip
Unpack the ZIP archive into your base Celestia folder and rebuild.
As currently implemented, cloud shadows rotate with the cloud layer, but they are unaffected by the sun direction. This is a reasonable approximation for low clouds, but accounting for the sun direction makes clouds look noticeably more realistic. When seen from above, a cloud's shadow will stretch and become more offset from the cloud as the sun approaches the horizon.
I tried the dynamic effect when I originally implemented cloud shadows in an early 1.5.0 prerelease. Unfortunately, there were some insurmountable problems with that approach. I'd come up with the idea to reproject cloud maps onto a cube map in order to do dynamic shadows. Unfortunately, that's expensive in both CPU time (when loading large textures) and memory usage. The technique implemented in my patch does use a cube map, but only as a lookup table--no reprojection is necessary.
There are still a couple problems, which I will fix shortly:
- Cloud shadows don't work for multiple light sources
- There's still one rendering artifact--a longitudinal 'seam'--that I will eliminate by being clever with OpenGL's cube map addressing modes.
Note that cloud shadows will only work in the OpenGL 2.0 render path.
--Chris
Posted: 22.12.2007, 02:24
by chris
I just uploaded a new version of the patch (to the same location) that removes the restriction that the planet surface texture maps not be larger than the maximum hardware texture size. Thus, cloud shadows will work very large surface textures or even virtual textures. The cloud map itself must still fit into a single hardware texture. There's no good workaround for this.
--Chris
Posted: 22.12.2007, 03:51
by chris
. . . and another version uploaded. This change makes cloud shadows work with multiple light sources.
--Chris
Posted: 22.12.2007, 04:57
by chris
In case anyone is wondering why cloud shadows are a big headache . . .
The problem of rendering cloud shadows can be broken down into three steps:
For some point on the surface of a planet:
1. Compute the intersection of the cloud sphere with a line from the surface point to the sun.
2. Find which texel in the cloud texture is mapped at the intersection point.
3. Reduce the amount of light hitting the surface point by the texel opacity.
All three steps are done in shaders. Step one is a straightforward ray-sphere intersection performed in the vertex shader. Step three is a simple multiplication in the pixel shader. Step two is the tricky part.
In principle, there's nothing hard about finding the (u, v) texture coordinate for some point on a sphere. For a simple cylindrical map, the texture coordinates are just the longitude and latitude normalized to values lying between zero and one. In Celestia's coordinate system, the north pole points along the positive y axis, so:
theta = atan2(z, x)
phi = asin(y)
and:
u = (theta / pi + 1) * 0.5
v = phi / pi + 0.5
The obvious solution is to calculate the cloud texture coordinate in the vertex shader and pass them on to the pixel shader. Unfortunately, this approach fails for triangles that span the -z side of the x=0 plane. The discontinuity in atan2 means that some of triangles vertices will have u near 0 and some will have u near 1. These values get interpolated and sent to the pixel shader. The interpolation means that nearly the entire horizontal range of the cloud texture will get mapped in a single triangle! The visual result is a ragged dark longitudinal stripe.
A possible workaround is to perform the inverse trig operations in the pixel shader. Since the calculation is done *after* interpolation, the discontinuity isn't a problem. What is a problem is a limitation of all current GPUs: there's no native support for inverse trig operations in the native shader instruction sets. Approximations are used instead, and experimentation has revealed these to be both slow and of too limited accuracy to be useful.
A common technique in shader programming is to replace expensive computation with lookup tables stored in textures. Could this work for the xyz to uv conversion? Yes, but with some catches. If the u and v coordinates are stored in a cube map, the interpolated cloud sphere intersection point can be used as a cube map texture coordinates to convert to cloud texture coordinates with a single GPU instruction. Unfortunately, only very recent graphics hardware supports cube maps with more than 8 bits per color component with linear interpolation, and 8 bits is not enough. The workaround I came up with for the new dynamic cloud shadow patch is to store the uv LUT values in four 8 bit components: 2 for u, and 2 for v, giving 16 bits of precision for each coordinate. The u coordinate is reconstructed from the red and green texel values:
u = red * 255/256 + green/255
Almost done . . . There's still a problem with a small longitudinal stripe where the -PI and PI sides of atan2's domain meet. This time it's texel interpolation of LUT values that's the problem, not interpolation of vertex attributes. Fortunately, we can work around this by playing games with cube map faces. If we rotate the cube map 45 degrees, we can make the atan2 discontinuity line up with a cube map seam. Setting the OpenGL clamp mode to clamp-to-edge can then prevent interpolation across values at the edges of atan2's range.
--Chris
Posted: 22.12.2007, 10:18
by t00fri
Chris,
I was trying your latest cloud-shadow patch.
I am afraid this implementation is not satisfactory at all.
The resolution of the shadows is way too small, compared to that of the clouds. This generates VERY unpleasant "digital" effects. Here are a few illustrations with my 2k x 1k clouds:
after deactivating the clouds over antarctica, you can see that the digital stuff is certainly NOT from the land texture
Bye Fridger
Posted: 22.12.2007, 15:29
by cartrite
Chris,
I tried your cloudshadow patch and I didn't see the "digital" effects Fridger showed. Probably because I used an 8k cloudmap or maybe it is the 8000 series card? Some with and without shadows can be seen here.
http://www.celestiaproject.net/forum/viewtopic ... 7401#97401
EDIT: I did however see this. You can even see the cube seem from the thumb. These 2 shots are taken east of the southern end of South America.
cartrite
Posted: 22.12.2007, 20:43
by chris
cartrite wrote:Chris,
I tried your cloudshadow patch and I didn't see the "digital" effects Fridger showed. Probably because I used an 8k cloudmap or maybe it is the 8000 series card? Some with and without shadows can be seen here.
http://www.celestiaproject.net/forum/viewtopic ... 7401#97401EDIT: I did however see this. You can even see the cube seem from the thumb. These 2 shots are taken east of the southern end of South America.
I spotted the cube seams as well, though they weren't as evident as in your example. I need to use texture borders to eliminate filtering artifacts between cube faces. Simply increasing the resolution of the cube map LUT (faces are just 128x128 right now) would also help, but isn't required if I get the cube face borders set up correctly.
I realized that there's a more serious problem though: I can't eliminate atan2 range interpolation artifacts on the top and bottom faces. I'm hoping that by increasing the texture resolution, I can at least reduce them to an acceptable level.
--Chris
Posted: 22.12.2007, 21:03
by chris
t00fri wrote:Chris,
I was trying your latest cloud-shadow patch.
I am afraid this implementation is not satisfactory at all.
The resolution of the shadows is way too small, compared to that of the clouds. This generates VERY unpleasant "digital" effects. Here are a few illustrations with my 2k x 1k clouds:
That's nothing like what I see on my GeForce 8800 either with 1k or 8k clouds (otherwise I wouldn't even have bothered posting the patch.) I see two possibilities: there's a bug in the shader compiler in the GeForce FX 5900 driver, or the texel interpolation precision is too low on the 5900. I strongly suspect a shader compiler bug, perhaps something to do with an optimization for the GeForce FX's mixed precision architecture. Tests of the patch on other hardware will be helpful--if there are problems on ATI hardware or GeForce 6/7 series cards, the problem is more likely related to texel interpolation precision.
--Chris
Posted: 22.12.2007, 21:09
by t00fri
chris wrote:t00fri wrote:Chris,
I was trying your latest cloud-shadow patch.
I am afraid this implementation is not satisfactory at all.
The resolution of the shadows is way too small, compared to that of the clouds. This generates VERY unpleasant "digital" effects. Here are a few illustrations with my 2k x 1k clouds:
That's nothing like what I see on my GeForce 8800 either with 1k or 8k clouds (otherwise I wouldn't even have bothered posting the patch.) I see two possibilities: there's a bug in the shader compiler in the GeForce FX 5900 driver, or the texel interpolation precision is too low on the 5900. I strongly suspect a shader compiler bug, perhaps something to do with an optimization for the GeForce FX's mixed precision architecture. Tests of the patch on other hardware will be helpful--if there are problems on ATI hardware or GeForce 6/7 series cards, the problem is more likely related to texel interpolation precision.
--Chris
Clearly the patch should not only work for 8800 cards
. I'll test the code on my laptop card which is more recent.
Of course, I use the latest driver for Linux.
Bye Fridger
Posted: 22.12.2007, 21:14
by chris
t00fri wrote:Clearly the patch should not only work for 8800 cards
. I'll test the code on my laptop card which is more recent.
Of course, I use the latest driver for Linux.
Thank you--this testing would be greatly appreciated!
--Chris
Posted: 22.12.2007, 21:50
by t00fri
Chris,
this time, I used the latest CVS & your latest patch with my Core2Duo Dell Laptop with NVIDIA Quadro NVS 110M card and latest official Dell driver. Windows Xp, recompiled everything with VS .Net 2003 .
Exactly the same "digital" problem! So there is something wrong in your implementation for NON-8800 cards.
Here is a screendump:
Bye Fridger
Posted: 22.12.2007, 22:06
by ElChristou
Fridger, could it be because you use a slightly blue not fully transparent cloud map? Would be odd, but...
Posted: 22.12.2007, 22:15
by t00fri
ElChristou wrote:Fridger, could it be because you use a slightly blue not fully transparent cloud map? Would be odd, but...
No idea, that must be answered by Chris. It is true that I have a blue gradient between Southpole and Northpole in my RGBA cloud texture to simulate atmospheric effects.
Anyhow Chris can check it out. My "famous" 2k clouds are still in my TextureFoundry.
http://www.celestiaproject.net/~t00fri/texfoundry.php4
Bye Fridger
EDIT: No, Christophe. I just switched to the default 1k clouds => same digital problem.
Posted: 22.12.2007, 22:47
by chris
ElChristou wrote:Fridger, could it be because you use a slightly blue not fully transparent cloud map? Would be odd, but...
No, that shouldn't make a difference at all. The only thing that comes to mind as a possibilities are limited texel interpolation precision and driver bugs, but I don't understand how that could be responsible for such blockiness neither quite fits the behavior that Fridger is seeing: we shouldn't see such precisely rectangular blocks from texel precision problems, and it would be odd to have the exact same driver bug on a Quadra NVS 110M and GeForce FX 5900.
--Chris
Posted: 22.12.2007, 22:51
by chris
Fridger,
Do the boundaries of the blocks that you're seeing fall right on polygon edges? It's easy to check by toggling wireframe with Ctrl+W.
--Chris
Posted: 22.12.2007, 23:14
by t00fri
chris wrote:Fridger,
Do the boundaries of the blocks that you're seeing fall right on polygon edges? It's easy to check by toggling wireframe with Ctrl+W.
--Chris
Can't say anything: after hitting CTRL+W, I only see the wireframe with some brighter and less bright regions of the wire.
Actually, I thought I had found the reason...but NO! My 2k clouds are DXT3 format. I thought the squares are from the DXT conversion. But after using Don.Edwards' 2k clouds in PNG format it's still the same.
Too bad...
Bye Fridger
Posted: 22.12.2007, 23:34
by Toti
Fridger,
Could you please post two screenshots taken from the same POV, one of them rendered as wireframe only?
Posted: 23.12.2007, 00:11
by t00fri
Toti wrote:Fridger,
Could you please post two screenshots taken from the same POV, one of them rendered as wireframe only?
Here are two identical images, one just with CTRL+W added . One also sees that familiar artefact band on the non-wireframe one.
Bye Fridger
Posted: 23.12.2007, 00:40
by Toti
Thanks. But doesn't seem to be any alignment between polygons and blocks:
Posted: 23.12.2007, 00:44
by cartrite
I tried everything I can think of short of putting my old 5500 card back in and I can't reproduce these blocks. The wire mode shot looks similar to mine in wire mode as far as polygon size.
cartrite