UWP四种光线

AmbientLight 发出显示在场景中的所有内容反射的非定向光线的光源。

public class MyAmbientLight : XamlLight
    {
        private static string GetIdStatic(string id)
        {
            if (string.IsNullOrEmpty(id))
            {
                return typeof(MyAmbientLight).FullName;
            }
            else
            {
                return string.Format("{0}{1}", typeof(MyAmbientLight).FullName, id);
            }
        }

        protected override string GetId()
        {
            return GetIdStatic(LightId);
        }

        #region LightId

        public static readonly DependencyProperty LightIdProperty = DependencyProperty.RegisterAttached("LightId", typeof(string), typeof(MyAmbientLight), new PropertyMetadata(null));

        public string LightId
        {
            get { return GetValue(LightIdProperty) as string; }
            set { SetValue(LightIdProperty, value); }
        }

        #endregion

        #region TargetIdProperty

        // Register an attached property that enables apps to set a UIElement
        // or Brush as a target for this light type in markup.
        public static readonly DependencyProperty TargetIdProperty = DependencyProperty.RegisterAttached("TargetId", typeof(string), typeof(MyAmbientLight), new PropertyMetadata(null, OnTargetIdPropertyChanged));

        public static void SetTargetId(DependencyObject target, string value)
        {
            target.SetValue(TargetIdProperty, value);
        }

        public static string GetTargetId(DependencyObject target)
        {
            return target.GetValue(TargetIdProperty) as string;
        }

        // Handle attached property changed to automatically target and untarget UIElements and Brushes.
        private static void OnTargetIdPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            string oldId = e.OldValue as string;
            string newId = e.NewValue as string;

            string[] oldIds = null;
            if (!string.IsNullOrEmpty(oldId))
            {
                oldIds = oldId.Split(',');
            }
            else
            {
                oldIds = new string[0];
            }
            string[] newIds = null;
            if (!string.IsNullOrEmpty(newId))
            {
                newIds = newId.Split(',');
            }
            else
            {
                newIds = new string[0];
            }

            List<string> added = new List<string>();
            List<string> removed = new List<string>();

            foreach (var id in newIds)
            {
                if (!oldIds.Contains(id))
                {
                    added.Add(id);
                }
            }
            foreach (var id in oldIds)
            {
                if (!newIds.Contains(id))
                {
                    removed.Add(id);
                }
            }

            foreach (var id in added)
            {
                if (obj is UIElement)
                {
                    XamlLight.AddTargetElement(GetIdStatic(id), obj as UIElement);
                }
                else if (obj is Brush)
                {
                    XamlLight.AddTargetBrush(GetIdStatic(id), obj as Brush);
                }
            }
            foreach (var id in removed)
            {
                if (obj is UIElement)
                {
                    XamlLight.RemoveTargetElement(GetIdStatic(id), obj as UIElement);
                }
                else if (obj is Brush)
                {
                    XamlLight.RemoveTargetBrush(GetIdStatic(id), obj as Brush);
                }
            }
        }

        #endregion

        #region ColorProperty

        public static DependencyProperty ColorProperty = DependencyProperty.Register("Color", typeof(Color), typeof(MyAmbientLight), new PropertyMetadata(Colors.Transparent, OnColorPropertyChanged));
        private static void OnColorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MyAmbientLight target)
            {
                target.OnColorChanged((Color)e.NewValue);
            }
        }

        private void OnColorChanged(Color newValue)
        {
            if (CompositionLight is Windows.UI.Composition.AmbientLight ambientLight)
            {
                ambientLight.Color = newValue;
            }
        }

        public Color Color
        {
            get { return (Color)GetValue(ColorProperty); }
            set { SetValue(ColorProperty, value); }
        }

        #endregion

        protected override void OnConnected(UIElement newElement)
        {
            if (CompositionLight == null)
            {
                // OnConnected is called when the first target UIElement is shown on the screen.
                // This enables delaying composition object creation until it's actually necessary.
                var ambientLight = Window.Current.Compositor.CreateAmbientLight();
                ambientLight.Color = Color;

                CompositionLight = ambientLight;
            }
        }

        protected override void OnDisconnected(UIElement oldElement)
        {
            // OnDisconnected is called when there are no more target UIElements on the screen.
            // The CompositionLight should be disposed when no longer required.
            if (CompositionLight != null)
            {
                CompositionLight.Dispose();
                CompositionLight = null;
            }
        }
    }

DistantLight 无限远的远距离光源,它以单个方向发出光。 类似于 sun。

