问题描述
我使用以下算法在画布上创建了一个捏合滤镜/效果:
I've created a pinch filter/effect on canvas using the following algorithm:
// iterate pixels
for (var i = 0; i < originalPixels.data.length; i+= 4) {
// calculate a pixel's position, distance, and angle
var pixel = new Pixel(affectedPixels, i, origin);
// check if the pixel is in the effect area
if (pixel.dist < effectRadius) {
// initial method (flawed)
// iterate original pixels and calculate the new position of the current pixel in the affected pixels
if (method.value == "org2aff") {
var targetDist = ( pixel.dist - (1 - pixel.dist / effectRadius) * (effectStrength * effectRadius) ).clamp(0, effectRadius);
var targetPos = calcPos(origin, pixel.angle, targetDist);
setPixel(affectedPixels, targetPos.x, targetPos.y, getPixel(originalPixels, pixel.pos.x, pixel.pos.y));
} else {
// alternative method (better)
// iterate affected pixels and calculate the original position of the current pixel in the original pixels
var originalDist = (pixel.dist + (effectStrength * effectRadius)) / (1 + effectStrength);
var originalPos = calcPos(origin, pixel.angle, originalDist);
setPixel(affectedPixels, pixel.pos.x, pixel.pos.y, getPixel(originalPixels, originalPos.x, originalPos.y));
}
} else {
// copy unaffected pixels from original to new image
setPixel(affectedPixels, pixel.pos.x, pixel.pos.y, getPixel(originalPixels, pixel.pos.x, pixel.pos.y));
}
}
我为此付出了很多努力我非常满意结果。不过,我有一个小问题;锯齿状的像素。将JS夹点与Gimp的比较:
I've struggled a lot to get it to this point and I'm quite happy with the result. Nevertheless, I have a small problem; jagged pixels. Compare the JS pinch with Gimp's:
I不知道我错过了什么。在实际过滤器之后是否需要应用另一个过滤器?或者我的算法是完全错误的?
I don't know what I'm missing. Do I need to apply another filter after the actual filter? Or is my algorithm wrong altogether?
我无法在此处添加完整代码(作为SO片段),因为它包含4个base64图像/纹理(总共65k个字符)。相反,这是一个。
I can't add the full code here (as a SO snippet) because it contains 4 base64 images/textures (65k chars in total). Instead, here's a JSFiddle.
推荐答案
清理结果的一种方法是超级采样。这是一个简单的例子:
One way to clean up the result is supersampling. Here's a simple example: https://jsfiddle.net/Lawmo4q8/
基本上,不是为单个像素计算单个值,而是在像素内/周围采用多个值样本...
Basically, instead of calculating a single value for a single pixel, you take multiple value samples within/around the pixel...
let color =
calcColor(x - 0.25, y - 0.25) + calcColor(x + 0.25, y - 0.25) +
calcColor(x - 0.25, y + 0.25) + calcColor(x + 0.25, y + 0.25);
...并以某种方式合并结果。
...and merge the results in some way.
color /= 4;
这篇关于光滑的锯齿状像素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!