フーノページ



SVG feTile

SVG、feDiffuseLightingで拡散照明
〜照明効果①。








SVGフィルター、使い方。

〽️ SVGフィルターのまとめ記事はコチラ。



syntax。

<filter id = "「「5filterName」」">
    <feDiffuseLighting
        lighting-color = "「「2光の色」」"
        surfaceScale = "「「2不透明度1の部分の高さ」」"
        diffuseConstant = "「「2拡散の度合い」」">
        
        「「3<!--光源要素-->」」
        <fePointLight|feDistantLight|feSpotLight/>

    </feDiffuseLighting>
</filter>


不透明度を盛り上げる。


こんにちは、「ふ」です。
SVGのフィルターシリーズ、今回から照明効果について紹介していきます。

どういう仕組みなのか?

2DフォーマットであるSVG要素に「照明効果を与える」とはどういうことなのか?
SVGの照明フィルターでは、不透明度の高い部分が盛り上がっているとみなして、仮想的な3D空間で照明効果をシミュレートします。


左の画像において、青い円の部分は不透明度1ですが、周りは不透明度0で透過されています。これを照明フィルターに掛けると右のように円の部分だけが「盛り上がっている」部分として効果が適用されます。

これまでのSVGフィルターに比べて実装はやや複雑になりますが、じっくりと学んでいきましょう。1回目である今回は照明効果の基本的な理解と、照明コンテナの1つであるfeDiffuseLightingを使った実例を解説していきます。



このたびSVGの書籍を出版しました。
しっかりとしたSVGスキルが身に付く内容となっています。参考にしてください。





照明コンテナと光源要素。


照明効果の実装は、照明コンテナ要素と光源要素の2つを組み合わせて行います。

照明効果を与えるには、2Dで受け取った画像情報をいったん仮想的な3D空間の中に取り込み、光源を与えて照明をシミュレートさせます。
そして次のフィルターやweb画面に渡すため、その後は2Dに戻す必要があります。

「一時的な3Dの照明空間を作る」役割をするのが、<feDiffuseLighting>と<feSpecularLighting>要素です。
<feDiffuseLighting>は要素の質感の表現に、<feSpecularLighting>は金属反射の表現に向いているとされます。

<feDiffuseLighting>や<feSpecularLighting>で作成した空間に光源要素を配置することで、照明効果を再現します。
照明空間の内部で使えるライト(光源要素)は3種類。

  <feDistantLight> 平行光源(自然光のイメージ)
  <fePointLight> 放射状(一点から放射状に広がる)
  <feSpotLight> 円錐状の光

〜それでは実際に試していきましょう。




feDiffuseLightingを試す。


<feDiffuseLighting
    lighting-color = "光の色" 初期値:#fff
    surfaceScale = "不透明度1の部分の高さ" 初期値:1
    diffuseConstant = "拡散の度合い" 初期値:1 >
</feDiffuseLighting>

今回の記事では、照明コンテナとして<feDiffuseLighting>をつかった実例を紹介していきます。プロパティは3種類⬆︎用意されています。

<svg viewBox="0 0 841.9 595.3">

「「3<!-- テキストロゴ -->」」
<g>
    <path class = "st1" d="...." fill = "#066DB0"/>
    <path class = "st1" d="...." fill = "#066DB0"/>
</g>

</svg>   


フィルターを掛ける要素を準備しました。
2つの文字は<g>要素でグループ化させています。

<svg viewBox="0 0 841.9 595.3">

<filter id = "「「5filter01」」">
    <「「1feDiffuseLighting」」> 
    <「「1/feDiffuseLighting」」>  
</filter>

「「3<!-- テキストロゴ -->」」
<g filter = "url(「「5#filter01」」)">
    <path class = "st1" d="...." fill = "#066DB0"/>
    <path class = "st1" d="...." fill = "#066DB0"/>
</g>

</svg>   

<filter>コンテナを定義し、内部に<feDiffuseLighting>要素を配置しました。
フィルターのidを「filter01」とし、テキストロゴ要素から参照させています。



現在の状態では、何も表示されません。
照明コンテナである<feDiffuseLighting>を置いただけにすぎず、ここに光源要素をセットしてやらないと効果は現れません。

<filter id = "filter01">
    <feDiffuseLighting> 
        <「「1fePointLight」」 z = "「「510」」"/>
    </feDiffuseLighting>  
