马黑黑 发表于 2023-10-24 11:34

svg :光滤镜(五)

<style>
.ma p, .ma pre, .ma svg { margin: 8px 0; }
.rred { color: red; }
.ma > pre { padding: 16px; background: #efefef; font: normal 16px monospace; white-space: pre-wrap; word-wrap: break-word; tab-size: 4; line-height:1.5em; }
</style>

<div class="ma">

<p>feDistantLight 是光源滤镜之一,用来定义一个<span class="rred">距离光源</span>。它有两个属性:其一是 <span class="rred">azimuth</span> 属性,<span class="rred">方位角</span>,默认值是 0 度;其二是 <span class="rred">elevation</span> 属性,<span class="rred">高度</span>,默认值是 0 度。</p>
<p>方位角属性 azimuth 指定光源在 XY 平面上的方向角(顺时针),以距 x 轴的度数为单位。方位角是太阳光照射的罗盘方向。正午,太阳总是在北半球的正南,在南半球的正北。方位角在一天中变化,在春分时,无论纬度如何,太阳都直接从东方升起、向西落下,从而使方位角在日出时为 90°,日落时为 270°。然而,一般来说,方位角随纬度和一年中的时间而变化。</p>
<p>高度属性 elevation 指定光源从 XY 平面朝向 Z 轴的方向角(以度为单位)。请注意,正 Z 轴指向观察者。</p>
<p>下面,我们设计一个 f1 滤镜组,该滤镜组是距离光源 feDistantLight 以镜面反射 feSpecularLighting 的方式作用于一个圆(circle)。以下是核心 svg 代码,镜面滤镜仅设置了光照颜色属性:</p>
<pre>
&lt;svg width="200" height="200" style="border: 1px solid gray;"&gt;
        &lt;filter id="f1"&gt;
                &lt;feSpecularLighting lighting-color="blue"&gt;
                        &lt;feDistantLight azimuth="90" elevation="0"&gt;&lt;/feDistantLight&gt;
                &lt;/feSpecularLighting&gt;
        &lt;/filter&gt;
        &lt;circle cx="100" cy="100" r="90" filter="url(#f1)"&gt;&lt;/circle&gt;
&lt;/svg&gt;
</pre>
<h3>距离光源 feDistantLight 镜面反射效果</h3>
<svg width="200" height="200" style="border: 1px solid gray;">
        <filter id="f1">
                <feSpecularLighting lighting-color="blue">
                        <feDistantLight azimuth="90" elevation="0" id="dLight"></feDistantLight>
                </feSpecularLighting>
        </filter>
        <circle cx="100" cy="100" r="90" filter="url(#f1)"></circle>
</svg>
<p>
        <label for="azimuthAngle">方位角 : </lable>
        <input type="range" min="0" max="360" value="90" id="azimuthAngle" />
        <output id="aziMsg">azimuth="90"</output>
        【<input type="radio" id="morning" name="azi" value="90" checked />
        <label for="morning">日出</label>
        <input type="radio" id="noon" name="azi" value="180" />
        <label for="noon">正午</label>
        <input type="radio" id="evening" name="azi" value="270" />
        <label for="evening">日落</label>】
</p>
<p>
        <label for="elevationAngle">高 度 : </lable>
        <input type="range" min="0" max="360" value="0" id="elevationAngle" />
        <output id="elevMsg">elevation="0"</output>
</p>
<p>上述演示可能还是有些抽象,不过距离光源总体上讲是直观的,光源的方位角和高度决定了镜面反射的样式。</p>
<p>我们至此讲完了应讲的光源滤镜和光的反射滤镜。光源滤镜共三个,点光源(fePointLight)、聚光灯光源(feSpotLight)和距离光源(feDistantLight);反射滤镜共两个,漫射滤镜(feDiffuseLighting)和镜面反射滤镜(feDiffuseLighting)。在 svg 里,光源滤镜被当成反射滤镜的子滤镜使用,光源发出的光经过反射滤镜产生预设的光影效果,这个可以称之为光滤镜组。光滤镜组通常会通过 feComposite 合成滤镜将光滤镜组营造的光影效果进一步加工并作用于目标图形对象。</p>

</div>

<script>

let radios = document.getElementsByName('azi');
azimuthAngle.oninput = () => {
        dLight.setAttribute('azimuth',azimuthAngle.value);
        aziMsg.innerText = 'azimuth="' + azimuthAngle.value + '"';
};
elevationAngle.oninput = () => {
        dLight.setAttribute('elevation',elevationAngle.value);
        elevMsg.innerText = 'elevation="' + elevationAngle.value + '"';
};

radios.forEach((item) => {
        item.onclick = () => {
                dLight.setAttribute('azimuth',item.value);
                azimuthAngle.value = item.value;
                aziMsg.innerText = 'azimuth="' + item.value + '"';
        }
});

</script>

红影 发表于 2023-10-24 12:25

这个距离光源的效果不需要用像素组合就能看到啊。{:4_173:}

红影 发表于 2023-10-24 12:28

方位用角度表示比较容易理解,高度也用角度单位,这个很难想到。

红影 发表于 2023-10-24 12:32

方位也不用记什么日出中午日落了,只记方向就行了吧,0度在西面,90度在北面,180度在东面。不对,我说错了,随着高度变化,这个方向还是变化的,我收回上面这句{:4_173:}

红影 发表于 2023-10-24 12:37

这两个数字好像是联合变化的,还挺麻烦。不过貌似高度90的时候,方位无论怎么变化都没什么影响。

马黑黑 发表于 2023-10-24 12:50

红影 发表于 2023-10-24 12:25
这个距离光源的效果不需要用像素组合就能看到啊。

其实都可以不需要合成的。合成是为了让滤镜组作用于原始图片之上。

马黑黑 发表于 2023-10-24 12:50

红影 发表于 2023-10-24 12:28
方位用角度表示比较容易理解,高度也用角度单位,这个很难想到。

这确实有点奇怪

马黑黑 发表于 2023-10-24 12:51

红影 发表于 2023-10-24 12:32
方位也不用记什么日出中午日落了,只记方向就行了吧,0度在西面,90度在北面,180度在东面。不对,我说错了 ...

因为都是角度,彼此的配合很重要

马黑黑 发表于 2023-10-24 12:51

红影 发表于 2023-10-24 12:37
这两个数字好像是联合变化的,还挺麻烦。不过貌似高度90的时候,方位无论怎么变化都没什么影响。

它们一般要配合着使用,要么高度不设置

红影 发表于 2023-10-24 15:06

马黑黑 发表于 2023-10-24 12:50
其实都可以不需要合成的。合成是为了让滤镜组作用于原始图片之上。

哦,不是用在原始图上就不用啊,还以为都需要用呢{:4_173:}

红影 发表于 2023-10-24 15:08

马黑黑 发表于 2023-10-24 12:50
这确实有点奇怪

是斜方向与xy平面构成的夹角吧,因为同样的夹角不同距离上高度距离不同。

红影 发表于 2023-10-24 15:09

马黑黑 发表于 2023-10-24 12:51
因为都是角度,彼此的配合很重要

是啊,这个两个角度原来还相互影响的,开始我只调一个角度,所以以为自己对了{:4_173:}

红影 发表于 2023-10-24 15:12

马黑黑 发表于 2023-10-24 12:51
它们一般要配合着使用,要么高度不设置

不设置的话,默认值是0 ,那我之前说的判断方位就对了{:4_173:}

马黑黑 发表于 2023-10-24 19:53

红影 发表于 2023-10-24 15:12
不设置的话,默认值是0 ,那我之前说的判断方位就对了

那是的

马黑黑 发表于 2023-10-24 19:53

红影 发表于 2023-10-24 15:09
是啊,这个两个角度原来还相互影响的,开始我只调一个角度,所以以为自己对了

不对也对

马黑黑 发表于 2023-10-24 19:54

红影 发表于 2023-10-24 15:08
是斜方向与xy平面构成的夹角吧,因为同样的夹角不同距离上高度距离不同。

反正就是高度,用角度表示

马黑黑 发表于 2023-10-24 19:54

红影 发表于 2023-10-24 15:06
哦,不是用在原始图上就不用啊,还以为都需要用呢

这里只是难事滤镜,所要没有被修饰的图片

红影 发表于 2023-10-24 22:12

马黑黑 发表于 2023-10-24 19:53
那是的

终于对了一回{:4_173:}

红影 发表于 2023-10-24 22:13

马黑黑 发表于 2023-10-24 19:53
不对也对

不管怎么说,试过了,至于结论对不对,等着以后验证了{:4_173:}

红影 发表于 2023-10-24 22:14

马黑黑 发表于 2023-10-24 19:54
反正就是高度,用角度表示

嗯嗯,这个比较特别,倒是好记呢。
页: [1] 2 3 4 5 6
查看完整版本: svg :光滤镜(五)