0
$\begingroup$

I am trying to achieve a border effect to a square tile on a xz plane. I am using max of coordinates x and z to achieve that. Here is my ShaderLab code:

    void surf (Input IN, inout SurfaceOutputStandard o)
    {
        half4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
        float max_xz = max(IN.worldPos.z , IN.worldPos.x);

        o.Albedo = c.rgb;
        o.Alpha = max_xz;
    }

This is how a corner of my tile looks like:

max artifact

Why does the shady line towards the corner appear? Is there a simple way to fix this?

$\endgroup$

1 Answer 1

1
$\begingroup$

You do not have a bug. This is not an artifact of your program, but of the human visual system — an optical illusion. The retina emphasizes the second spatial derivative of the image, a phenomenon known as Mach bands (unfortunately, the Wikipedia article isn't very clear and I didn't find any definitely better one). The most common example of this phenomenon when working with gradients is a gradient which reverses direction:

Gradient from white, to dark gray, to white

This image transitions smoothly from white, to dark gray, to white again. It has no abrupt changes in intensity (the first derivative is small everywhere). Despite this, there will be a strong perception of a vertical line in the center.

Your image is doing almost exactly the same thing, but on a diagonal. If I rotate your image 45° and crop it to a similar shape, then the only difference is that it also has a uniform vertical gradient component:

Cropped and rotated image from question

This can be understood not as a bug, but as our vision trying to help us out — a gradient like these, if it were present in the image of a physical object, likely would be some kind of corner, so highlighting it helps us perceive the shape of the object.


In order to avoid this perception of a diagonal line, you will have to do something more complex. (For example, if you made a rounded corner instead of a sharp rectangular corner, that would work.) There is no mathematical error. You must elaborate your algorithm until you find something that looks good for your purposes, in context with the rest of your rendered scene.

(Perhaps there is some sort of standard “correction” formula that cancels out Mach bands, but if there is, I haven't heard of it, and it would probably have secondary effects.)

$\endgroup$
2
  • $\begingroup$ Great response, thank you. $\endgroup$
    – hungry91
    Commented May 23 at 20:28
  • $\begingroup$ Adding noise can help with this issue, the noise can be as simple as random values within the range of the current dithered value, or sampling a noise texture. $\endgroup$
    – pmw1234
    Commented May 24 at 12:08

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