(原文:https://en.wikibooks.org/wiki/Cg_Programming/Unity/Minimal_Shader)
This tutorial covers the basic steps to create a minimal Cg shader in Unity.
本节课包含了在Unity中创建一个最小的Cg着色器的基本步骤。
Starting Unity and Creating a New Project(打开Unity创建一个新工程)
After downloading and starting Unity, you might see an empty project. If not, you should create a new project by choosing File > New Project... from the menu. For this tutorial, you don't need to import any packages but some of the more advanced tutorials require the scripts and skyboxes packages.
下载并打开Unity之后,你可能会看到一个空工程。否则,你应该通过在菜单中选择 File > New Project... 来创建一个新的工程。在本节课里,你不需要导入任何package包,但是在一些更高级的课程中,可能会需要导入一些脚本和天空盒的package包。
If you are not familiar with Unity's Scene View, Hierarchy View, Project View and Inspector View, now would be a good time to read the first two (or three) sections (“Unity Basics” and “Building Scenes”) of the Unity User Guide.
如果你还不熟悉Unity中的Scene窗口、Hierarchy窗口、Project窗口或者Inspector窗口,现在就是一个阅读相关教程的好时机,Unity用户向导的前两(或前三)个部分(“Unity基础”和“创建场景”)。
Creating a Shader(创建一个着色器)
Creating a Cg shader is not complicated: In the Project View, click on Create and choose Shader. A new file named “NewShader” should appear in the Project View. Double-click it to open it (or right-click and choose Open). An editor with the default shader in Cg should appear. Delete all the text and copy & paste the following shader into this file:
创建一个Cg着色器并不复杂:在Project窗口中,点击Create,选择Shader。一个命名为“NewShader”的新文件就会出现在Project窗口中。双击打开它(或者邮件选择Open)。一个写好了默认着色器的编辑器会出现。删除其中所有的字符,复制下面的着色器代码粘贴到其中:
Shader "Cg basic shader" { // defines the name of the shader
SubShader { // Unity chooses the subshader that fits the GPU best
Pass { // some shaders require multiple passes
CGPROGRAM // here begins the part in Unity's Cg #pragma vertex vert
// this specifies the vert function as the vertex shader
#pragma fragment frag
// this specifies the frag function as the fragment shader float4 vert(float4 vertexPos : POSITION) : SV_POSITION
// vertex shader
{
return mul(UNITY_MATRIX_MVP, vertexPos);
// this line transforms the vertex input parameter
// vertexPos with the built-in matrix UNITY_MATRIX_MVP
// and returns it as a nameless vertex output parameter
} float4 frag(void) : COLOR // fragment shader
{
return float4(1.0, 0.0, 0.0, 1.0);
// this fragment shader returns a nameless fragment
// output parameter (with semantic COLOR) that is set to
// opaque red (red = 1, green = 0, blue = 0, alpha = 1)
} ENDCG // here ends the part in Cg
}
}
}
Save the shader (by clicking the save icon or choosing File > Save from the editor's menu).
保存这个Shader(点击保存图标或者选择编辑器的菜单中的File > Save)。
Congratulations, you have just created a shader in Unity. If you want, you can rename the shader file in the Project View by clicking the name, typing a new name, and pressing Return. (After renaming, reopen the shader in the editor to make sure that you are editing the correct file.)
祝贺你,你已经在Unity中创建好了一个Shader。如果你愿意,你可以重命名这个Shader文件,在Project窗口中点击文件名,输入新的文件名,回车。(改名以后,最好在编辑器中重新打开一下,确认你编辑的是正确的文件。)
Unfortunately, there isn't anything to see until the shader is attached to a material.
不幸的是,直到shader被附加到材质上之前,是看不到任何现象的。
Creating a Material and Attaching a Shader(创建材质并指定着色器)
To create a material, go back to Unity and create a new material by clicking Create in the Project Viewand choosing Material. A new material called “New Material” should appear in the Project View. (You can rename it just like the shader.) If it isn't selected, select it by clicking. Details about the material appear now in the Inspector View. In order to set the shader to this material, you can either
要创建一个材质,回到Unity中,通过在Project窗口中点击“Create”,并选择Material,来创建一个新的材质。一个名为“New Material”的新材质应该出现在了Project窗口中。(你可以向重命名shader一样来重命名材质)如果它没被选中,那么点击选中它。关于此材质的详细信息将会出现在Inspector窗口中。为了将shader设置到这个材质上,你可以
- drag & drop the shader in the Project View over the material or
拖拽shader到Project窗口中的这个材质上,或者
- select the material in the Project View and then in the Inspector View choose the shader (in this case “Cg basic shader” as specified in the shader code above) from the drop-down list labeledShader.
在Project窗口中选择这个材质,然后在Inspector窗口中的shader的下拉列表中选择这个shader。(在本例中,就选择名为“Cg basic shader”的shader,就在shader代码最上面一行中)
In either case, the Preview in the Inspector View of the material should now show a red sphere. If it doesn't and an error message is displayed at the bottom of the Unity window, you should reopen the shader and check in the editor whether the text is the same as given above.
如果做好了上面的操作,在Inspector窗口中的材质球的预览,应该显示为一个红球。如果不是这样,并且在Unity窗口的底部(控制台)显示了一条错误信息,那么你应该重新打开这个shader,在编辑器中检查一下其中的代码是否和上面所给的完全一致。
Interactively Editing Shaders(交互地编辑shader)
This would be a good time to play with the shader; in particular, you can easily change the computed fragment color. Try neon green by opening the shader and replacing the fragment shader in the frag
function with this code:
这是个赏玩这个shader代码的好机会;甚至,你可以容易地改变计算好的片段颜色(fragment color)。尝试一下荧光绿,打开这个shader代码,用下面的代码替换掉frag方法中的片段着色器(fragment shader):
float4 frag(void) : COLOR // fragment shader
{
return float4(0.6, 1.0, 0.0, 1.0); // (red = 0.6, green = 1.0, blue = 0.0, alpha = 1.0)
}
You have to save the code in the editor and activate the Unity window again to apply the new shader. If you select the material in the Project View, the sphere in the Inspector View should now be green. You could also try to modify the red, green, and blue components to find the warmest orange or the darkest blue. (Actually, there is a movie about finding the warmest orange and another about dark blue that is almost black.)
你得在编辑器中保存这段代码,然后返回到Unity窗口中使新的shader产生作用。如果你在Project窗口中选择了这个材质,在Inspector窗口中的材质球预览就能够看到变绿了。你也可以通过修改红、绿、蓝的三个值来找到最暖的橙色,或者最深的蓝色。(还真的有一部电影是关于寻找最暖的橙色的,还有另一部关于深蓝色的电影,几乎是黑色的了)(作者真能扯)
You could also play with the vertex shader in the function vert
, e.g. try this vertex shader:
你也可以在vert方法中,把玩一下顶点着色器(vertex shader),比如尝试一下这个顶点着色器:
float4 vert(float4 vertexPos : POSITION) : SV_POSITION // vertex shader
{
return mul(UNITY_MATRIX_MVP, float4(1.0, 0.1, 1.0, 1.0) * vertexPos);
}
This flattens any input geometry by multiplying the coordinate with . (This is a component-wise vector product; for more information on vectors and matrices in Cg see the discussion in Section “Vector and Matrix Operations”.)
这段代码通过将y坐标乘以0.1,将任何输入的几何体压扁。(这是向量的一个经典用法;如果想了解Cg中的向量和矩阵的更多信息,请阅读 “Vector and Matrix Operations向量和矩阵操作”中的讨论部分)
In case the shader does not compile, Unity displays an error message at the bottom of the Unity window and displays the material as bright magenta. In order to see all error messages and warnings, you should select the shader in the Project View and read the messages in the Inspector View, which also include line numbers, which you can display in the text editor by choosing View > Line Numbers in the text editor menu. You could also open the Console View by choosing Window > Console from the menu, but this will not display all error messages and therefore the crucial error is often not reported.
如果这个shader没编译过去,Unity窗口底部显示了一条错误信息,并且材质球显示为高亮的紫红色。为了看到所有的错误信息和警告,你应该在Project窗口中选择这个shader,然后在Inspector窗口中阅读所看到的信息,包含了行号,你可以在文本编辑器菜单中选择View > Line Numbers,把行号显示出来。(在MonoDevelop中没找着,但已经默认显示行号了,可以忽略这句)你也可以在Unity菜单中选择Window > Console 来打开控制台窗口,但是这可能不会显示出所有的错误信息,因为有些严重的错误经常不在这里报出来。
Attaching a Material to a Game Object(把材质赋给游戏物体)
We still have one important step to go: attaching the new material to a triangle mesh. To this end, create a sphere (which is one of the predefined game objects of Unity) by choosing GameObject > Create Other > Sphere from the menu. A sphere should appear in the Scene View and the label “Sphere” should appear in the Hierarchy View. (If it doesn't appear in the Scene View, click it in the Hierarchy View, move (without clicking) the mouse over the Scene View and press “f”. The sphere should now appear centered in the Scene View.)
我们仍然有很重要的一步要做:把这个材质赋给一个三角形网格(p.s:Unity中已经全部自动转为三角形了,说的就是Unity中普通的mesh)。为此,创建一个球体(这是Unity中的一些预定义好的物体之一),在菜单中选择 GameObject > Create Other > Sphere。一个球体应该出现在Scene窗口,同时名为 “Sphere”的标签应该出现在Hierarchy窗口。(如果在Scene窗口中没看到球体,那么在Hierarchy窗口中单击一下“Sphere”标签,然后把鼠标移动到Scene窗口中(不要点击),按 “f”键。这时球体就应该出现在Scene窗口的正中间了。)
To attach the material to the new sphere, you can:
要把材质赋给这个新建的球体,你可以:
- drag & drop the material from the Project View over the sphere in the Hierarchy View or
将材质从Project窗口中拖拽到Hierarchy窗口中的球体上,或者
- drag & drop the material from the Project View over the sphere in the Scene View or
将材质从Project窗口中拖拽到Scene窗口中的球体上,或者
- select the sphere in the Hierarchy View, locate the Mesh Renderer component in the Inspector View(and open it by clicking the title if it isn't open), open the Materials setting of the Mesh Renderer by clicking it. Change the “Default-Diffuse” material to the new material by clicking the dotted circle icon to the right of the material name and choosing the new material from the pop-up window.
在Hierarchy窗口中选择球体,在Inspector窗口中找到Mesh Renderer组件(如果该组件没展开,就点击组件名字让它展开),将“Default-Diffuse”默认材质修改为新的材质,单击打开Mesh Renderer中的Materials设置。点击材质 名称右侧的小原点图标,然后在弹出的窗口中选择想要指定的材质。
In any case, the sphere in the Scene View should now have the same color as the preview in the Inspector View of the material. Changing the shader should (after saving and switching to Unity) change the appearance of the sphere in the Scene View.
无论如何,此时Scene窗口中的球体应该已经与Inspector窗口中的材质球预览显示为相同的颜色了。再修改shader代码的话(保存并切换回Unity窗口之后),就应该是立刻改变了Scene窗口中的球体的表现。
Saving Your Work in a Scene(在场景中保存你的工作)
There is one more thing: you should save you work in a “scene” (which often corresponds to a game level). Choose File > Save Scene (or File > Save Scene As...) and choose a file name in the “Assets” directory of your project. The scene file should then appear in the Project View and will be available the next time you open the project.
还有一件事:你应该把你的工作保存到“场景”中(经常被说成是game level;p.s:此处翻译为游戏关卡比较合适)。选择File > Save Scene(或者 File > Save Scene As...)并在你的工程中的“Assets”目录中起个文件名。然后,这个场景文件应该出现在了Project窗口中,在你下一次打开工程的时候有可能被用到。
One More Note about Terminology(对于术语的一个说明)
It might be good to clarify the terminology. In some APIs, a “shader” is either a vertex shader or a fragment shader. The combination of both is called a “program”. In other APIs, it's just the other way around: a “program” is either a vertex program or a fragment program, and the combination of both is a “shader”. Unfortunately, Unity's documentation mixes both conventions. To keep things simple, we try to avoid the term “program” here and use the term “shader” to denote the combination of a vertex shader and a fragment shader.
可能有必要把几个术语明确一下。在有些API中,“shader”(着色器)既不是vertex shader(顶点着色器),也不是fragment shader(片段着色器)。两者合起来称为一个“program”(程序)。而另一些API中,对于“program”(程序)是另一种理解,既不是vertex program(顶点程序),也不是fragment program(片段程序),两者合起来称为 “shader”(着色器)。不幸的是,Unity的文档中同时混有以上两种规则。为了简明,我们在这里尝试避免 “program”这个叫法,只使用“shader”来表示一个vertex shader和一个fragment shader的合称。
Summary(摘要)
Congratulations, you have reached the end of this tutorial. A few of the things you have seen are:
恭喜你,你已经读到了本节课的末尾。你已经学到的几个知识点是:
- How to create a shader.
怎样创建一个shader。
- How to define a Cg vertex and fragment shader in Unity.
在Unity中如何定义一个Cg的顶点和片段shader。
- How to create a material and attach a shader to the material.
怎样创建一个材质,并把一个shader赋给这个材质。
- How to manipulate the fragment ouput parameter with the semantic
COLOR
in the fragment shader.在fragment shader中如何使用COLOR语义操作片段的输出参数。
- How to transform the vertex input parameter with the semantic
POSITION
in the vertex shader.在vertex shader中如何通过POSITION语义变换顶点输入参数。
- How to create a game object and attach a material to it.
怎样创建一个游戏物体并给它赋上一个材质。
Actually, this was quite a lot of stuff.
其实已经学了很多东西了。
Further Reading(延伸阅读)
If you still want to know more
如果你想了解更多
- about vertex and fragment shaders in general, you should read the description in Section “Programmable Graphics Pipeline”.
关于综合了解顶点和片段着色器,你应该阅读“可编程图形管线”部分的描述。
- about the vertex transformations such as
UNITY_MATRIX_MVP
, which contains a product of the model-view matrix and the projection matrix, you should read Section “Vertex Transformations”.关于顶点变化,比如UNITY_MATRIX_MVP,包含了一个模型视图矩阵和投影矩阵的结果(p.s:这句话没翻译通顺),你应该阅读“顶点变化”部分。
- about handling vectors (e.g. the
float4
type) and matrices in Cg, you should read Section “Vector and Matrix Operations”.关于在Cg中处理向量(例如float4类型)和矩阵,你应该阅读 “向量和矩阵操作”部分。
- about how to apply vertex transformations such as
UNITY_MATRIX_MVP
, you should read Section “Applying Matrix Transformations”.关于如何应用顶点变化,比如UNITY_MATRIX_MVP,你应该阅读“应用矩阵变化”部分。
- about Unity's ShaderLab language for specifying shaders, you should read Unity's ShaderLab reference.
关于Unity的ShaderLab语言中的具体shader,你应该阅读Unity的ShaderLab的参考文献。