Thanks for the responses.
I tried some things yesterday.
I started out by skipping the shading and just shade based on distance, i.e: (dist * 10.0f) % 1.0f.
The problematic parts showed a nice zebra pattern (no image here at work).
This indicated that I got distances over 100.0 units!
I though about precision etc and tried various things.
I've always kept step distances at DE (no scaling).
So I tried both to scale down and scale up, too my surprise things looked MUCH better using a step distance of 2xDE.
It still doesn't work 100% as expected, but from messing up 25% of the image it went down to less than 1% I would say, so it's an improvement.
Doing this however caused other artifacts to become worse (dust).
Old image:
http://www.solidicon.se/eq/mb/LessProblems.pngNew image (different size and lighting, sorry about that):
http://www.solidicon.se/eq/mb/MoreProblems.pngI think I also need to clarify how my ray marching code works.
I imagine that some people do:
d = distanceEstimate(pos);
pos = pos + normalizedRayDir * d * scale;
I do it somewhat differently because I think it will improve precision:
pos = rayOrigin + normalizedRayDir * dist * scale;
d = distanceEstimate(pos);
dist = dist + d;
The case I think it helps is when the ray dir has a component with a very small value, i.e rayDir.x = 0.000000001¨
Using the first method the new pos.x could be something like: large_number (prev position) + small_number (rayDir) * small_number (DE).
The effect of the addition is no change in component due to internal precision (LargeNumber + SmallNumber = LargeNumber).
In order to avoid getting stuck in an endless loop you either need to have a maximum iteration count (which is bas as we've seen) or to make sure that we get a new position at each step.
I ensure it by comparing the new pos with the old, if equal I do:
while (oldPos == newPos){
d = d * 2;
dist = oldDist + d;
newPos = rayOrigin + rayDir * dist * scale;
}
Anyway, I have a few more things I'd like to test.
One good thing is that I switched back to an older HLSL compiler and now my shader compiles in less than a minute instead of over ten, so I can test things more easy.