This doesn't mean anything.Any more than that, the application drops about 15 frames per light added

Say the app was running at 16fps and it dropped by 15 to 1fps, that means it increased from 62.5ms per frame to 1000ms per frame -- or an increase of 937.5ms.

Say the app was running at 100fps and it dropped by 15 to 85fps, that means it increased from 10ms per frame to 11.8ms per frame -- or an increase of 1.8ms.

Is a drop of 15fps equal to the workload increasing by 1ms or by 1000ms? It's both, so it's meaningless

For a "drop in FPS" to be meaningful, you need to know what FPS it dropped from so you've got an absolute starting point. It's generally better to just always use "1000/FPS" (

*milliseconds per frame*) rather than FPS so that you're always talking in absolute terms rather than relative terms.

float distance = length(toPointLight - v_Position); vec3 lightVector = normalize(toPointLight - v_Position);Both length and normalize involve a square root. You're also performing the same subtraction twice. Maybe your device/driver will optimize this code for you, but maybe it won't

If you don't trust it, you can rewrite it optimally yourself as:

vec3 lightVector = toPointLight - v_Position; float distance = length(lightVector); lightVector /= distance;

diffuseDiff = max(dot(v_Normal, lightVector), 0.0);GPUs can usually clamp the results of operations to the 0-1 range "for free", but clamping from 0-infinity has a cost. In this case, it may be faster to use:

diffuseDiff = clamp(dot(v_Normal, lightVector), 0.0, 1.0);

diffuseDiff = diffuseDiff * (1.0 / (1.0 + ((1.0-u_LightPower[i])* distance * distance))); //Determine attenuationHere you're performing math on a uniform variable. You can eliminate the "1-u..." operation by doing it once on the CPU, and storing "1-u_blah" in the uniform instead.

You may also be able to compute distance*distance (

*distance squared*) for free, by changing the earlier distance calculation like this:

vec3 lightVector = toPointLight - v_Position; float distanceSquared = dot(lightVector, lightVector); float distance = sqrt(distanceSquared); lightVector /= distance;

gl_FragColor.rgb *= vec3(1.0) / ((vec3(1.0) + ((vec3(1.0) - vec3(u_LightColours[i]))*diffuseDiff))); //The expensive partWhat's the theory behind this line? Is it necessary?