停止时 SGV 梯度变暗

RBa*_*ung 5 html graphics svg linear-gradients

我正在尝试制作一个带有阴影的夜晚行星的球形图像,以在浏览器中渲染以用于模拟网页,但我一直在与一个我似乎无法弄清楚的奇怪视觉问题作斗争。

这是在 Chrome 中显示的 SVG 图像片段(这也发生在 IE 中),然后放大 3 倍:

SVG 星球终结者

您会注意到,在昼/夜终结符的正上方,有一条较暗的微弱水平带,宽度约为其在终结符上方的距离的 1/3。这应该不是在那里,我想不通为什么它的存在或如何摆脱它。

以下是 HTML 片段中的 SVG 代码,以便于查看:

<div style="position:absolute; z-index:1; margin:15px; 
            width:640px; height:640px; 
            background-color:black">

  <svg id="svgEa" style="width:100%; height:100%;" viewBox="-5000 -5000 10000 10000" preserveAspectRatio="xMidYMid meet" clip-path="url(#svgEaClip)" transform="scale(1.0,1.0)" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
                <!-- NOTE: All internal units are in KM (or %)  -->
    
                <defs id="defsEa">
                    <clipPath id="svgEaClip">
                        <rect width="100%" height="100%" />
                    </clipPath>
                    <linearGradient id="lgdEaSphere">
                        <stop style="stop-color:#ffffff;stop-opacity:1.00;" offset="0.00" id="stopEarthCenter" />
                        <stop style="stop-color:#dfffef;stop-opacity:1.00" offset="0.30" id="stopEarthInner" />
                        <stop style="stop-color:#91ffc8;stop-opacity:1.00" offset="0.31" id="stopEarthMid" />
                        <stop style="stop-color:#00A064;stop-opacity:1.00" offset="0.95264" id="stopEarthOuter" />
                        <stop style="stop-color:#44ffff;stop-opacity:0.66" offset="0.95264" id="stopAirInner" />
                        <stop style="stop-color:#44ffff;stop-opacity:0.10" offset="1.00" id="stopAirOuter"  />
                    </linearGradient>
                    <radialGradient id="rgdEaSphere"  xlink:href="#lgdEaSphere"
                        gradientUnits="userSpaceOnUse"
                        cx="0" cy="0"
                        fx="0" fy="0"
                        r="3339.05" 
                        />
    
                    <linearGradient id="lgdEaNightSide" 
                        x1="0%" y1="0%" x2="0%" y2="100%"
                        spreadMethod="pad" >
                        <stop style="stop-color:#000000;stop-opacity:0.7;" offset="0.00" id="stopEaMidnight" />
                        <!-- this stop seems to cause the artifact -->
                        <stop style="stop-color:#000000;stop-opacity:0.6;" offset="0.99" id="stopEaDusk" /> 
                        <stop style="stop-color:#000000;stop-opacity:0.5;" offset="1.00" id="stopEaTerminator" />
                    </linearGradient>
                </defs>
    
                <g id="gEaAll" transform="scale(1.2,1.2)" >
                    <g id="gEaSunFacing" >
                        <!-- contains everything that stays oriented with the Sun -->
                        <circle
                            id="cEarthAir"
                            cx="0" cy="0" r="3339.05"
                            style="display:inline;fill-opacity:1;fill:url(#rgdEaSphere)" />
                        <!--  overlay to give Earth a night side.  -->
                        <path id="pNight" 
                            style="stroke:none; fill:url(#lgdEaNightSide)"
                            d="M -3189.05,0 
                                A 3189.05,15945.25 0 1,1 3189.05,0
                                Z" 
                            />
                    </g>
                </g>
    
            </svg>

</div>
Run Code Online (Sandbox Code Playgroud)

