如何评价微软在 Build 2017 上提出的 Fluent Design System?

Windows 10 NEON 新界面设计正式命名:Fluent Design System。参见官网 Fluent Design System。Microsoft Fluent Design System 由 5 大元素组成:光感、深度、动效、材质、缩放。这些新的元素的引入不光是为了让我们创建出更好的设计感受,更多代表更加自然交互的方式,新的设计体系将带来直观、和谐、兼容广泛的跨设备的体验和互动操作。新的体系下需要考虑多种因素,比如材质,需要考虑膨胀,摩擦等。
关注者
3,049
被浏览
295,402

几点巨大的工作。有空了再来更新。


先列个大纲吧,不然太空了我自己都会忘记。今天实在没空写,周五早上我们组还有个关于这个系统的talk,欢迎大家参与。


* 2017/5/17 更新了Light部分 *

* 2017/5/18 更新了Depth部分*

* 2017/5/22 更新了Motion部分*

* 2017/5/23 更新了Material部分 *

* 2017/5/24 更新了Scale和主打的特效部分 *

* 2017/5/31 更新了幕后花絮 *

* 2017/6/6 更新了常见误解,全文完 *


BUILD上有3个相关的内容:

  1. high level讲一下Fluent Design System的各个部分:channel9.msdn.com/Event
  2. Fluent Design的细节:Introducing Fluent Design
  3. 我们组的talk,提供更多细节:Explore the next generation of innovative UI in the Visual Layer

Light(光照)

为什么是现在

其实,想在UI里加光照这件事情,设计师早就想过了。只是苦于之前UI系统里没有光照计算的支持。用预先生成的mask应做,会有分辨率和资源大小的问题,遂放弃了。

直到v1607里面,我们组写了个新族API CompositionLight Class,让UI可以直接接受光照。(by 我们组,I mean 我。API是我一个人设计的,95%的代码是我一个人写的,80%的bug是我一个人创造的。debug和补齐系统的过程养活了整个组。)

按照首席设计师的原话,“你这是提供了一个核武器给我啊”。于是,设计师们可以正式开始考虑如何在UI中使用光照来高亮你需要注意的东西。不需要添加额外资源,不需要考虑分辨率问题,都是实时计算的。

这套系统在计算上保持和当年的D3D/OpenGL固定流水线里的光照一致。在秋季更新里,我还加入了Physically-based BRDF。可以达到游戏级别的光照能力。并且XAML将会支持光照,以至于你只要在XAML里写tag就行了,不需要直接写代码来使用光照。

性能上,影响微乎其微。开不开光照,并不会造成明显的续航下降或者相应变慢。甚至因为算的太快,Windows电源管理会觉得不需要给那么高的频率。在打开光照后照样可以让CPU/GPU保持较低的耗用率。

和游戏里光照不同之处是,UI里的光照更注重性能响应,会和别的特效一起生成个单一的shader,必须在一个pass内完成,必须支持各种奇葩的变换,而且必须支持极老的硬件。这些看似不起眼的东西,实现起来细节超多。以至于可以从中抽出一些独特的东西,申请个专利。

还有一个偶然的发现。开了光照后,如果颜色搭配得当,对比度会很大。视障人士可以很容易观察到焦点在哪里,而不需要特别开高对比度设置。也就是说,视障人士终于有机会用普通的界面进行操作。

怎么用

你可以在UWP里直接调用CompositionLight,例子已经开源 Microsoft/WindowsUIDevLabs。也可以等XAML里封装好的XamlLight。那只要一行就能开启reveal光照效果。


Depth(深度)

UI为什么有深度

实际上从WPF开始,UI一直是2.5D的形态。但因为没有depth buffer,绘制顺序是由Visual在树中的顺序决定的,Visual的深度并不能用来表示遮挡。即便如此,这样的深度,在perspective matrix的配合下,其实已经可以构造出很多视觉效果,比如视差、前后变换、空间运动,等。

实际上,原先也可以这么用深度。但Win里面有个至少从Vista以来一直都有的bug,使得深度+旋转+perspective matrix这么组合使用的话,如果一个Visual有一个顶点比近平面还近,就会屏幕错乱。表现就是你的app漏了个洞,直接看到下面窗口的东西。做过渲染器的人都知道,这个情况是因为顶点坐标/w之后再插值造成的。我在看到的第一眼就感觉到了是这个问题,无奈的是调了3个星期才找到bug所在,真的是/w问题。之间被无数次误导到别的坑里,最后改了2行,好了。所以现在可以随便用深度,不会出这样的幺蛾子。

