I have a simple demo that shows strange lightning artifacts on two Adreno 320 devices(Nexus 4 and Nexus 7 both running Android 4.4.2).
Here's the relevant part of the code:
This code as it is shows this kind of behavior: http://www.youtube.com/watch?v=Gxzfyz_VQzw. But then, if I remove the for loop and just hard code only one light source, such as:
vec3 lightDirection = normalize(u_directionalLightDirection); combinedColor += computeLighting(normalVector, -lightDirection, u_directionalLightColor, 1.0);
the artifact disappears and it renders fine. http://www.youtube.com/watch?v=979p8rE3nYo&feature=youtu.be
The same for loop seems to work fine in other devices.
I would really appreciate any suggestion.
The GLES shading language spec says that uniform arrays in fragment shaders need to be indexed with constant integral expressions (not variables).
http://www.khronos.org/files/opengles_shading_language.pdf p 103
Try removing the i variable when accessing the uniform arrays.
Thank you so much! That really explains the situation.
After reading a little bit more, I saw that the GLSL specification also says that:
Üstün - Could you provide us with your complete shader code? You might be correct with your comment on the preprocessor constant but we want to verify a few things. Also can you provide us with the device and build information that is installed? Lastly can you try updating the device to it's most recent update?
Here's the link to the simplified version of the vertex and fragment shaders I'm using that shows the strange behavior.
In the line where I'm accessing the u_directionalLightDirection[i], in the fragment shader, the problem disappears when I multiply it by 2.0 when passing it to the normalize() function. This should not be changing the result of the computation as the factor would be eliminated when normalizing.
I first found out that if I pass a light direction vector that doesn't need normalization in the shader from the application, and remove the normalize call, the problem disappears. Then I tried assigning the array element to another vec3 variable and passing it to the normalize function but I suppose that redundant assignment gets optimized out by the compiler and it didn't change the result. But after that, I tried assigning the array element to a vec3 variable, multiply it by 2.0 and then pass it to the normalize() function and it worked. This is why I thought there could be something with the shader compiler.
I'm observing this behavior on a Nexus 4 and a Nexus 7(2013 model) both with an Adreno 320 GPU. I have the latest Android version(4.4.2) installed and build number is KOT49H on both devices.
Our compiler team is investigating the problem in depth. Would you be able to share an apk (without the multiply workaround) so that we could verify a potential fix?
here are two versions of the same code, one with the multiply workaround and one without
Thanks for your time!
Hi ...Our shader compiler team has fixed this issue and will be a forthcoming update for your device.