独立于分辨率的SVG过滤器



我想使用svg过滤器作为我的一个svg对象的纹理,但有一个问题(我在使用Illustrator时没有意识到,因为它会光栅化过滤器(。问题是svg过滤器会随着svg本身的大小而缩放(响应网页,所以我们不知道最终的svg大小(。而不是想要的纹理,我们可以得到那个或那个等

有什么变通办法吗?也许有css vars和calc((或原生svg功能?我应该用一些";查询";HDPI显示器使其稍微大一点(x倍(?

以下是具有正确显示的固定svg大小的片段(应该看起来像图片"所需"(:

#wrap {
height: 2320px;
width:  2744px;
}
svg {
width: 41%;
}
<div id="wrap">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1232 1232">
<defs>
<filter  height="100%" id="noise" width="100%" x="0%" y="0%">
<feTurbulence  baseFrequency="0.75" numOctaves="5" stitchTiles="noStitch" type="fractalNoise"></feTurbulence>
<feDiffuseLighting  lighting-color="#ccc" surfaceScale="17">
<feDistantLight  azimuth="45" elevation="65"></feDistantLight>
</feDiffuseLighting>
</filter>
<style>
.a {
fill: #dedede;
filter:url(#noise);
}
</style>
</defs>
<title>-stackoverex</title>
<rect class="a" width="1232" height="1232"/>
</svg>
</div>

让我试着澄清一下情况。有一个响应块,其右侧被svg图像占据,在不同的屏幕分辨率(或浏览器缩放(下,块(图像(必须缩放以适应用户的视口。该图像仅显示在从992px开始的桌面上,其初始大小约为655x440,在PRO XDR显示器上,它将增加到2620x1760(如果我没有弄错的话(。svg的一个重要部分被一个带有";石膏";纹理,应该看起来足够逼真,而且使用位图太贵,即使使用最大的avif压缩,全尺寸纹理也会太重。

更新:

这样我们就可以看到纹理应该如何改变(或不改变(Kaiido 的各种尺寸

这是一个具有所需结果的片段(使用了高分辨率嵌入图像(使用了一个干净的原始svg,其中包含墙和标头的基本标记。您可以转到整页视图,并根据需要进行游戏。

也许我做错了什么,但我仍然无法摆脱某些分辨率下的纹理平铺;"原始滤波器";,此外,一些设备没有以最正确的方式显示该过滤器。此外,我找不到一种方法来缩小lighting过滤器的小分辨率(如果可能的话(。

事实上,作为一种变通方法,我们可以排除lighting过滤器,只使用去饱和的Turbulence。在分辨率低于1400甚至更高的情况下,它在视觉上非常相似,过滤器本身的渲染速度更快,并且在所有设备上都能正确显示。

<filter id="stucco" height="100%" width="100%" x="0%" y="0%">
<feTurbulence baseFrequency="0.9" xresult="colorNoise" stitchTiles="stitch" numOctaves="90" type="fractalNoise" />
<feColorMatrix in="colorNoise" type="matrix" values=".33 .33 .33 0 0 .33 .33 .33 0 0 .33 .33 .33 0 0 0 0 0 1 0"/>
<feComposite operator="in" in2="SourceGraphic" result="monoNoise"/>
<feBlend in="SourceGraphic" in2="monoNoise" mode="multiply" />
</filter>

不理想,但可以接受,尽管这里也有一些问题。

第一个是过滤器缺乏对比度(尽管有"乘法"混合模式(,第二个

<svg>
<defs>
<style type="text/css">
@media (-webkit-min-device-pixel-ratio: 1) and (min-width:: 992px)  {
#SVG-noise {
filter:url(#stucco-sm);
}
}
@media (-webkit-min-device-pixel-ratio: 1) and (min-width:: 1920px)  {
#SVG-noise {
filter:url(#stucco-xl);
}
}
@media (-webkit-min-device-pixel-ratio: 2) and (min-width:: 992px)  {
#SVG-noise {
filter:url(#stucco-hdpi);
}
}

如果SVG具有viewBox,则内容将按比例缩放。如果不需要缩放行为,请删除viewBox

在这里,我把矩形做得很大(3000x3000(,以覆盖各种尺寸。您可以将svg的宽度和高度设置为小于此值的任何值,并且过滤器模式将保持不变。如果你需要大于3000x3000的东西,那么增加矩形的大小,使其边缘不可见。

svg {
width: 50%;
height: 300px;
}
<div id="wrap">
<svg>
<defs>
<filter  height="100%" id="noise" width="100%" x="0%" y="0%">
<feTurbulence  baseFrequency="0.75" numOctaves="5" stitchTiles="noStitch" type="fractalNoise"></feTurbulence>
<feDiffuseLighting  lighting-color="#ccc" surfaceScale="17">
<feDistantLight  azimuth="45" elevation="65"></feDistantLight>
</feDiffuseLighting>
</filter>
<style>
.a {
fill: #dedede;
filter:url(#noise);
}
</style>
</defs>
<title>-stackoverex</title>
<rect class="a" width="3000" height="3000"/>
</svg>
</div>

最新更新