Shaders: Getting started来源网址:http://unity3d.com/support/documentation/Manual/ShaderTut1.html
Unity Manual > Advanced > Shaders > Shaders: Getting started
This tutorial will teach you how you can create your own shaders and make you game look a lot better!
此教程将指引你如何建立自己的Shaders,让你的游戏场景看起来更好
Unity is equipped with a powerful shading and material language called ShaderLab. In style it is similar to CgFX and Direct3D Effects languages - it describes everything needed to display a Material, not just plain vertex/pixel shaders.
Unity配备了强大的阴影和材料的语言工具称为ShaderLab,以程式语言来看,它类似于CgFX和Direct3D的语法,它不只纪录基本的端点或者映像点(vertex/pixel)资讯,也描述了材质所必要的一切资讯。
Shaders describe properties that are exposed in Unity's Material Inspector and multiple shader implementations (SubShaders) targeted at different graphics hardware capabilities, each describing complete graphics hardware rendering state, fixed function pipeline setup or vertex/fragment programs to use. Vertex and fragment programs are written in high-level Cg programming language or low-level shader assembly.
在unity材质检视器中可以看到Shaders的性质及多重shader(SubShaders)的描述,针对不同图形硬件,每个描述也都完整的说明了图形硬件的彩现状态,fixed function pipeline如何设定、vertex/ fragment programs如何作用。 Vertex and fragment程序可以使用高阶Cg程式语言或低阶shader组合。
In this tutorial we describe how to write shaders in ShaderLab using both fixed function and programmable pipelines. We assume that the reader has a basic understanding of OpenGL or Direct3D render states, fixed function and programmable pipelines and has some knowledge of Cg, HLSL or GLSL programming languages. Some shader tutorials and documentation can be found on NVIDIA and AMD developer sites.
在这个教程中,我们将描述如何使用fixed function与programmable pipelines两种方式于ShaderLab中撰写shaders,我们假设读者拥有基本的OpenGL或Direct3D彩现概念,并对cg有fixed function与programmable pipelines的常识,HLSL或GLSL编程语言技术,一些Shader教程与参考文件可于NVIDIA以及AMD的开发站上取得
Getting started
To create a new shader, either choose Assets->Create->Shader from the menubar, or duplicate an existing shader, and work from that. The new shader can be edited by double-clicking it in the Project View.
建立一个新的shader有两种方法,可以由菜单Assets->Create->Shader新增,或复制一个既有的shader再进行编辑,新的shader可以透过双击来启动编辑画面(UniSciTE)
We'll start with a very basic shader:
下面开始介绍一个基础的shader范例:
[javascript] view plaincopy
Shader "Tutorial/Basic" {
Properties {
_Color ("Main Color", Color) = (1,0.5,0.5,1)
}
SubShader {
Pass {
Material {
Diffuse [_Color]
}
Lighting On
}
}
}
This simple shader demonstrates one of the most basic shaders possible. It defines a color property called Main Color and assigns it a default value of rose-like color (red=100% green=50% blue=50% alpha=100%). It then renders the object by invoking a Pass and in that pass setting the diffuse material component to the property _Color and turning on the vertex lighting.
这个shader范例只是众多shader中最基本的一个,它定义了一个颜色性质,名称为Main Color,并指定了玫瑰色的效果(red=100% green=50% blue=50% alpha=100%),在调用时会跳过Diffuse的材质设定(_Color)并开启顶点光源
To test this shader, create a new material, select the shader from the drop-down menu (Tutorial->Basic) and assign the Material to some object. Tweak the color in the Material Inspector and watch the changes. Time to move onto more complex things!
要测试这个shader,你可以建立一个新的材质,并于Shader下拉菜单选择(Tutorial->Basic),再把这个新材质指定到物件上,拖拉材质检视器的颜色表并查看其变化。是时候研究更复杂的事情了!
Basic Vertex Lighting
If you open an existing complex shader, it can be a bit hard to get a good overview. To get you started, we will dissect the built-in VertexLit shader that ships with Unity. This shader uses fixed function pipeline to do standard per- vertex lighting.
假如你开启一个既有的复合shader,刚开始看可能会觉得有点难,在开始以前,我们将详细说明unity内建的VertexLit shader。这个shader使用fixed function pipeline产生标准的per-vertex照明。
[javascript] view plaincopy
Shader "VertexLit" {
Properties {
_Color ("Main Color", Color) = (1,1,1,0.5)
_SpecColor ("Spec Color", Color) = (1,1,1,1)
_Emission ("Emmisive Color", Color) = (0,0,0,0)
_Shininess ("Shininess", Range (0.01, 1)) = 0.7
_MainTex ("Base (RGB)", 2D) = "white" { }
}
SubShader {
Pass {
Material {
Diffuse [_Color]
Ambient [_Color]
Shininess [_Shininess]
Specular [_SpecColor]
Emission [_Emission]
}
Lighting On
SeperateSpecular On
SetTexture [_MainTex] {
constantColor [_Color]
Combine texture * primary DOUBLE, texture * constant
}
}
}
}
All shaders start with the keyword Shader followed by a string that represents the name of the shader. This is the name that is shown in the Inspector. All code for this shader must be put within the curly braces after it: { } (called a block).
所有的shaders都必须以Shader作为开始,接着是这个shader的名称(例如:VertexLit),这个名称将会显示于检视器(Inspector)。所有的语法都必须放在{ }之内。
The name should be short and descriptive. It does not have to match the .shader file name.
这个名称必须短且足以代表其功能,它并不会等于.shader的档案名称
To put shaders in submenus in Unity, use slashes - eg MyShaders/Test would be shown as Test in a submenu called MyShaders, or MyShaders->Test.
如果要把shaders放在unity的submenus下面,请使用斜线,例如:MyShaders/Test,你将会看到有个submenu名为MyShaders,下面有个shader名为Test,或是像这样MyShaders->Test
The shader is composed of a Properties block followed by SubShader blocks. Each of these is described in sections below.
在Properties block下面接着的是SubShader block,每个描述都在这个段落中
Properties
At the beginning of the shader block you can define any properties that artists can edit in the Material Inspector. In the VertexLit example the properties look like this:
properties位于shader block一开始的位置,你可以定义任何性质,这些性质将可在材质检视器中编辑,在VertexLit的个范例中,properties block看起来像这样:
图片一
The properties are listed on separate lines within the Properties block. Each property starts with the internal name (Color, MainTex). After this in parentheses comes the name shown in the inspector and the type of the property. After that, the default value for this property is listed:
properties block内的语法都是单行的,每一个性质描述都由内名称开始(例如:Color, MainTex),在后方的括弧号中所显示的名字也会显示于inspector检视器上,在此之后,描述的是该性质的预设值
图片二
The list of possible types are in the Properties Reference. The default value depends on the property type. In the example of a color, the default value should be a four component vector.
可用的性质类型请参考Properties Reference。预设值与性质有关,以color为例,预设值应该由四个值组成
We now have our properties defined, and are ready to start writing the actual shader.
现在我们已经定义了四个性质,可以开始撰写实际的shader了
The Shader Body
Before we move on, let's define the basic structure of a shader file.
在开始以前,先了解shader的结构是如何定义的
Different graphic hardware has different capabilities. For example, some graphics cards support fragment programs and others don't; some can lay down four textures per pass while the others can do only two or one; etc. To allow you to make full use of whatever hardware your user has, a shader can contain multiple SubShaders. When Unity renders a shader, it will go over all subshaders and use the first one that the hardware supports.
不同的绘图卡有不同的能力,例如:有的绘图卡支援fragment programs但有些没有,有些可以一次处理四个贴图?(four textures)其他的可能只能处理两个或一个,为了要符合所有用户的硬体需求,一个shader可以包涵多个SubShaders,当unity在运算shader时,它将详细察看所有的subshaders而且使用硬体可支持的第一个。
[javascript] view plaincopy
Shader "Structure Example" {
Properties { /* ...shader properties... }
SubShader {
// ...subshader that uses vertex/fragment programs...
}
SubShader {
// ...subshader that uses four textures per pass...
}
SubShader {
// ...subshader that uses two textures per pass...
}
SubShader {
// ...subshader that might look ugly but runs on anything : )
}
}
This system allows Unity to support all existing hardware and maximize the quality on each one. It does, however, result in some long shaders.
此系统提供unity可以支援现有所有的硬体并取得最佳的品质。它作到了,然而,结果是必须撰写很长的shaders语法
Inside each SubShader block you set the rendering state shared by all passes; and define rendering passes themselves. A complete list of available commands can be found in the SubShader Reference.
在每一个SubShader block,你可以设定彩现途径的状态;并定义彩现途径本身。完整的SubShader语法请参照SubShader Reference章节
Passes
Each subshader is a collection of passes. For each pass, the object geometry is rendered, so there must be at least one pass. Our VertexLit shader has just one pass:
每个subshader等于是一个途径集。要对几何物件进行彩现,至少一定要有一个途径,内定的VertexLit shader里面仅有一个途径:
[javascript] view plaincopy
// ...snip...
Pass {
Material {
Diffuse [_Color]
Ambient [_Color]
Shininess [_Shininess]
Specular [_SpecColor]
Emission [_Emission]
}
Lighting On
SeperateSpecular On
SetTexture [_MainTex] {
constantColor [_Color]
Combine texture * primary DOUBLE, texture * constant
}
}
// ...snip...
Any commands defined in a pass configures the graphics hardware to render the geometry in a specific way.
通过指令可以定义一个特殊的方法,用来驱动绘图硬体彩现指定的几何物件
In the example above we have a Material block that binds our property values to the fixed function lighting material settings. The command Lighting On turns on the standard vertex lighting, and SeperateSpecular On enables the use of a separate color for the specular highlight.
例如:上方语法中有一个Material block,定义了照明时所需要几项固定参数。而指令Lighting On用来开启该照明设备,而SeperateSpecular On则是启用Seperate作为特殊镜射效果
All of these command so far map very directly to the fixed function OpenGL/Direct3D hardware model. Consult OpenGL red book for more information on this.
到目前为止的所有命令,皆属于支援OpenGL/Direct3D技术硬体本身可使用的固定功能,您可以参考OpenGL红皮书,可以找到更多相关资料
The next command, SetTexture, is very important. These commands define the textures we want to use and how to mix, combine and apply them in our rendering. SetTexture command is followed by the property name of the texture we would like to use (_MainTex here) This is followed by a combiner block that defines how the texture is applied. The commands in the combiner block are executed for each pixel that is rendered on screen.
下一个命令是SetTexture,这是个非常重要的命令,这个命令可以定义影像纹理如何混合、组合以及如何运用于我们的彩现环境里,SetTexture通常跟随于纹理的属性名称之后(我们在这里使用_MainTex ),接下来的combiner block也是定义纹理的应用方式,这个combiner block的命令会在萤幕显示每一个被执行的动作
Within this block we set a constant color value, namely the Color of the Material, _Color. We'll use this constant color below.
在这个block内我们设定了一个颜色值,并命名为_Color,我们会在后面使用这个颜色
In the next command we specify how to mix the texture with the color values. We do this with the Combine command that specifies how to blend the texture with another one or with a color. Generally it looks like this:
在下个命令,我们指定如何混合纹理以及颜色值。我们用Combine命令来混合其他纹理或颜色,看起来像下面这样:
Combine ColorPart, AlphaPart
Here ColorPart and AlphaPart define blending of color (RGB) and alpha components respectively. If AlphaPart is omitted, then it uses the same blending as ColorPart.
在这里ColorPart与AlphaPart定义了混合的颜色(RGB)以及alpha值(A)个别的资料,假如AlphaPart被省略了,那它将与ColorPart的资料作混合
In our VertexLit example:
在我们的VertexLit范例中:
Combine texture * primary DOUBLE, texture * constant
Here texture is the color coming from the current texture (here _MainTex). It is multiplied (*) with the primary vertex color. Primary color is the vertex lighting color, calculated from the Material values above. Finally, the result is multiplied by two to increase lighting intensity (DOUBLE).
这里的texture来源是当前的纹理(_MainTex),它将与主要的颜色互相搭配(*),主色为照明设备的颜色,它是由Material计算出来的结果。最终是这两个倍增后的结果会增加照明强度
The alpha value (after the comma) is texture multiplied by constant value (set with constantColor above). Another often used combiner mode is called previous (not used in this shader). This is the result of any previous SetTexture step, and can be used to combine several textures and/or colors with each other.
aplha值(在逗号以后)是由constantColor倍增而得的结果。另一个常用的混合模式称为previous(在这个shader未使用),这是所有previous SetTexture的结果,并且可以用来混合多种纹理和颜色