• API
• FAQ
• Tools
• Trends
• Archive
SHARE
TWEET

a guest Aug 21st, 2010 1,169 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1.         protected OrthographicCamera CalculateFrustum(DirectionalLight light, Camera mainCamera, float minZ, float maxZ)
2.         {
3.             // Shorten the view frustum according to the shadow view distance
4.             Matrix cameraMatrix;
5.             mainCamera.GetWorldMatrix(out cameraMatrix);
6.
7.             for (int i = 0; i < 4; i++)
8.                 splitFrustumCornersVS[i] = frustumCornersVS[i + 4] * (minZ / mainCamera.FarClip);
9.
10.             for (int i = 4; i < 8; i++)
11.                 splitFrustumCornersVS[i] = frustumCornersVS[i] * (maxZ / mainCamera.FarClip);
12.
13.             Vector3.Transform(splitFrustumCornersVS, ref cameraMatrix, frustumCornersWS);
14.
15.             // Position the shadow-caster camera so that it's looking at the centroid,
16.             // and backed up in the direction of the sunlight
17.             Matrix viewMatrix = Matrix.CreateLookAt(Vector3.Zero - (light.Direction * 100), Vector3.Zero, new Vector3(0, 1, 0));
18.
19.             // Determine the position of the frustum corners in light space
20.             Vector3.Transform(frustumCornersWS, ref viewMatrix, frustumCornersLS);
21.
22.             // Calculate an orthographic projection by sizing a bounding box
23.             // to the frustum coordinates in light space
24.             Vector3 mins = frustumCornersLS[0];
25.             Vector3 maxes = frustumCornersLS[0];
26.             for (int i = 0; i < 8; i++)
27.             {
28.                 if (frustumCornersLS[i].X > maxes.X)
29.                     maxes.X = frustumCornersLS[i].X;
30.                 else if (frustumCornersLS[i].X < mins.X)
31.                     mins.X = frustumCornersLS[i].X;
32.                 if (frustumCornersLS[i].Y > maxes.Y)
33.                     maxes.Y = frustumCornersLS[i].Y;
34.                 else if (frustumCornersLS[i].Y < mins.Y)
35.                     mins.Y = frustumCornersLS[i].Y;
36.                 if (frustumCornersLS[i].Z > maxes.Z)
37.                     maxes.Z = frustumCornersLS[i].Z;
38.                 else if (frustumCornersLS[i].Z < mins.Z)
39.                     mins.Z = frustumCornersLS[i].Z;
40.             }
41.
42.             // We snap the camera to 1 pixel increments so that moving the camera does not cause the shadows to jitter.
43.             // This is a matter of integer dividing by the world space size of a texel
44.             float diagonalLength = (frustumCornersWS[0] - frustumCornersWS[6]).Length();
45.             diagonalLength += 2;    //Without this, the shadow map isn't big enough in the world.
46.             float worldsUnitsPerTexel = diagonalLength / (float)ShadowMapSize;
47.
48.             Vector3 vBorderOffset = (new Vector3(diagonalLength, diagonalLength, diagonalLength) - (maxes - mins)) * 0.5f;
49.             maxes += vBorderOffset;
50.             mins -= vBorderOffset;
51.
52.             mins /= worldsUnitsPerTexel;
53.             mins.X = (float)Math.Floor(mins.X);
54.             mins.Y = (float)Math.Floor(mins.Y);
55.             mins.Z = (float)Math.Floor(mins.Z);
56.             mins *= worldsUnitsPerTexel;
57.
58.             maxes /= worldsUnitsPerTexel;
59.             maxes.X = (float)Math.Floor(maxes.X);
60.             maxes.Y = (float)Math.Floor(maxes.Y);
61.             maxes.Z = (float)Math.Floor(maxes.Z);
62.             maxes *= worldsUnitsPerTexel;
63.
64.             // Create an orthographic camera for use as a shadow caster
65.             const float nearClipOffset = 100.0f;
66.             OrthographicCamera lightCamera = new OrthographicCamera(mins.X, maxes.X, mins.Y, maxes.Y, -maxes.Z - nearClipOffset, -mins.Z);
67.             lightCamera.SetViewMatrix(ref viewMatrix);
68.
69.             return lightCamera;
70.         }
RAW Paste Data
Top