<p>Your code just works !</p>
<p>There is no problem with your shader on my windows 10 laptop.
Maybe your should try on another device.</p>
<p><a href="https://i.sstatic.net/uEnRi.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/uEnRi.png" alt="The shader works" /></a></p>

CC BY-SA 4.0
2023-06-16T14:13:28.520Z
The problem is still evident where the floor, background, and sphere meet.
pmw1234
CC BY-SA 4.0
2023-06-16T15:51:57.407Z
It seems that this is indeed the case. I tried shader on other machine and everything worked properly.  I have also tried few more shaders that gave me headache. It seems that I have problem with my graphics driver (`mesa 23.1.2-1`  on `linux 6.3.8`). Thank you!
Nikola Ubavić
CC BY-SA 4.0
2023-06-16T13:20:31.187Z
2023-06-16T13:20:31.187Z
babali
<p>The code isn't taking enough steps for the ray to hit anything where the sphere and the floor meet. minF is smaller in that region, so the ray marches forward until it runs out of steps and then gives up and returns the background color.</p>
<p>A simple &quot;fix&quot; is to increase the number of steps. 200 worked for me. Then you can also decrease the minF&lt;0.01 to something that gives a lot better rendering. Like 0.0001.</p>
<p>Also position is being recomputed before calling floorColor this alters the pattern on the floor increasingly as the ray marches. It's usually best to recompute the ray at the very end of the loop.</p>

CC BY-SA 4.0
2023-06-16T15:44:49.480Z
I did tried to raise number of iterations and decrease $\varepsilon$ value, but that made things even worse. Current values are similar to values used in other ray marchers. You are right about calculating `position` at the end of the loop. Thank you for your comment.
Nikola Ubavić
CC BY-SA 4.0
2023-06-16T15:46:30.023Z
What number did you raise it to. I had to go up to 1000 in one case.
pmw1234
CC BY-SA 4.0
2023-06-16T15:49:59.247Z
The opposite problem is that you are taking to BIG of steps and you step past the objects. This code as written will exhibit both problems. And in some cases it will "just work" because you got lucky.  Just plugging in numbers without understanding the fundamental issue only leads people to confusion and blaming floating point error which seems to be a catch all when it is almost never the issue!
pmw1234
CC BY-SA 4.0
2023-06-16T14:28:44.843Z
2023-06-16T14:28:44.843Z
pmw1234
<p>I have been programing a simple ray marcher with GLES, using <a href="http://editor.thebookofshaders.com/" rel="nofollow noreferrer">The Book of Shaders editor</a>. I noticed that on scenes with multiple objects (multiple SDFs), I am getting glitches on edges of object which are superimposed over other objects:</p>
<p><a href="https://i.sstatic.net/ZIzbH.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/ZIzbH.png" alt="Shader output" /></a></p>
<p>The source of this shader is:</p>
<pre><code>#ifdef GL_ES
precision highp float;
#endif

uniform vec2 u_resolution;

vec3 floorColor(vec3 pos) {
    if(mod(floor(pos.x) + floor(pos.z), 2.0) &lt; 1.0) {
        return vec3(0.7, 0.8, 0.7);
    } else {
        return vec3(0.3,0.4,0.3);
    }
}

vec3 iterate(vec3 ray){
    vec3 position = vec3(0.0);
    for(int i = 0; i &lt; 100; i++) {
        float sphereF = length(position - vec3(0.0, 0.0, 2.0)) - 1.0;
        float floorF = position.y + 1.;
        float minF = min(sphereF, floorF);
        position += minF*ray;
        
        if(minF &lt;= 0.01) { 
            if(sphereF &lt; floorF) {
               return vec3(0.9, 0.2, 0.2);
            } else {
               return floorColor(position);
            }
        }
    }
    
    return vec3(0.2, 0.5, 0.8);
}

