Coloring rectangle in function of distance to near

2020-07-26 11:45发布

问题:

I'm trying to color a rectangle in ShaderToy/GLSL in function of each pixel's distance to the nearest rectangle edge. However, a weird (darker) result can be seen on its diagonals:

I'm using the rectangle UV coordinates for it, with the following piece of code:

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // Normalized pixel coordinates (from 0 to 1)
    vec2 uv = fragCoord/iResolution.xy;

    vec2 uvn=abs(uv-0.5)*2.0;
    float maxc=max(uvn.y,uvn.x);

    vec3 mate=vec3(maxc);

    fragColor = vec4(mate.xyz,1);
}

As you can see, the error seems to come from the max(uvn.y,uvn.x); line of code, as it doesn't interpolate smoothly the color values as one would expect. For comparison, those are the images obtained by sampling uvn.y and uvn.x instead of the maximum between those two:

You can play around with the shader at this URL: https://www.shadertoy.com/view/ldcyWH

回答1:

The effect that you can see is optical illusion. You can make this visible by grading the colors. See the answer to stackoverflow question Issue getting gradient square in glsl es 2.0, Gamemaker Studio 2.0.

To achieve a better result, you can use a shader, which smoothly change the gradient, from a circular (or elliptical) gradient in the middle of the the view, to a square gradient at the borders of the view:

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // Normalized pixel coordinates (from 0 to 1)
    vec2 uv = fragCoord/iResolution.xy;

    vec2 uvn=abs(uv-0.5)*2.0;

    vec2 distV     = uvn;
    float maxDist  = max(abs(distV.x), abs(distV.y));
    float circular = length(distV);
    float square   = maxDist;

    vec3 color1 = vec3(0.0);
    vec3 color2 = vec3(1.0);
    vec3 mate=mix(color1, color2, mix(circular,square,maxDist));

    fragColor = vec4(mate.xyz,1);
}

Preview: