Yes, the CPU sky is for:
- ambient lighting spherical harmonic (for directional ambient lighting)
- maximum brightness value (needed before the GPU sky is generated - see below)
- average sky colour (I'm trying to move away from any uses of this)
The GPU sky can still be stored as a 32-bit SRGB texture, doesn't need to be 64-bit HDR if I know the maximum value (from the CPU) before it is generated on the GPU. Each pixel is then multiplied by (1.0 / max_brightness) so the sky uses the full 24-bit range of colours.
I'd sometimes like to be able to generate things on the GPU and read the texture back into system memory for analysis by the program, and I do this, not in realtime, in a few places:
- baked ambient and artificial lighting render
- path-based echo map
- path-based ambient lighting render for cars (called 'lightmap' in LFS)
- path-based occlusion test (called 'optimiser' in LFS)
- calculating average colours from textures
But as far as I know, reading back the texture from GPU to CPU will always cause a small glitch or hesitation, because the CPU must stop and wait, when it calls GetRenderTargetData, until the GPU is ready to send the data. I'm not sure if this is the case with later versions of DirectX - I think later versions are better for getting data back from the GPU because of compute shaders and so on. But I think this is a limitation with DX9 so I've avoided using that in real time situations. Anyway the CPU sky at 64x64 only takes 3 milliseconds in the debug build, and as it's on that separate thread there is no glitch at all, so I think it's quite good now. The lighting system judges that the sun has moved enough to need a new sky, asks the CPU sky thread to make a new sky, then when the CPU sky is generated a few ms later, the main thread tells the GPU to generate the new sky (seems to take no time at all).