Windows 应用 SDK 中的 Microsoft.UI.Composition API 使你能够创建实时动画和效果。 合成照明支持 2D 应用程序中的 3D 照明。 在本概述中,我们将介绍如何设置合成灯、识别视觉对象以接收每个光线以及使用效果来定义内容材料的功能。
注释
若要阅读 XamlLight 对象如何应用 CompositionLights 来照亮 XAML UIElements,请参阅 XAML 照明。
合成照明允许你通过以下方式创建有趣的 UI:
- 转换与场景中其他对象无关的光线,以实现沉浸式方案,如音乐播放场景。
- 具备将对象与光源配对的能力,使它们能独立于场景的其他部分移动,从而实现 Fluent Reveal 高亮等效果。
- 将光和整个场景作为一个整体来转变,以创建材料和深度。
合成照明支持三个关键概念: 光、 目标和SceneLightingEffect。
浅色
CompositionLight 允许你创建各种灯光并将其放置在坐标空间中。 这些灯以你希望识别为由光点亮的视觉对象为目标。
光源类型
| 类型 | 说明 |
|---|---|
| AmbientLight | 一种光源,它发出非方向光,光在场景中所有物体上似乎都被反射。 |
| DistantLight | 一个无限大的遥远的光源,以单个方向发出光。 像太阳一样。 |
| PointLight | 向所有方向发出光的光点源。 就像灯泡一样。 |
| 聚光灯 | 发出内部和外锥光的光源。 就像手电筒一样。 |
目标
当灯光面向视觉对象(添加到 目标 列表)时,视觉对象及其所有后代都知道并响应此光源。 这可以像在树根处设置 PointLight 源一样简单,下面的所有视觉对象都对点光方向的动画做出反应。
ExclusionsFromTargets 使你能够以与添加目标类似的方式取消视觉对象或视觉对象子树的照明效果。 因为视觉对象被排除,树中的子节点不会亮起。
示例(目标)
在下面的示例中,我们使用 PointLight 以 XAML TextBlock 为目标。
_pointLight = _compositor.CreatePointLight();
_pointLight.Color = Colors.White;
_pointLight.CoordinateSpace = text; //set up co-ordinate space for offset
_pointLight.Targets.Add(text); //target XAML TextBlock
通过将动画添加到点光源的偏移量,可以轻松实现闪烁效果。
_pointLight.Offset = new Vector3(-(float)TextBlock.ActualWidth, (float)TextBlock.ActualHeight / 2, (float)TextBlock.FontSize);
请参阅 GitHub 上的完整 文本填充 示例,了解详细信息。
Restrictions
确定 CompositionLight 将点亮哪些内容时需要考虑几个因素。
| 概念 | 详细信息 |
|---|---|
| 环境光 | 向场景添加非环境光将关闭所有现有光。 未被非环境光照射到的项目将呈现为黑色。 若要以自然方式照亮未以光线为目标的周围视觉对象,请使用环境光与其他灯光结合使用。 |
| 灯数 | 可以在任意组合中使用任意两个非环境组合灯用于 UI。 环境光不受限制;聚光灯、点光、和远光灯是有限制的。 |
| 生命周期 | CompositionLight 可能会遇到生存期条件(例如:垃圾回收器可以在使用光对象之前回收它)。 建议通过将灯作为成员添加以帮助应用程序管理生命周期,从而保留对灯光的引用。 |
| 转换 | 光必须放置在 UI 上方的节点中,该节点使用视觉结构中的 透视转换 等效果才能正确绘制。 |
| 目标和坐标空间 | CoordinateSpace 是需要设置所有灯光属性的视觉空间。 CompositionLight.Targets 必须位于 CoordinateSpace 树中。 |
照明属性
根据所使用的光线类型,光可以具有衰减和空间的属性。 并非所有类型的灯都使用所有属性。
| 财产 | 说明 |
|---|---|
| 颜色 | 光的 颜色。 照明颜色值由 D3D 漫射光、环境光和镜面反射光来定义,以确定所发射的颜色。 照明对灯光使用 RGBA 值;不使用 alpha 颜色组件。 |
| 方向 | 光的方向。 光线的指向相对于其 CoordinateSpace 可视空间来指定。 |
| 坐标空间 | 每个视觉对象都有一个隐式 3D 坐标空间。 X方向是从左到右。 Y 方向从上到下。 Z 方向是指向平面外的一条方向。 此坐标的原始点是视觉对象的左上角,单位为设备独立像素(DIP)。 在此坐标中定义光的偏移量。 |
| 内锥体和外锥体 | 聚光灯发出有两部分的光锥:明亮的内锥和外锥。 合成允许你控制内部和外部圆锥角度和颜色。 |
| 偏移量 | 相对于其坐标空间视觉对象的光源偏移量。 |
注释
当多个光源同时影响同一个视觉元素,或某个光源的颜色值大到超过1.0时,该光源的颜色可能会因为颜色通道的限制而发生变化。
高级照明属性
| 财产 | 说明 |
|---|---|
| 强度 | 控制光的亮度。 |
| 衰减 | 衰减控制光线强度如何降低到范围属性指定的最大距离。 可以使用常量、二次和线性衰减属性。 |
照明入门
按照以下常规步骤添加灯:
- 创建并放置灯:创建灯光并将其放置在指定的坐标空间中。
- 识别要照亮的对象:将光线投射到相关视觉对象上。
- [可选]定义单个对象对灯光的反应:将 SceneLightingEffect 与 EffectBrush 配合使用,自定义用于显示 SpriteVisual 的光反射。 反射默认值支持光源的 CoordinateSpace 子级的照明。 使用 SceneLightingEffect 绘制的视觉对象覆盖该视觉对象的默认照明。
场景照明效果
SceneLightingEffect 用于修改应用于由 CompositionLight 定义的 SpriteVisual 内容的默认照明。
SceneLightingEffect 通常用于材料创建。 SceneLightingEffect 是一种效果,用于实现更复杂的内容,例如在图像上启用反射属性和/或为普通地图提供深度错觉。 SceneLightingEffect 提供使用反射量和漫射量等照明属性自定义 UI 的功能。 可以通过效果管道的其余部分进一步自定义照明效果,使您能够单独混合和组合内容的不同光照效果。
注释
场景照明不产生阴影;它是以 2D 呈现为重点的效果。 它不考虑包含真实照明模型的 3D 照明方案,包括阴影。
| 财产 | 说明 |
|---|---|
| 法线贴图 | NormalMaps 创造纹理效果,其中指向光源的法线会更亮,而背向光源的法线将变暗。 若要将 NormalMap 添加到目标视觉对象,请使用 CompositionSurfaceBrush ,使用 LoadedImageSurface 加载 NormalMap 资产。 |
| 环境 | 环境属性主要用于控制整体颜色反射。 |
| 反射 | 镜面反射在物体上产生高光,使它们看起来更加光亮。 你可以控制反射的高光级别以及光泽级别。 这些属性被操控,以产生材料效果,例如闪亮的金属或亮光纸。 |
| 漫射 | 漫射反射将光线分散到所有方向。 |
| 反射模型 | 反射模型 允许你在 Blinn Phong 和基于物理的 Blinn Phong 之间进行选择。 如果要具有凝结的反射高光,可以选择基于物理的 Blinn Phong。 |
示例(场景照明效果)
下面的示例演示如何将普通地图添加到 SceneLightingEffect。
CompositionBrush CreateNormalMapBrush(ICompositionSurface normalMapImage)
{
var colorSourceEffect = new ColorSourceEffect()
{
Color = Colors.White
};
var sceneLightingEffect = new SceneLightingEffect()
{
NormalMapSource = new CompositionEffectSourceParameter("NormalMap")
};
var compositeEffect = new ArithmeticCompositeEffect()
{
Source1 = colorSourceEffect,
Source2 = sceneLightingEffect,
};
var factory = _compositor.CreateEffectFactory(sceneLightingEffect);
var normalMapBrush = _compositor.CreateSurfaceBrush();
normalMapBrush.Surface = normalMapImage;
normalMapBrush.Stretch = CompositionStretch.Fill;
var brush = factory.CreateBrush();
brush.SetSourceParameter("NormalMap", normalMapBrush);
return brush;
}