Getting Started with Shaders

Intro
If you want to learn how to write shaders, it's really hard because there aren't many learning resources, and those that do exist are hard to find. You may get the feeling this is some dark art, handed on by word-of-mouth like Freemason handshakes. And to an extent it is true; existing shader writers just have to take small jumps from the existing to the new technology; however a beginner is faced with an impossible jump! I can't find any central organisation / repository, so this is as good a spot as any to pitch camp.

I'm going to list the Cg resources in the order in which I think you should dig into them. As a relative n00b, I hope and expect the page gets bashed into shape by the pros.

Since there are so few available resources, it wouldn't hurt to browse through all of them just so you know where to go.

Finally, if you get stuck, the forum is manned 24/7 by awesome people.

ShaderLab
If you want to write a shader in Unity, you have to use ShaderLab

Whether you do it IN ShaderLab's own language (invented by the Unity people) or through ShaderLab (usually by tunnelling into Cg, as this gives low-level control and good all-round performance ... i.e. does pretty much everything on pretty much all platforms, although you can also tunnel into GLSL or a couple of shader languages) -- that's up to you. But you do need to get familiar with ShaderLab. That is your entry point.

So first get your head around knocking out simple shaders using ShaderLab; Jessy Catterwaul has made an excellent set of video tutorials for creating shaders in ShaderLab here.

So, take it from the top; get familiar with working in ShaderLab first -- watch Jessy's videos and read through the ShaderLab ref!

Cg
If you need more control, you need to learn how to dip into Cg. Jessy doesn't cover that.

(Cg (C-for-graphics) is a generic shader language. 'Generic' is the key word here.   Before Cg there were different languages for different platforms, e.g. OpenGL extensions and Direct3D pixel shaders, etc. But now you can write in Cg and the same code can be used on many platforms.)

If you look at the default Unity shader, you can see this:

Some of it is still in ShaderLab, only the part between CGPROGRAM and ENDCG is in Cg. Notice the _MainTex variable in the above example -- when users attach the shader to some material, they will see this variable in the Inspector -- they will be able to drag and drop a texture/image onto it. If you want to access it from ShaderLab, you have to use [_MainTex]. If you want to access it from within the Cg chunk, ... well you can see from the above how it is done.

Unite 08 Video
There is an excellent video Unite 08 here on how to program Cg vertex and fragment shaders in Unity. I recommend downloading it in HD ( download link here; open, right click, save as... ) -- if you have a local copy you can scrub around...

Cg Programming for Unity WIKIBOOK
Cg Programming for Unity is a really good from-the-ground-up comprehensive introduction to knocking out Cg shaders from Unity. It has an excellent section on using Blend mode, which is a really difficult concept (for me anyway -- it really took a couple of chapters to explain this single one line command).

nVidia Resources: CG Tutorial, reference manual, user manual, ...
I'm listing this underneath the WIKIBOOK, as that wikibook is geared to Unity, and so takes care of embedding your Cg shader in ShaderLab; getting them playing nicely together.

Resources on nVidia (the guys that made Cg) are completely platform agnostic. They don't even reference Unity.

The standard resource for learning C seems to be the Cg Tutorial. Unfortunately it isn't available as PDF, only online HTML. I recommend jumping straight into chapter 2, as chapter 1 is turgid as hell.

If you ever get your head in a spin about world / object / view / clip / screen space, model view transforms, etc this guide has the clearest explanation I can find anywhere.

Also from the same site you can download from here 3 PDFs: a reference manual, a user manual and some demo (that is basically an addendum to the CG tutorial). I recommend downloading the user manual PDF.

Surface Shaders
Writing full-blown Cg vertex and fragment shaders can be a lot of hard work -- you kind of need to get your head round vector maths for the lighting, e.g. even to render a diffuse material, you still need to look at the tangent plane, calculate ' how much light should be bouncing from each of my light sources, off this tangent plane, bearing in mind the colour characteristics of the surface, into the eye of the beholder? ' which involves vector maths e.g. dot products amongst other things. Added to this you need to worry about transforming vectors from object space into world space. (I wonder how many people know what happens to a normal vector under such a transformation?)

So the Unity folks seem to have made a compromise; surface shaders! As far as I can see this looks like a set of macros for working in Cg while reducing the amount of typing required and hard stuff that needs to be understood. I recommend leaving surface shaders alone until you are comfortable with writing Cg shaders.

I am placing this in the list more as something to know to leave alone for the time being. (i.e. at this point on the page you should have enough of a advantage point to understand the explanation of what surface raiders are).

Unity Manual
Start with the manual, move on to the reference.

In the advanced section of the Unity Manual you can find a page on shaders with three subtopics: Surface Shaders (in ShaderLab and Cg), vertex and fragment shaders (in Cg/HLSL/GLSL and ShaderLab), and fixed function shaders (only ShaderLab).

Unity Reference
The Reference Manual gives you Shader Reference.

Fixed versus Programmable Pipeline
If you are writing in ShaderLab without any Cg code, this gets compiled into 'fixed function pipeline' code -- remember oldschool graphics cards were all fixed function pipeline before the programmable pipeline came in. I think it was the iPhone 3G that was the first iPhone that had a programmable pipeline. So ShaderLab code is solid, it is going to work on everything, even totally dinosaur graphics cards.

But if you're breaking into Cg, you will be using vertex and fragment shaders;  first you will be processing the vertices in the vertex shader (maybe for each vertex you will be calculating the amount of light hitting it,  the  texture coordinate at that place, maybe even you could be deforming the normal vector to make a wavelike effect, heck you could even be moving the vertex around, like a fully height-mapped planet). Then you throw a bundle of information from the vertex shader to the fragment shader. The fragment shader just renders triangles, mainly by interpolating values at the three corners (which it gets courtesy of the vertex shader), although you can obviously do funky stuff, up to you.

Now we even have geometry shaders coming out, where you can actually create a set of points in the geometry shader. So geometry -> vertex -> fragment. Unity doesn't support these yet. But it's coming!

Miscellaneous
NOTE: I've found what appeared to be outdated pages on unity.ru.

http://docs.unity3d.ru/Manual/Shaders.html

http://docs.unity3d.ru/Components/SL-ShaderPrograms.html

I think all of the material has been correctly ported to the .com site ... I wouldn't bet on it though.

EDIT 11.11.12 http://unitygems.com/ contains a set of tutorials, maybe someone can look through these and at them as appropriate to the above page