public class MyDistantLight : XamlLight
    {
        // These properties are set up to make it easier to use from XAML. EG: using double instead of float and splitting up Vector3 into separate properties.

        private static string GetIdStatic(string id)
        {
            if (string.IsNullOrEmpty(id))
            {
                return typeof(MyDistantLight).FullName;
            }
            else
            {
                return string.Format("{0}{1}", typeof(MyDistantLight).FullName, id);
            }
        }

        protected override string GetId()
        {
            return GetIdStatic(LightId);
        }

        #region LightId

        public static readonly DependencyProperty LightIdProperty = DependencyProperty.RegisterAttached("LightId", typeof(string), typeof(MyDistantLight), new PropertyMetadata(null));

        public string LightId
        {
            get { return GetValue(LightIdProperty) as string; }
            set { SetValue(LightIdProperty, value); }
        }

        #endregion

        #region TargetIdProperty

        // Register an attached property that enables apps to set a UIElement
        // or Brush as a target for this light type in markup.
        public static readonly DependencyProperty TargetIdProperty = DependencyProperty.RegisterAttached("TargetId", typeof(string), typeof(MyDistantLight), new PropertyMetadata(null, OnTargetIdPropertyChanged));

        public static void SetTargetId(DependencyObject target, string value)
        {
            target.SetValue(TargetIdProperty, value);
        }

        public static string GetTargetId(DependencyObject target)
        {
            return target.GetValue(TargetIdProperty) as string;
        }

        // Handle attached property changed to automatically target and untarget UIElements and Brushes.
        private static void OnTargetIdPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            string oldId = e.OldValue as string;
            string newId = e.NewValue as string;

            string[] oldIds = null;
            if (!string.IsNullOrEmpty(oldId))
            {
                oldIds = oldId.Split(',');
            }
            else
            {
                oldIds = new string[0];
            }
            string[] newIds = null;
            if (!string.IsNullOrEmpty(newId))
            {
                newIds = newId.Split(',');
            }
            else
            {
                newIds = new string[0];
            }

            List<string> added = new List<string>();
            List<string> removed = new List<string>();

            foreach (var id in newIds)
            {
                if (!oldIds.Contains(id))
                {
                    added.Add(id);
                }
            }
            foreach (var id in oldIds)
            {
                if (!newIds.Contains(id))
                {
                    removed.Add(id);
                }
            }

            foreach (var id in added)
            {
                if (obj is UIElement)
                {
                    XamlLight.AddTargetElement(GetIdStatic(id), obj as UIElement);
                }
                else if (obj is Brush)
                {
                    XamlLight.AddTargetBrush(GetIdStatic(id), obj as Brush);
                }
            }
            foreach (var id in removed)
            {
                if (obj is UIElement)
                {
                    XamlLight.RemoveTargetElement(GetIdStatic(id), obj as UIElement);
                }
                else if (obj is Brush)
                {
                    XamlLight.RemoveTargetBrush(GetIdStatic(id), obj as Brush);
                }
            }
        }

        #endregion

        #region ColorProperty

        public static DependencyProperty ColorProperty = DependencyProperty.Register("Color", typeof(Color), typeof(MyDistantLight), new PropertyMetadata(Colors.White, OnColorPropertyChanged));
        private static void OnColorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MyDistantLight target)
            {
                target.OnColorChanged((Color)e.NewValue);
            }
        }

        private void OnColorChanged(Color newValue)
        {
            if (CompositionLight is Windows.UI.Composition.DistantLight distantLight)
            {
                distantLight.Color = newValue;
            }
        }

        public Color Color
        {
            get { return (Color)GetValue(ColorProperty); }
            set { SetValue(ColorProperty, value); }
        }

        #endregion

        #region IntensityProperty

        public static DependencyProperty IntensityProperty = DependencyProperty.Register("Intensity", typeof(double), typeof(MyDistantLight), new PropertyMetadata((double)1, OnIntensityPropertyChanged));

        private static void OnIntensityPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MyDistantLight target)
            {
                target.OnIntensityChanged((double)e.OldValue, (double)e.NewValue);
            }
        }

        private void OnIntensityChanged(double oldValue, double newValue)
        {
            if (CompositionLight is Windows.UI.Composition.DistantLight distantLight)
            {
                distantLight.Intensity = (float)newValue;
            }
        }

        public double Intensity
        {
            get { return (double)GetValue(IntensityProperty); }
            set { SetValue(IntensityProperty, value); }
        }

        #endregion

        #region CoordinateSpaceUIElementProperty

        public static readonly DependencyProperty CoordinateSpaceUIElementProperty = DependencyProperty.Register("CoordinateSpaceUIElement", typeof(UIElement), typeof(MyDistantLight), new PropertyMetadata(null, OnCoordinateSpaceUIElementPropertyChanged));

        private static void OnCoordinateSpaceUIElementPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MyDistantLight target)
            {
                target.CoordinateSpaceUIElementChanged(e.OldValue as UIElement, e.NewValue as UIElement);
            }
        }

        private void CoordinateSpaceUIElementChanged(UIElement oldValue, UIElement newValue)
        {
            if (CompositionLight is Windows.UI.Composition.DistantLight distantLight)
            {
                if (newValue == null)
                {
                    distantLight.CoordinateSpace = null;
                }
                else
                {
                    distantLight.CoordinateSpace = ElementCompositionPreview.GetElementVisual(newValue);
                }
            }
        }

        public UIElement CoordinateSpaceUIElement
        {
            get { return GetValue(CoordinateSpaceUIElementProperty) as UIElement; }
            set { SetValue(CoordinateSpaceUIElementProperty, value); }
        }

        #endregion

        #region DirectionXProperty

        public static readonly DependencyProperty DirectionXProperty = DependencyProperty.Register("DirectionX", typeof(double), typeof(MyDistantLight), new PropertyMetadata((double)0, OnDirectionXPropertyChanged));

        private static void OnDirectionXPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MyDistantLight target)
            {
                target.OnDirectionXChanged((double)e.OldValue, (double)e.NewValue);
            }
        }

        private void OnDirectionXChanged(double oldValue, double newValue)
        {
            if (CompositionLight is Windows.UI.Composition.DistantLight distantLight)
            {
                var oldDirection = distantLight.Direction;
                distantLight.Direction = new Vector3((float)newValue, oldDirection.Y, oldDirection.Z);
            }
        }

        public double DirectionX
        {
            get { return (double)GetValue(DirectionXProperty); }
            set { SetValue(DirectionXProperty, value); }
        }

        #endregion

        #region DirectionYProperty

        public static readonly DependencyProperty DirectionYProperty = DependencyProperty.Register("DirectionY", typeof(double), typeof(MyDistantLight), new PropertyMetadata((double)0, OnDirectionYPropertyChanged));

        private static void OnDirectionYPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MyDistantLight target)
            {
                target.OnDirectionYChanged((double)e.OldValue, (double)e.NewValue);
            }
        }

        private void OnDirectionYChanged(double oldValue, double newValue)
        {
            if (CompositionLight is Windows.UI.Composition.DistantLight distantLight)
            {
                var oldDirection = distantLight.Direction;
                distantLight.Direction = new Vector3(oldDirection.X, (float)newValue, oldDirection.Z);
            }
        }

        public double DirectionY
        {
            get { return (double)GetValue(DirectionYProperty); }
            set { SetValue(DirectionYProperty, value); }
        }

        #endregion

        #region DirectionZProperty

        public static readonly DependencyProperty DirectionZProperty = DependencyProperty.Register("DirectionZ", typeof(double), typeof(MyDistantLight), new PropertyMetadata((double)-1, OnDirectionZPropertyChanged));

        private static void OnDirectionZPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MyDistantLight target)
            {
                target.OnDirectionZChanged((double)e.OldValue, (double)e.NewValue);
            }
        }

        private void OnDirectionZChanged(double oldValue, double newValue)
        {
            if (CompositionLight is Windows.UI.Composition.DistantLight distantLight)
            {
                var oldDirection = distantLight.Direction;
                distantLight.Direction = new Vector3(oldDirection.X, oldDirection.Y, (float)newValue);
            }
        }

        public double DirectionZ
        {
            get { return (double)GetValue(DirectionZProperty); }
            set { SetValue(DirectionZProperty, value); }
        }

        #endregion

        protected override void OnConnected(UIElement newElement)
        {
            if (CompositionLight == null)
            {
                // OnConnected is called when the first target UIElement is shown on the screen.
                // This enables delaying composition object creation until it's actually necessary.
                var distantLight = Window.Current.Compositor.CreateDistantLight();
                distantLight.Color = Color;
                distantLight.Intensity = (float)Intensity;
                var element = CoordinateSpaceUIElement;
                if (element != null)
                {
                    distantLight.CoordinateSpace = ElementCompositionPreview.GetElementVisual(element);
                }
                distantLight.Direction = new Vector3((float)DirectionX, (float)DirectionY, (float)DirectionZ);

                CompositionLight = distantLight;
            }
        }

        protected override void OnDisconnected(UIElement oldElement)
        {
            // OnDisconnected is called when there are no more target UIElements on the screen.
            // The CompositionLight should be disposed when no longer required.
            if (CompositionLight != null)
            {
                CompositionLight.Dispose();
                CompositionLight = null;
            }
        }
    }

