Skip to content

Instantly share code, notes, and snippets.

@varphone
Created May 18, 2016 05:58
Show Gist options
  • Save varphone/e21618adcdb687ce5c6cf54021593949 to your computer and use it in GitHub Desktop.
Save varphone/e21618adcdb687ce5c6cf54021593949 to your computer and use it in GitHub Desktop.
YUV to RGBA GL Shader
uniform sampler2D texY; // Y
uniform sampler2D texU; // U
uniform sampler2D texV; // V
varying vec2 vary_tex_cord;
vec3 yuv2rgb(in vec3 yuv)
{
// YUV offset
// const vec3 offset = vec3(-0.0625, -0.5, -0.5);
const vec3 offset = vec3(-0.0625, -0.5, -0.5);
// RGB coefficients
const vec3 Rcoeff = vec3( 1.164, 0.000, 1.596);
const vec3 Gcoeff = vec3( 1.164, -0.391, -0.813);
const vec3 Bcoeff = vec3( 1.164, 2.018, 0.000);
vec3 rgb;
yuv = clamp(yuv, 0.0, 1.0);
yuv += offset;
rgb.r = dot(yuv, Rcoeff);
rgb.g = dot(yuv, Gcoeff);
rgb.b = dot(yuv, Bcoeff);
return rgb;
}
vec3 get_yuv_from_texture(in vec2 tcoord)
{
vec3 yuv;
yuv.x = texture(texY, tcoord).r;
// Get the U and V values
yuv.y = texture(texU, tcoord).r;
yuv.z = texture(texV, tcoord).r;
return yuv;
}
vec4 mytexture2D(in vec2 tcoord)
{
vec3 rgb, yuv;
yuv = get_yuv_from_texture(tcoord);
// Do the color transform
rgb = yuv2rgb(yuv);
return vec4(rgb, 1.0);
}
out vec4 out_color;
void main()
{
// That was easy. :)
out_color = mytexture2D(vary_tex_cord);
}
@heyanlong
Copy link

precision lowp float;
uniform sampler2D samplerY;
uniform sampler2D samplerU;
uniform sampler2D samplerV;
varying vec2 v_texCoord;

void main() {
    float r, g, b, y, u, v, fYmul;
    
    vec3 rgb, yuv;

    yuv.x = texture2D(samplerY, v_texCoord).r;
    yuv.y = texture2D(samplerU, v_texCoord).r;
    yuv.z = texture2D(samplerV, v_texCoord).r;
    
    const vec3 offset = vec3(-0.0625, -0.5, -0.5);
    // RGB coefficients
    const vec3 Rcoeff = vec3( 1.164, 0.000,  1.596);
    const vec3 Gcoeff = vec3( 1.164, -0.391, -0.813);
    const vec3 Bcoeff = vec3( 1.164, 2.018,  0.000);
    
    yuv = clamp(yuv, 0.0, 1.0);
    yuv += offset;

    rgb.r = dot(yuv, Rcoeff);
    rgb.g = dot(yuv, Gcoeff);
    rgb.b = dot(yuv, Bcoeff);
    gl_FragColor = vec4(rgb, 1.0);
}

@MindStudioOfficial
Copy link

@AhmedX6 I need to do the same. How did you convert from 4:2:2 to per pixel yuv values?

@AhmedX6
Copy link

AhmedX6 commented May 23, 2022

const char gFragmentNV12ToRGB[] =
    "#version 320 es\n"
    "precision highp float;\n"
    "in vec2 TexCoords;\n"
    "out vec4 color;\n"
    "uniform sampler2D text;\n"
    "layout(binding = 0) uniform sampler2D textureY;\n"
    "layout(binding = 1) uniform sampler2D textureUV;\n"
    "void main() {\n"
    "   float r, g, b, y, u, v;\n"
    "   y = texture(textureY, TexCoords).r;\n"
    "   u = texture(textureUV, TexCoords).r - 0.5;\n"
    "   v = texture(textureUV, TexCoords).a - 0.5;\n"
    "   r = y + 1.13983 * v;\n"
    "   g = y - 0.39465 * u - 0.58060 * v;\n"
    "   b = y + 2.03211 * u;\n"
    "   color = vec4(r, g, b, 1.0);\n"
    "}\n";

I used this one

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment