Translate

2020年12月12日 星期六

有趣的 SVG filter - 打光

光源濾鏡專門用來打光,參數如下

in                輸入
surfaceScale      表面渲染放大率
diffuseConstant   擴散光量 (feDiffuseLighting 才有)
specularExponent  渲染強度 (feSpecularLighting 才有)  

可以用的光源

fePointLight      點光源, 參數有 x,y,z
feDistantLight    遠光, 參數有 azimuth (方位角), elevation(海拔)
feSpotLight       聚光燈, 參數有 
                  x,y,z 
                  pointsAtX,pointsAtY,pointsAtZ
                  specularExponent (渲染強度)
                  limitingConeAngle (擴散角度)

feDiffuseLighting


<div style="display:inline-block">
fePointLight<br>
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
  <filter id="a121201_L1">
    <feDiffuseLighting lighting-color="#fff">
      <fePointLight x="130" y="60" z="30"></fePointLight>
    </feDiffuseLighting>
  </filter>
  <circle cx="100" cy="100" r="80" fill="#0af" filter="url(#a121201_L1)"></circle>
</svg>
</div>
<div style="display:inline-block">
feDistantLight<br>
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
  <filter id="a121201_L2">
    <feDiffuseLighting lighting-color="#fff">
      <feDistantLight azimuth="45" elevation="30"></feDistantLight>
    </feDiffuseLighting>
  </filter>
  <circle cx="100" cy="100" r="80" fill="#0af" filter="url(#a121201_L2)"></circle>
</svg>
</div>
<div style="display:inline-block">
feSpotLight<br>
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
  <filter id="a121201_L3">
    <feDiffuseLighting lighting-color="#fff">
      <feSpotLight x="0" y="0" z="100" pointsAtX="200" pointsAtY="200" pointsAtZ="0" limitingConeAngle="30"></feSpotLight>
    </feDiffuseLighting>
  </filter>
  <circle cx="100" cy="100" r="80" fill="#0af" filter="url(#a121201_L3)"></circle>
</svg>
</div>
<br>
光源加上兩個 circle 用不同的 alpha 值時,似忽有上下層打光的感覺
<svg width="200" height="200">
<g filter="url(#a121201_L1)">
<circle cx="100" cy="100" r="80" fill="#fff8"></circle>
<circle cx="50" cy="50" r="25" fill="#ffff" stroke-width="20" stroke="#000a"></circle>
</g>
</svg>
fePointLight
feDistantLight
feSpotLight

光源加上兩個 circle 用不同的 alpha 值時,似忽有上下層打光的感覺

feSpecularLighting

feSpecularLighting 和 feDiffuseLighting 有點不同,feSpecularLighting 會創造出一個有 Alpha 的圖層,然後可以在原圖再疊上這個有 Alpha 的圖後,就成了打光後的圖

在這個範例中,我設定了 specularExponent="5" 加強渲染強度,以及加上背景設定,可以更清楚的看到打光圖層實際的作用範圍


<style>
#a121202_bk:checked ~ div
{
  background-color:#88f
}
</style>
<input id="a121202_bk" type="checkbox">
<label for="a121202_bk">背景</label>
<br>
<svg width="200" height="25">
<text id="a121202_ww" x="0" y="22">白光</text>
<text id="a121202_yy" x="50" y="22">黃光</text>
</svg>
<br><br>
<div style="display:inline-block">
fePointLight<br>
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
  <filter id="a121202_L1">
    <feSpecularLighting lighting-color="#fff" specularExponent="5">
      <set attributeName="lighting-color" to="#ff0" begin="a121202_yy.click"></set>
      <set attributeName="lighting-color" to="#fff" begin="a121202_ww.click"></set>
      <fePointLight x="130" y="60" z="30"></fePointLight>
    </feSpecularLighting>
  </filter>
  <circle cx="100" cy="100" r="80" fill="#000"></circle>
  <circle cx="100" cy="100" r="80" fill="#0af" filter="url(#a121202_L1)"></circle>
</svg>
</div>
<div style="display:inline-block">
feDistantLight<br>
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
  <filter id="a121202_L2">
    <feSpecularLighting lighting-color="#fff" specularExponent="5">
      <set attributeName="lighting-color" to="#ff0" begin="a121202_yy.click"></set>
      <set attributeName="lighting-color" to="#fff" begin="a121202_ww.click"></set>
      <feDistantLight azimuth="45" elevation="30"></feDistantLight>
    </feSpecularLighting>
  </filter>
  <circle cx="100" cy="100" r="80" fill="#000"></circle>
  <circle cx="100" cy="100" r="80" fill="#0af" filter="url(#a121202_L2)"></circle>
</svg>
</div>
<div style="display:inline-block">
feSpotLight<br>
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
  <filter id="a121202_L3">
    <feSpecularLighting lighting-color="#fff" specularExponent="5">
      <set attributeName="lighting-color" to="#ff0" begin="a121202_yy.click"></set>
      <set attributeName="lighting-color" to="#fff" begin="a121202_ww.click"></set>
      <feSpotLight x="0" y="0" z="100" pointsAtX="200" pointsAtY="200" pointsAtZ="0" limitingConeAngle="30"></feSpotLight>
    </feSpecularLighting>
  </filter>
  <circle cx="100" cy="100" r="80" fill="#000"></circle>
  <circle cx="100" cy="100" r="80" fill="#0af" filter="url(#a121202_L3)"></circle>
</svg>
</div>
<br>
光源加上兩個 circle 用不同的 alpha 值時,似忽有上下層打光的感覺
<div style="display:inline-block">
<svg width="200" height="200">
<circle cx="100" cy="100" r="80" fill="#000"></circle>
<g filter="url(#a121202_L1)">
<circle cx="100" cy="100" r="80" fill="#fff8"></circle>
<circle cx="50" cy="50" r="25" fill="#ffff" stroke-width="20" stroke="#000a"></circle>
</g>
</svg>
</div>

白光 黃光

fePointLight
feDistantLight
feSpotLight

光源加上兩個 circle 用不同的 alpha 值時,似忽有上下層打光的感覺

實測結果 firefox 的 feDiffuseLighting 打光結果和 chrome 及 safari 都不同,偏暗,對比較強,而 feSpecularLighting 的結果,三個瀏覽器都很接近,

沒有留言:

張貼留言