消除生成的渐变纹理上的伪影
Getting rid of artifacts on generated gradient textures
我正在通过向我拥有的白色图像添加渐变部分来生成衰减纹理。如果实现是相关的,我将使用 HTML5 canvas 来实现。出于某种原因,我得到了奇怪的光线,就像它应该是渐变平滑的伪影一样。我找不到任何方法来在实现级别上解决这个问题,所以我必须在生成后摆脱它们。问题是,如果我可以按像素访问图像,我如何识别那些白色像素并替换为像素以保持渐变平滑?
光线是由重叠和舍入误差引起的。可以通过使用高斯模糊滤镜(实际上充当低通滤镜)来移除或至少减少它们。
为了避免内部形状的黑色像素渗入渐变等新问题,我建议采取以下步骤:
- 使用与渐变起始颜色相同的颜色填充内部形状。
- 产生渐变
- 使用
filter
property of context(f.ex context.filter = "blur(7px)";
,通过将其设置为 none
进行重置)或使用手动实施来应用高斯模糊
- 以目标颜色重新绘制内部形状。
现在通过试验模糊半径来找到最佳值是一件简单的事情。请注意,模糊会添加到渐变中,因此您可能需要 link 两者,以便在增加模糊半径时减小渐变半径。
专业提示:您也可以将渐变制作全部放在一起,使用高斯模糊简单地制作发光效果(下面的运行示例)。
var ctx = c.getContext("2d");
ctx.moveTo(300, 50);
ctx.quadraticCurveTo(325, 300, 550, 550);
ctx.quadraticCurveTo(300, 500, 50, 550);
ctx.quadraticCurveTo(250, 300, 300, 50);
ctx.closePath();
// blur next drawings
ctx.filter = "blur(20px)"; // glow radius
// produce a full base using fill and heavy stroke
ctx.fillStyle = ctx.strokeStyle = "#fff";
ctx.fill();
ctx.lineWidth = 40; // thicker = stronger spread
ctx.stroke();
// final, fill center in destination color
ctx.filter = "none";
ctx.fillStyle = "#000";
ctx.fill();
#c {background:#000}
<canvas id=c width=600 height=600></canvas>
我正在通过向我拥有的白色图像添加渐变部分来生成衰减纹理。如果实现是相关的,我将使用 HTML5 canvas 来实现。出于某种原因,我得到了奇怪的光线,就像它应该是渐变平滑的伪影一样。我找不到任何方法来在实现级别上解决这个问题,所以我必须在生成后摆脱它们。问题是,如果我可以按像素访问图像,我如何识别那些白色像素并替换为像素以保持渐变平滑?
光线是由重叠和舍入误差引起的。可以通过使用高斯模糊滤镜(实际上充当低通滤镜)来移除或至少减少它们。
为了避免内部形状的黑色像素渗入渐变等新问题,我建议采取以下步骤:
- 使用与渐变起始颜色相同的颜色填充内部形状。
- 产生渐变
- 使用
filter
property of context(f.excontext.filter = "blur(7px)";
,通过将其设置为none
进行重置)或使用手动实施来应用高斯模糊 - 以目标颜色重新绘制内部形状。
现在通过试验模糊半径来找到最佳值是一件简单的事情。请注意,模糊会添加到渐变中,因此您可能需要 link 两者,以便在增加模糊半径时减小渐变半径。
专业提示:您也可以将渐变制作全部放在一起,使用高斯模糊简单地制作发光效果(下面的运行示例)。
var ctx = c.getContext("2d");
ctx.moveTo(300, 50);
ctx.quadraticCurveTo(325, 300, 550, 550);
ctx.quadraticCurveTo(300, 500, 50, 550);
ctx.quadraticCurveTo(250, 300, 300, 50);
ctx.closePath();
// blur next drawings
ctx.filter = "blur(20px)"; // glow radius
// produce a full base using fill and heavy stroke
ctx.fillStyle = ctx.strokeStyle = "#fff";
ctx.fill();
ctx.lineWidth = 40; // thicker = stronger spread
ctx.stroke();
// final, fill center in destination color
ctx.filter = "none";
ctx.fillStyle = "#000";
ctx.fill();
#c {background:#000}
<canvas id=c width=600 height=600></canvas>