我知道如何编码使用片段着色器将平面数据(YUV420图像)转换为打包数据(RGB图像)的着色器,但如何将RGB编码为YUV420。 我不需要YUV420图像进行渲染,而是将其传递给h264压缩代码。
答案 0 :(得分:8)
来自http://www.fourcc.org/fccyvrgb.php:
RGB到YUV转换
Y =(0.257 * R)+(0.504 * G)+(0.098 * B)+16
Cr = V =(0.439 * R) - (0.368 * G) - (0.071 * B)+ 128
Cb = U = - (0.148 * R) - (0.291 * G)+(0.439 * B)+ 128
在OpenGL着色器中,最后的常量偏移需要乘以1/256。另外,如果仔细观察,这是一个向量矩阵乘法。您可以通过
来表达这一点mat4 RGBtoYUV(0.257, 0.439, -0.148, 0.0,
0.504, -0.368, -0.291, 0.0,
0.098, -0.071, 0.439, 0.0,
0.0625, 0.500, 0.500, 1.0 );
YUV = RGBtoYUV * RGB;
给出了一些其他公式
答案 1 :(得分:3)
由于YUV像素未打包,您应将多个颜色缓冲区附加到着色器程序(即一个用于亮度,两个用于色度)。
由于色度采样,色度输出缓冲器的大小与亮度输出缓冲器的大小不同。因此,您应测试ARB_framebuffer_object扩展名。如果不可用,您应计算未采样的色度值,并在渲染后对其进行采样。另请注意,着色器中的采样并不容易,因为您必须知道源像素位置,确实要注意纹理坐标。
因此,创建一个framebuffer对象,附加3个renderbuffer对象(或纹理),并将片段着色器输出变量声明为长度为3的vec4数组。
附加缓冲区可以具有RED内部格式,因为它们只存储一个组件。
渲染后,获取渲染缓冲区数据(或纹理数据),根据需要交错YUV图层(可能使用SSE),并完成了自己的工作。
也许你想生成非抽样的色度值。在这种情况下,你应该自己采样色度缓冲,也许混合连续色度值。