目标
我正在尝试编写一个 SVG 过滤器来在给定形状上渲染波浪照明。所以在那个形状里面我想要波浪应用,但我不想要那个形状之外的可见效果。据我了解,我不能将相同的图像源用于波浪的高度图和atop
合成的目标域。所以我认为<feImage>
可以使用一个元素从一个单独的渐变填充对象中获取高度图。但到目前为止,我还没有成功地让该对象在滤镜效果区域内可见。
第一次尝试
我到目前为止的代码:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg version="1.1" width="512" height="512"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<radialGradient id="waveFill" r="5%" spreadMethod="reflect">
<stop offset="0%" stop-opacity="1.00"/>
<stop offset="20%" stop-opacity="0.90"/>
<stop offset="40%" stop-opacity="0.65"/>
<stop offset="60%" stop-opacity="0.35"/>
<stop offset="80%" stop-opacity="0.10"/>
<stop offset="100%" stop-opacity="0.00"/>
</radialGradient>
<rect id="waveImg" x="-210" y="-105" width="420" height="210"
stroke="none" fill="url(#waveFill)"/>
<filter id="waveFilter">
<feImage xlink:href="#waveImg" result="waves"/>
<!-- feSpecularLighting and so on will be added later on -->
<feComposite operator="atop" in="waves" in2="SourceImage"/>
</filter>
</defs>
<g transform="translate(256 256)">
<!-- use xlink:href="#waveImg"/ works -->
<ellipse rx="200" ry="100" fill="#0000ff" stroke="none"
style="filter:url(#waveFilter)"/>
</g>
</svg>
相关文件
状态的文档<feImage>
:
如果'xlink:href'</a> 引用了独立的图像资源,例如 JPEG、PNG 或 SVG 文件,则根据'image'</a> 元素的行为呈现图像资源;否则,引用的资源将根据'use'</a> 元素的行为呈现。在任何一种情况下,当前用户坐标系都取决于'filter'</a> 元素上的属性'primitiveUnits'</a>的值。
第二次尝试
use
而不是在image
我看来没问题,但我不确定在这种情况下如何定义矩形区域。的文档use
似乎表明在这种情况下(引用的元素既不是 asymbol
也不是svg
元素),width
andheight
属性是无关紧要的,但是它如何描述一个矩形区域呢?我还认为也许改变原始单位会有所帮助。或将图像装箱在symbol
. 所以我的第二次尝试是以下一次:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg version="1.1" width="512" height="512"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<radialGradient id="waveFill" r="5%" spreadMethod="reflect">
<stop offset="0%" stop-opacity="1.00"/>
<stop offset="20%" stop-opacity="0.90"/>
<stop offset="40%" stop-opacity="0.65"/>
<stop offset="60%" stop-opacity="0.35"/>
<stop offset="80%" stop-opacity="0.10"/>
<stop offset="100%" stop-opacity="0.00"/>
</radialGradient>
<symbol viewBox="0 0 100 100" id="waveImg" preserveAspectRatio="none">
<rect width="100" height="100" stroke="none" fill="url(#waveFill)"/>
</symbol>
<filter id="waveFilter" primitiveUnits="objectBoundingBox">
<feImage xlink:href="#waveImg" x="0" y="0" width="100%" height="100%"
preserveAspectRatio="none" result="waves"/>
<!-- feSpecularLighting and so on will be added later on -->
<feComposite operator="atop" in="waves" in2="SourceImage"/>
</filter>
</defs>
<g transform="translate(256 256)">
<!-- use xlink:href="#waveImg"/ works -->
<ellipse rx="200" ry="100" fill="#0000ff" stroke="none"
style="filter:url(#waveFilter)"/>
<ellipse rx="200" ry="100" fill="none" stroke="#ff0000"/>
</g>
</svg>
仍然没有图像可见。我究竟做错了什么?
核心问题
如何将 SVG 文件的片段用作照明的凹凸贴图,而不将其用作SourceGraphic
过滤器?
光栅化器
此图像不适用于 Web 部署,但将在本地进行光栅化。所以浏览器兼容性不是什么大问题。如果东西在 Inkscape 或 rsvg-convert 下正确渲染,那对我来说就足够了。