Search code examples
webgl

Adding color gradient to a webgl point


Is it possible to give a webgl point not a color but a color gradient?

In webgl I have created a 2D grid consisting of points with a position and a size using this minimal vertex shader:

precision mediump float;
uniform int size;
attribute vec2 position;
attribute vec3 color;
varying vec3 vcolor;
void main() {
    gl_PointSize = float(size);
    gl_Position = vec4(position.x, position.y, 0.0, 1.0);
    vcolor = color;
}

I can set the color of a point with a fragment shader like this:

precision mediump float;
varying vec3 vcolor;
void main() {
    gl_FragColor = vec4(vcolor, 1.0);
}

But would it be possible to create a gradient across a single point like in this triangle example?


Solution

  • Solution

    You need to pass additional information to your shaders, such as the position within the point. This can be done by using the gl_PointCoord built-in variable in the fragment shader, which gives you the coordinates within the point.

    Code

    Vertex Shader:

    precision mediump float;
    uniform int size;
    attribute vec2 position;
    attribute vec3 color;
    varying vec3 vcolor;
    void main() {
        gl_PointSize = float(size);
        gl_Position = vec4(position.x, position.y, 0.0, 1.0);
        vcolor = color;
    }
    

    Fragment Shader:

    precision mediump float;
    varying vec3 vcolor;
    void main() {
        vec2 coord = gl_PointCoord;
        // Create a gradient based on the coordinates within the point
        vec3 gradientColor = mix(vcolor, vec3(1.0, 0.0, 0.0), coord.x); // Example: gradient from vcolor to red
        gl_FragColor = vec4(gradientColor, 1.0);
    }
    

    Notes

    In the fragment shader:

    1. gl_PointCoord is a built-in variable that gives you the coordinates within the point, ranging from (0, 0) to (1, 1).

    2. You can use gl_PointCoord to create gradients. In this example, a linear gradient is created along the x-axis of the point from vcolor to red.