PointLight 光的点,可在所有方向发出光。 类似于灯泡。

public class MyPointLight : XamlLight
    {
        // These properties are set up to make it easier to use from XAML. EG: using double instead of float and splitting up Vector3 into separate properties.

        private static string GetIdStatic(string id)
        {
            if (string.IsNullOrEmpty(id))
            {
                return typeof(MyPointLight).FullName;
            }
            else
            {
                return string.Format("{0}{1}", typeof(MyPointLight).FullName, id);
            }
        }

        protected override string GetId()
        {
            return GetIdStatic(LightId);
        }

        #region LightId

        public static readonly DependencyProperty LightIdProperty = DependencyProperty.RegisterAttached("LightId", typeof(string), typeof(MyPointLight), new PropertyMetadata(null));

        public string LightId
        {
            get { return GetValue(LightIdProperty) as string; }
            set { SetValue(LightIdProperty, value); }
        }

        #endregion

        #region TargetIdProperty

        // Register an attached property that enables apps to set a UIElement
        // or Brush as a target for this light type in markup.
        public static readonly DependencyProperty TargetIdProperty = DependencyProperty.RegisterAttached("TargetId", typeof(string), typeof(MyPointLight), new PropertyMetadata(null, OnTargetIdPropertyChanged));

        public static void SetTargetId(DependencyObject target, string value)
        {
            target.SetValue(TargetIdProperty, value);
        }

        public static string GetTargetId(DependencyObject target)
        {
            return target.GetValue(TargetIdProperty) as string;
        }

        // Handle attached property changed to automatically target and untarget UIElements and Brushes.
        private static void OnTargetIdPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            string oldId = e.OldValue as string;
            string newId = e.NewValue as string;

            string[] oldIds = null;
            if (!string.IsNullOrEmpty(oldId))
            {
                oldIds = oldId.Split(',');
            }
            else
            {
                oldIds = new string[0];
            }
            string[] newIds = null;
            if (!string.IsNullOrEmpty(newId))
            {
                newIds = newId.Split(',');
            }
            else
            {
                newIds = new string[0];
            }

            List<string> added = new List<string>();
            List<string> removed = new List<string>();

            foreach (var id in newIds)
            {
                if (!oldIds.Contains(id))
                {
                    added.Add(id);
                }
            }
            foreach (var id in oldIds)
            {
                if (!newIds.Contains(id))
                {
                    removed.Add(id);
                }
            }

            foreach (var id in added)
            {
                if (obj is UIElement)
                {
                    XamlLight.AddTargetElement(GetIdStatic(id), obj as UIElement);
                }
                else if (obj is Brush)
                {
                    XamlLight.AddTargetBrush(GetIdStatic(id), obj as Brush);
                }
            }
            foreach (var id in removed)
            {
                if (obj is UIElement)
                {
                    XamlLight.RemoveTargetElement(GetIdStatic(id), obj as UIElement);
                }
                else if (obj is Brush)
                {
                    XamlLight.RemoveTargetBrush(GetIdStatic(id), obj as Brush);
                }
            }
        }

        #endregion

        #region ColorProperty

        public static DependencyProperty ColorProperty = DependencyProperty.Register("Color", typeof(Color), typeof(MyPointLight), new PropertyMetadata(Colors.White, OnColorPropertyChanged));
        private static void OnColorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MyPointLight target)
            {
                target.OnColorChanged((Color)e.NewValue);
            }
        }

        private void OnColorChanged(Color newValue)
        {
            if (CompositionLight is Windows.UI.Composition.PointLight pointlight)
            {
                pointlight.Color = newValue;
            }
        }

        public Color Color
        {
            get { return (Color)GetValue(ColorProperty); }
            set { SetValue(ColorProperty, value); }
        }

        #endregion

        #region ConstantAttenuationProperty

        public static DependencyProperty ConstantAttenuationProperty = DependencyProperty.Register("ConstantAttenuation", typeof(double), typeof(MyPointLight), new PropertyMetadata((double)0, OnConstantAttenuationPropertyChanged));

        private static void OnConstantAttenuationPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MyPointLight target)
            {
                target.OnConstantAttenuationChanged((double)e.OldValue, (double)e.NewValue);
            }
        }

        private void OnConstantAttenuationChanged(double oldValue, double newValue)
        {
            if (CompositionLight is Windows.UI.Composition.PointLight pointlight)
            {
                pointlight.ConstantAttenuation = (float)newValue;
            }
        }

        public double ConstantAttenuation
        {
            get { return (double)GetValue(ConstantAttenuationProperty); }
            set { SetValue(ConstantAttenuationProperty, value); }
        }

        #endregion

        #region LinearAttenuationProperty

        public static DependencyProperty LinearAttenuationProperty = DependencyProperty.Register("LinearAttenuation", typeof(double), typeof(MyPointLight), new PropertyMetadata((double)0, OnLinearAttenuationPropertyChanged));

        private static void OnLinearAttenuationPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MyPointLight target)
            {
                target.OnLinearAttenuationChanged((double)e.OldValue, (double)e.NewValue);
            }
        }

        private void OnLinearAttenuationChanged(double oldValue, double newValue)
        {
            if (CompositionLight is Windows.UI.Composition.PointLight pointlight)
            {
                pointlight.LinearAttenuation = (float)newValue;
            }
        }

        public double LinearAttenuation
        {
            get { return (double)GetValue(LinearAttenuationProperty); }
            set { SetValue(LinearAttenuationProperty, value); }
        }

        #endregion

        #region QuadraticAttenuationProperty

        public static DependencyProperty QuadraticAttenuationProperty = DependencyProperty.Register("QuadraticAttenuation", typeof(double), typeof(MyPointLight), new PropertyMetadata((double)0, OnQuadraticAttenuationPropertyChanged));

        private static void OnQuadraticAttenuationPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MyPointLight target)
            {
                target.OnQuadraticAttenuationChanged((double)e.OldValue, (double)e.NewValue);
            }
        }

        private void OnQuadraticAttenuationChanged(double oldValue, double newValue)
        {
            if (CompositionLight is Windows.UI.Composition.PointLight pointlight)
            {
                pointlight.QuadraticAttenuation = (float)newValue;
            }
        }

        public double QuadraticAttenuation
        {
            get { return (double)GetValue(QuadraticAttenuationProperty); }
            set { SetValue(QuadraticAttenuationProperty, value); }
        }

        #endregion

        #region IntensityProperty

        public static DependencyProperty IntensityProperty = DependencyProperty.Register("Intensity", typeof(double), typeof(MyPointLight), new PropertyMetadata((double)1, OnIntensityPropertyChanged));

        private static void OnIntensityPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MyPointLight target)
            {
                target.OnIntensityChanged((double)e.OldValue, (double)e.NewValue);
            }
        }

        private void OnIntensityChanged(double oldValue, double newValue)
        {
            if (CompositionLight is Windows.UI.Composition.PointLight pointlight)
            {
                pointlight.Intensity = (float)newValue;
            }
        }

        public double Intensity
        {
            get { return (double)GetValue(IntensityProperty); }
            set { SetValue(IntensityProperty, value); }
        }

        #endregion

        #region CoordinateSpaceUIElementProperty

        public static readonly DependencyProperty CoordinateSpaceUIElementProperty = DependencyProperty.Register("CoordinateSpaceUIElement", typeof(UIElement), typeof(MyPointLight), new PropertyMetadata(null, OnCoordinateSpaceUIElementPropertyChanged));

        private static void OnCoordinateSpaceUIElementPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MyPointLight target)
            {
                target.CoordinateSpaceUIElementChanged(e.OldValue as UIElement, e.NewValue as UIElement);
            }
        }

        private void CoordinateSpaceUIElementChanged(UIElement oldValue, UIElement newValue)
        {
            if (CompositionLight is Windows.UI.Composition.PointLight pointlight)
            {
                if (newValue == null)
                {
                    pointlight.CoordinateSpace = null;
                }
                else
                {
                    pointlight.CoordinateSpace = ElementCompositionPreview.GetElementVisual(newValue);
                }
            }
        }

        public UIElement CoordinateSpaceUIElement
        {
            get { return GetValue(CoordinateSpaceUIElementProperty) as UIElement; }
            set { SetValue(CoordinateSpaceUIElementProperty, value); }
        }

        #endregion

        #region OffsetXProperty

        public static readonly DependencyProperty OffsetXProperty = DependencyProperty.Register("OffsetX", typeof(double), typeof(MyPointLight), new PropertyMetadata((double)0, OnOffsetXPropertyChanged));

        private static void OnOffsetXPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MyPointLight target)
            {
                target.OnOffsetXChanged((double)e.OldValue, (double)e.NewValue);
            }
        }

        private void OnOffsetXChanged(double oldValue, double newValue)
        {
            if (CompositionLight is PointLight pointlight)
            {
                var oldOffset = pointlight.Offset;
                pointlight.Offset = new Vector3((float)newValue, oldOffset.Y, oldOffset.Z);
            }
        }

        public double OffsetX
        {
            get { return (double)GetValue(OffsetXProperty); }
            set { SetValue(OffsetXProperty, value); }
        }

        #endregion

        #region OffsetYProperty

        public static readonly DependencyProperty OffsetYProperty = DependencyProperty.Register("OffsetY", typeof(double), typeof(MyPointLight), new PropertyMetadata((double)0, OnOffsetYPropertyChanged));

        private static void OnOffsetYPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MyPointLight target)
            {
                target.OnOffsetYChanged((double)e.OldValue, (double)e.NewValue);
            }
        }

        private void OnOffsetYChanged(double oldValue, double newValue)
        {
            if (CompositionLight is Windows.UI.Composition.PointLight pointlight)
            {
                var oldOffset = pointlight.Offset;
                pointlight.Offset = new Vector3(oldOffset.X, (float)newValue, oldOffset.Z);
            }
        }

        public double OffsetY
        {
            get { return (double)GetValue(OffsetYProperty); }
            set { SetValue(OffsetYProperty, value); }
        }

        #endregion

        #region OffsetZProperty

        public static readonly DependencyProperty OffsetZProperty = DependencyProperty.Register("OffsetZ", typeof(double), typeof(MyPointLight), new PropertyMetadata((double)100, OnOffsetZPropertyChanged));

        private static void OnOffsetZPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MyPointLight target)
            {
                target.OnOffsetZChanged((double)e.OldValue, (double)e.NewValue);
            }
        }

        private void OnOffsetZChanged(double oldValue, double newValue)
        {
            if (CompositionLight is Windows.UI.Composition.PointLight pointlight)
            {
                var oldOffset = pointlight.Offset;
                pointlight.Offset = new Vector3(oldOffset.X, oldOffset.Y, (float)newValue);
            }
        }

        public double OffsetZ
        {
            get { return (double)GetValue(OffsetZProperty); }
            set { SetValue(OffsetZProperty, value); }
        }

        #endregion

        public new CompositionLight CompositionLight
        {
            get => base.CompositionLight;
            set => base.CompositionLight = value;
        }

        protected override void OnConnected(UIElement newElement)
        {
            if (CompositionLight == null)
            {
                // OnConnected is called when the first target UIElement is shown on the screen.
                // This enables delaying composition object creation until it's actually necessary.
                var pointlight = Window.Current.Compositor.CreatePointLight();
                pointlight.Color = Color;
                pointlight.ConstantAttenuation = (float)ConstantAttenuation;
                pointlight.LinearAttenuation = (float)LinearAttenuation;
                pointlight.QuadraticAttenuation = (float)QuadraticAttenuation;
                pointlight.Intensity = (float)Intensity;
                var element = CoordinateSpaceUIElement;
                if (element != null)
                {
                    pointlight.CoordinateSpace = ElementCompositionPreview.GetElementVisual(element);
                }
                pointlight.Offset = new Vector3((float)OffsetX, (float)OffsetY, (float)OffsetZ);

                CompositionLight = pointlight;
            }
        }

        protected override void OnDisconnected(UIElement oldElement)
        {
            // OnDisconnected is called when there are no more target UIElements on the screen.
            // The CompositionLight should be disposed when no longer required.
            if (CompositionLight != null)
            {
                CompositionLight.Dispose();
                CompositionLight = null;
            }
        }
    }

