お絵描きソフトInkscape(インクスケープ)の使い方を初級レベルから上級レベルまで広く紹介しています。
情報追加のリクエストや分かりにくい点があれば下のCONTACTフォームからどうぞ。

Inkscapeで使えるフィルタプリミティブ要素:feSpecularLighting/feDiffuseLighting

 このページでは、Inkscapeがサポートしている、SVGで定義されている「光が当たっているような絵に変換する」機能のフィルタプリミティブ要素を紹介します。

 そのようなフィルタプリミティブ要素には、feSpecularLightingfeDiffuseLightingの2種類があります。

 feSpecularLightingは鏡のように反射した状態の絵に変換するものです。

 feDiffuseLightingは当てた光が乱反射した状態の絵に変換するものです。

 Inkscapeのフィルタエディタ上ではそれぞれ反射光拡散照明と表示されるフィルタプリミティブ要素です。

(2023.05.19更新)

 このフィルタプリミティブ要素についてネットで検索したところ、意外なことに明確な説明を見つけることができなかったので、例によって(?)つまみ食いした情報をまとめて、こんな感じで理解すれば良さそうという内容でまとめてみたいと思います。

 feSpecularLightingfeDiffuseLightingは、指定するパラメータも変換結果も似た部分が多いです。

 どちらも、変換元の画像を、不透明度の大きいピクセルは手前に出っ張り、不透明度の小さいピクセルは奥に引っ込んでいるものと解釈して、その凸凹の表面の光の反射をシミュレーションします。

 どのぐらい反射するか、光源の位置や角度、光の色などをパラメータで指定します。

 そして、変換元の画像の各ピクセルに対して所定の計算式を使って、画面(キャンバス)の正面から見たときに反射して見える光の強さを変換後のピクセルにします。

 ・・・ということは、変換元の画像の色(RGB)は変換結果に関係ないということですね。あくまでも各ピクセルの不透明度(RGBAのA)が使われるということです。また、強い反射光のところは不透明度が高く、弱いところは不透明度が低いように変換されるので、全く反射していないところは透明になります。

 というように、変換後の画像は、反射した光の分布を、パラメータで指定した色とその不透明度で表した画像になるので、変換元の画像に重ねて表示したりすれば、指定した色の光の反射を加えたような絵にすることができるというわけです。

feSpecularLighting

 鏡のように入射した光が同じ角度で反射するような表面を模した絵に変換するものです。

 パラメータとして、反射色表面スケール定数指数核単位長(kernelUnitLength)、光源(とそのパラメータ)を指定します。

 表面スケールは、不透明度の値をどのぐらい出っ張ったものと解釈するかを指定するもので、表面スケールが大きければ大きいほど、同じ不透明度のピクセルでも手前に出っ張ったものとして扱われます。

 定数は、反射光を計算するときに用いられるもので、鏡面反射係数に当たります。同じ強さの光を反射させたときの違い(反射率)のことらしいです。

 指数は、反射した光を正面から見たときに、その反射した表面の周囲に「輝き具合」が現れるように描くハイライトの強さを指定するものです。反射した表面の周囲に小さくハイライトを描けばその表面はピカピカしたもののように見えるというテクニックを自動的に実行しようということですね。指数が大きいほどハイライトが小さくなって、より輝いた表面のように見えるそうです。

 (核単位長は現時点で理解できていません)

 光源(とそのパラメータ)は、どんな光をどこから当てるかを指定するもので、SVGの中で光源要素(Light source elements)を使って記述します。

 光源要素には、スポットライト(feSpotLight)、遠くの光(feDistantLight)、点光源(fePointLight)の3種類があります。光源を設定するためのパラメータは光源要素ごとに異なります。各光源要素についての詳細は別のページ(フィルタプリミティブ要素と光源要素)のほうにまとめます。

feDiffuseLighting

 当てた光が表面で乱反射する様子を模した絵に変換するものです。

 feSpecularLightingのパラメータとほぼ同じものを指定しますが、指数はパラメータに含まれません。乱反射する表面にハイライトの描画は必要ないからでしょうか。

ライティングのフィルタを試してみた

 feSpecularLightingに各種光源要素を組み合わせて試してみました。

 まず、フィルタ適用先のオブジェクトとして、次のように真ん中の不透明度を高くして、真ん中が出っ張っている円錐状のオブジェクトを描きます。

 これに、反射色を黄色にしたfeSpecularLightingを適用します。光源はまず遠くの光を指定します。

 左上から光があたるように、方位角30度、仰角30度を指定しています。

 この変換結果は、影に当たる部分の不透明度が小さくなっている、いわばマスクのような画像になっているので、影に当たる部分(右下)が白っぽく輝いているように見えますが、それは単に背景が透けているだけです。次のように、この画像の後ろ側に濃い色で塗った同じ大きさの円を重ねると、本来描きたい絵になると思います。

 次に点光源を指定してみます。

 光源の位置は、左上隅の少し手前にあるように、X=0、Y=0,Z=30を指定しました。

 次にスポットライトを指定してみます。

 こちらも左上隅の少し手間から光があたるように、光源の位置はX=0、Y=0、Z=30にして、光源の指す先はX=30、Y=30、Z=0を指定しました。

 なお、スポットライトは他のパラメータの指定に少しクセがあって、それなりの値を指定しないといい感じに光があたったようにならず、指数が大きいとオブジェクトが輝きすぎで見えなくなってしまったり、反射指数を1以外にするとスポットライトが1点に集中しすぎるせいか全部影になってしまったり、コーンが小さいとオブジェクトのほとんどがその範囲に入らず光があたっているところが小さくなりすぎてしまったりします。