I'm wondering if anyone has managed to get decent shader performance on Tegra devices. My shader uses all 8 lights provided by jPCT and calculates per-pixel lighting on textured geometry in the fragment shader. It does nothing else and has no conditional statements. On a Galaxy S4, my game (including all game logic etc) gets 50-60fps. No surprises there. Even on my old HTC Evo I get an acceptable framerate (20-30fps). On a Motorola Xoom, it's down to an unplayable 1-3fps.
I tried the default shaders and it runs at a solid 60fps. I tried using a stripped-down version of my shader with just one light and the framerate dropped immediately to 20fps. Am I doing something inefficient? Is per-pixel lighting just a no-go for Tegra 2? My stripped-down 1 light shaders are below:
Vertex shader:
uniform mat4 modelViewMatrix;
uniform mat4 modelViewProjectionMatrix;
uniform mat4 textureMatrix;
attribute vec4 position;
attribute vec3 normal;
attribute vec2 texture0;
varying vec2 texCoord;
varying vec3 vNormal, vPosition;
void main()
{
texCoord = (textureMatrix * vec4(texture0, 0, 1)).xy;
// Transform the vertex into eye space.
vPosition = vec3(modelViewMatrix * position);
// Transform the normal's orientation into eye space.
vNormal = vec3(modelViewMatrix * vec4(normal.xyz, 0.0));
gl_Position = modelViewProjectionMatrix * position;
}
Fragment shader:
precision mediump float;
varying vec2 texCoord;
varying vec3 vNormal, vPosition;
uniform vec4 ambientColor;
uniform sampler2D textureUnit0;
uniform float shininess;
uniform vec3 lightPositions[8];
uniform vec3 diffuseColors[8];
uniform vec3 specularColors[8];
uniform float attenuation[8];
void main()
{
float diffuse0 = 0.0;
vec3 diffColor0 = vec3(0.0,0.0,0.0);
// For attenuation
float quadratic = 0.01;
float distance = length(lightPositions[0] - vPosition);
// Get a lighting direction vector from the light
vec3 lightVector = normalize(lightPositions[0] - vPosition);
// Calculate the dot product of the light vector and vertex normal.
diffuse0 = max(dot(vNormal, lightVector), 0.1);
// Add attenuation
float att = 1.0 / (1.0 + (attenuation[0] * distance) + (quadratic * distance * distance));
diffuse0 = att * diffuse0;
diffColor0 = (diffuseColors[0] * diffuse0) + (att * specularColors[0] * shininess);
vec4 base = texture2D(textureUnit0, texCoord);
gl_FragColor = (base) * (ambientColor + (vec4(diffColor0, 1.0)));
}
On Tegra2 and Tegra3 is very slow per-pixel lighting, nothing we can do...
Bummer. Thanks, Thomas.
Tegra 3 actually isn't that bad...but Tegra 2 surely is...