SpotLight 发出灯光的内部和外部圆锥的光源。 类似于闪光灯。

public class MySpotlight : XamlLight
    {
        // These properties are set up to make it easier to use from XAML. EG: using double instead of float and splitting up Vector3 into separate properties.

        private static string GetIdStatic(string id)
        {
            if (string.IsNullOrEmpty(id))
            {
                return typeof(MySpotlight).FullName;
            }
            else
            {
                return string.Format("{0}{1}", typeof(MySpotlight).FullName, id);
            }
        }

        protected override string GetId()
        {
            return GetIdStatic(LightId);
        }

        #region LightId

        public static readonly DependencyProperty LightIdProperty = DependencyProperty.RegisterAttached("LightId", typeof(string), typeof(MySpotlight), new PropertyMetadata(null));

        public string LightId
        {
            get { return GetValue(LightIdProperty) as string; }
            set { SetValue(LightIdProperty, value); }
        }

        #endregion

        #region TargetIdProperty

        // Register an attached property that enables apps to set a UIElement
        // or Brush as a target for this light type in markup.
        public static readonly DependencyProperty TargetIdProperty = DependencyProperty.RegisterAttached("TargetId", typeof(string), typeof(MySpotlight), new PropertyMetadata(null, OnTargetIdPropertyChanged));

        public static void SetTargetId(DependencyObject target, string value)
        {
            target.SetValue(TargetIdProperty, value);
        }

        public static string GetTargetId(DependencyObject target)
        {
            return target.GetValue(TargetIdProperty) as string;
        }

        // Handle attached property changed to automatically target and untarget UIElements and Brushes.
        private static void OnTargetIdPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            string oldId = e.OldValue as string;
            string newId = e.NewValue as string;

            string[] oldIds = null;
            if (!string.IsNullOrEmpty(oldId))
            {
                oldIds = oldId.Split(',');
            }
            else
            {
                oldIds = new string[0];
            }
            string[] newIds = null;
            if (!string.IsNullOrEmpty(newId))
            {
                newIds = newId.Split(',');
            }
            else
            {
                newIds = new string[0];
            }

            List<string> added = new List<string>();
            List<string> removed = new List<string>();

            foreach (var id in newIds)
            {
                if (!oldIds.Contains(id))
                {
                    added.Add(id);
                }
            }
            foreach (var id in oldIds)
            {
                if (!newIds.Contains(id))
                {
                    removed.Add(id);
                }
            }

            foreach (var id in added)
            {
                if (obj is UIElement)
                {
                    XamlLight.AddTargetElement(GetIdStatic(id), obj as UIElement);
                }
                else if (obj is Brush)
                {
                    XamlLight.AddTargetBrush(GetIdStatic(id), obj as Brush);
                }
            }
            foreach (var id in removed)
            {
                if (obj is UIElement)
                {
                    XamlLight.RemoveTargetElement(GetIdStatic(id), obj as UIElement);
                }
                else if (obj is Brush)
                {
                    XamlLight.RemoveTargetBrush(GetIdStatic(id), obj as Brush);
                }
            }
        }

        #endregion

        #region ConstantAttenuationProperty

        public static DependencyProperty ConstantAttenuationProperty = DependencyProperty.Register("ConstantAttenuation", typeof(double), typeof(MySpotlight), new PropertyMetadata((double)0, OnConstantAttenuationPropertyChanged));

        private static void OnConstantAttenuationPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MySpotlight target)
            {
                target.OnConstantAttenuationChanged((double)e.OldValue, (double)e.NewValue);
            }
        }

        private void OnConstantAttenuationChanged(double oldValue, double newValue)
        {
            if (CompositionLight is Windows.UI.Composition.SpotLight spotlight)
            {
                spotlight.ConstantAttenuation = (float)newValue;
            }
        }

        public double ConstantAttenuation
        {
            get { return (double)GetValue(ConstantAttenuationProperty); }
            set { SetValue(ConstantAttenuationProperty, value); }
        }

        #endregion

        #region LinearAttenuationProperty

        public static DependencyProperty LinearAttenuationProperty = DependencyProperty.Register("LinearAttenuation", typeof(double), typeof(MySpotlight), new PropertyMetadata((double)0, OnLinearAttenuationPropertyChanged));

        private static void OnLinearAttenuationPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MySpotlight target)
            {
                target.OnLinearAttenuationChanged((double)e.OldValue, (double)e.NewValue);
            }
        }

        private void OnLinearAttenuationChanged(double oldValue, double newValue)
        {
            if (CompositionLight is Windows.UI.Composition.SpotLight spotlight)
            {
                spotlight.LinearAttenuation = (float)newValue;
            }
        }

        public double LinearAttenuation
        {
            get { return (double)GetValue(LinearAttenuationProperty); }
            set { SetValue(LinearAttenuationProperty, value); }
        }

        #endregion

        #region QuadraticAttenuationProperty

        public static DependencyProperty QuadraticAttenuationProperty = DependencyProperty.Register("QuadraticAttenuation", typeof(double), typeof(MySpotlight), new PropertyMetadata((double)0, OnQuadraticAttenuationPropertyChanged));

        private static void OnQuadraticAttenuationPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MySpotlight target)
            {
                target.OnQuadraticAttenuationChanged((double)e.OldValue, (double)e.NewValue);
            }
        }

        private void OnQuadraticAttenuationChanged(double oldValue, double newValue)
        {
            if (CompositionLight is Windows.UI.Composition.SpotLight spotlight)
            {
                spotlight.QuadraticAttenuation = (float)newValue;
            }
        }

        public double QuadraticAttenuation
        {
            get { return (double)GetValue(QuadraticAttenuationProperty); }
            set { SetValue(QuadraticAttenuationProperty, value); }
        }

        #endregion

        #region InnerConeAngleInDegreesProperty

        public static DependencyProperty InnerConeAngleInDegreesProperty = DependencyProperty.Register("InnerConeAngleInDegrees", typeof(double), typeof(MySpotlight), new PropertyMetadata((double)0, OnInnerConeAngleInDegreesPropertyChanged));

        private static void OnInnerConeAngleInDegreesPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MySpotlight target)
            {
                target.OnInnerConeAngleInDegreesChanged((double)e.OldValue, (double)e.NewValue);
            }
        }

        private void OnInnerConeAngleInDegreesChanged(double oldValue, double newValue)
        {
            if (CompositionLight is Windows.UI.Composition.SpotLight spotlight)
            {
                spotlight.InnerConeAngleInDegrees = (float)newValue;
            }
        }

        public double InnerConeAngleInDegrees
        {
            get { return (double)GetValue(InnerConeAngleInDegreesProperty); }
            set { SetValue(InnerConeAngleInDegreesProperty, value); }
        }

        #endregion

        #region InnerConeColorProperty

        public static DependencyProperty InnerConeColorProperty = DependencyProperty.Register("InnerConeColor", typeof(Color), typeof(MySpotlight), new PropertyMetadata(Colors.White, OnInnerConeColorPropertyChanged));

        private static void OnInnerConeColorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MySpotlight target)
            {
                target.OnInnerConeColorChanged((Color)e.OldValue, (Color)e.NewValue);
            }
        }

        private void OnInnerConeColorChanged(Color oldValue, Color newValue)
        {
            if (CompositionLight is Windows.UI.Composition.SpotLight spotlight)
            {
                spotlight.InnerConeColor = newValue;
            }
        }

        public Color InnerConeColor
        {
            get { return (Color)GetValue(InnerConeColorProperty); }
            set { SetValue(InnerConeColorProperty, value); }
        }

        #endregion

        #region InnerConeIntensityProperty

        public static DependencyProperty InnerConeIntensityProperty = DependencyProperty.Register("InnerConeIntensity", typeof(double), typeof(MySpotlight), new PropertyMetadata((double)1, OnInnerConeIntensityPropertyChanged));

        private static void OnInnerConeIntensityPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MySpotlight target)
            {
                target.OnInnerConeIntensityChanged((double)e.OldValue, (double)e.NewValue);
            }
        }

        private void OnInnerConeIntensityChanged(double oldValue, double newValue)
        {
            if (CompositionLight is Windows.UI.Composition.SpotLight spotlight)
            {
                spotlight.InnerConeIntensity = (float)newValue;
            }
        }

        public double InnerConeIntensity
        {
            get { return (double)GetValue(InnerConeIntensityProperty); }
            set { SetValue(InnerConeIntensityProperty, value); }
        }

        #endregion

        #region OuterConeAngleInDegreesProperty

        public static DependencyProperty OuterConeAngleInDegreesProperty = DependencyProperty.Register("OuterConeAngleInDegrees", typeof(double), typeof(MySpotlight), new PropertyMetadata((double)0, OnOuterConeAngleInDegreesPropertyChanged));

        private static void OnOuterConeAngleInDegreesPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MySpotlight target)
            {
                target.OuterConeAngleInDegreesChanged((double)e.OldValue, (double)e.NewValue);
            }
        }

        private void OuterConeAngleInDegreesChanged(double oldValue, double newValue)
        {
            if (CompositionLight is Windows.UI.Composition.SpotLight spotlight)
            {
                spotlight.OuterConeAngleInDegrees = (float)newValue;
            }
        }

        public double OuterConeAngleInDegrees
        {
            get { return (double)GetValue(OuterConeAngleInDegreesProperty); }
            set { SetValue(OuterConeAngleInDegreesProperty, value); }
        }

        #endregion

        #region OuterConeColorProperty

        public static DependencyProperty OuterConeColorProperty = DependencyProperty.Register("OuterConeColor", typeof(Color), typeof(MySpotlight), new PropertyMetadata(Colors.White, OnOuterConeColorPropertyChanged));

        private static void OnOuterConeColorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MySpotlight target)
            {
                target.OnOuterConeColorChanged((Color)e.OldValue, (Color)e.NewValue);
            }
        }

        private void OnOuterConeColorChanged(Color oldValue, Color newValue)
        {
            if (CompositionLight is Windows.UI.Composition.SpotLight spotlight)
            {
                spotlight.OuterConeColor = newValue;
            }
        }

        public Color OuterConeColor
        {
            get { return (Color)GetValue(OuterConeColorProperty); }
            set { SetValue(OuterConeColorProperty, value); }
        }

        #endregion

        #region OuterConeIntensityProperty

        public static DependencyProperty OuterConeIntensityProperty = DependencyProperty.Register("OuterConeIntensity", typeof(double), typeof(MySpotlight), new PropertyMetadata((double)1, OnOuterConeIntensityPropertyChanged));

        private static void OnOuterConeIntensityPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MySpotlight target)
            {
                target.OnOuterConeIntensityChanged((double)e.OldValue, (double)e.NewValue);
            }
        }

        private void OnOuterConeIntensityChanged(double oldValue, double newValue)
        {
            if (CompositionLight is Windows.UI.Composition.SpotLight spotlight)
            {
                spotlight.OuterConeIntensity = (float)newValue;
            }
        }

        public double OuterConeIntensity
        {
            get { return (double)GetValue(OuterConeIntensityProperty); }
            set { SetValue(OuterConeIntensityProperty, value); }
        }

        #endregion

        #region CoordinateSpaceUIElementProperty

        public static readonly DependencyProperty CoordinateSpaceUIElementProperty = DependencyProperty.Register("CoordinateSpaceUIElement", typeof(UIElement), typeof(MySpotlight), new PropertyMetadata(null, OnCoordinateSpaceUIElementPropertyChanged));

        private static void OnCoordinateSpaceUIElementPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MySpotlight target)
            {
                target.CoordinateSpaceUIElementChanged(e.OldValue as UIElement, e.NewValue as UIElement);
            }
        }

        private void CoordinateSpaceUIElementChanged(UIElement oldValue, UIElement newValue)
        {
            if (CompositionLight is Windows.UI.Composition.SpotLight spotlight)
            {
                if (newValue == null)
                {
                    spotlight.CoordinateSpace = null;
                }
                else
                {
                    spotlight.CoordinateSpace = ElementCompositionPreview.GetElementVisual(newValue);
                }
            }
        }

        public UIElement CoordinateSpaceUIElement
        {
            get { return GetValue(CoordinateSpaceUIElementProperty) as UIElement; }
            set { SetValue(CoordinateSpaceUIElementProperty, value); }
        }

        #endregion

        #region DirectionXProperty

        public static readonly DependencyProperty DirectionXProperty = DependencyProperty.Register("DirectionX", typeof(double), typeof(MySpotlight), new PropertyMetadata((double)0, OnDirectionXPropertyChanged));

        private static void OnDirectionXPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MySpotlight target)
            {
                target.OnDirectionXChanged((double)e.OldValue, (double)e.NewValue);
            }
        }

        private void OnDirectionXChanged(double oldValue, double newValue)
        {
            if (CompositionLight is Windows.UI.Composition.SpotLight spotlight)
            {
                var oldDirection = spotlight.Direction;
                spotlight.Direction = new Vector3((float)newValue, oldDirection.Y, oldDirection.Z);
            }
        }

        public double DirectionX
        {
            get { return (double)GetValue(DirectionXProperty); }
            set { SetValue(DirectionXProperty, value); }
        }

        #endregion

        #region DirectionYProperty

        public static readonly DependencyProperty DirectionYProperty = DependencyProperty.Register("DirectionY", typeof(double), typeof(MySpotlight), new PropertyMetadata((double)0, OnDirectionYPropertyChanged));

        private static void OnDirectionYPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MySpotlight target)
            {
                target.OnDirectionYChanged((double)e.OldValue, (double)e.NewValue);
            }
        }

        private void OnDirectionYChanged(double oldValue, double newValue)
        {
            if (CompositionLight is Windows.UI.Composition.SpotLight spotlight)
            {
                var oldDirection = spotlight.Direction;
                spotlight.Direction = new Vector3(oldDirection.X, (float)newValue, oldDirection.Z);
            }
        }

        public double DirectionY
        {
            get { return (double)GetValue(DirectionYProperty); }
            set { SetValue(DirectionYProperty, value); }
        }

        #endregion

        #region DirectionZProperty

        public static readonly DependencyProperty DirectionZProperty = DependencyProperty.Register("DirectionZ", typeof(double), typeof(MySpotlight), new PropertyMetadata((double)-1, OnDirectionZPropertyChanged));

        private static void OnDirectionZPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MySpotlight target)
            {
                target.OnDirectionZChanged((double)e.OldValue, (double)e.NewValue);
            }
        }

        private void OnDirectionZChanged(double oldValue, double newValue)
        {
            if (CompositionLight is Windows.UI.Composition.SpotLight spotlight)
            {
                var oldDirection = spotlight.Direction;
                spotlight.Direction = new Vector3(oldDirection.X, oldDirection.Y, (float)newValue);
            }
        }

        public double DirectionZ
        {
            get { return (double)GetValue(DirectionZProperty); }
            set { SetValue(DirectionZProperty, value); }
        }

        #endregion

        #region OffsetXProperty

        public static readonly DependencyProperty OffsetXProperty = DependencyProperty.Register("OffsetX", typeof(double), typeof(MySpotlight), new PropertyMetadata((double)0, OnOffsetXPropertyChanged));

        private static void OnOffsetXPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MySpotlight target)
            {
                target.OnOffsetXChanged((double)e.OldValue, (double)e.NewValue);
            }
        }

        private void OnOffsetXChanged(double oldValue, double newValue)
        {
            if (CompositionLight is Windows.UI.Composition.SpotLight spotlight)
            {
                var oldOffset = spotlight.Offset;
                spotlight.Offset = new Vector3((float)newValue, oldOffset.Y, oldOffset.Z);
            }
        }

        public double OffsetX
        {
            get { return (double)GetValue(OffsetXProperty); }
            set { SetValue(OffsetXProperty, value); }
        }

        #endregion

        #region OffsetYProperty

        public static readonly DependencyProperty OffsetYProperty = DependencyProperty.Register("OffsetY", typeof(double), typeof(MySpotlight), new PropertyMetadata((double)0, OnOffsetYPropertyChanged));

        private static void OnOffsetYPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MySpotlight target)
            {
                target.OnOffsetYChanged((double)e.OldValue, (double)e.NewValue);
            }
        }

        private void OnOffsetYChanged(double oldValue, double newValue)
        {
            if (CompositionLight is Windows.UI.Composition.SpotLight spotlight)
            {
                var oldOffset = spotlight.Offset;
                spotlight.Offset = new Vector3(oldOffset.X, (float)newValue, oldOffset.Z);
            }
        }

        public double OffsetY
        {
            get { return (double)GetValue(OffsetYProperty); }
            set { SetValue(OffsetYProperty, value); }
        }

        #endregion

        #region OffsetZProperty

        public static readonly DependencyProperty OffsetZProperty = DependencyProperty.Register("OffsetZ", typeof(double), typeof(MySpotlight), new PropertyMetadata((double)100, OnOffsetZPropertyChanged));

        private static void OnOffsetZPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MySpotlight target)
            {
                target.OnOffsetZChanged((double)e.OldValue, (double)e.NewValue);
            }
        }

        private void OnOffsetZChanged(double oldValue, double newValue)
        {
            if (CompositionLight is Windows.UI.Composition.SpotLight spotlight)
            {
                var oldOffset = spotlight.Offset;
                spotlight.Offset = new Vector3(oldOffset.X, oldOffset.Y, (float)newValue);
            }
        }

        public double OffsetZ
        {
            get { return (double)GetValue(OffsetZProperty); }
            set { SetValue(OffsetZProperty, value); }
        }

        #endregion

        protected override void OnConnected(UIElement newElement)
        {
            if (CompositionLight == null)
            {
                // OnConnected is called when the first target UIElement is shown on the screen.
                // This enables delaying composition object creation until it's actually necessary.
                var spotlight = Window.Current.Compositor.CreateSpotLight();
                spotlight.ConstantAttenuation = (float)ConstantAttenuation;
                spotlight.LinearAttenuation = (float)LinearAttenuation;
                spotlight.QuadraticAttenuation = (float)QuadraticAttenuation;
                spotlight.InnerConeAngleInDegrees = (float)InnerConeAngleInDegrees;
                spotlight.InnerConeColor = InnerConeColor;
                spotlight.InnerConeIntensity = (float)InnerConeIntensity;
                spotlight.OuterConeAngleInDegrees = (float)OuterConeAngleInDegrees;
                spotlight.OuterConeColor = OuterConeColor;
                spotlight.OuterConeIntensity = (float)OuterConeIntensity;
                var element = CoordinateSpaceUIElement;
                if (element != null)
                {
                    spotlight.CoordinateSpace = ElementCompositionPreview.GetElementVisual(element);
                }
                spotlight.Direction = new Vector3((float)DirectionX, (float)DirectionY, (float)DirectionZ);
                spotlight.Offset = new Vector3((float)OffsetX, (float)OffsetY, (float)OffsetZ);

                CompositionLight = spotlight;
            }
        }

        protected override void OnDisconnected(UIElement oldElement)
        {
            // OnDisconnected is called when there are no more target UIElements on the screen.
            // The CompositionLight should be disposed when no longer required.
            if (CompositionLight != null)
            {
                CompositionLight.Dispose();
                CompositionLight = null;
            }
        }
    }

复制粘贴以后就能直接用了

<Grid x:Name="parent_Grid" Width="310" Height="310">
                        <Grid.Lights>
                            <local:MyDistantLight LightId="myGridDistantLight" Color="Black" Intensity="0.2" DirectionX="0" DirectionZ="-1"/>
                            <local:MyPointLight x:Name="myGridPointLight" LightId="myGridPointLight" Color="White" ConstantAttenuation="0.4" LinearAttenuation="0" OffsetX="150" OffsetY="150" QuadraticAttenuation="1" OffsetZ="30" Intensity="1"/>
                        </Grid.Lights>
                        <Grid x:Name="image_Grid" Width="300" Height="300" local:MyDistantLight.TargetId="myGridDistantLight" local:MyPointLight.TargetId="myGridPointLight">
                            <Grid.ScaleTransition>
                                <Vector3Transition/>
                            </Grid.ScaleTransition>
                            <Image Source="{Binding}" Stretch="Fill"/>
                        </Grid>
                    </Grid>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值