Something from Monday's lecture triggered me to investigate variable-length loops in GLSL. It is a limitation in GLSL that loops must be of a constant length, i.e., iterating from a constant defined number to another, so that the length of the loop is determinable at compile time.
This becomes a problem for this project since the whole point of this ray marching method is to minimize the number of steps taken per ray. So I decided to investigate the use of breaks to terminate loops. The GLSL limits only the maximum length of the loop, but forward branching with breaks are allowed. However, this turns out to be more tricky than it seems. As I learned from previous semester GLSL (especially GLSL ES 1.0) is often quite mysterious: sometimes thing will stop working if GLSL decides "it doesn't like it." There are many more limitations that are not written in the documentation.
In the end I managed to make breaks work in for loops. The result is a minor performance improvement, of a few FPS on average. I expect the performance improvement to increase as I scale up the maximum number of steps to do ray march; right now it is set to only 32 steps per ray.
For the breaks to work, there were two requirements that I had to have: 1) use "if else" instead of "if", and 2) place the "break" in the "else" statement. Now you can see a little bit how GLSL can be very strange at times, but it is what it is. Here's some code that demonstrates my point #2 above.
Working code.
if(h >= EPS)
steps++;
else
break;
Does not work.
if(h < EPS)
break;
else
steps++;
Interesting. I will remember that for JSC new C# to GLSL compiler. :)
ReplyDelete