我正在尝试为iOS 8创建一个置换贴图cikernel,它将像素从地图R通道水平移动,并从G通道垂直移动。 必须相对于源图像大小拾取地图像素坐标mapPixel =((dest.x / source.width)* map.width,(dest.y / source.height)* map.height)
我测试的输入图像尺寸是2048 x 2048 而地图是红绿色的柏林噪音2560 x 2560
在Quartz Composer中,cikernel几乎按预期工作,除了地图未应用于整个图像
kernel vec4 coreImageKernel(sampler image, sampler displaceMap, float scaleX, float scaleY)
{
vec2 destination = destCoord();
vec2 imageSize = samplerSize(image);
float xPercent = destination.x / imageSize.x;
float yPercent = destination.y / imageSize.y;
vec2 mapSize = samplerSize(displaceMap);
vec2 mapCoord = vec2(mapSize.x * xPercent, mapSize.y * yPercent);
vec4 mapPixel = sample(displaceMap, mapCoord);
float ratioShiftX = ((mapPixel.x) * 2.0) - 1.0;
float ratioShiftY = ((mapPixel.y) * 2.0) - 1.0;
vec2 pixelShift = vec2(ratioShiftX * scaleX, ratioShiftY * scaleY);
return sample(image, destination - pixelShift);
}
这是过滤器功能的样子:
function __image main(__image image, __image displaceMap, __number scaleX, __number scaleY) {
return coreImageKernel.apply(image.definition, null, image, displaceMap, scaleX, scaleY);
}
但是当我在CIFilter中加载cikernel时,结果远非我在Quartz Composer中看到的结果。 这是我的应用函数在CIFilter中的样子
override var outputImage:CIImage? {
if let inputImage = inputImage {
if let inputMap = inputMap {
let args = [inputImage as AnyObject, inputMap as AnyObject, inputScaleX, inputScaleY]
return CIDisplacementMapFilter.kernel?.applyWithExtent(inputImage.extent, roiCallback: {
(index, rect) in
if index == 0 {
return rect
}
return CGRectInfinite
}, arguments: args)
}
}
return nil
}
我猜测投资回报率是错误的,采样器是平铺的,但我无法弄明白。
答案 0 :(得分:1)
事实证明内核是错误的。 这是一个完成工作的内核
kernel vec4 displace(sampler source, sampler map, float scaleX, float scaleY)
{
vec2 d = destCoord();
vec4 mapPixel = sample(map, samplerTransform(map, d));
float shiftX = ((mapPixel.x * 2.0) - 1.0) * scaleX;
float shiftY = ((mapPixel.y * 2.0) - 1.0) * scaleY;
vec2 s = samplerTransform(source, d + vec2(shiftX, shiftY));
return sample(source, s);
}