Search code examples
opengl-eslibgdxopengl-es-2.0shadervertex-shader

Colored Vignette Shader (the outer part) - LIBGDX


I've seen lots of tutorials on vignette shaders just like these but none of them say how to change the color of the vignette, they only talk about applying sepia or grey shaders to the whole composite image.

For example the video above gives the below code for the vignette shader. How do I change the color of the vignette ? So it's not black but red or orange and the part of the image in the interior of the vignette remains unmodified.

const float outerRadius = .65, innerRadius = .4, intensity = .6;

void main(){
    vec4 color = texture2D(u_sampler2D, v_texCoord0) * v_color;
    vec2 relativePosition = gl_FragCoord.xy / u_resolution - .5;
    relativePosition.y *= u_resolution.x / u_resolution.y;
    float len = length(relativePosition);
    float vignette = smoothstep(outerRadius, innerRadius, len);
    color.rgb = mix(color.rgb, color.rgb * vignette, intensity);

    gl_FragColor = color;
}

Solution

  • In the shader you posted, it looks like the vignette value is basically a darkness value that's blended over the image, so in the line with the mix function, it's just multiplied by the texture color.

    So to modify this to work with arbitrary color, you need to change it to an opacity value (invert it). And now that it's opacity, you can multiply it by intensity to simplify the next calculation. And finally, you can blend to the vignette color you choose.

    So first declare the color you want before the main function.

    const vec3 vignetteColor = vec3(1.0, 0.0, 0.0); //red
    //this could be a uniform if you want to dynamically change it.
    

    Then your second-to-last two lines change to the following.

    float vignetteOpacity = smoothstep(innerRadius, outerRadius, len) * intensity; //note inner and outer swapped to switch darkness to opacity
    color.rgb = mix(color.rgb, vignetteColor, vignetteOpacity);
    

    By the way, "intensity = .6f" will cause the shader not to compile on mobile, so remove the f. (Unless you target OpenGL ES 3.0, but that's not fully supported by libgdx yet.)