- Home /
Surface vs Vertex/Fragment shaders
Hi,
I'm looking to get into shader programming and I'm doing a small research. I watched a couple videos at cgcookie.com 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?
Surface shaders are compiled to a bunch of vertex/fragment shaders anyway. They are more expensive because they automatically handle lighting calculations even if you don't want to.
In my case I want them to calculate lighting, so that's fine. I'm more interested in point 1 of my question - how big is the performance hit and should I be worried about it
It looks like you can override lighting as described here: https://docs.unity3d.com/$$anonymous$$anual/SL-SurfaceShaderLightingExamples.html
Answer by tanoshimi · Nov 26, 2013 at 10:24 PM
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 ;)
ShaderLab is mostly Unity specific. The code in surface shaders is almost identical to "real" CG code (except for all the missing lighting math, and any Unity-specific function calls.)
Answer by MaT227 · Nov 26, 2013 at 06:10 PM
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.
Answer by Owen-Reynolds · Nov 26, 2013 at 09:36 PM
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.)
Answer by Khalanar_Dev · Apr 24, 2014 at 07:08 AM
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?
It's you ;) Did your follow "decoding lightmaps" at https://docs.unity3d.com/Documentation/Components/SL-SurfaceShaderLighting.html?
Wow, totally ran over that, thanks!! Anyway, I'm trying to get lightdir into this, and I am not able to do it. I would know how to do so in Vert/Frag but not in surface. Any advice tanoshimi?
half4 LightingRamp_SingleLightmap (SurfaceOutput s, fixed4 color){
half3 lm = DecodeLightmap (color);
return half4 (lm, 0);
}
Your answer
![](https://koobas.hobune.stream/wayback/20220613122841im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
How does Unity apply a lightmap? 0 Answers
How to make a submesh from part of my character 1 Answer
A node in a childnode? 1 Answer
Alpha Transparency Shader Issue 1 Answer
How to implement shader 0 Answers