具有漫射照明的 SVG 过滤器凹凸贴图溢出

SVG filter bump mapping with diffuse lighting spills out

我正在尝试使用图像的 luminanceToAlpha 转换在 SVG 中创建凹凸贴图效果,然后改变点光源在整个表面上的位置。

这是我创作的 fiddle 短片, https://jsfiddle.net/5g2qncq8/6/

代码片段:

<defs>
<filter id="bump" x="0" y="0" height="100%" width="100%" >
<feColorMatrix in="SourceGraphic" type="luminanceToAlpha" result="bumpMap"/>
<feDiffuseLighting in="bumpMap" surfaceScale="1" diffuseConstant="10" result="shading"> 
<fePointLight in="SourceGraphic" id="light" x="300" y="300" z="10">
</fePointLight>
</feDiffuseLighting>
<feBlend in="SourceGraphic" mode="multiply" result="lit"/>
</filter>
</defs>

当您在图像上滚动时,点光源的位置会更新,并且随着指针远离图像,图像会变暗。我遇到的问题是,虽然房子实际上是多边形形状,但当点光源不在时,我看到一些额外的灰色矩形区域(在房子上方)。为什么会这样?

当灯光照在房子的顶部时,它显然消失了。有人可以建议摆脱这个灰色区域的方法吗?

我知道我可能遗漏了一些明显的东西。任何帮助或指示表示赞赏。干杯!

这是因为 feBlend 公式是 cr = (1-qa)*cb + (1-qb)ca + cacb。如果你的光是 A(比如不透明的中灰色)而你的透明黑色背景是 B,那么像素的颜色将为 (1-1)(.0/.0/.0) + ( 1-0)(0.5/.05/.05) +.5*.0 ==>> 灰色。

不透明度为 qr = 1 - (1-qa)(1-qb): 1 - (1-1)(1-0) = 1.

换句话说,如果您有至少一个不透明的来源,您将获得不透明的结果。

您可以通过添加以下内容来剪掉背景:

  <feComposite operator="in" in2="SourceGraphic"/>

到过滤器的末尾。