2015-09-14 3 views
5

Ich versuche, eine Verschiebungskarte cikernel für iOS 8 zu erstellen, die die Pixel horizontal vom R-Kanal der Karte und vertikal vom G-Kanal verschiebt. Die Kartenpixelkoordinaten müssen in Bezug auf die Quellbildgröße mapPixel = ((dest.x/source.width) * map.width, (dest.y/source.height) * map.height)Benutzerdefinierte CIKernel Displacement Map

Die gepflückt werden Eingabebildgröße, die ich mit testen, ist 2048 x 2048 und die Karte ist rot-grün Perlin Noise 2560 x 2560

In Quartz Composer die cikernel arbeitet fast wie erwartet, mit der Ausnahme, dass die Karte nicht auf das gesamte Bild angewendet

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); 
} 

Hier ist, was die Filterfunktion wie folgt aussieht:

function __image main(__image image, __image displaceMap, __number scaleX, __number scaleY) { 
    return coreImageKernel.apply(image.definition, null, image, displaceMap, scaleX, scaleY); 
} 

Aber wenn ich den Cikernel in CIFilter laden, ist das Ergebnis weit von dem, was ich in Quartz Composer sehe. Hier ist, was Funktion gilt meine wie in der CIFilter sieht

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 
} 

Ich vermute, die ROI ist falsch und der Sampler ist gefliest, aber ich kann es nicht herausgefunden.

Antwort

1

Wie sich herausstellt, war der Kernel falsch. Hier ist ein Kernel, der den Job erledigt

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); 
} 
Verwandte Themen