</filter>  

光源要素を配置しましょう。
今回は<feSpotLight>を使用することにします。この光源要素はx/y/z属性を持ち、原点からのそれぞれの方向に対する距離を指定します。
z方向に「10」としておきました。


テキストロゴに照明が入りました。
〜やっと入口に立てましたね💧




feDiffuseLightの属性。


それでは<feDiffuseLighting>の属性を操作して、変化の様子を見てみましょう。


surfaceScale。

surfaceScale = "1"

surfaceScale属性は「不透明度1の部分の高さ」を指定します。つまり「どれだけ出っ張った状態にするか」ということですね。
指定は数値で行い、初期値は「1」となっています。

<filter id = "filter01">
    <feDiffuseLighting surfaceScale = "「「110」」"> 
        <fePointLight z = "10"/>
    </feDiffuseLighting>  
</filter>  

surfaceScaleを「10」にしてみます。


表面の高さを大きくしたことにより、凹凸がくっきりとしましたね。



lighting-color。

lighting-color = "#fff"

lighting-color属性はその名の通り、照明の色を指定します。
初期値は「#fff」で、完全な白。黄色っぽい色にしてみましょう。

<filter id = "filter01">
    <feDiffuseLighting surfaceScale = "10"
     lighting-color = "「「1#ff2」」"> 
        <fePointLight z = "10"/>
    </feDiffuseLighting>  
</filter>  

lighting-colorは「〇〇-〇〇」というように、ハイフン「-」で挟んだケバブ表記になるので注意してください。


光源の色が黄色になりました。


diffuseConstant。

diffuseConstant = "1"

diffuseConstant属性は、光の広がり具合を指定します。
初期値は「1」で、これも数値による指定です。

<filter id = "filter01">
    <feDiffuseLighting surfaceScale = "10"
     lighting-color = "#ff2"
     diffuseConstant = "「「15」」">
        <fePointLight z = "10"/>
    </feDiffuseLighting>  
</filter>  

値を「5」に増やしてみます。


ずいぶんと輝かしくなりました。
左上の部分をみると、光源が明らかに広がっていますね。




feCompositeで切り抜き。



ここまでのサンブルでは、テキストロゴの周りにも光源の影響が描画されていました。SVGフィルターでは、要素のバウンディングボックスの外側10%の範囲に効果が描画される、という特性があるためです。

照明効果をテキストロゴの形に切り抜きたい。そのバヤイは<feComposite>フィルターを掛け合わせましょう。

<filter id = "filter01">
    <feDiffuseLighting 
        lighting-color = "#ff2" 
        surfaceScale = "10" 
        diffuseConstant = "5" 
        result = "「「5light」」"> 「「1..@1@」」

            <fePointLight z = "50"/> 「「1..@2@」」

    </feDiffuseLighting>

    <feComposite 
        in = "「「5light」」" 
        in2 = "SourceGraphic" 
        operator = "in"/> 「「1..@3@」」

</filter>

@1@ <feDiffuseLighting>のresult属性に「light」をいう名前を付け、<feComposite>に渡せるようにしています。

@2@ 効果を観察しやすいように、<fePointLight>のz属性を「50」に増やしています。

@3@ <feComposite>のin属性に先ほどの照明効果を渡し、in2には元要素の「SourceGraphic」を指定。
operator属性を「in(2つの要素が重なっている部分のみを表示)」にします。


切り取りが成功しました。
が、シビアに切り取りすぎたせいか、ちょっと味気ない。<feDropShadow>で影を落としてやりましょう。


影がついて、質感が出ましたね。




いろいろやっていきます。


最後までお読みくださり、 ありがとうございました。

今回は<feDiffuseLighting>を使い、SVGの照明効果を試してきました。3次元コンテナを使ってシミュレートすることで、グラデーションよりもリアルな陰影を作ることができましたね。

ところで照明フィルターを掛けると、オブジェクトの元の色が完全に失われてしまいます。ここにブレンド機能などを加えて「元の色とも融合させてみたい」と思った方もいるのではないでしょうか。
SVGの照明効果シリーズはまだ始まったばかりです。今あげたブレンド効果もふくめ、今後色々試していきますので、お楽しみに。

ではまた〜 🎵




「ふ」です。

ふ

ベクターグラフィック、web、ガジェットなど。役立つ情報や観ていてたのしいページを書いていきたいと思います。