WebGL alpha depending on distance from origin

Viewed 118

I have the following setup: enter image description here

The plane grid consists of lines, with brighter dots where lines intersect. I would like to introduce an alpha gradient on the entire scene, with the current alpha (0.2) at the very centre, linearly fading to 0.0 at the edges. The only examples I can find online end up doing nothing but changing the background to a random colour depending on the near/far values.

I'm looking for something like this: https://i.stack.imgur.com/92LEU.png

How can I achieve this? Here are the grid shaders:

vertex:

precision mediump float;

attribute vec4 position;
attribute vec2 uv;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
varying vec2 vUv;

int scale = 1;

void main()
{
        vUv = uv;
        gl_Position = projection * view * model * position * vec4(scale, scale, scale, 1);
}

fragment:

precision mediump float;

vec2 spacing = vec2(32, 32);
varying vec2 vUv;

int scale = 1;

void main()
{
        float scaleFactor = 32.0 * 8.0 * float(scale);
        float offX = scaleFactor * vUv.x;
        float offY = scaleFactor * vUv.y;

        int remX = int(mod(offX, spacing[0]));
        int remY = int(mod(offY, spacing[1]));

        if (remX == 0 || remY == 0)
        {
                if (remX == remY)
                {
                        gl_FragColor = vec4(1.0, 1.0, 1.0, 0.2);
                }
                else
                {
                        gl_FragColor = vec4(1.0, 1.0, 1.0, 0.05);
                }
        }
        else
        {
                gl_FragColor = vec4(1.0, 1.0, 1.0, 0.0);
        }
}

The cubes use a different, basic shader - I will also want these affected by the fog. Will I just have to copy the fog logic to that shader and manipulate gl_FragColor's alpha in the same way?

Many thanks

2 Answers

Solved thanks to the accepted answer - I modified the distance -> alpha mapping to allow for any min/max alpha.

It looks like this:

enter image description here

precision mediump float;

vec2 spacing = vec2(32, 32);
varying vec2 vUv;

int scale = 32;

// fog scale describes the amount of space where the fog's opacity is affected by the linear interpolation. larger fog scale = larger gradient
int fog_scale = 2;

float map(float x, float in_min, float in_max, float out_min, float out_max)
{
        return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

float get_distance_alpha(float min, float max)
{
        float dist = length(vUv - vec2(0.5)) * float(scale) / float(fog_scale);
        return map(dist, 0.0, 0.5, max, min); // at origin: max; at edge: min
}

void main()
{
        float scaleFactor = 32.0 * 8.0 * float(scale);
        float offX = scaleFactor * vUv.x;
        float offY = scaleFactor * vUv.y;

        int remX = int(mod(offX, spacing[0]));
        int remY = int(mod(offY, spacing[1]));

        if (remX == 0 || remY == 0)
        {
                if (remX == remY)
                {
//                      gl_FragColor = vec4(1.0, 1.0, 1.0, get_distance_alpha(0.0, 0.5));
                }
                else
                {
                        gl_FragColor = vec4(1.0, 1.0, 1.0, get_distance_alpha(0.0, 0.2));
                }
        }
        else
        {
                gl_FragColor = vec4(1.0, 1.0, 1.0, 0.0);
        }
}

Set the alpha channel depending on the distance from the center. The vUv cooridante of the center is (0.5, 0.5). Compute the Euclidean distance using the length function and set the alpha channel as a function of this distance:

void main()
{
    // [...]    


    if (remX == 0 || remY == 0)
    {
        float dist = length(vUv - vec2(0.5));     
        float alpha = (1.0 - 2.0*dist) * 0.2;
        gl_FragColor = vec4(1.0, 1.0, 1.0, alpha);
    }
    else
    {
        // [...]
    }
}
Related