Getting Started with Shaders

From Unify Community Wiki
(Difference between revisions)
Jump to: navigation, search
(copied from Shaders; originally written by User:Pi 27.9.2012)
 
(more or less cosmetic changes; note that Cg is also used in Surface Shaders! (your example in the Cg section is actually a surface shader))
Line 3: Line 3:
 
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 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 [http://docs.unity3d.com/Documentation/Components/SL-Reference.html ShaderLab]  
+
If you want to write a shader in Unity, you have to use [http://docs.unity3d.com/Documentation/Components/SL-Shader.html 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 [http://www.burgzergarcade.com/unity-ios-shaderlab here].
 
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 [http://www.burgzergarcade.com/unity-ios-shaderlab here].
Line 9: Line 9:
 
==Cg==
 
==Cg==
  
If you need more control,  you need to learn how to dip into cG.  Jessy doesn't cover that.
+
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 platformse.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.)''
+
''(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 that it does this:
+
If you look at the default Unity shader, you can see this:
 
<source lang="c">
 
<source lang="c">
 
  Shader "Custom/foo" {
 
  Shader "Custom/foo" {
Line 43: Line 43:
 
</source>
 
</source>
  
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.
+
Most 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.
  
The standard resource for learning cG is the [http://http.developer.nvidia.com/CgTutorial/cg_tutorial_chapter01.html 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.
+
The standard resource for learning Cg is the [http://http.developer.nvidia.com/CgTutorial/cg_tutorial_chapter01.html 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 [http://developer.nvidia.com/cg-toolkit 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.
 
Also from the same site you can download from [http://developer.nvidia.com/cg-toolkit 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.
Line 51: Line 51:
 
==Surface Shaders==
 
==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?)
+
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.
+
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==
 
==Unite 08 Video==
  
There is an excellent video [http://video.unity3d.com/video/3274383/unite-08-shaders Unite 08 here] on how to program cG shaders from Unity.  I recommend downloading it in HD ( download link [http://video.unity3d.com/1984080/3274383/be78d2e51ac4711a76c5052ccc0be7b2/video_hd/unite-08-shaders-video.mp4 here]; open, right click, save as... )
+
There is an excellent video [http://video.unity3d.com/video/3274383/unite-08-shaders Unite 08 here] on how to program Cg vertex and fragment shaders in Unity.  I recommend downloading it in HD ( download link [http://video.unity3d.com/1984080/3274383/be78d2e51ac4711a76c5052ccc0be7b2/video_hd/unite-08-shaders-video.mp4 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!
 
But take it from the top; get familiar with working in ShaderLab first -- watch Jessy's videos and read through the ShaderLab ref!
Line 65: Line 65:
 
Start with the manual, move on to the reference.
 
Start with the manual, move on to the reference.
  
In the [http://docs.unity3d.com/Documentation/Manual/Advanced.html ADVANCED]section of the Unity MANUAL you can find a [http://docs.unity3d.com/Documentation/Manual/Shaders.html page on shaders] with two subtopics.
+
In the [http://docs.unity3d.com/Documentation/Manual/Advanced.html advanced] section of the Unity Manual you can find a [http://docs.unity3d.com/Documentation/Manual/Shaders.html 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).
 
+
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==
 
==Unity Reference==
  
The [http://docs.unity3d.com/Documentation/Components/ Reference Manual] gives you [http://docs.unity3d.com/Documentation/Components/SL-Reference.html Shader Reference] -- same link that is at the top of this section
+
The [http://docs.unity3d.com/Documentation/Components/ Reference Manual] gives you [http://docs.unity3d.com/Documentation/Components/SL-Reference.html Shader Reference].
  
Here the sub-pages are presented in the wrong order.  The order should be {ShaderLab, cG, surface shaders}.
+
==Fixed versus Programmable Pipeline==
  
==Vertex and Fragment shaders, 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. 
  
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 in 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.
 
+
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!
 
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!
Line 86: Line 82:
  
 
NOTE:  I've found what appeared to be outdated pages on unity.ru.
 
NOTE:  I've found what appeared to be outdated pages on unity.ru.
 +
 
http://docs.unity3d.ru/Manual/Shaders.html
 
http://docs.unity3d.ru/Manual/Shaders.html
 +
 
http://docs.unity3d.ru/Components/SL-ShaderPrograms.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.
+
 
 +
I think all of the material has been correctly ported to the .com site ... I wouldn't bet on it though.

Revision as of 14:10, 27 September 2012

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 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:

 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"
 }

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

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

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

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

Personal tools
Namespaces

Variants
Actions
Navigation
Extras
Toolbox