3

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: vec3 mate=vec3(maxc);

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:

vec3 mate=vec3(uvn.y); vec3 mate=vec3(uvn.x);

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

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Ivelate
  • 298
  • 2
  • 10
  • Please, clarify the way of measuring the distance. Perpendicular to edge? The mininum of dx,dy? – Ripi2 Feb 14 '18 at 17:13
  • Perpendicular to edge, normalized. Looking at the bottom-right image you can see for example the values of uvn.x: 1 when in the right, left edge, 0 in the middle of the image, the same happening to uvn.y being 1 at the top and bottom. The weird thing is that when mixing those two variables doing max(uvn.x,uvn.y), those weird black margins appear on the final image, when i should expect a smooth transition – Ivelate Feb 14 '18 at 17:26
  • That's how it should look. If you are not convinced, try playing around with a color picker. – Hans Lehnert Feb 14 '18 at 17:37
  • The result is correct:See [Issue getting gradient square in glsl](https://stackoverflow.com/questions/47417916/issue-getting-gradient-square-in-glsl-es-2-0-gamemaker-studio-2-0/47418190#47418190) – Rabbid76 Feb 14 '18 at 17:41

1 Answers1

5

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:

enter image description here

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • 3
    All this time trying to correct a bug in the code, and turns out the bug was in our eyes. Seems we need a patch :) Thank you! – Ivelate Feb 17 '18 at 00:22