Misadventures in Shaderland: the jumping uniform array element
I work on OpenGL ES for an Android and iOS app, and from time to time a weird glitch shows up on a specific device (or a set of devices with the same GPU series). This was one of those times.
So, I was writing a new GLSL shader and all was going well. This shader has a uniform array as input, that is used to move the vertices dynamically along a polyline, without the need to reload geometry:
Then, the vertex shader is doing the following to interpolate a position between two points of the polyline:
That worked correctly, and the vertices were moving smoothly along the polyline, based on some data that is specific to each vertex. That was until I tested the app on a Nexus 7 (2nd Gen). On that device, which has an Adreno 320 GPU, vertex positions seemed to be a displaced. After checking everything I could remember, including precision issues, I've noticed that pos was indeed incorrect on that device, and was calculated as:
For some reason, the GPU is using pt2 instead of pt1 for the sum, but it is using pt1 correctly on the subtraction (direction). Interestingly, if I change to the following, the pos is correctly calculated and everything is rendered as expected:
I haven't found the reason for that behavior. As far as I know, the code is compliant with the GLSL 100, so that is probably a bug on the Adreno GPU.
So, I was writing a new GLSL shader and all was going well. This shader has a uniform array as input, that is used to move the vertices dynamically along a polyline, without the need to reload geometry:
#define POLYLINE_SIZE 16
uniform highp vec2 u_polyline[POLYLINE_SIZE];
Then, the vertex shader is doing the following to interpolate a position between two points of the polyline:
vec2 pt1 = u_polyline[int(idx)];
vec2 pt2 = u_polyline[int(idx)+1];
vec2 pos = pt1 + (pt2 - pt1) * idx_diff;
That worked correctly, and the vertices were moving smoothly along the polyline, based on some data that is specific to each vertex. That was until I tested the app on a Nexus 7 (2nd Gen). On that device, which has an Adreno 320 GPU, vertex positions seemed to be a displaced. After checking everything I could remember, including precision issues, I've noticed that pos was indeed incorrect on that device, and was calculated as:
vec2 pos = pt2 + (pt2 - pt1) * idx_diff;
For some reason, the GPU is using pt2 instead of pt1 for the sum, but it is using pt1 correctly on the subtraction (direction). Interestingly, if I change to the following, the pos is correctly calculated and everything is rendered as expected:
vec2 pos = u_polyline[int(idx)] + (pt2 - pt1) * idx_diff;
I haven't found the reason for that behavior. As far as I know, the code is compliant with the GLSL 100, so that is probably a bug on the Adreno GPU.
Comments
Post a Comment