YUV RGB Conversion in OpenGL - tonykwok/made-mistakes-again GitHub Wiki

BT.601 Full Range YUV <-> RGB Conversion

// Kr = 0.299, Kg = 0.587, Kb = 0.114
const mat3 cscMatrix = mat3(
    1.0,    1.0,                1.0,
    0.0,   -0.3441362862010221, 1.772,
    1.402, -0.7141362862010221, 0.0
};

vec3 yuv = texture(...);
yuv.r = yuv.r - 0.0;
yuv.g = yuv.g - 0.5;
yuv.b = yuv.b - 0.5;

// full-range
vec3 rgb = clamp(cscMatrix * yuv, 0.0, 1.0);

// full-range
yuv.r = 0.0 + (0.299 * rgb.r)              + (0.587 * rgb.g)              + (0.114 * rgb.b)
yuv.g = 0.5 - (0.1687358916478555 * rgb.r) - (0.3312641083521445 * rgb.g) + (0.5 * rgb.b)
yuv.b = 0.5 + (0.5 * rgb.r)                - (0.4186875891583452 * rgb.g) - (0.08131241084165478 * rgb.b)

BT.601 Limited Range YUV <-> RGB Conversion

// Kr = 0.299, Kg = 0.587, Kb = 0.114
const mat3 cscMatrix = mat3(
    1.164383561643835,   1.164383561643835,   1.164383561643835,
    0.0,                -0.3917622900949136,  2.017232142857143,
    1.596026785714285,  -0.8129676472377707,  0.0
);

vec3 yuv = texture(...);
yuv.r = yuv.r - 0.06274509803921569;
yuv.g = yuv.g - 0.5019607843137255;
yuv.b = yuv.b - 0.5019607843137255;

vec3 rgb = clamp(cscMatrix * yuv, 0.0, 1.0);

// limited-range
yuv.r = 0.06274509803921569 + (0.2567882352941176 * rgb.r) + (0.5041294117647059 * rgb.g) + (0.09790588235294118 * rgb.b)
yuv.g = 0.5019607843137255  - (0.1482229008985084 * rgb.r) - (0.2909927853760014 * rgb.g) + (0.4392156862745098 * rgb.b)
yuv.b = 0.5019607843137255  + (0.4392156862745098 * rgb.r) - (0.3677883136136052 * rgb.g) - (0.07142737266090459 * rgb.b)

BT.709 Full Range YUV -> RGB Conversion

// Kr = 0.2126, Kg = 0.7152, Kb = 0.0722
const mat3 cscMatrix = mat3(
    1.0,     1.0,                1.0,
    0.0,    -0.1873242729306487, 1.8556,
    1.5748, -0.4681242729306488, 0.0
);

vec3 yuv = texture(...);
yuv.r = yuv.r - 0.0;
yuv.g = yuv.g - 0.5;
yuv.b = yuv.b - 0.5;

vec3 rgb = clamp(cscMatrix * yuv, 0.0, 1.0);

BT.709 Limited Range YUV -> RGB Conversion

const mat3 cscMatrix = mat3(
    1.164383561643835,  1.164383561643835,   1.164383561643835,
    0.0,               -0.2132486142737296,  2.112401785714286,
    1.792741071428571, -0.532909328559444,   0.0
);

vec3 yuv = texture(...);
yuv.r = yuv.r - 0.06274509803921569;
yuv.g = yuv.g - 0.5019607843137255;
yuv.b = yuv.b - 0.5019607843137255;

vec3 rgb = clamp(cscMatrix * yuv, 0.0, 1.0);

BT.2020 Full Range YUV -> RGB Conversion

// Kr = 0.2627, Kg = 0.6870, Kb = 0.0593
const mat3 cscMatrix = mat3(
    1.0,     1.0,                1.0,
    0.0,    -0.1623974090247452, 1.8814,
    1.4746, -0.5638681513828239, 0.0
);

vec3 yuv = texture(...);
yuv.r = yuv.r - 0.0;
yuv.g = yuv.g - 0.5;
yuv.b = yuv.b - 0.5;

vec3 rgb = clamp(cscMatrix * yuv, 0.0, 1.0);

BT.2020 Limited Range YUV -> RGB Conversion

const mat3 cscMatrix = mat3(
    1.167808219178082,  1.167808219178082,  1.167808219178082,
    0.0,               -0.1854157917771366, 2.148071651785714,
    1.683611383928571, -0.6437914273042732, 0.0
);

vec3 yuv = texture(...);
yuv.r = yuv.r - 0.06256109481915934;
yuv.g = yuv.g - 0.5004887585532747;
yuv.b = yuv.b - 0.5004887585532747;

vec3 rgb = clamp(cscMatrix * yuv, 0.0, 1.0);

Mozilla/Firefox

YUV-RGB.mac (Maxima Algebra System)

T-REC-H.Sup18-201710-I!!PDF-E-1.pdf