2017-06-15 18 views
0

我有一个矩形:制作的UIElement仅可见聚光灯下

<Border x:Name="Elem1" BorderThickness="2" Height="100" Width="200" BorderBrush="Red" /> 

并有Windows.UI.Composition。 射灯与指针togehter移动:

const float LightDistance = 20; 
_compositor = Window.Current.Compositor; 
_pointLight = _compositor.CreatePointLight(); 
_pointLight.Color = Colors.White; 
_pointLight.Targets.Add(ElementCompositionPreview.GetElementVisual(Elem1)); 

PointerMoved += (o, e) => { 
    var point = e.GetCurrentPoint(this).Position; 
    _pointLight.Offset = new Vector3((float)point.X, (float)point.Y, LightDistance); 
}; 

当存在超过rectagle无光,它保持黑色:

enter image description here

我想的矩形的其余部分是透明的,所以只有开明的部分将是可见的

我试图添加透明AmblientLight,但APLHA通道是我gnored。

我想这可能由SceneLightingEffect来实现,但如何? :)

+0

你可以使用口罩,而不是聚光灯下,如果它适合你的情况 –

+0

我也试过这个,但没有成功的。不是因为它不可能我们,而是因为,我的有限UWP的knowlegde我不知道如何创建径向渐变面具和移动它 – Liero

回答

0

特别为您提供:d

public MainPage() 
    { 
     InitializeComponent(); 
     Loaded += MainPage_Loaded; 
    } 

    private CompositionSurfaceBrush _maskSurfaceBrush; 
    private readonly float _size = 512; 

    private async void MainPage_Loaded(object sender, RoutedEventArgs e) 
    { 
     PointerMoved += MainPage_PointerMoved; 

     var compositor = ElementCompositionPreview.GetElementVisual(this).Compositor; 
     var canvasDevice = CanvasDevice.GetSharedDevice(); 
     var graphicsDevice = CanvasComposition.CreateCompositionGraphicsDevice(compositor, canvasDevice); 

     var canvasBitmap = await CanvasBitmap.LoadAsync(canvasDevice, new Uri("ms-appx:///Assets/44578.jpg")); 

     var sourceDrawingSurface = graphicsDevice.CreateDrawingSurface(new Size(_size, _size), DirectXPixelFormat.B8G8R8A8UIntNormalized, DirectXAlphaMode.Premultiplied); 
     using (var ds = CanvasComposition.CreateDrawingSession(sourceDrawingSurface)) 
     { 
      ds.Clear(Colors.Transparent); 
      ds.DrawImage(canvasBitmap); 
     } 

     var sourceSurfaceBrush = compositor.CreateSurfaceBrush(sourceDrawingSurface); 

     var maskRenderTarget = new CanvasRenderTarget(canvasDevice, _size, _size, 96); 
     using (var ds = maskRenderTarget.CreateDrawingSession()) 
     { 
      ds.Clear(Colors.Transparent); 
      ds.FillCircle(_size/2, _size/2, _size/8, Colors.Black); 
     } 

     var blur = new GaussianBlurEffect 
     { 
      BlurAmount = 16, 
      Source = maskRenderTarget 
     }; 

     var blurredMaskDrawingSurface = graphicsDevice.CreateDrawingSurface(new Size(_size, _size), DirectXPixelFormat.B8G8R8A8UIntNormalized, DirectXAlphaMode.Premultiplied); 
     using (var ds = CanvasComposition.CreateDrawingSession(blurredMaskDrawingSurface)) 
     { 
      ds.Clear(Colors.Transparent); 
      ds.DrawImage(blur); 
     } 

     _maskSurfaceBrush = compositor.CreateSurfaceBrush(blurredMaskDrawingSurface); 

     var composite = new CompositeEffect 
     { 
      Sources = { new CompositionEffectSourceParameter("source"), new CompositionEffectSourceParameter("mask") }, 
      Mode = CanvasComposite.DestinationAtop 
     }; 

     var effectFactory = compositor.CreateEffectFactory(composite); 
     var fxBrush = effectFactory.CreateBrush(); 
     fxBrush.SetSourceParameter("source", sourceSurfaceBrush); 
     fxBrush.SetSourceParameter("mask", _maskSurfaceBrush); 

     var sprite = compositor.CreateSpriteVisual(); 
     sprite.Size = new Vector2(_size, _size); 
     sprite.Brush = fxBrush; 

     ElementCompositionPreview.SetElementChildVisual(this, sprite); 
    } 

    private void MainPage_PointerMoved(object sender, PointerRoutedEventArgs e) 
    { 
     var position = e.GetCurrentPoint(this).Position.ToVector2(); 

     _maskSurfaceBrush.Offset = position - new Vector2(_size/2, _size/2); 
    } 

作品比以前更好!