public override void Render(Mesh mesh, Camera camera, Matrix4x4[] matrices)
        {
            Bind();
            VertexArray.Bind();

            PositionBuffer.Bind();
            PositionBuffer.SetData(mesh.Attributes["POSITION"].BufferData);

            NormalBuffer.Bind();
            NormalBuffer.SetData(mesh.Attributes["NORMAL"].BufferData);

            MatrixBuffer.Bind();
            MatrixBuffer.SetData(matrices);

            var projectionCast         = camera.GetComponent <CameraComponent>().Projection().Cast();
            var projectionViewLocation = GL.GetUniformLocation(ProgramId, "uViewProjection");

            GL.ProgramUniformMatrix4(ProgramId, projectionViewLocation, false, ref projectionCast);

            var colorLocation = GL.GetUniformLocation(ProgramId, "uColor");
            var colorCast     = Color.CastRendering();

            GL.ProgramUniform3(ProgramId, colorLocation, ref colorCast);

            GL.DrawElementsInstancedBaseInstance(PrimitiveType.Triangles, mesh.Attributes["INDEX"].BufferData.Length / 2, DrawElementsType.UnsignedShort, mesh.Attributes["INDEX"].BufferData, matrices.Length, 0);
        }
        public override void Render(Mesh mesh, Camera camera, Matrix4x4[] matrices)
        {
            Bind();
            VertexArray.Bind();

            PositionBuffer.Bind();
            PositionBuffer.SetData(mesh.Attributes["POSITION"].BufferData);

            NormalBuffer.Bind();
            NormalBuffer.SetData(mesh.Attributes["NORMAL"].BufferData);

            ColorBuffer.Bind();
            ColorBuffer.SetData(mesh.Attributes["COLOR_0"].BufferData);

            MatrixBuffer.Bind();
            MatrixBuffer.SetData(matrices);

            Vector3 lightInvDir = new Vector3(0.5f, 2, 2);

            // Compute the MVP matrix from the light's point of view
            Matrix4x4 depthProjectionMatrix = Matrix4x4.CreateOrthographicOffCenter(-10, 10, -10, 10, -10, 20);
            Matrix4x4 depthViewMatrix       = Matrix4x4.CreateLookAt(lightInvDir, new Vector3(0, 0, 0), Vector3.UnitY);
            Matrix4x4 depthModelMatrix      = Matrix4x4.Identity;;
            Matrix4x4 depthMVP = depthProjectionMatrix * depthViewMatrix * depthModelMatrix;

            var projectionCast         = camera.GetComponent <CameraComponent>().Projection().Cast();
            var projectionViewLocation = GL.GetUniformLocation(ProgramId, "uViewProjection");

            GL.ProgramUniformMatrix4(ProgramId, projectionViewLocation, false, ref projectionCast);

            var depthProjectionCast         = depthMVP.Cast();
            var depthProjectionViewLocation = GL.GetUniformLocation(ProgramId, "uDepthMVP");

            GL.ProgramUniformMatrix4(ProgramId, depthProjectionViewLocation, false, ref depthProjectionCast);

            Matrix4x4 biasMatrix = new Matrix4x4(
                0.5f, 0.0f, 0.0f, 0.0f,
                0.0f, 0.5f, 0.0f, 0.0f,
                0.0f, 0.0f, 0.5f, 0.0f,
                0.5f, 0.5f, 0.5f, 1.0f
                );
            Matrix4x4 depthBiasMVP = biasMatrix * depthMVP;

            var depthBiasCast     = depthBiasMVP.Cast();
            var depthBiasLocation = GL.GetUniformLocation(ProgramId, "uDepthBias");

            GL.ProgramUniformMatrix4(ProgramId, depthBiasLocation, false, ref depthBiasCast);

            var colorLocation = GL.GetUniformLocation(ProgramId, "uColor");
            var colorCast     = Color.CastRendering();

            GL.ProgramUniform3(ProgramId, colorLocation, ref colorCast);

            GL.DrawElementsInstancedBaseInstance(PrimitiveType.Triangles, mesh.Attributes["INDEX"].BufferData.Length / 2, DrawElementsType.UnsignedShort, mesh.Attributes["INDEX"].BufferData, matrices.Length, 0);
        }