Unity Shaders
types
surface shaders
glsl/hlsl equivalent
fixed function
hardware dependent
ShaderLab
Properties { ... }
Shaders can define a list of parameters to be set by artists in Unity's material inspector. The Properties block in the shader file defines them.
_name
in Unity, it's common to start shader property names with underscore
[_name]
Later on in the shader, property values are accessed using property name in square brackets
"display name"
The property will show up in material inspector as display name
type
Color
_Color ("Main Color", Color) = (1,1,1,1)
_name ("display name", Color) = (number,number,number,number)
Texture
_MainTex ("Base (RGB)", 2D) = "white" {}
access in Shader
[_MainTex]
type
Float
_name ("display name", Float) = number
_name ("display name", Range (min, max)) = number
Vector4
_name ("display name", Vector) = (number,number,number,number)
SubShader { [Tags] [CommonState] Passdef [Passdef ...] }
Each shader in Unity consists of a list of subshaders. When Unity has to display a mesh, it will find the shader to use, and pick the first subshader that runs on the user's graphics card.
Tags { "TagName1" = "Value1" "TagName2" = "Value2" }
Specifies TagName1 to have Value1, TagName2 to have Value2. You can have as many tags as you like.
Tags are basically key-value pairs. Inside a SubShader tags are used to determine rendering order and other parameters of a subshader. Note that the following tags recognized by Unity must be inside SubShader section and not inside Pass!
Queue
Tags {"Queue" = "Transparent" }
You can determine in which order your objects are drawn using the Queue tag. A Shader decides which render queue its objects belong to, this way any Transparent shaders make sure they are drawn after all opaque objects and so on.
predefined
There are four pre-defined render queues, but there can be more queues in between the predefined ones.
For special uses in-between queues can be used. Internally each queue is represented by integer index; Background is 1000, Geometry is 2000, AlphaTest is 2450, Transparent is 3000 and Overlay is 4000. If a shader uses a queue like this:
Tags {"Queue" = "Geometry + 1" }
Background
this render queue is rendered before any others. It is used for skyboxes and the like.
Geometry
(default) - this is used for most objects. Opaque geometry uses this queue.
AlphaTest
alpha tested geometry uses this queue. It's a separate queue from Geometry one since it's more efficient to render alpha-tested objects after all solid ones are drawn.
Transparent
this render queue is rendered after Geometry and AlphaTest, in back-to-front order. Anything alpha-blended (i.e. shaders that don't write to depth buffer) should go here (glass, particle effects).
Overlay
this render queue is meant for overlay effects. Anything rendered last should go here (e.g. lens flares).
RenderType
Tags { "RenderType"="Ethereal" }
RenderType tag categorizes shaders into several predefined groups, e.g. is is an opaque shader, or an alpha-tested shader etc. This is used by Shader Replacement and in some cases used to produce camera's depth texture.
predefined
Opaque
most of the shaders (Normal, Self Illuminated, Reflective, terrain shaders).
Transparent
most semitransparent shaders (Transparent, Particle, Font, terrain additive pass shaders).
TransparentCutout
masked transparency shaders (Transparent Cutout, two pass vegetation shaders).
Background
Skybox shaders.
Overlay
GUITexture, Halo, Flare shaders.
terrain engine
TreeOpaque
terrain engine tree bark.
TreeTransparentCutout
terrain engine tree leaves.
TreeBillboard
terrain engine billboarded trees.
Grass
terrain engine grass.
GrassBillboard
terrain engine billboarded grass.
ForceNoShadowCasting
Tags { "ForceNoShadowCasting"="True" }
If ForceNoShadowCasting tag is given and has a value of "True", then an object that is rendered using this subshader will never cast shadows. This is mostly useful when you are using shader replacement on transparent objects and you do not wont to inherit a shadow pass from another subshader.
IgnoreProjector
Tags { "IgnoreProjector"="True" }
If IgnoreProjector tag is given and has a value of "True", then an object that uses this shader will not be affected by Projectors. This is mostly useful on semitransparent objects, because there is no good way for Projectors to affect them.
Pass { [Name and Tags] [RenderSetup] [TextureSetup] }
Name and Tags
A Pass can define its Name and arbitrary number of Tags - name/value strings that communicate Pass' intent to the rendering engine.
RenderSetup
A pass sets up various states of the graphics hardware, for example should alpha blending be turned on, should fog be used, and so on.
diagram
type (vertex op?)
(Cull)
Cull Back | Front | Off
Set polygon culling mode.
(ZTest)
ZTest (Less | Greater | LEqual | GEqual | Equal | NotEqual | Always)
Set depth testing mode.
(ZWrite)
ZWrite On | Off
Set depth writing mode.
(Blend)
(ColorMask)
ColorMask RGB | A | 0 | any combination of R, G, B, A
// Set color channel writing mask.
// Writing ColorMask 0 turns off rendering to all color channels. Default mode is writing to all channels (RGBA), but for some special effects you might want to leave certain channels unmodified, or disable color writes completely.
(Offset)
Offset OffsetFactor, OffsetUnits
// Set Z buffer depth offset.
fixed function
Details
HLSL/CGFX
rendering path
UnityEngine.Rendering
Classes
Shader
// Shader class is mostly used just to check ,
// Shader can run on the user's hardware (isSupported property)
// Setting up global shader properties and keywords
// Finding shaders by name (Find method).
(global properties)
PropertyToID
// Gets unique identifier for a shader property name.
// Each name of shader property (for example, _MainTex or _Color) is assigned an unique integer number in Unity, that stays the same for the whole game. The numbers will not be the same between different runs of the game or between machines, so do not store them or send them over network.
// Do this for Uv to transform
SetGlobalBuffer
// Sets a global compute buffer property for all shaders.
SetGlobalColor
// Usually this is used if you have a set of custom shaders that all use the same "global" color (for example, color of the sun). Then you can set the global property from script and don't have to setup the same color in all materials.
Shader.SetGlobalColor("_EnvironmentColor", color);
Shader.SetGlobalColor("_SkyColor", color);
SetGlobalFloat
SetGlobalInt
// Usually this is used if you have a set of custom shaders that all use the same "global" float (for example, density of some custom fog type). Then you can set the global property from script and don't have to setup the same float in all materials.
// Internally float and integer shader properties are treated exactly the same, so this function is just an alias to SetGlobalFloat.
SetGlobalMatrix
SetGlobalTexture
SetGlobalVector
(func)
Find
// Finds a shader with the given name.
WarmupAllShaders
// Fully load all shaders to prevent future performance hiccups.
(keyword)
DisableKeyword
// Unset a global shader keyword.
EnableKeyword
// Set a global shader keyword.
IsKeywordEnabled
// Is global shader keyword enabled?
Enumerations
(stencil)
CompareFunction
// Depth or stencil comparison function.
StencilOp
// Specifies the operation that's performed on the stencil buffer when rendering.
UnityEngine.Rendering.StencilOp
(renderTarget)
BlendOp
// The blend operation that is used to combine the pixel shader output with the render target. This can be passed through Material.SetInt() to change the blend operation during runtime.
//Note that the logical operations are only supported in Gamma (non-sRGB) colorspace, on DX11.1 hardware running on DirectX 11.1 runtime.
BlendMode
// Blend mode for controlling the blending.
// The blend mode is set separately for source and destination, and it controls the blend factor of each component going into the blend equation. It is also possible to set the blend mode for color and alpha components separately. Note: the blend modes are ignored if logical blend operations or advanced OpenGL blend operations are in use.
AmbientMode
// Ambient lighting mode.
// Unity can provide ambient lighting in several modes, for example directional ambient with separate sky, equator and ground colors, or flat ambient with a single color.
Skybox
// Skybox-based or custom ambient lighting.
Trilight
// Trilight ambient lighting.
sky
RenderSettings.ambientSkyColor
equator
RenderSettings.ambientEquatorColor
ground
RenderSettings.ambientGroundColor
Flat
// Flat ambient lighting.
Custom
// Ambient lighting is defined by a custom cube map.
RenderTarget
Stencil
SubShader { ... }
Stencil { ... }
(example)
// Keep buffer if stencil buffer is not equal to 1
Ref
1
(referenceValue)
0–255 integer
The value to be compared against (if Comp is anything else than always) and/or the value to be written to the buffer (if either Pass, Fail or ZFail is set to replace)
Comp
notequal
(comparisonFunction)
// The function used to compare the reference value to the current contents of the buffer. Default: always.
Pass
keep
(stencilOperation)
// What to do with the contents of the buffer if the stencil test (and the depth test) passes. Default: keep.
(reference)
Comparison Function
Greater
Only render pixels whose reference value is greater than the value in the buffer.
GEqual
Only render pixels whose reference value is greater than or equal to the value in the buffer.
Less
Only render pixels whose reference value is less than the value in the buffer.
LEqual
Only render pixels whose reference value is less than or equal to the value in the buffer.
Equal
Only render pixels whose reference value equals the value in the buffer.
NotEqual
Only render pixels whose reference value differs from the value in the buffer.
Always
Make the stencil test always pass.
Never
Make the stencil test always fail.
Stencil Operation
Keep
Keep the current contents of the buffer.
Zero
Write 0 into the buffer.
Replace
Write the reference value into the buffer.
IncrSat
Increment the current value in the buffer. If the value is 255 already, it stays at 255.
DecrSat
Decrement the current value in the buffer. If the value is 0 already, it stays at 0.
Invert
Negate all the bits.
IncrWrap
Increment the current value in the buffer. If the value is 255 already, it becomes 0.
DecrWrap
Decrement the current value in the buffer. If the value is 0 already, it becomes 255.
Deferred rendering path