Getting Started with Shaders

From Unify Community Wiki
Revision as of 13:30, 27 September 2012 by Martin Kraus (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Contents

ShaderLab

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. I can't find any central organisation so I'm going to do this here.

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

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.

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 (reasonably new) generic shader language. 'GENERIC' is the key word here. Before cG there were different languages for different platforms. e.g. OpenGL vs DirectX vs ... (a handful of others). But now you can write in cG and the same code can deploy to all these platforms.)

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

 Shader "Custom/foo" {
 	Properties {
 		_MainTex ("Base (RGB)", 2D) = "white" {}
 	}
 	SubShader {
 		Tags { "RenderType"="Opaque" }
 		LOD 200
 
 		CGPROGRAM
 		#pragma surface surf Lambert
 
 		sampler2D _MainTex;
 
 		struct Input {
 			float2 uv_MainTex;
 		};
 
 		void surf (Input IN, inout SurfaceOutput o) {
 			half4 c = tex2D (_MainTex, IN.uv_MainTex);
 			o.Albedo = c.rgb;
 			o.Alpha = c.a;
 		}
 		ENDCG
 	} 
 	FallBack "Diffuse"
 }

So you are still working in ShaderLab. You just create CG chunks inside of shader lab. Notice the _MainTex variable in the above example -- when the user attaches the shader to some material, they will see in the Inspector this variable -- 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.

The standard resource for learning cG is 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.

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 chunks 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.

Unite 08 Video

There is an excellent video Unite 08 here on how to program cG shaders from Unity. I recommend downloading it in HD ( download link here; open, right click, save as... )

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

Unity Manual

Start with the manual, move on to the reference.

In the ADVANCEDsection of the Unity MANUAL you can find a page on shaders with two subtopics.

The manual presents {ShaderLab, cG, surface shaders} in the wrong order on that page, and doesn't IMHO make a respectable effort to disambiguate them.

Unity Reference

The Reference Manual gives you Shader Reference -- same link that is at the top of this section

Here the sub-pages are presented in the wrong order. The order should be {ShaderLab, cG, surface shaders}.

Vertex and Fragment shaders, Fixed versus Programmable pipeline

Note that I'm saying cG, and the documentation is saying "Vertex / Fragment shaders". Let me clear this up. If you are writing in ShaderLab, this gets compiled into ' fixed function pipeline ' code -- remember oldskool 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 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 tho.
Personal tools
Namespaces

Variants
Actions
Navigation
Extras
Toolbox