title: LibGDX assigning a specific shader to a ModelInstance
body: <p>I have recently been learning an implementing my own shaders in libgdx.
  So far I did this with a custom shader provider, which chooses between a few shaders based on the userdata value of the object;</p>
  
  
  
  <pre><code>public class MyShaderProvider extends DefaultShaderProvider {
      public final DefaultShader.Config config;
      final static String logstag = "ME.MyShaderProvider";
      //known shaders
      static public enum shadertypes {
          prettynoise,
          invert,
          standardlibgdx, 
          noise,
          distancefield,
          conceptbeam
      }
  
      public MyShaderProvider (final DefaultShader.Config config) {
          this.config = (config == null) ? new DefaultShader.Config() : config;
      }
  
      public MyShaderProvider (final String vertexShader, final String fragmentShader) {
          this(new DefaultShader.Config(vertexShader, fragmentShader));
  
  
      }
  
      public MyShaderProvider (final FileHandle vertexShader, final FileHandle fragmentShader) {
          this(vertexShader.readString(), fragmentShader.readString());
      }
  
      public MyShaderProvider () {
          this(null);
      }
  
      public void testListShader(Renderable instance){
  
          for (Shader shader : shaders) {
  
              Gdx.app.log(logstag, "shader="+shader.getClass().getName());
  
              Gdx.app.log(logstag, "can render="+shader.canRender(instance));
  
          }
      }
  
      @Override
      protected Shader createShader (final Renderable renderable) {
  
          //pick shader based on renderables userdata?
          shadertypes shaderenum = (shadertypes) renderable.userData;
  
          if (shaderenum==null){
                  return super.createShader(renderable);
          }
          Gdx.app.log(logstag, "shaderenum="+shaderenum.toString());
  
  
          switch (shaderenum) {
  
          case prettynoise:
          {           
              return new PrettyNoiseShader();
  
          }
          case invert:
          {
                String vert = Gdx.files.internal("shaders/invert.vertex.glsl").readString();
                String frag = Gdx.files.internal("shaders/invert.fragment.glsl").readString();
  
  
              return new DefaultShader(renderable, new DefaultShader.Config(vert, frag)); 
          }
          case noise:
          {
              return new NoiseShader();
          }
          case conceptbeam:
          {
              Gdx.app.log(logstag, "creating concept gun beam ");
              return new ConceptBeamShader();
          }
          case distancefield:
          {
              return new DistanceFieldShader();
          }
          default:
              return super.createShader(renderable);
  
          }
          //return new DefaultShader(renderable, new DefaultShader.Config());
  
      }
  }
  </code></pre>
  
  
  
  <p><strong>This seemed to work.</strong>
  I have an object with a noise shader applied, animated fine.<br> 
  I have an object with a inverted textured shader, again looking fine.<br> 
  I have a whole bunch of other objects being rendered with the normal default shader. 
  It seems the provider as I have set it up is correctly rendering different objects with different shaders based on userData.</p>
  
  <p>However,I recently found a new object I created with a new shader type (ConceptBeamShader) is only being rendered with the Default shader.</p>
  
  <p>The objects user data is set the same as the others;</p>
  
  <pre><code>newlazer.userData = MyShaderProvider.shadertypes.conceptbeam;
  </code></pre>
  
  <p>However, at no point does the conceptbeamshader get created or used.</p>
  
  <p>In fact createShader() doesn't seem to run for it at all...implying that an existing shader in the shaders array is good enough.</p>
  
  <p>Using the testListShader() function above I see "DefaultShader" is in the "shader" list, which canRender anything, and thus it never gets to creating that new shader I want that object to use :-/</p>
  
  <p>I assume the other shaders only got picked before because those objects were created before DefaultShader got added to that internal shader list.</p>
  
  <p>Surely as soon as a DefaultShader is used, it gets stored in that provider list and will "gobble up" any other shaders. The getShader function in the class MyShaderProvider extends is;</p>
  
  <pre><code>    public Shader getShader (Renderable renderable) {
      Shader suggestedShader = renderable.shader;
      if (suggestedShader != null &amp;&amp; suggestedShader.canRender(renderable)) return suggestedShader;
      for (Shader shader : shaders) {
          if (shader.canRender(renderable)) return shader;
      }
      final Shader shader = createShader(renderable);
      shader.init();
      shaders.add(shader);
      return shader;
  }
  </code></pre>
  
  <p>As you can see the shaders are looped over and the first one which returns true for "canRender" is used. </p>
  
  <p>So...umm...<strong>how exactly are you supposed to say "render this ModelInstance with this shader"</strong> ? </p>
  
  <p>None of the tutorials I have read online seemed to cover this - in fact the one on the official site seems to recommend exactly what I am doing so theres clearly something I am missing.</p>
  
  <p>Thanks,</p>
  
  <hr>
  
  <p><em>edit</em>
  The place it was instanced was asked for. Not sure how this helps but here;</p>
  
  <pre><code>public static MyShaderProvider myshaderprovider = new MyShaderProvider();
  </code></pre>
  
  <p>Its then assigned to the modelbatch at the games setup</p>
  
  <pre><code>modelBatch = new ModelBatch(myshaderprovider);
  </code></pre>
  
  <p>As mentioned, my other shaders are working and visible on the objects I assigned the matching userdata too, so I am 99.9% sure the provider is being called and is, at least in some cases, picking the right shader for the right object.
  My hunch where its going wrong is as soon as "DefaultShader" gets added to the internal shader list.</p>