(如果您愿意,可以将其保存到 HTML ( .html) 文件(添加 html 和 body 标签),然后在浏览器中运行以查看它。或者将其保存到 SVG 文件 ( .svg),然后删除div 和 br 标签,如果你想在上面使用任何 SVG 工具。

这种伪影发生在线性渐变停止之一的位置,特别是#stopEaDusk在第 33 行,在线性渐变中#lgdEaNightSide,它被用作覆盖路径的填充#pNight。这种伪影可能看起来很微弱,但当没有缩小 300% 时,它是真实的并且更加明显。我的实际 SVG 也有一个免费的#pDay覆盖层,我删除了它以简化代码。但是当它被添加时,我得到了三个暗带伪像,一个在上面,一个在另一边的相应位置(我有另一个黎明/黄昏停止),一个在两个叠加层相遇的中点. 当它们三个都可见时,它看起来很可怕,所以我不能忽略它。

其他要点:

  • 据我所知,这不仅仅是这里建议的视觉错觉,因为它即使被炸毁也仍然存在。如果是,我仍然需要修复它。
  • 我不相信这是这个答案中建议的这个旧的 Chrome 错误,因为它看起来不同,但主要是因为我也在 IE 中看到它(尽管它可能更微弱)。

tl,dr: 是什么导致了这个黑暗带,我该如何摆脱它?


这里的问题似乎有些混乱,所以请允许我澄清一下。线性梯度lgdEaNightSide是为显式效果而编写的,它似乎正在这样做,但它产生了不想要的副作用,这不是故意的,并且就我对 SVG 的理解而言,应该发生。

预期的效果是 pNight 叠加添加: 1. 70% 的黑暗,在其弧的顶部(非常高且离屏幕),在向下的 99% 处平滑地着色到 60% 的黑暗。2. 然后从 60% 黑暗 99% 向下快速着色,到 50% 黑暗 100% 向下。这是为了提供一个黄昏般的过渡区。

然而,除此之外,它还增加了不希望有的效果: - 在大约 98.8% 的地方,它突然变暗 - 然后在大约 99.2% 的地方,它又突然变亮了。

这不应该发生,据我所知,我写的 SVG应该这样做。

我正在寻找的是如何保持第一个(期望的)效果,同时摆脱第二个(不期望的)效果。

我不需要被告知第二站导致了问题。我知道,我在上面说过,并在代码注释中指出。我不需要答案来告诉我我已经知道的事情。我正在寻找的是:

  1. 如何修复它,同时保留我最初为其编写的视觉效果,以及

  2. 为什么会发生,当 AFAIK 时,它应该发生。

wiz*_*zeb 3

代码没有任何问题。

\n\n

条带的存在是因为显示器没有足够的颜色来表示细微的变化。您正在尝试在大面积上更改 10% 的不透明度,这对于大多数显示器来说是不可能的。

\n\n

您可以通过切换屏幕来确定这是显示器问题。根据显示器的质量和像素密度,您会看到略有不同的结果。一些浏览器使用抖动,这会减少色带并牺牲像素化。

\n\n

解决这个问题的唯一方法是引入更多的颜色变化,就像普林斯所说的那样。

\n\n

另一篇文章的答案很好地解释了这个概念。它值得一读,但我将引用解决方案以节省人们的点击次数。/sf/answers/789223921/

\n\n
\n

如果您想让当前的 24 位颜色显示器不那么明显,您可以:

\n\n
    \n
  • 更改您的设计,在渐变中引入微妙的颜色变化(例如,从深蓝色到灰绿色)。这会导致不同的 RGB 通道位可以在不同的时间转换,从而将您的色带分解为较小的差异化颜色。

  • \n
  • 更改您的设计以增加动态范围(例如从纯白色到纯黑色),以便您可以使用更多的颜色条。

  • \n
  • 更改您的设计以减少渐变发生的总距离,从而减少带的宽度。

  • \n
\n\n

\xe2\x80\xa6 或以上的某种组合。

\n
\n\n

我实施了这个策略,但它并不完美。如果你真的想摆脱色带,你将不得不做出其他权衡。例如,您可能无法使用纯黑色。

\n\n

\r\n
\r\n
<div style="position:absolute; z-index:1; margin:15px; \r\n            width:640px; height:640px; \r\n            background-color:#0c0c26">\r\n\r\n  <svg id="svgEa" style="width:100%; height:100%;" viewBox="-5000 -5000 10000 10000" preserveAspectRatio="xMidYMid meet" clip-path="url(#svgEaClip)" transform="scale(1.0,1.0)" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">\r\n                <!-- NOTE: All internal units are in KM (or %)  -->\r\n    \r\n                <defs id="defsEa">\r\n                    <clipPath id="svgEaClip">\r\n                        <rect width="100%" height="100%" />\r\n                    </clipPath>\r\n                    <linearGradient id="lgdEaSphere">\r\n                        <stop style="stop-color:#ffffff;stop-opacity:1.00;" offset="0.00" id="stopEarthCenter" />\r\n                        <stop style="stop-color:#dfffef;stop-opacity:1.00" offset="0.30" id="stopEarthInner" />\r\n                        <stop style="stop-color:#91ffc8;stop-opacity:1.00" offset="0.31" id="stopEarthMid" />\r\n                        <stop style="stop-color:#00A064;stop-opacity:1.00" offset="0.95264" id="stopEarthOuter" />\r\n                        <stop style="stop-color:#44ffff;stop-opacity:0.66" offset="0.95264" id="stopAirInner" />\r\n                        <stop style="stop-color:#44ffff;stop-opacity:0.10" offset="1.00" id="stopAirOuter"  />\r\n                    </linearGradient>\r\n                    <radialGradient id="rgdEaSphere"  xlink:href="#lgdEaSphere"\r\n                        gradientUnits="userSpaceOnUse"\r\n                        cx="0" cy="0"\r\n                        fx="0" fy="0"\r\n                        r="3339.05" \r\n                        />\r\n    \r\n                    <linearGradient id="lgdEaNightSide" x1="0%" y1="0%" x2="0%" y2="100%" spreadMethod="pad">\r\n                        <stop style="stop-color:#00033e;stop-opacity:0.7;" offset="0.00" id="stopEaMidnight"></stop>\r\n                        <!-- this stop seems to cause the artifact -->\r\n                        <stop style="stop-color:#090d24;stop-opacity:0.6;" offset="0.99" id="stopEaDusk"></stop> \r\n                        <stop style="stop-color:#000;stop-opacity:0.5;" offset="1.00" id="stopEaTerminator"></stop>\r\n                    </linearGradient>\r\n                </defs>\r\n    \r\n                <g id="gEaAll" transform="scale(1.2,1.2)" >\r\n                    <g id="gEaSunFacing" >\r\n                        <!-- contains everything that stays oriented with the Sun -->\r\n                        <circle\r\n                            id="cEarthAir"\r\n                            cx="0" cy="0" r="3339.05"\r\n                            style="display:inline;fill-opacity:1;fill:url(#rgdEaSphere)" />\r\n                        <!--  overlay to give Earth a night side.  -->\r\n                        <path id="pNight" \r\n                            style="stroke:none; fill:url(#lgdEaNightSide)"\r\n                            d="M -3189.05,0 \r\n                                A 3189.05,15945.25 0 1,1 3189.05,0\r\n                                Z" \r\n                            />\r\n                    </g>\r\n                </g>\r\n    \r\n            </svg>\r\n\r\n</div>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n