public Frustum BindShadowDrawing(int a_index, Camera a_camera) { if (m_shadowBuffer == null) { return(null); } Transform transform = m_light.Transform; Vector4[] corners = new Vector4[] { new Vector4(1.0f, 1.0f, 1.0f, 1.0f), new Vector4(1.0f, 1.0f, -1.0f, 1.0f), new Vector4(1.0f, -1.0f, 1.0f, 1.0f), new Vector4(1.0f, -1.0f, -1.0f, 1.0f), new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Vector4(-1.0f, -1.0f, -1.0f, 1.0f) }; Matrix4 viewInv = Matrix4.Identity; Matrix4 camProj = Matrix4.Identity; lock (a_camera) { viewInv = a_camera.Transform.ToMatrix(); camProj = Matrix4.CreatePerspectiveFieldOfView(a_camera.FOV, a_camera.Width / (float)a_camera.Height, m_splits[a_index], m_splits[a_index + 1]); } Matrix4 projInv = Matrix4.Invert(camProj); Vector3 position = Vector3.Zero; Vector3 min = new Vector3(float.PositiveInfinity); Vector3 max = new Vector3(float.NegativeInfinity); Matrix3 rot3 = transform.RotationMatrix; for (int i = 0; i < 8; ++i) { corners[i] = corners[i] * projInv; corners[i] /= corners[i].W; corners[i] = corners[i] * viewInv; position += corners[i].Xyz * 0.125f; } Matrix4 transformMat = Matrix4.CreateFromQuaternion(transform.Quaternion) * Matrix4.CreateTranslation(position); Matrix4 view = Matrix4.Invert(transformMat); Vector4[] endCorners = new Vector4[8]; for (int i = 0; i < 8; ++i) { endCorners[i] = corners[i] * view; min.X = Math.Min(endCorners[i].X, min.X); min.Y = Math.Min(endCorners[i].Y, min.Y); min.Z = Math.Min(endCorners[i].Z, min.Z); max.X = Math.Max(endCorners[i].X, max.X); max.Y = Math.Max(endCorners[i].Y, max.Y); max.Z = Math.Max(endCorners[i].Z, max.Z); } Vector3 extent = max - min; Matrix4 proj = Matrix4.CreateOrthographic(extent.X * 2, extent.Y * 2, -extent.Z * 2, extent.Z); Matrix4 viewProj = view * proj; m_light.SetViewProjection(view, proj, a_index); OpenTKProgram program = (OpenTKProgram)m_light.ShadowProgram.InternalObject; int handle = program.Handle; GL.UseProgram(handle); GL.Viewport(0, 0, DirectionalLight.MapResolution, DirectionalLight.MapResolution); GL.UniformMatrix4(0, false, ref viewProj); GL.BindFramebuffer(FramebufferTarget.Framebuffer, m_shadowBuffer[a_index]); #if DEBUG_INFO Pipeline.GLError("Directional Light: Bind Shadow Drawing: "); #endif return(new Frustum(viewProj)); }