Forums - Strange lightning problem on Adreno 320 with for loop in fragment shader

9 posts / 0 new
Last post
Strange lightning problem on Adreno 320 with for loop in fragment shader
Üstün Ergenoglu
Join Date: 29 Dec 13
Posts: 6
Posted: Sun, 2013-12-29 15:56

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:

https://gist.github.com/rgngl/c6849beed2d56e80fdbe

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[0]);
combinedColor += computeLighting(normalVector, -lightDirection, u_directionalLightColor[0], 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.

  • Up0
  • Down0
mhfeldma Moderator
Join Date: 29 Nov 12
Posts: 312
Posted: Mon, 2013-12-30 13:20

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.

 

 

 

  • Up0
  • Down0
Üstün Ergenoglu
Join Date: 29 Dec 13
Posts: 6
Posted: Mon, 2013-12-30 15:53

Thank you so much! That really explains the situation.

  • Up0
  • Down0
Üstün Ergenoglu
Join Date: 29 Dec 13
Posts: 6
Posted: Sat, 2014-01-04 04:06

Hi,

After reading a little bit more, I saw that the GLSL specification also says that: 

The following are constant-index-expressions:

• Constant expressions

• Loop indices as defined in section 4

• Expressions composed of both of the above
and the for loop I use is of the form: "for (int i = 0; i < DIRECTIONAL_LIGHT_COUNT; i++) { }" where DIRECTIONAL_LIGHT_COUNT is a preprocessor constant. According to the section 4 this for loop looks OK. So, I think the shader code is correct. Could this be a bug in the driver?
 
I have furthermore isolated the weird behaviour to the line 
vec3 lightDirection = normalize(u_directionalLightDirection[0]);
 
If I remove the normalize() call the artifact disappears. The normalize() is there just to make sure the light direction uniform coming from the application side is normalized, but why would it cause a problem? I should add that in the original code I posted the for loop expression was ++i instead of i++, but changing the prefix increment operator to postfix, as said in the specs, didn't help anyway.
  • Up0
  • Down0
mhfeldma Moderator
Join Date: 29 Nov 12
Posts: 312
Posted: Mon, 2014-01-13 11:29

Ü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?

thanks...

  • Up0
  • Down0
Üstün Ergenoglu
Join Date: 29 Dec 13
Posts: 6
Posted: Mon, 2014-01-13 13:14

Hi,

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.

Cheers,

Üstün

  • Up0
  • Down0
mhfeldma Moderator
Join Date: 29 Nov 12
Posts: 312
Posted: Wed, 2014-01-22 13:43

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?

  • Up0
  • Down0
Üstün Ergenoglu
Join Date: 29 Dec 13
Posts: 6
Posted: Wed, 2014-01-22 14:31

Hi,

here are two versions of the same code, one with the multiply workaround and one without

https://dl.dropboxusercontent.com/u/5907799/ShaderProblem-noworkaround.apk

https://dl.dropboxusercontent.com/u/5907799/ShaderProblem-withworkaround...

Thanks for your time!

-Ustun

  • Up0
  • Down0
mhfeldma Moderator
Join Date: 29 Nov 12
Posts: 312
Posted: Fri, 2014-01-24 15:44

Hi ...Our shader compiler team has fixed this issue and will be a forthcoming update for your device.

  • Up0
  • Down0
or Register

Opinions expressed in the content posted here are the personal opinions of the original authors, and do not necessarily reflect those of Qualcomm Incorporated or its subsidiaries (“Qualcomm”). The content is provided for informational purposes only and is not meant to be an endorsement or representation by Qualcomm or any other party. This site may also provide links or references to non-Qualcomm sites and resources. Qualcomm makes no representations, warranties, or other commitments whatsoever about any non-Qualcomm sites or third-party resources that may be referenced, accessible from, or linked to this site.