2013-07-30 195 views
2

我正在考慮使用HLSL執行從YUV422到RGB的顏色空間轉換。四字節的YUYV將產生兩個三字節的RGB值,例如,Y1UY2V將給出R1G1B1(左像素)和R2G2B2(右像素)。給定像素着色器中的紋理座標梯度增加,如何區分左像素的紋理座標,即全部R1G1B1和右像素的紋理座標,即全部R2G2B2。通過這種方式,我可以將所有R1G1B1和所有R2G2B2渲染爲單個紋理而不是兩個。使用GPU着色器將YUV422轉換爲RGB HLSL

謝謝!

回答

1

不知道您使用的DirectX版本是什麼,但這裏是我用於dx11的版本(請注意,在這種情況下,我會在StructuredBuffer中發送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; 
} 

希望有所幫助。