Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/96.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 金属计算着色器:将alpha设置为零不会产生完全的透明度_Ios_Swift_Shader_Gpu_Metal - Fatal编程技术网

Ios 金属计算着色器:将alpha设置为零不会产生完全的透明度

Ios 金属计算着色器:将alpha设置为零不会产生完全的透明度,ios,swift,shader,gpu,metal,Ios,Swift,Shader,Gpu,Metal,我正试图修改这家伙的代码: 它从iphone/ipad摄像头接收视频,并用一些金属GPU计算内核实时过滤 我想改变金属代码来做一些简单的色度键控,我们使视频中的某种颜色透明(即,对于该颜色alpha=0) 问题在于,即使在metal compute内核的末尾强制alpha为零,metal compute内核产生的视频输出也永远不会达到完全透明: outTexture.write(float4(float3(rgb), 0.0), gid); 生成的视频仅部分透明 请注意,我正在设置 laye

我正试图修改这家伙的代码:

它从iphone/ipad摄像头接收视频,并用一些金属GPU计算内核实时过滤

我想改变金属代码来做一些简单的色度键控,我们使视频中的某种颜色透明(即,对于该颜色alpha=0)

问题在于,即使在metal compute内核的末尾强制alpha为零,metal compute内核产生的视频输出也永远不会达到完全透明:

outTexture.write(float4(float3(rgb), 0.0), gid);
生成的视频仅部分透明

请注意,我正在设置 layer.不透明=假 对于正在进行渲染的MTKView

有人知道为什么会这样吗

这是UIView的alpha=0和红色背景的结果:

Columbo的答案对我很有用,下面是我的chromakey过滤器的代码:

kernel void ChromaKey(texture2d<float, access::read> yTexture [[texture(0)]],
                                   texture2d<float, access::read> cbcrTexture [[texture(1)]],
                                   texture2d<float, access::write> outTexture [[texture(2)]],
                                   uint2 gid [[thread_position_in_grid]])
{
    float2 green = float2(54.0/255.0, 34.0/255.0);
    float threshold = 0.05;
    float3 colorOffset = float3(-(16.0/255.0), -0.5, -0.5);
    float3x3 colorMatrix = float3x3(
                                    float3(1.164,  1.164, 1.164),
                                    float3(0.000, -0.392, 2.017),
                                    float3(1.596, -0.813, 0.000)
                                    );

    uint2 cbcrCoordinates = uint2(gid.x / 2, gid.y / 2);
    float y = yTexture.read(gid).r;
    float2 cbcr = cbcrTexture.read(cbcrCoordinates).rg;
    float alpha = smoothstep(threshold, threshold + 0.5, distance(cbcr, green));
    float3 ycbcr = float3(y, cbcr);
    float4 rgba = alpha * float4(colorMatrix * (ycbcr + colorOffset), 1.0);
    outTexture.write(rgba, gid);
}
kernel void ChromaKey(texture2d yTexture[[texture(0)],
纹理2D cbcrTexture[[纹理(1)],
纹理2D outTexture[[纹理(2)],
uint2 gid[[螺纹位置在网格中]]
{
浮动2绿色=浮动2(54.0/255.0,34.0/255.0);
浮动阈值=0.05;
float3 colorOffset=float3(-(16.0/255.0),-0.5,-0.5);
float3x3颜色矩阵=float3x3(
浮动3(1.164,1.164,1.164),
浮动3(0.000,-0.392,2.017),
浮动3(1.596,-0.813,0.000)
);
uint2 CBCR坐标=uint2(gid.x/2,gid.y/2);
float y=yTexture.read(gid.r);
float2 cbcr=cbcrTexture.read(cbcrCoordinates.rg);
浮点alpha=平滑步长(阈值,阈值+0.5,距离(cbcr,绿色));
浮动3 ycbcr=浮动3(y,cbcr);
float4 rgba=alpha*float4(colorMatrix*(ycbcr+colorfostate),1.0;
outTexture.write(rgba,gid);
}

我猜您的图层使用的是预乘alpha()。如果是这样,那么您有两个简单的解决方案:

  • 将层从预乘alpha合成更改为使用非预乘alpha合成
  • 更改计算内核以执行alpha预乘 要执行#2,您需要更改如下内容:

    float alpha = <something_or_other>;
    float3 rgb = colorMatrix * (ycbcr + colorOffset);
    outTexture.write(float4(float3(rgb), alpha), gid);
    
    float alpha = <something_or_other>;
    float3 rgb = (colorMatrix * (ycbcr + colorOffset)) * alpha;
    outTexture.write(float4(float3(rgb), alpha), gid);
    
    float alpha=;
    float3 rgb=彩色矩阵*(ycbcr+彩色偏移);
    write(float4(float3(rgb),alpha),gid);
    
    对这样的事情:

    float alpha = <something_or_other>;
    float3 rgb = colorMatrix * (ycbcr + colorOffset);
    outTexture.write(float4(float3(rgb), alpha), gid);
    
    float alpha = <something_or_other>;
    float3 rgb = (colorMatrix * (ycbcr + colorOffset)) * alpha;
    outTexture.write(float4(float3(rgb), alpha), gid);
    
    float alpha=;
    float3 rgb=(colorMatrix*(ycbcr+colorfostate))*α;
    write(float4(float3(rgb),alpha),gid);
    
    如果我将每个像素的alpha硬编码为0,我根本不明白为什么我应该看到任何视频。它不应该是完全透明的吗?我的理解是,通过alpha预乘图像会使alpha不是1.0的像素变暗。当我强制每个像素的alpha为零时,我看不出这会如何影响透明度。这个网站解释了预乘混合的数学和推理:好的,那么我的下一个问题是:有没有办法改变金属计算管道的alpha预乘状态?我在这里看到了一个为渲染管道执行此操作的示例:但不是一个使用计算管道执行此操作的示例。我认为建议的技术仍然适用。问题的关键在于,要通过核心动画正确合成,颜色数据必须采用预乘alpha格式,因此在管道的末尾(无论是写入可绘制图形的计算着色器,还是从片段函数返回颜色),应该将RGB乘以alpha。