void main() {
    vec2 st = gl_FragCoord.xy/u_resolution.xy;
    st.x *= u_resolution.x/u_resolution.y;
    st = 2.0 * st - vec2(1.0); 
    
    vec3 color = iterate(normalize(vec3(st.x, st.y, 1.0)));

    gl_FragColor = vec4(color, 1.0);
}
</code></pre>
<p>After a lot of debugging, I realized that glitches are produced return stantments inside loop in <code>iterate</code> function, but I am still not sure <em>why</em> this happens.</p>
<p>Using other shader editors produced similar glitches.</p>
<p>Edit: Provided source is the minimal shader that produced described artifacts (blue squares). I did try various combination of <span class="math-container">$\varepsilon$</span> or number of iterations, but that only made things worse. As I said, it seems that <code>return</code> statement inside a loop is source of the artifacts (If you do a slight rewrite of <code>iterate</code> function in such way that loop can't break before it reaches end, squares will be gone!). This is most surly a graphics driver/card bug as babali suggested in the accepted answer.</p>

CC BY-SA 4.0
2023-06-16T09:58:04.877Z
@YvesDaoust 0.01 is my $\varepsilon$ value. If `position` is less then $\varepsilon$ form object, then I suppose ray hit that object. Similar values are used in other raymarchers on ShaderToy.
Nikola Ubavić
<raymarching>
Glitches with raymarcher shader
Nikola Ubavić
# Glitches with raymarcher shader

(Asked by: username_0 on 2023-06-15)

I have been programing a simple ray marcher with GLES, using [The Book of Shaders editor](http://editor.thebookofshaders.com/). I noticed that on scenes with multiple objects (multiple SDFs), I am getting glitches on edges of object which are superimposed over other objects:

[![Shader output](https://i.sstatic.net/ZIzbH.png)](https://i.sstatic.net/ZIzbH.png)

The source of this shader is:

```
#ifdef GL_ES
precision highp float;
#endif

uniform vec2 u_resolution;

vec3 floorColor(vec3 pos) {
    if(mod(floor(pos.x) + floor(pos.z), 2.0) < 1.0) {
        return vec3(0.7, 0.8, 0.7);
    } else {
        return vec3(0.3,0.4,0.3);
    }
}

vec3 iterate(vec3 ray){
    vec3 position = vec3(0.0);
    for(int i = 0; i < 100; i++) {
        float sphereF = length(position - vec3(0.0, 0.0, 2.0)) - 1.0;
        float floorF = position.y + 1.;
        float minF = min(sphereF, floorF);
        position += minF*ray;
        
        if(minF <= 0.01) { 
            if(sphereF < floorF) {
               return vec3(0.9, 0.2, 0.2);
            } else {
               return floorColor(position);
            }
        }
    }
    
    return vec3(0.2, 0.5, 0.8);
}

void main() {
    vec2 st = gl_FragCoord.xy/u_resolution.xy;
    st.x *= u_resolution.x/u_resolution.y;
    st = 2.0 * st - vec2(1.0); 
    
    vec3 color = iterate(normalize(vec3(st.x, st.y, 1.0)));

    gl_FragColor = vec4(color, 1.0);
}

```

After a lot of debugging, I realized that glitches are produced return stantments inside loop in `iterate` function, but I am still not sure *why* this happens.

Using other shader editors produced similar glitches.

Edit: Provided source is the minimal shader that produced described artifacts (blue squares). I did try various combination of $\varepsilon$ or number of iterations, but that only made things worse. As I said, it seems that `return` statement inside a loop is source of the artifacts (If you do a slight rewrite of `iterate` function in such way that loop can't break before it reaches end, squares will be gone!). This is most surly a graphics driver/card bug as username_1 suggested in the accepted answer.

**Tags:** raymarching

> **Comments:**
> **username_0**: @YvesDaoust 0.01 is my $\varepsilon$ value. If `position` is less then $\varepsilon$ form object, then I suppose ray hit that object. Similar values are used in other raymarchers on ShaderToy.  

---

## 2 answers

### Answer by username_1 on 2023-06-16. Score: 0 | Accepted answer

Your code just works !

There is no problem with your shader on my windows 10 laptop.
Maybe your should try on another device.

[![The shader works](https://i.sstatic.net/uEnRi.png)](https://i.sstatic.net/uEnRi.png)

> **Comments:**
> **username_2**: The problem is still evident where the floor, background, and sphere meet.  
> **username_0**: It seems that this is indeed the case. I tried shader on other machine and everything worked properly.  I have also tried few more shaders that gave me headache. It seems that I have problem with my graphics driver (`mesa 23.1.2-1`  on `linux 6.3.8`). Thank you!  

---

### Answer by username_2 on 2023-06-16. Score: 1

The code isn't taking enough steps for the ray to hit anything where the sphere and the floor meet. minF is smaller in that region, so the ray marches forward until it runs out of steps and then gives up and returns the background color.

A simple "fix" is to increase the number of steps. 200 worked for me. Then you can also decrease the minF<0.01 to something that gives a lot better rendering. Like 0.0001.

Also position is being recomputed before calling floorColor this alters the pattern on the floor increasingly as the ray marches. It's usually best to recompute the ray at the very end of the loop.

> **Comments:**
> **username_0**: I did tried to raise number of iterations and decrease $\varepsilon$ value, but that made things even worse. Current values are similar to values used in other ray marchers. You are right about calculating `position` at the end of the loop. Thank you for your comment.  
> **username_2**: What number did you raise it to. I had to go up to 1000 in one case.  
> **username_2**: The opposite problem is that you are taking to BIG of steps and you step past the objects. This code as written will exhibit both problems. And in some cases it will "just work" because you got lucky.  Just plugging in numbers without understanding the fundamental issue only leads people to confusion and blaming floating point error which seems to be a catch all when it is almost never the issue!  

---

