1

I am stuck with a fragment shader. I managed to display a linear gradient from top to bottom (cp. left image). The goal is to overlay a radial white gradient to this linear gradient (illustrated as the black dotted line in the left image => the right image illustrates the goal).

I know that I have to combine the x and y coordinates somehow, but all trials so far failed - I am just too bad in math I think :-/ I also didn't figured out how to mix the blue color in order to achieve white shades.

Could somebody help me out with a hint ?

enter image description here

This is the current shader that gives the left image as a result (depending on the color uniforms):

// Precision
precision highp float;
// Uniforms
uniform vec2 uResolution;
// Colors
uniform vec3 uColor1;
uniform vec3 uColor2;

void main(void) {
    vec2 position = gl_FragCoord.xy/uResolution;
    vec3 color = vec3(uColor2.x+(uColor1.x-uColor2.x)*position.y, uColor2.y+(uColor1.y-uColor2.y)*position.y, uColor2.z+(uColor1.z-uColor2.z)*position.y);
    gl_FragColor = vec4(color.x, color.y, color.z, 1.);
}
salocinx
  • 3,715
  • 8
  • 61
  • 110

1 Answers1

4

Here is some code which should do what you need:

// Precision
precision highp float;
// Uniforms
uniform vec2 uResolution;
// Colors
uniform vec3 uColor1;
uniform vec3 uColor2;

// parameters of the radial gradient
uniform vec2  uRadialFxCenter; // this should be in [0-1], so normalized screen coords
uniform float uRadialFxRadius; // this should be in [0-1], so normalized screen coords
uniform vec3 uRadialFxColor;    // should be white
uniform float uRadialFxOpacity; // between [0-1]

void main(void) {
    vec2 position = gl_FragCoord.xy/uResolution;
    vec3 color = vec3(uColor2.x+(uColor1.x-uColor2.x)*position.y, 
                      uColor2.y+(uColor1.y-uColor2.y)*position.y, 
                      uColor2.z+(uColor1.z-uColor2.z)*position.y);

    // compute radial fx opacity => alpha
    vec2 posToRadialFxCenter = uRadialFxCenter - position;
    float distToCenterNormalized = min((length(posToRadialFxCenter)/uRadialFxRadius), 1.0);
    float alpha = (1.0-distToCenterNormalized) * uRadialFxOpacity;

    // alpha blending radialFxColor / color 
    color = color * (1.0-alpha) + uRadialFxColor * alpha;

    //
    gl_FragColor = vec4(color.x, color.y, color.z, 1.);
}

You can also control the "slope" at which the radial gradient fades by adding something like this :

distToCenterNormalized = pow(distToCenterNormalized, slope);
VB_overflow
  • 1,763
  • 11
  • 15
  • WOW - thank your very, very much ! I didn't expect a complete solution :-D Just GREAT - your code runs flawlessly !!! Exactly what I needed. – salocinx Aug 14 '15 at 10:02
  • Happy to know this ! If you need more "math" explanation I will be happy to help, just tell me what you would not understand. – VB_overflow Aug 14 '15 at 10:07
  • Thanks for your offer. Currently no more math issue, I am still experimenting with your very cool shader :-) But I saw that you're an OpenGL ES specialist - maybe you could help me with another OpenGL issue I am fighting with: http://stackoverflow.com/questions/32008308/opengl-es-2-0-how-to-improve-frame-rate-of-drawing-sprites – salocinx Aug 14 '15 at 10:54