There is a modified section is SkyShader.fx, PSSky() function:
// Calculate angular difference between LightVector and vertex normal, radians float dotproduct = dot(LightVector, In.Normal); float angleRcp = 1 / acos(dotproduct / (length(LightVector) * length(In.Normal)));
When inspecting it by fxc.exe, it turns out that the most of these equations are optimized out to a preshader, which means it is impossible to compile it in XNA4. Also, preshaders are unsupported in DX10, so this section must be optimized anyway. Reading about it on internet, turns out that acos() function is a very expensive one, and using it in a pixel shader makes it to be avoidable if at all possible. So the code can be optimized like this:
float dotproduct = dot(LightVector, normalize(In.Normal)); float angleRcp = 1 / (1 - dotproduct) / 1.57; // Pi / 2 = 1.57It is not exactly as the above, but close enough.
The normalization of the LightVector in the end can be done in Sky.cs, at about line 260, where it is calculated, just a new line needs to be inserted:
solarDirection.Normalize();
Also the following calculations could be done outside of HLSL shader, since they are constants during the whole shader operation:
5000 / Fog.a saturate(Fog.a / 5000) saturate(Fog.a / 10000)
As I read everywhere, even in current DX9 preshader optimization they run on the CPU (as the preshaders are getting executed on CPU), but it doesn't work at all in XNA4, and will work, but not optimized out on DX10.
In PSClouds() function the test
if (!Overcast.y && !Overcast.z)compiles to 6 (preshader) instructions! This could be calculated in Materials.cs, and be passed to HLSL as e.g. Overcast.w