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

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

在此处输入图像描述

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

在此处输入图像描述

在Direct3D11中,我将其作为Texture2D加载,格式为R8_UNorm,尺寸为1280×1080。 棘手的部分是重建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; } 

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

在此处输入图像描述

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

在此处输入图像描述

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