Surface vs Vertex/Fragment shaders


I’m looking to get into shader programming and I’m doing a small research. I watched a couple videos at about shader writing in Unity (great website btw) and the guy claimed that surface shaders are more expensive to render than vertex/fragment shaders. However, I couldn’t find such information in the Unity docs.

Can anyone confirm or disregard this?

If that’s really the case:

  • is it a big performance hit?
  • should I use fragment shaders instead for my mobile game?

As already pointed out, “surface shaders” are not really shaders - think of them as (Unity-specific) macros/templates that can be used to automate a lot of standard shader code - which are then compiled into regular Cg vertex/fragment shaders. Everything that can be done in a surface shader could be written by hand in a vertex/fragment shader (although note that the reverse is not always true).

As with any process, there is necessarily a bit of a trade-off between convenience of using an automated system, compared to the loss of control over fine optimisation that could be achieved manually. However, particularly if you’re new to shader writing, there is also the potential for you to make your own mistakes that will cost far more than those apparent inefficiencies caused by the surface shader template.

I’d like to point out that by adding #pragma debug to your surface shader you can view the complete vertex/fragment shader code that it translates to, and then, if you feel any optimisation is necessary, you can edit that shader by hand, which gives the best of both worlds.

As a final point, you might want to notice that most of the built-in Unity shaders are created as surface shaders, including: Diffuse, Bumped, Reflective/Specular, Transparent/Parallax… if there was a noticeable performance hit involved, I don’t think Unity would be doing so :wink:

If you want to get into shader programming, I suggest you to start with surface shader because a lot of lighting calculation are done under the hood and the results are ready to use. With this you can discover shader programming.

But of course there is a performance hit. But I think this is not significant. Unless you want super optimized mobile shader. But if you want this, I think you are quite comfortable with shaders.

When you are comfortable with surface shader you can look at fragment shader and start developping them. A very good point is that they handle lighting which is a hard piece in fragment I think.

With fragment shader you have total control of what is calculated and with this you can optimize your shader. But I think it’s a bit hard for a beginner.

This depends of what shader you want to develop. Simple rim, unlit etc… shaders can be easily done with fragment shader.

As you said CGCookie have a very good tutorial selection about fragment shader which can help you jump into fragment shader programming.

Hope it helped.

Cars with air-conditioning are more expensive than cars without. But buying a non-air-conditioned car, then installing AC, that will probably cost more and not work as well.

Surface shaders “cost more” since they perform lighting. But, same as cars, if you’re going to have lighting anyway, you may as well use a surface shader. Also, same as cars, if you really know what you’re doing, in some cases you may save by custom-adding your own lighting to a vertex shader (but there are probably a dozen better non-shader speedups, depending on the game.)

As far as I’m concerned there is one more important difference, surface shaders get all messed up when lightmapping them with beast and Vertex/Frag seem to work correctly. Is this correct or I’m not seeing the whole of it?