- Home /
Specular shader on iOS
I'm trying to use the specular shader on iOS to create a Earth object. As texture I have a normal earth surface color in the RGB channel and a specular color in the alpha channel. (I have used the textures from http://learningwebgl.com/blog/?p=1778 ).
In the editor I get the desired effect:
But when I run the program on my iPad I get much different effect (much more specular):
I know that there are differences between shaders running different devices. But what is the exact reason why this don't work? And where can I find a detailed description of the differences between the two platforms?
Additional info:
- I have used a mesh with many polygons (it seems the light are computed in the vertex shader).
- I have tried to use different image compression methods for iOS, but it didn't change anything
- I have used Unity 3.3 Pro + iPhone iOS (not Pro)
I don't know if the entire lighting calculation is done in the vertex shader, but it makes sense that the specular highlight is calculated in the vertex shader for performance reasons. I haven't seen the GL ES 2.0 shaders Unity includes yet.
I assumes that Unity uses GL ES 2.0, since GL ES 1.x does not support shaders (only fixed function pipeline). Since I use a highly detailed mesh, it doesn't really matter where the ligth-calculation is done.
I'm experiencing this same phenomenon on iOS. It also is occurring on some Android devices but not others. Droid 2 looks like this, but the Galaxy Tab looks correct.
Answer by equalsequals · Jun 17, 2011 at 03:31 PM
There is a slight problem with the BlinnPhong lighting model and OpenGLES. If you check the source code of the Mobile shaders, you will see that they provide an alternative lighting model "MobileBlinnPhong".
I was able to isolate the issue to these lines in BlinnPhong:
inline fixed4 LightingBlinnPhong (SurfaceOutput s, fixed3 lightDir, fixed3 viewDir, fixed atten)
{
fixed3 h = normalize (lightDir + viewDir); //normalize light direction added to the view direction
fixed diff = max (0, dot (s.Normal, lightDir));
float nh = max (0, dot (s.Normal, h)); //calculate the dot product of the surface normal and our normalized light+view, then make sure it is no smaller than 0 (black)
float spec = pow (nh, s.Specular*128.0) * s.Gloss;
fixed4 c;
c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * _SpecColor.rgb * spec) * (atten * 2);
c.a = s.Alpha + _LightColor0.a * _SpecColor.a * spec * atten;
return c;
}
The mobile version MobileBlinnPhong:
inline fixed4 LightingMobileBlinnPhong (SurfaceOutput s, fixed3 lightDir, fixed3 halfDir, fixed atten)
{
fixed diff = max (0, dot (s.Normal, lightDir));
fixed nh = max (0, dot (s.Normal, halfDir)); //Instead of injecting the normalized light+view, we just inject view, which is provided as halfasview in the initial surface shader CG parameters
fixed spec = pow (nh, s.Specular*128) * s.Gloss;
fixed4 c;
c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * spec) * (atten*2);
c.a = 0.0;
return c;
}
So by comparison we can see that the GPU seems to fumble on the standard BlinnPhong model, and UT's mobile version accounts for and corrects it.
For a quick fix, I suggest that any time you use OpenGLES (either 1.1 or 2.0) use a shader which employs the mobile-safe version of BlinnPhong lighting model as opposed to the standard.
If you need me to I'll go more in-depth, I just wanted to get this out quickly.
Hope this helps!
==
@equalsequals Where can I find the best perfor$$anonymous$$g specular shader for use on iOS?
Hey, I'm sorry for a noob question, but how (where) do you implement this code? I am really new to shaders and only a little familiar with ShaderLab, but it doesn't look like ShaderLab code to me. Oh and I'm having the same issue. Here's my shader code: http://pastebin.com/NhXfskDq
Answer by ilya_ca · Nov 16, 2012 at 07:19 AM
Another great solution would be to create a specularity look-up table as described in here: http://aras-p.info/blog/2011/02/01/ios-shader-tricks-or-its-2001-all-over-again/ It gives per-pixel specularity without the performance hit.