I wrote a fragment shader that generates a plot of a fractal using some maths which aren't particularly relevant to this question.
On my MacBook Pro, the plot works fine (Chrome and Safari). On my iPhone, it shows only a bright green (#00FF00) rectangle. In iPhone simulator (on my MacBook Pro), it works 100% fine.
I suspect there is something in my fragment shader that is not compatible with the graphics hardware on the phone. I can't figure what. I have enabled debugging but don't see anything that indicates a problem.
f-shader.glsl
precision mediump float;
varying vec2 v_coord;
void color_wheel(in float hue, out vec3 rgb) {
float x;
if (0.0 <= hue && hue < 60.0) {
x = 1.0 - hue/60.0;
rgb = vec3(1.0, x, 0.0);
} else if (hue < 120.0) {
x = (hue - 60.0)/60.0;
rgb = vec3(x, 1.0, 0.0);
} else if (hue < 180.0) {
x = 1.0 - (hue - 120.0)/60.0;
rgb = vec3(0.0, 1.0, x);
} else if (hue < 240.0) {
x = (hue - 180.0)/60.0;
rgb = vec3(0.0, x, 1.0);
} else if (hue < 300.0) {
x = 1.0 - (hue - 240.0)/60.0;
rgb = vec3(x, 0.0, 1.0);
} else if (hue < 360.0) {
x = (hue - 300.0)/60.0;
rgb = vec3(1.0, 0.0, x);
} else {
rgb = vec3(0.0, 0.0, 0.0);
}
}
void color_step_ratio(in int steps, in int max_steps, out vec3 rgb) {
if (steps == max_steps) {
rgb = vec3(0.0, 0.0, 0.0);
} else {
float ratio = float(steps)/float(max_steps);
color_wheel(60.0*(1.0 - ratio), rgb);
}
}
void main() {
float w = v_coord.x;
float a = v_coord.y;
float b = 0.05;
float h = 0.001;
float h2 = h/2.0;
float t = 0.0;
const int max_steps = 60000;
vec2 k0 = vec2(0.0, 0.0);
vec2 k1, k1P, k2, k2P, k3, k3P, k4;
int steps = 0;
for (int i = 0; i < max_steps; i++) {
k1 = vec2( k0.y, -b*k0.y - k0.x + k0.x*k0.x + a*sin(w*t));
k1P = k0 + h2*k1;
k2 = vec2(k1P.y, -b*k1P.y - k1P.x + k1P.x*k1P.x + a*sin(w*(t + h2)));
k2P = k0 + h2*k2;
k3 = vec2(k2P.y, -b*k2P.y - k2P.x + k2P.x*k2P.x + a*sin(w*(t + h2)));
k3P = k0 + h*k3;
k4 = vec2(k3P.y, -b*k3P.y - k3P.x + k3P.x*k3P.x + a*sin(w*(t + h)));
t += h;
k0 += (h/6.0)*(k1 + 2.0*(k2 + k3) + k4);
steps++;
if (k0.x >= 1.0) break;
}
vec3 rgb;
color_step_ratio(steps, max_steps, rgb);
gl_FragColor = vec4(rgb, 1);
}
I don't know where to go from here. Any suggestions?
You can check out a live demo here and the full source code here.
What I expect: plot on my laptop (MacBook Pro - Retina, 13-inch, Late 2013 - OS X 10.10.5):
What actually happens: on my iPhone (iPhone 6 - iOS 9.2 - Mobile Safari):
This is the problem:
const int max_steps = 60000;
...
for (int i = 0; i < max_steps; i++) { ... }
I suspect that the for
loop is being "unrolled" by the graphics driver. It works fine when I reduce max_steps
to 60, 600, and 6000. 60000 is just too much.