I was messing with glowing lighting when I noticed an odd artifact in my first try.

For some reason I can see three defined edges inside of the glowing pattern. I downloaded the image and marked where I see the edges. enter image description here

I am just curious why they appear to be there as I can see no mathematical reason why they should be there. Is it just the way I am displaying it, or is there some sort of computational precision issue?

For reference here is the ShaderToy code that created this:

void mainImage( out vec4 fragColor, in vec2 fragCoord )
    vec2 uv = fragCoord.xy / iResolution.xy;
    float disty = abs(uv.y - 0.5);
    float distx = abs(uv.x - 0.5);
    distx *= 100.0;
    disty *= 100.0;
    fragColor = vec4(0.0, 1.0 / pow(abs((1.0 - distx) + (1.0 - disty)), 0.5), 0.0, 1.0);

Although I am not sure it is physically accurate to have those spikes on the edges of the diamond I sure do like the effect that creates.

  • $\begingroup$ When i copy/paste that into shadertoy I don't get anything like the output you are seeing, and just have a small green diamond. Did you post the right code? $\endgroup$ – Alan Wolfe Nov 26 '16 at 22:04
  • $\begingroup$ Correct the shader is just a triangle. It should be glowing. Those are lines I marked in to express where I am seeing edges in the gradient. They are not apart of the shader code. $\endgroup$ – J.Doe Nov 26 '16 at 22:31

Updated answer, now that pow is getting valid arguments:

What you are seeing is called "banding" and it comes from the fact that the color channels are quantized into 8 bits - in other words, it comes from the fact that there are only 256 different shades of green, even though the math generating the colors is capable of much larger resolution.

The banding on my system isn't as bad as what you are describing but it's still present. The reason it isn't as bad on my system is because you and I have different displays.

Some computer displays don't actually even have a full 256 different shades of green. For instance, instead of having 8 bit color, they may only have 6 bit color, and they either dither it, temporally dither it, or neither and just let it look worse.

One way to get around this problem is by dithering. There are various algorithms for dithering, with different computation and quality trade offs.

A good modern dithering algorithm is called "interleaved gradient noise" which is fairly close to blue noise - which is the ideal - and is pretty cheap to calculate.

Check out this link for more detailed information on different types of dithering, and how they compare:


First answer, from when pow was getting a negative value parameter:

The issue is that you are passing a negative value to pow for the first argument, which has undefined behavior.

What shows up on my screen is completely different than what shows up on yours.

enter image description here

You shouldn't rely on the behavior of anything in the red pixel areas in this image:

enter image description here

More info:


| improve this answer | |
  • $\begingroup$ Just updated the code so you can see what I see now $\endgroup$ – J.Doe Nov 27 '16 at 3:04
  • $\begingroup$ Ah ok. The negative was a red herring. Answer updated. $\endgroup$ – Alan Wolfe Nov 27 '16 at 5:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.