那么FDS里提出的深度,有什么特别之处呢?FDS的设计观念是,一套设计语言适应0D到3D的各种场合。在2D的屏幕上你看到的是2D的UI,带上Hololens你看到的就可以是3D的UI。比如说,从侧面看一个窗口的内部。

另一个方面是对深度的定位,这来自于阴影。打上阴影之后,深度的空间方位一下就明朗了。之前v1607里有DropShadow,现在还会加入一个增强版的shadow。

Sky Box的例子,更是把UI带入了3D的世界。这时候深度变成一个自然而然需要的东西了。这里我把游戏引擎中常见的sky box概念带入了UI系统,构造一个全方向的UI。

怎么用

对于程序来说,直接用Visual.Offset里的Z就是了,或者用XAML里封装好的Z。对于设计来说,需要习惯用Z来表示相对关系,不要太早合并层。DropShaodw的文档在这里DropShadow Class

如果要自适应2D和3D,建议用AR/VR设备测试一下。一开始会发现很多坑,找到规律后会顺利很多。

Motion(动态)

以前不能动吗

能,但程序写起来比较痛苦,而且局限性高。

dcomp一开始就有动画系统,可以用简单的脚本驱动Visual和特效的动画。然而,脚本是通过字符串的形式传给系统的。就像这样

那么,问题来了。如果你脚本里写错了,在编译的时候不会有任何提示,只有在运行的时候才有异常抛出。而且抛出的时候只知道有错,不知道是哪里错误。只能手动的一行一行找。而在秋季更新里,新增加的一个库让动画驱动可以通过C#来完成,有智能提示,有编译检查。比原先方便得多。而且还会提供更多动画的基础元素,比如弹簧运动,让开发者更容易创造出自己想要的效果。并且现在可以通过鼠标、滚动条等UI输入直接作为脚本的输入。这样就不需要在程序里自己检测这些信息后提供给脚本。一切都是自动在dwm里完成了。

怎么用

很快会有一个expression builder的库,解决动画脚本开发麻烦的问题。

Material(材质)

什么是材质

这里材质的概念跟游戏中的有相同点,也有些许不同。比如金银铜铁锡塑料橡皮,这样基本的材质,和游戏一样算材质。毛玻璃、亚克力这样的高层次的组合效果,也算材质。

在FDS里,基本材质用的是Lambert表示diffuse,Blinn-Phong表示specular。熟悉图形的人都会知道这些BRDF,参数调整的方法也和D3D/OpenGL里一致。在秋季更新里,我还特别加入了Physically-based Blinn-Phong,已达到跟游戏相同的开发方式和用户体验。

这些材质是可以自由调参数的,不是说定死了几个让你选。所以只要你调得合适,就能做出各种各样的材质。我不管是在组内还是组外,都是推荐用Matusik的一篇paper的数据 Experimental Analysis of BRDF Models。他里面提供了100中常见物体的参数。以此为参考,调材质会容易得多。

怎么用

API叫SceneLightingEffect Class。也是我独立完成的。支持ambient/diffuse/specular,normal map等。用法和游戏引擎里的类似。

在这次的Build上,我们组还公开展示了一个Material editor。在里面可以方便地调整各种材质及其组合。所见即所得的风格。设计师可以直接用这个来调参数。

Scale(伸缩性)

如意金箍棒

因为FDS的目的是一次设计,可以用于0D(只有语音)、1D(Surface Dial)、2D(UI)、3D(VR/AR)的种种情况。所以伸缩性比其他UI设计语言都要更重要。

不过实际上scale这部分还没有充分展开,更像是前面几项的组合和应用。

怎么用

按照FDS的知道规范设计完UI后,理论上就能适用于0D-3D了。但实际上还需要不少测试,尤其是在VR/AR设备上。

主打的特效

上面已经把FDS的几个组成介绍了一遍。这部分讲的是这次在主打的两个FDS的应用,Acrylic和Reveal。这两个都已经封装到XAML里,在insider里可以直接打开。

Acrylic(亚克力)

从去年年底关于NEON泄露的新闻开始,媒体就一直再说“毛玻璃的回归”,而且搞得NEON有且只有毛玻璃的样子。接到这些消息,你媒体本身也要判断,明白意思吗?

亚克力是毛玻璃吗?不是。

设计师想到亚克力这个特效的时候,正拿着这块板子。

