使用HLSL进行YUV到RGB转换的奇怪的模糊边缘图案

时间:2014-06-07 03:56:24

标签: c# direct3d hlsl sharpdx

我正在尝试在HLSL中将YUV写入RGB着色器。具体来说,它转换Yuv420p格式,该格式由Y值的N M平面组成,接着是U值的(N / 2)(M / 2)平面,然后是(N / 2) *(M / 2)V值平面。例如,这张1280x720图片:

enter image description here

在YUV格式中看起来像这样解释为8位,1280x1080纹理:

enter image description here

在Direct3D11中,我将其作为Texture2D加载,格式为R8_UNorm,尺寸为1280x1080。棘手的部分是重建U和V平面,因为正如你所看到的,一半的线位于纹理的左侧,另一半位于右侧。在着色器中,我这样做:

struct PS_IN
{
    float4 pos : SV_POSITION;
    float2 tex : TEXCOORD;
};

Texture2D picture;
SamplerState pictureSampler;

float4 PS(PS_IN input) : SV_Target
{
    int pixelCoord = input.tex.y * 720;
    bool evenRow = (pixelCoord / 2) % 2 == 0;

    //(...) illustrating U values:
    float ux = input.tex.x / 2.0;
    float uy = input.tex.y / 6.0 + (4.0 / 6.0);
    if (!evenRow)
    {
        ux += 0.5;
    }

    float u = picture.Sample(pictureSampler, float2(ux, uy)).r;
    u *= 255.0;

    // for debug purposes, display just the U values
    float4 rgb;
    rgb.r = u;//y + (1.402 * (v - 128.0));
    rgb.g = u;//y - (0.344 * (u - 128.0)) - (0.714 * (v - 128.0));
    rgb.b = u;//y + (1.772 * (u - 128.0));
    rgb.a = 255.0;

    return rgb / 255.0;
}

然而,由于一些奇怪的原因,这似乎产生了一个奇怪的水平边缘模糊图案:

enter image description here

请注意,如果将条件设置为true或false(以便ux始终或从不增加0.5f),则不会出现模式 - 尽管我们当然得到一半的分辨率。另请注意,我对HLSL代码进行了基本的复制粘贴C#转换,但它不会产生这种效果:

enter image description here

FWIW,我正在使用WPF创建窗口并通过WindowInteropHelper使用其HWND初始化Direct3D。窗口的大小设置为1280x720。

0 个答案:

没有答案