Different shaders for iPad1 and iPad2

Is it possible to write shaders so that they work on iPad 2/3 and fall back to another shader on iPad1? The 1st gen iPad isn’t fast enough to render my scenes with rim lighting and specular highlights, but the iPad 2 is. I suppose I can swap materials in code to replace low quality materials with better ones, but I wondered if it’s possible to do it directly in the shader.

I can use #pragma exclude_renderers to stop the shader being rendered on all iOS devices, but I haven’t found anything more granular than that.

It will be better to detect device in script and swap materials imho.

You could use custom keywords in custom shader then in game script call

Shader.EnableKeyword (“IPAD3_ON”);
Shader.DisableKeyword (“IPAD3_OFF”);

then in shader

#pragma multi_compile IPAD3_ON IPAD3_OFF

#if ( IPAD3_ON )
// do ipad 3 stuff
#else
// do non ipad3 stuff
#endif

// another method ================================

in game code set shader manually based on device ( i think the shaders all need to exist in scene to work on device like this )

Shader myshader = Shader.Find(“MyShaderName”)

gameobject.renderer.material.shader = myshader;

Thanks, echologin, #pragma multi_compile seems perfect!

Cool !, then call the Shader.enable(“keyword”) and disable at Start() + Awake(), ive seen examples where they call it every frame before rendering but Start + Awake seems to work for me.

I’m not having any luck. All of my shaders are surface shaders. Is the use of #pragma multi_compile and #ifdef not available inside surface shaders?

I don’t know i never wrote any surface shaders, only vertex/frag,

the #pragma has to go under the CGPROGRAM part ( maybe that is problem ? )

EDIT: i tried this and it seems to work as expected

Shader "Example/SurfaceTest	" 
{
	Properties 
 	{
 		_MainTex ("Texture", 2D) = "white" {}
 	}
    SubShader 
    {
      Tags { "RenderType" = "Opaque" }
      CGPROGRAM
      #pragma surface surf Lambert
      #pragma multi_compile IPAD3_ON IPAD3_OFF
      
      struct Input 
      {
          float2 uv_MainTex;
      };
      
      sampler2D _MainTex;
      
      void surf (Input IN, inout SurfaceOutput o) 
      {
          #ifndef IPAD3_OFF
	          o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
          #else
	          o.Albedo = fixed3 ( 1,0,0 );
          #endif
      }
      
      ENDCG
    } 
    
    Fallback "Diffuse"
  }

in unity shaders i do not think #ifdef works, it is #if and #ifndef

Aha, you’re right. It was the #ifdef which was causing me problems. Using #if and #ifndef works fine.

Thanks very much for the help.