我正在尝试制作一个球形行星的图像,其中夜间一面会投影阴影,并在浏览器中呈现,用于模拟网页。但我一直在与一个奇怪的视觉问题斗争,无法解决。
这是一个HTML片段中的SVG代码,以便于查看:
如果您想要,可以将此保存为HTML( .html )文件(添加html和body标签),然后在浏览器中运行以查看它。或者将其保存为SVG文件( .svg ),并删除div和br标记,如果您想在其上使用任何SVG工具。
该伪影恰好出现在线性渐变的一个停止点上,具体是第33行的
这是SVG的图像片段,在Chrome(在IE中也会发生)中显示,然后放大3倍:
你会注意到在白昼和黑夜的分界线上方,有一条淡淡的水平暗带,宽度约为其距离分界线的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>
该伪影恰好出现在线性渐变的一个停止点上,具体是第33行的
#stopEaDusk
,它正在用作覆盖路径#pNight
的填充的线性渐变#lgdEaNightSide 中。虽然这个伪影很微弱,但当缩放未达到300%时,它会更加明显。我的实际SVG还有一个补充的#pDay 叠加层,我已经删除了它以简化代码。但是当它被添加时,我会得到三个这样的黑暗带伪影,一个在上面,在另一侧的相应位置(那里我有另一个黎明/黄昏停止点),还有一个恰好位于两个叠加层相遇的中点处。当它们全部可见时,它看起来很糟糕,所以我不能忽视它。
其他要点:
- 据我所知,这不仅仅是一个视觉错觉,如此处所示,即使放大后仍然存在。如果是,我仍需要修复它。
- 我不认为这是旧版Chrome bug,如此答案中所建议的那样,因为它显示方式不同,但主要是因为我在IE中也看到它(虽然可能更微弱)。
简而言之:是什么导致了这个黑暗带,我该如何摆脱它?
有关问题的混淆似乎存在,因此请允许我澄清一下。线性渐变lgdEaNightSide是为了实现明确的效果而编写的,它似乎正在实现这个效果,但它也产生了一个不希望出现的副作用,这并不是预期的结果,根据我对SVG的理解,这种情况不应该发生。
期望的效果是pNight叠加:
1. 在其弧顶部(非常高且超出屏幕)添加70%的暗度,平滑地阴影到99%的60%暗度。
2. 然后从99%的60%暗度快速阴影到100%的50%暗度。这是为了提供类似黄昏的过渡区域。
然而,除此之外,它还会产生不希望的效果:
- 在接近下降的98.8%处,它突然变暗。
- 然后在约99.2%的位置,它又突然变亮。
这不应该发生,据我所知,我编写的SVG不应该出现这种情况。
我需要的是如何保留最初编写代码时的视觉效果,同时消除不必要的第二个效果。我不需要被告知第二个停止位会导致问题,因为我已经在上面说明了,并在代码注释中指出了这一点。我需要的是:
1. 如何修复它,同时保留最初编写代码时的视觉效果;
2. 为什么会发生这种情况,因为据我所知,它不应该发生。