IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    搞懂SVG中各种Light相关的光源滤镜

    张 鑫旭发表于 2024-09-08 16:10:51
    love 0

    by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=11330
    本文可全文转载,独立域名个人网站无需授权,但需要保留原作者、出处以及文中链接,任何网站均可摘要聚合,商用请联系授权。

    光影相机

    SVG中有多个与光源相关的滤镜,看起来有些小复杂,今天就好好学一学,想办法都弄懂了,说不定哪一天就用到了。

    一、fePointLight滤镜

    顾名思义就是点光源滤镜效果。

    和很多其他光源滤镜一样,要想生效,需要用在照明过滤器元件中。

    所谓的照明过滤器,在SVG中,其实指的是<feDiffuseLighting> 和 <feSpecularLighting>这两个元素。

    前者指的漫反射,后者指的镜面反射。

    其实,SVG光源滤镜就是那么回事,一是确定光源的类型,是点光(灯泡)、平行光(太阳),还是聚光(聚光灯),二是确定物体表面发射的类型,是漫反射还是镜面反射,这些初中还是高中物理应该都讲过的。

    好,为了方便学习,有必要先学习<feDiffuseLighting> 和 <feSpecularLighting>这两个元素。

    二、以feSpecularLighting元素举例

    先从案例开始说起吧。

    使用feSpecularLighting,也就是镜面反射源实现一个点光照射的按钮效果吧。

    相关SVG代码如下所示(复制到页面任意位置):

    <svg
      width="0"
      height="0"
      xmlns="http://www.w3.org/2000/svg"
      xmlns:xlink="http://www.w3.org/1999/xlink">
      <defs>
        <filter id="spotlight">
          <feSpecularLighting
            result="spotlight"
            specularConstant="0.5"
            specularExponent="50"
            lighting-color="#FFF">
            <fePointLight x="20" y="10" z="50" />
          </feSpecularLighting>
          <feComposite
            in="SourceGraphic"
            in2="spotlight"
            operator="arithmetic"
            k1="0"
            k2="1"
            k3="1"
            k4="0" />
        </filter>
      </defs>
    </svg>

    然后给需要应用该滤镜效果的元素使用CSS代码就可以了,例如:

     button {
      filter: url(#spotlight);
    }

    此时,按钮的左上角就可以看到光照特效了。

    如下图效果所示:

    按钮滤镜效果示意

    眼见为实,您可以狠狠地点击这里:SVG光影滤镜应用在按钮demo

    下面,讲下feSpecularLighting滤镜的语法。

    语法

    支持下面5个属性。

    • in

      输入光源元素的id,可以缺省(如果光源元素是其子元素)。

    • surfaceScale

      surfaceScale属性表示应用光源元素的曲面高度。

    • specularConstant

      表示镜面反射常数,此值越大,光影越亮越明显。

    • specularExponent

      镜面反射指数。

    • kernelUnitLength

      此属性已经不推荐使用,字面意思是核心单位长度。

    顺便fePointLight的语法

    <fePointLight>滤镜的语法就简单多了,为 x, y, z三个值,分别表示光源中心点的横纵坐标和高度。

    其他就没啥了。

    三、再来说说feDiffuseLighting

    接下来讲讲漫反射滤镜。

    还是上面的例子,如果我们给按钮使用漫反射滤镜光影效果,那么该如何处理呢?这里有个使用案例:

    <svg
      width="0"
      height="0"
      xmlns="http://www.w3.org/2000/svg"
      xmlns:xlink="http://www.w3.org/1999/xlink">
      <defs>
        <filter id="spotlight">
          <feDiffuseLighting
            result="spotlight"
            diffuseConstant="1"
            lighting-color="#FFF">
            <fePointLight x="20" y="10" z="40" />
          </feDiffuseLighting>
          <feComposite
            in="SourceGraphic"
            in2="spotlight"
            operator="arithmetic"
            k1="1"
            k2="0"
            k3="0"
            k4="0" />
        </filter>
      </defs>
    </svg>
     button {
      filter: url(#spotlight);
    }

    此时,按钮的光影效果则是这样的:

    漫反射按钮效果示意

    可以看到,出现了光照阴影,而镜面反射则是白光叠加。

    眼见为实,您可以狠狠地点击这里:SVG漫反射光影按钮特效demo

    其中的变化有:

    • 参数名称不同;
    • feComposite参数不同,也就是颜色混合算法不同;

    语法

    • in

      同feSpecularLighting。

    • surfaceScale

      surfaceScale属性表示应用光源元素的曲面高度。

    • diffuseConstant

      表示Phong照明模型中的kd值。在SVG中,这可以是任何非负数。

    • kernelUnitLength

      同feSpecularLighting。

    Phong光照模型

    Phong光照模型是真实图形学中提出的第一个有影响的光照明模型,该模型只考虑物体对直接光照的反射作用,认为环境光是常量,没有考虑物体之间相互的反射光,物体间的反射光只用环境光表示。Phong光照模型属于简单光照模型。

    更多内容见百科解释:Phong光照模型

    四、还有feDistantLight和feSpotLight

    最后再解释下平行光源和聚光光源,还是案例说话吧,对比下用在按钮上的效果。

    代码的话这里就不展示了,想要了解,可以访问demo页面:SVG不同光源下的按钮滤镜demo

    这是最终几个光源下的效果截图:

    不同光源效果

    feDistantLight语法

    feDistantLight表示远光,或者平行光,代表性的光源就是太阳。其支持两个参数值:

    azimuth
    表示方位角。下图所示的是角度0和角度240时候,漫反射的光影效果图(应用图形是个圆形)。

    平行光角度示意

    elevation
    表示光源和照射物体平面照射的角度,例如太阳初升或日落可以看出是0,太阳当空就是90。下图示意的是照射高度角是0和45度时候(方位角使用默认的0,也就是从右往左照射)的效果:

    不同照射高度角效果

    feSpotLight语法

    feSpotLight表示聚光光源,代表性的光源就是戏剧表演舞台上的聚光灯,手电筒也可以看成是聚光光源。

    语法如下:

    x、y、z
    光源坐标
    pointsAtX、pointsAtY、pointsAtZ
    光源照射落点坐标。
    specularExponent
    镜面指数属性,用来控制光源的焦点。值越大,灯光越亮。
    limitingConeAngle
    表示聚光灯轴(即光源与其指向的点之间的轴)和聚光灯锥体之间的角度(以度为单位)。因此,它定义了一个限制锥,限制了光线投射的区域。锥体外没有光线投射。

    以上所有数值,都可以配合SVG的<animate>, <set>元素实现动画效果。

    五、反正我是弄懂了

    好,基本上SVG光影相关的滤镜就上面这些了。

    经过这些天的学习,我反正是弄懂了。

    也为某些效果的实现提供了新的思路,例如卡牌元素呈现的时候,是不是可以使用聚光灯效果实现,就像电影开幕那样,绝对可以。

    台灯皮克斯

    市面上很少见到这样的效果,是因为设计师和前端并不知道Web有这样的能力。

    这毕竟属于视觉表现领域的深水区了。

    学习其实就是这样,学得足够多,就会触类旁通,加深对过往知识的理解,并且自成体系。

    即所谓的厚积薄发,量变产生质变。

    不要等到需要用了,再去学,那就慢了,很多机会可能就这么错过了。

    好,不展开哔哔了,就这样,感谢阅读。

    就不要求大家分享了,毕竟小众领域。

    元瑶洗澡

    本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
    本文地址:https://www.zhangxinxu.com/wordpress/?p=11330

    (本篇完)



沪ICP备19023445号-2号
友情链接