v 这一节我们来学习一下svg光照滤镜,这个css中没有的。下面我们详细解释一下svg的光照,如果使用个过three.js做3D效果的同学,都知道three中也有光照效果,我感觉道理是相通的。
光照原理
我们可以先考虑一下现实中的光照,首先我们需要光源,只有光源才能有光照效果,光源可以分为三类:点光源个平行光源和聚光灯,可以想象一下手电筒和太阳光,照出来的效果是不同的。下面做一个简单的示例:
光源分类svg和three稍有不同,感兴趣的同学可以研究一下。通过上图我们可以看出,对于电光源和聚光灯我们需要位置信息。然后就是光源颜色,光强等这个就很好理解了。接下来就是被照射对象的材质,不同材质的物体对光源的反射光是不同的,并且材质不同,反射类型也不同,可以分为镜面反射和漫反射。我们这一节只讲svg的光照滤镜,合成效果我们在下一节讲解。有了上面的分析,我们不管是学习svg还是three.js中的光照都大有裨益。
这里面有一点需要注意,svg滤镜的光照和three是不同的,svg光照效果不考虑材质的影响,什么意思呢?就是说如果是红色的光照到了绿色的物体上,这时候应该是没有反射光的,但是svg的实际效果是会反射出红色的光,这就和three.js有很大不同。svg想要做真实的光照效果需要和其他滤镜一起实现。记住一点svg中光照滤镜的,物体的颜色只和光照颜色有关,和物体本身的颜色没有关系。
svg光照语法
svg的光照语法是定义反射类型漫反射和镜面反射,在反射类型元素里面添加光源。
漫反射
语法feDiffuseLighting属性值:
light-color:定义光源颜色
surfaceScale:这是一个突起的效果,有光照就有阴影,该值越大滤镜的突起效果越明显
diffuseConstant:漫反射强度,叫做这个名字也不合适,我还没想到合适的词汇,该值越大就越发白,为0是黑色。如果只是漫反射强度不应该成为大数字为白色。从字面意思看叫做漫反射常数,
镜面反射
语法feSpecularLighting属性值:
light-color:定义光源颜色
surfaceScale:这是一个突起的效果,有光照就有阴影,该值越大滤镜的突起效果越明显
specularConstant:光滑程度,数值越大越光滑,反射光的能力越强,0则没有反射效果
specularExponent:光照强度,数值越大颜色越发白,0为正常强度。
平行光光源
语法feDistantLight属性值:
azimuth:入射光线相对于x轴的入射角度,默认0度为x轴正方向
elevation:光源相对于z轴的夹角,svg的z轴垂直于屏幕向外
虽然svg是二维图形但是对于光线的入射角度需要从3维考虑,所以我们需要两个角度.下面是示意图:
这样使用两个角度我们就可以确定入射光线相对于xy平面的角度。
点光源
语法fePointLight属性值:
这个属性值比较好解释,因为对于点光源我们只要知道x,y,z坐标就行了。所以点光源的属性值为x,y,z,默认值均为0
聚光灯
我们仔细考虑一下对于这样的光源怎么定义位置和方向呢?我们可以像电光源一样定义x,y,z为光源点,那方向呢?这个滤镜使用(pointsAtX,pointsAtY,pointsAtZ),定义另一个点,有了这两个点我们就可以确定聚光灯光源相对于xy平面的位置和方向了。还需要知道一个量,聚光灯圆锥形的夹角如图:
有了这个角度我们就可以确定聚光灯光源了。所以语法feSpotLight属性值:
x,y,z:聚光灯光源的坐标点
pointsAtX,pointsAtY,pointsAtZ:聚光灯朝向的坐标点
limitingConeAngle:聚光灯锥顶的夹角
上面介绍完了svg光照的语法,下面我们写几个例子,加强对光照的理解。
svg光照例子
漫反射平行光源
<svg width="1000" height="500">
<defs>
<filter id="diffuseDistant" x="0" y="0" width="100%" height="100%">
<feDiffuseLighting
in="SourceGraphic"
lighting-color="#5f0b2c"
surfaceScale="5"
diffuseConstant="5">
<feDistantLight azimuth="0" elevation="25"/>
</feDiffuseLighting>
</filter>
<polygon filter="url(#diffuseDistant)" transform="scale(2)" points="50 160 55 180 70 180 60 190 65 205 50 195 35 205 40 190 30 180 45 180"
stroke="#00ff00" fill="#0000ff" stroke-width="5"/>
</svg>
效果如下:
我们还可以加上动画,来感受一下光照效果:
<feDiffuseLighting
in="SourceGraphic"
lighting-color="#5f0b2c"
surfaceScale="5"
diffuseConstant="5">
<feDistantLight azimuth="0" elevation="25">
<animate attributeName="azimuth" from="0" to="360" begin="0s" dur="5s" repeatCount="100"></animate>
</feDistantLight>
</feDiffuseLighting>
有兴趣的同学可以自己尝试一下效果。并且修改里面的数字,看看不同的效果。
漫反射点光源
<feDiffuseLighting
in="SourceGraphic"
lighting-color="#5f0b2c"
surfaceScale="5"
diffuseConstant="20">
<fePointLight x="180" y="100" z="50">
<animate attributeName="x" from="0" to="360" begin="0s" dur="5s" repeatCount="indefinite"></animate>
</fePointLight>
</feDiffuseLighting>
效果如下:
漫反射聚光灯
<feDiffuseLighting
in="SourceGraphic"
lighting-color="#5f0b2c"
surfaceScale="5"
diffuseConstant="20">
<feSpotLight x="50" y="183" z="200" pointsAtX = "20" pointsAtY="183" pointsAtZ="50" limitingConeAngle="7">
<animate attributeName="pointsAtX" from="20" to="80" begin="0s" dur="5s" repeatCount="indefinite"></animate>
</feSpotLight>
</feDiffuseLighting>
效果如下:
镜面反射平行光源
<filter id="specularDistant" x="0" y="0" color-interpolation-filters="sRGB" width="100%" height="100%">
<feSpecularLighting
lighting-color="#5f0b2c"
surfaceScale="5"
specularConstant="2"
specularExponent="2"
>
<feDistantLight azimuth="45" elevation="45"/>
</feSpecularLighting>
</filter>
效果如下
可以看到镜面反射五角星的线条是白色的,并且镜面反射的颜色和要比漫反射的颜色浅
镜面反射点光源
<feSpecularLighting
lighting-color="#5f0b2c"
surfaceScale="5"
specularConstant="2"
specularExponent="2"
>
<fePointLight x="180" y="100" z="50">
<animate attributeName="x" from="0" to="360" begin="0s" dur="3s" repeatCount="indefinite"></animate>
</fePointLight>
</feSpecularLighting>
结果如下:
镜面反射聚光灯
<feSpecularLighting
lighting-color="#5f0b2c"
surfaceScale="5"
specularConstant="2"
specularExponent="2"
>
<feSpotLight x="50" y="183" z="200" pointsAtX = "20" pointsAtY="183" pointsAtZ="50" limitingConeAngle="7">
<animate attributeName="pointsAtX" from="20" to="80" begin="0s" dur="5s" repeatCount="indefinite"></animate>
</feSpotLight>
</feSpecularLighting>
为科技球添加光照效果
我们可以为科技球加一个漫反射聚光灯的白色光照效果。效果如下:
代码地址:科技球光照效果。