(嗯,对,这块板子现在流落到我手里了)

Win7里的毛玻璃,就是一个小半径的高斯模糊,再加上一个色调的调整。想要表达的是光滑的毛玻璃表面,把背景模糊了,同时自己的高光也加上去。

而这么多年后,审美已经改变。人们更喜欢亚光的材质。这次的亚克力,合成则复杂得多了。需要这样的effect graph才能组合出来。而且每一个参数都是经过设计师仔细调整的(这个过程甚至还没完全完成)。

性能方面,亚克力和毛玻璃也有巨大的区别。虽然用的都是我的快速gaussian blur算法(专利已得),但这次的版本更加优化了,可以支持几十上百的模糊半径。不像毛玻璃,因为性能问题在Win8上就关掉了。

Reveal

Reveal是个光照效果,当鼠标移到按钮上方的时候,可以看到那个按钮被照亮,周围几个控件的边框也被照亮。就好像手电筒一样。

这主要就是用CompositionLight,加上SceneLightingEffect等多个特效,经过仔细调整才得到现在的结果。目前的insider里面,计算器已经开始用Reveal。

幕后花絮

下面开始进入八卦的环节。

团队组成

FDS这个项目的开发过程,跟微软传统的自上而下的体系很不一样。这个项目更多的是横向的联系。Designer说有个想法,PM说想做,dev说能做。于是我们组成了一个分散于不同部门之间,工种齐全的虚拟小组。一两个designer,两个PM,一到两个dev,一个techart,一个lead,幕后还有一个大佬。开会的时候像一个组,散会了各奔东西。就以这样的方式,在早期非常高效地把Acrylic和Reveal的设计到实现一条龙打通了。

随着工作的进展,加入的团队越来越多。从一开始一间小会议室就把所有人都装下,到后来订了个20人的大会议室,仍然有坐票有站票有蹲票有趴票(还有实在没辙了远程连进来的,算不算挂票?)。我很欣慰。

工作方式

FDS虚拟小组的工作方式也有别于微软传统的团队。我们从有一点原型的时候就开始到各组“推销”。很快就收到了来自于公司里多个app团队的肯定,并且表示如果Acrylic和Reveal做出来了,他们会用上。又因为app都用的xaml,也毫无疑问地把xaml拉下水,大量实现是在xaml层完成。这样一来,app只要简单的加一两个tag就能开启这些特效。

具体流程,是designer出一个设计;techart按照photoshop/aftereffect里的层设定和参数实现到代码里;一个dev(我)拿来,从公式的角度进行优化;另一个dev把我优化后的公式转成代码;xaml团队拿去加入xaml套餐。整个流程过一遍的时间可以小于一个星期,从最初techart的版本到优化后的结果,性能可以差10倍甚至更多。得益于这样的流水线作业,在离最终review前几天,即便designer大改了配方,我们还是可以赶得上review。

常见的误解

风格不一致?

有人提到在build上演示的几个不同app,对于透明程度、阴影等方面存在不一致的情况。那是因为,build上的那些图片和视频都是设计稿,由设计师用PS或者AE做的。每个设计师负责一两张图/一两段视频,手工做。这样并没有办法保证参数相同,所以不一致是正常的。正式版本是由程序渲染,推荐参数都是一样的。不会不一致。

传统Win32程序?

这些现代UI的修改都只存在与UWP。但是UWP也是native得啊,也可以从传统Win32程序中调用,技术上并没有问题,只是麻烦点。

如果你希望有官方的方法可以在传统Win32程序里用现代UI,就到这里投票吧。

wpdev.uservoice.com/for

非焦点窗口特效消失?

有人以为那是因为失去焦点后程序没响应,所以特效消失。然而这些渲染都是在dwm进程,而不是app进程做的。不存在没响应的问题。目前非焦点窗口关闭Acrylic是有意而为之。因为如果不那么做的话,就会需要把每一层窗口都单独渲染一遍,不管是否被遮挡。比如说,你有10个窗口,互相层叠。如果都开着Acrylic,就需要从后往前渲染窗口和桌面,blur,贴到上一层窗口上,如此类推。还会涉及到两个Acrylic叠加的噩梦。对于电能消耗和响应速度都不是好事。然而因为各方面的要求,这一点以后可能会渐渐放松。

我可以表达出对FDS的喜欢吗?

能。已经把大家都拉下水了,已经被砍两次都原地满血复活,不怕了。