我正在浏览这个关于自定义icfilter的教程:
https://medium.com/@m_tuzer using-metal-shading-language-for-custom-cikernels-metal-swift-7bc8e7e913e6
除了采样器的坐标没有归一化之外,一切都工作得很好。因此,例如pos.y < 0.33
这样的条件不工作,内核使用实际的图像坐标。
由于教程是旧的,可能在CIFilter中已经有了"破坏"这段代码的更改。我看了CI内核的手册,但找不到一种方法来获得内核内采样器的标准化坐标。
内核代码:
#include <metal_stdlib>
using namespace metal;
#include <CoreImage/CoreImage.h> // (1)
float3 multiplyColors(float3, float3);
float3 multiplyColors(float3 mainColor, float3 colorMultiplier) { // (2)
float3 color = float3(0,0,0);
color.r = mainColor.r * colorMultiplier.r;
color.g = mainColor.g * colorMultiplier.g;
color.b = mainColor.b * colorMultiplier.b;
return color;
};
extern "C" { namespace coreimage { // (3)
float4 dyeInThree(sampler src, float3 redVector, float3 greenVector, float3 blueVector) {
float2 pos = src.coord();
float4 pixelColor = src.sample(pos); // (4)
float3 pixelRGB = pixelColor.rgb;
float3 color = float3(0,0,0);
if (pos.y < 0.33) { // (5)
color = multiplyColor(pixelRGB, redVector);
} else if (pos.y >= 0.33 && pos.y < 0.66) {
color = multiplyColor(pixelRGB, greenVector);
} else {
color = multiplyColor(pixelRGB, blueVector);
}
return float4(color, 1.0);
}
}}
您可以使用源的范围将源坐标转换为相对值,如下所示:
#include <metal_stdlib>
using namespace metal;
#include <CoreImage/CoreImage.h>
extern "C" { namespace coreimage {
float4 dyeInThree(sampler src, float3 redVector, float3 greenVector, float3 blueVector) {
float2 pos = src.coord();
float4 pixelColor = src.sample(pos);
// transform to relative coordinates
pos -= src.origin();
pos /= src.size();
float3 color = float3(0,0,0);
if (pos.y < 0.33) {
color = pixelColor.rgb * redVector;
} else if (pos.y < 0.66) {
color = pixelColor.rgb * greenVector;
} else {
color = pixelColor.rgb * blueVector;
}
return float4(color, pixelColor.a);
}
}}