【发布时间】:2020-04-16 20:33:21
【问题描述】:
我正在尝试制作一个带有阴影的行星的球形图像,以便在浏览器中渲染以用于模拟网页,但我一直在与一个我似乎无法弄清楚的奇怪视觉问题作斗争。
这是 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>
(如果您愿意,可以将其保存到 HTML (.html) 文件(添加 html 和 body 标签),然后在浏览器中运行以查看它。或者将其保存到 SVG 文件(.svg),并删除 div 和 br 标签,如果你想在上面使用任何 SVG 工具。
这个伪影发生在线性渐变停止点之一的位置,特别是第 33 行的#stopEaDusk,在线性渐变#lgdEaNightSide 中,它被用作覆盖路径#pNight 的填充。这个伪影可能看起来很微弱,但在不缩小 300% 时它是真实的并且更加明显。我实际的 SVG 也有一个免费的 #pDay 覆盖,我删除了它以简化代码。但是当它被添加时,我得到了三个这样的暗带伪影,一个在上面,一个在另一侧的相应位置(我有另一个黎明/黄昏停止),一个在两个叠加层相遇的中点.当它们三个都可见时,它看起来很可怕,所以我不能忽略它。
其他要点:
- 据我所知,这不仅仅是here 建议的视觉错觉,因为即使被炸毁,它仍然存在。如果是,我仍然需要修复它。
- 我不相信它是 old Chrome bug 中建议的 this answer,因为它看起来不同,但主要是因为我在 IE 中也看到它(尽管它可能更微弱)。
tl,dr:是什么导致了这个黑暗带,我该如何摆脱它?
这里的问题似乎有些混乱,所以请允许我澄清一下。线性渐变lgdEaNightSide 是为显式效果而编写的,它似乎正在这样做,但它也产生了一种不希望的副作用,不是预期的,并且就我对 SVG 的理解而言,应该不发生。
想要的效果是 pNight 叠加层添加: 1. 70% 的暗度,在其弧线的顶部(非常高且在屏幕外),平滑地着色到 60% 的暗度,向下 99%。 2. 然后从 60% 暗度 99% 下降到 50% 暗度 100% 下降。这是为了提供一个类似黄昏的过渡区域。
但是,除此之外,它还添加了不希望的效果: - 在下降约 98.8% 处,突然变暗 - 然后在下降到大约 99.2% 时,它又突然变轻了。
这不应该发生,据我所知,我编写的 SVG不应该这样做。
我正在寻找的是如何保持第一个(期望的)效果,同时摆脱第二个(不希望的)效果。
我不需要被告知是第二站导致了问题。我知道,我在上面说过,并在代码 cmets 中指出了这一点。我不需要答案来告诉我我已经知道的。我要找的是:
如何在保留我最初编写它的视觉效果的同时修复它,以及
为什么会发生,当 AFAIK 时,它应该不发生。
【问题讨论】:
标签: html svg graphics linear-gradients