# Which will be faster? Switching shaders or ignore that some cases don't need full code?

I have two types of 2d objects:

In first case (for about 70% of objects), I need that code in the shader:

float2 texCoord = input.TexCoord + textureCoord.xy


But in the second case I have to use:

float2 texCoord = fmod(input.TexCoord, texCoordM.xy - textureCoord.xy) + textureCoord.xy


I can use second code also for first case, but it will be a little slower (fmod is useless here, input.TexCoord will be always lower than textureCoord.xy - textureCoord.xy for sure).

My question is, which way will be faster:

1. Making two independent shaders for both types of rectangles, group rectangles by types and switch shaders during rendering.
2. Make one shader and use some if statement.
3. Make one shader and ignore that sometimes (70% of cases) I don't need to use fmod.
• Why don't you try all the methods, profile them and find out? Whatever answer you get here will be speculation at best anyways, since this is highly dependent upon the rest of your shader code. – Richard Marskell - Drackir Dec 13 '12 at 5:37
• Have you benchmarked anything yet? Until you have, go for option 3. There is no need for any of the complexity you are trying to add until you know what is slow. – sam hocevar Dec 13 '12 at 8:24
• Option three does allow you front to back sorting and batching which will probably give you a much higher benefit than using a shader with one or two instructions less. If this is done in the vertex shader, dont bother with profiling, take option 3. If done in the fragment shader you will have to draw a whole lot of fragments to get a measureable difference. – Archy Dec 13 '12 at 9:35
• Possible duplicate of gamedev.stackexchange.com/questions/22216/… and related to: gamedev.stackexchange.com/questions/28407/… – MichaelHouse Dec 13 '12 at 14:17

## 2 Answers

My inclination would be to go for option 3. Yes, I accept ktodisco's rationale behind suggesting option 1, but you're potentially going to need to do extra work to sort all your geometry, and it will kill you if you ever need to implement translucency (where your sort will need to be by depth rather than by shader used). Option 3 will be slightly slower for sure (although your GPU and/or driver may be able to optimize the fmod call internally depending on the params passed) but it's a huge win on code simplicity, and - all other things being equal - code simplicity would nail it for me.

Count out option two immediately. You should avoid at all costs branching in a shader. The only exception is if the branch is consistent for the entire rendering pass. Yes, branching is not as expensive now as it used to be, and shader compilation will often optimize such that the branch is negligible, but if it can be avoided, why do it?

From there I think the best choice is option one. If you can group the rectangles by type, then you will only be switching shaders twice per frame. Now, I don't know the exact performance specifications for switching shaders in DirectX; you can bet there will be some performance hit, but likely not much for just one or two switches, considering that programs with many different types of objects and materials can render quite fast, just fine. Another reason I'd advocate this is it creates the need for a system to swap shaders based on object type, and is therefore more extendable should you add new objects to your program.

Option three could (maybe?) end up being more efficient than option one, but the only way you'll find out is if you profile both. It's more likely though that option one will be the fastest.

• Honestly, in this case, it's not the branching that is expensive, it's setting the uniform that will be used for branching. – sam hocevar Dec 13 '12 at 8:22