我正在考虑使用HLSL执行从YUV422到RGB的色彩空间转换。四字节YUYV将产生2个三字节RGB值,例如,Y1UY2V将给出R1G1B1(左像素)和R2G2B2(右像素)。给定像素着色器中的纹理坐标渐变增加,我如何区分左像素的纹理坐标,即所有R1G1B1和右像素的纹理坐标,即所有R2G2B2。这样我就可以在一个纹理上渲染所有R1G1B1和所有R2G2B2,而不是两个。
谢谢!
答案 0 :(得分:1)
不确定您使用的是哪个版本的DirectX,但这里是我用于dx11的版本(请注意,在这种情况下,我在结构化缓冲区中发送yuv数据,这可以节省我处理行间距的事实。您可以应用同样的技术发送你的yuv数据作为纹理当然(下面的代码几乎没有什么变化)。
这是像素着色器代码(我假设您的渲染目标与输入图像的大小相同,并且您渲染全屏四边形/三角形)。
StructuredBuffer<uint> yuy;
int w;
int h;
struct psInput
{
float4 p : SV_Position;
float2 uv : TEXCOORD0;
};
float4 PS(psInput input) : SV_Target
{
//Calculate pixel location within buffer (if you use texture change lookup here)
uint2 xy = input.p.xy;
uint p = (xy.x) + (xy.y * w);
uint pixloc = p / 2;
uint pixdata = yuy[pixloc];
//Since pixdata is packed, use some bitshift to remove non useful data
uint v = (pixdata & 0xff000000) >> 24;
uint y1 = (pixdata & 0xff0000) >> 16;
uint u = (pixdata & 0xff00) >> 8;
uint y0 = pixdata & 0x000000FF;
//Check if you are left/right pixel
uint y = p % 2 == 0 ? y0: y1;
//Convert yuv to rgb
float cb = u;
float cr = v;
float r = (y + 1.402 * (cr - 128.0));
float g = (y - 0.344 * (cb - 128.0) - 0.714 * (cr - 128));
float b = (y + 1.772 * (cb - 128));
return float4(r,g,b,1.0f) / 256.0f;
}
希望有所帮助。