Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

GLSL artefacts when ray marching

In the following shadertoy I illustrate an artefact that occurs when raymarching

https://www.shadertoy.com/view/stdGDl

This is my "scene" (see code fragment below). It renders a primitive "tunnel_fragment" which is an SDF (Signed Distance Function), and uses modulo on the coordinates to calculate "infinite" repetitions of these fragments. It then also calculates which disk we are in (odd/even) to displace them.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I really don’t understand why these artefacts occur when the disks (or rings -> see tunnel_fragment, if you remove a comment they become rings instead of disks) present these artefacts when the alternate movement in x direction becomes large.

These artefacts don’t appear when the disk structure moves to the right on its whole, it only appears when the disks alternate and the entire structure becomes more complex.

What am I doing wrong? It’s really boggling me.

vec2 scene(in vec3 p)
{
    float thick = 0.1;
    vec3 cp = p;

    // Use modulo to simulate inf disks
    vec3 c = vec3(0,0,6.0*thick);
    vec3 q = mod(cp+0.5*c,c)-0.5*c;
    
    // Find index of the disk
    vec3 disk = (cp+0.5*c) / (c);
    float idx = floor(disk.z);
    
    // Do something simple with odd/even disks
    // Note: changing this shows the artefacts are always there
    if(mod(idx,2.0) == 0.0) {
        q.x += sin(disk.z*t)*t*t;
    } else {
        q.x -= sin(disk.z*t)*t*t;
    }

    float d = tunnel_fragment(q, vec3(0.0), vec3(0.0, 0.0, 1.0), 2.0, thick, 0.2);
    return vec2(d, idx);
}

>Solution :

The problem is illustrated with this diagram:

enter image description here

When the current disk (based on modulo) is offset by more than the spacing between the disks, then the distance that you calculate is larger than the distance to the next disk. Consequently you risk in over-stepping the next disk.

To solve this you need to either limit the offset (as said — no more than the spacing between the disks), or sample odd/even disks separately and min() between them.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading