/// <summary> /// Update shadow map. /// </summary> /// <param name="ctx"> /// A <see cref="GraphicsContext"/> used for allocating resources. /// </param> public override void UpdateShadowMap(GraphicsContext ctx, SceneGraph shadowGraph) { CheckCurrentContext(ctx); if (shadowGraph == null) { throw new ArgumentNullException("shadowGraph"); } // Compute light matrix IModelMatrix viewMatrix = new ModelMatrix(); // LocalModel.Multiply(LightMatrix.GetInverseMatrix()).GetInverseMatrix(); viewMatrix.LookAtDirection((Vertex3d)LocalModel.Position, (Vertex3f)Direction, Vertex3d.UnitY); // Set light scene view shadowGraph.ProjectionMatrix = new PerspectiveProjectionMatrix(FalloffAngle * 2.0f, 1.0f, 0.1f, 100.0f); shadowGraph.ViewMatrix = viewMatrix; _ShadowFramebuffer.BindDraw(ctx); // Reset viewport new ViewportState(0, 0, (int)_ShadowMap.Width, (int)_ShadowMap.Height).Apply(ctx, null); _ShadowFramebuffer.Clear(ctx, ClearBufferMask.DepthBufferBit); shadowGraph.Draw(ctx, _ShadowProgram); _ShadowFramebuffer.UnbindDraw(ctx); // Cache view matrix _ShadowViewMatrix = _BiasMatrix.Multiply(shadowGraph.ProjectionMatrix.Multiply(viewMatrix)); }