Any way to fake textureLod on GLES2? I've been having nightmares at work this week trying to get Unity's Standard shader, and my own custom car paint shader modded from it, to look good on Android. 

The most obvious problem was fractured specular highlights, which I  identified as a float precision issue, and solved by changing all the directional math to use float3 instead of half3. 

It now looks fine on GLES3, but on GLES2, which we want to support, the glossy reflections coming from reflection probes look terrible, with noisy matte areas all over the place.

I finally tracked this down to the cube map texture lookup itself - different blur levels are stored in different MIP levels, and a textureCubeLod lookup samples the reflection at the right smoothness level. Trouble is, GLES2 doesn't natively support lod texture lookups, so it relies on an extension. If the extension is not found, and it seems most Android devices don't have it, it falls back to a regular texture sample, with the lod parameter becoming a bias. This explains the matte areas - sharp features are causing the tex lookup to be kicked down the mip chain to the rougher maps, and the bias applied from there. From certain angles, a single bit of noise in the normal map is enough to cause the effect. 

What I want to know is, does any workaround exist for this? My first thought was to 'bias the bias' using dfdx, dfdy, but unfortunately these are also GLES3 only. I may just have to kill glossy reflections altogether on older droids otherwise.
One way would be to break out the mip levels of the cube into a bunch of separate textures, then implement the mip selection and trilinear filtering yourself, by branching based on the LOD value.

That doesn't sound fast, though, given you're targeting older devices. You could speed it up by forgoing trilinear filtering and just using the nearest-neighbor mip level. Gloss values would be effectively quantized to the number of mip levels, but maybe it won't look too bad.