Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/100.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 与OpenGL mix相当的金属_Ios_Swift_Shader_Metal - Fatal编程技术网

Ios 与OpenGL mix相当的金属

Ios 与OpenGL mix相当的金属,ios,swift,shader,metal,Ios,Swift,Shader,Metal,我试图理解什么是金属中的mixOpenGL函数的等价物。这是我试图转换的OpenGL代码: float udRoundBox( vec2 p, vec2 b, float r ) { return length(max(abs(p)-b+r,0.0))-r; } void mainImage( out vec4 fragColor, in vec2 fragCoord ) { // setup float t = 0.2 + 0.2 * sin(mod(iTime, 2

我试图理解什么是金属中的
mix
OpenGL
函数的等价物。这是我试图转换的
OpenGL
代码:

float udRoundBox( vec2 p, vec2 b, float r )
{
    return length(max(abs(p)-b+r,0.0))-r;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // setup
    float t = 0.2 + 0.2 * sin(mod(iTime, 2.0 * PI) - 0.5 * PI);
    float iRadius = min(iResolution.x, iResolution.y) * (0.05 + t);
    vec2 halfRes = 0.5 * iResolution.xy;

    // compute box
    float b = udRoundBox( fragCoord.xy - halfRes, halfRes, iRadius );

    // colorize (red / black )
    vec3 c = mix( vec3(1.0,0.0,0.0), vec3(0.0,0.0,0.0), smoothstep(0.0,1.0,b) );

    fragColor = vec4( c, 1.0 );
} 
到目前为止,我能够转换其中的一部分:

float udRoundBox( float2 p, float2 b, float r )
{
    return length(max(abs(p)-b+r,0.0))-r;
}

float4 cornerRadius(sampler_h src) {

    float2 greenCoord = src.coord(); // this is alreay in relative coords; no need to devide by image size

    float t = 0.5;
    float iRadius = min(greenCoord.x, greenCoord.y) * (t);
    float2 halfRes = float2(greenCoord.x * 0.5, greenCoord.y * 0.5);

    float b = udRoundBox( float2(greenCoord.x - halfRes.x, greenCoord.y - halfRes.y), halfRes, iRadius );

    float3 c = mix(float3(1.0,0.0,0.0), float3(0.0,0.0,0.0), smoothstep(0.0,1.0,b) );

    return float4(c, 1.0);
}
但它正在生产绿色屏幕。我试图在视频中实现拐角半径,如下所示:


混合函数是线性插值的一种实现,通常称为Lerp函数

你可以使用线性插值,你有一个值,比如说t,你想知道这个值在一定范围内是如何映射的

例如,如果我有三个值:

a=0 b=1 和 t=0.5

我可以调用mix(a,b,t),结果是0.5。这是因为mix函数需要一个起始范围值、一个结束范围值和一个用于插值的因子,所以我得到0.5,介于0和1之间

查看文档Metal有一个执行线性插值的mix实现


问题是,
greenCoord
(顺便说一句,这只是你问的另一个问题的一个好变量名)是当前像素的相对坐标,与绝对输入分辨率无关

如果您想更换
iResolution
,请使用
src.size()

看起来你需要绝对(像素)单位的输入坐标。您可以通过向内核的输入中添加
destination
参数来实现这一点,如下所示:

float4 cornerRadius(sampler src, destination dest) {
    const float2 destCoord = dest.coord(); // pixel position in the output buffer in absolute coordinates
    const float2 srcSize = src.size();

    const float t = 0.5;
    const float radius = min(srcSize.x, srcSize.y) * t;
    const float2 halfRes = 0.5 * srcSize;

    const float b = udRoundBox(destCoord - halfRes, halfRes, radius);

    const float3 c = mix(float3(1.0,0.0,0.0), float3(0.0,0.0,0.0), smoothstep(0.0,1.0,b) );

    return float4(c, 1.0);
}

感谢您为我解释了基本原理,要在Metal/OpenGL中掌握所有基本操作还有很长的路要走!嘿,弗兰克!再次感谢你。我想这是一个糟糕的名字,但我没有冒险哈哈。工作!:)我开始更好地理解发生了什么,尽管我今天花了半天的时间才意识到我需要用金属而不是用EAGL上下文来初始化
CIContext
,只是为了让它看起来更真实。Ey Frank,刚刚在我们以前制造的VHS过滤器上遇到了内存消耗方面的新问题。似乎当我们使用4K视频时——这对设备来说非常困难,而且它正在崩溃。问题是,我们的应用程序产生的最终输出不超过1080p,而我们正在做额外的工作,但没有任何回报。如果你有一个空闲的分钟,我希望你能看看,并指导我在正确的方向(一如既往)