GLSL Programming/Unity/Minimal Shader

本教程包含了在Unity中建立一个最小GLSLshader的基本步骤.

开始Unity并建立一个工程

编辑

下载完并打开Unity(Windows用户需要使用命名行-force-opengl),将见到一个新项目.如果没有,通过菜单File > New Project...来建新项目.本教程不需导入任何包但一些高级教程需要导入scripts和sky boxes包.在Windows建完项目后,Unity可能没有启用OpenGL支持;因此,Windows用户应该退出并用命令行参数-force-opengl重启Unity.之后从菜单File > Open Project...打开项目.

如果不熟悉Unity的Scene,Hierarchy,Project和Inspector窗口,最好花点时间来阅读下Unity的用户指南(“Unity Basics” 和 “Building Scenes”)开始的章节.

创建一个 Shader

编辑

建立GLSL shader很简单,Project View中点击Create,选Shader.Project中将出现名为"NewShader"的文件.双击来打开(或右键选Open).将出现一个编辑器,里面有默认的Cg代码.删除全部的文本,将下面的shader粘贴过来.

Shader "GLSL basic shader" { // 定义shader的名字
   SubShader { // Unity 选择最符合GPU的SubShader
      Pass { // 有些shader需要多个pass
         GLSLPROGRAM // 这里开始 Unity的 GLSL部分

         #ifdef VERTEX // 这里开始顶点 shader

         void main() // 所有的顶点shader定义一个 main() 方法
         {
            gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
               // 此行将预定义的类型为vec4,gl_Vertex属性,
               //用mat4的gl_ModelViewProjectionMatrix进行变换.
               //将结果存放在预定义vec4类型的输出变量gl_Position
         }

         #endif // 这里结束顶点shader的定义


         #ifdef FRAGMENT // 这里开始片段shader

         void main() // 所有的片段shader定义一个 main() 方法
         {
            gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); 
               //此片段shader仅仅设置输出颜色为不透明红色(红=1.0,绿=1.0,蓝=0.0,透明=1.0)
         }

         #endif // 这里结束片段shader定义

         ENDGLSL // 这里结束GLSL部分
      }
   }
}

保存shader(单击保存图标或菜单选File > Save).

恭喜,你已经在Unity中建立了一个shader.你还可以在Project中重命名shader文件.(重命名完毕,重开编辑器中的shader确保你编辑的是正确的文件).

不幸的话,现在还什么都看不到,除非将shader附加到材质上.

建立材质并附加shader

编辑

为了建立材质,返回Unity,在Project中点击CreateMaterial. Project中将出现一个名字为"New Material"的材质.(可以如shader那样重命名.) 通过单击来选中新材质,如果没选中的话. Inspector中将出现材质的细节.通过下面的操作将shader附加到材质上.

  • Project中拖放shader到材质上或
  • Project中选择材质,然后在InspectorShader下拉列表中选shader(本教程shader的名字为"GLSL basic shader").

不论如何操作,材质Inspector中Preview应该显示红色的球体. 如果没显示并且Unity窗口底部显示了一个错误信息,你应该打开shader编辑器,查看shader代码跟上面给出的是否一致. Windows用户应该用命令行-force-opengl来重开Unity,以开启OpenGL的支持.

交互编辑 Shaders

编辑

这是一个玩shader的好机会;尤其是,可以容易的改变片段的颜色.尝试下柠檬绿,打开shader将片段shader的代码替换为:

         #ifdef FRAGMENT 

         void main()
         {
            gl_FragColor = vec4(0.6, 1.0, 0.0, 1.0); 
               // red = 0.6, green = 1.0, blue = 0.0, alpha = 1.0
         }

         #endif

保存shader并切回Unity来生效新shader. 如果在Project中选中了材质,Inspector中现在应该是绿色了. 你也可以尝试修改红,绿蓝元素来找寻最暖的橙色或最黑的蓝色. (实际这里movie有一个关于找到最暖橙色和another几乎全黑的黑蓝色的视频)

你也可以尝试玩下顶点shader,如尝试下这个顶点shader:

         #ifdef VERTEX
 
         void main() 
         {
            gl_Position = gl_ModelViewProjectionMatrix 
            * (vec4(1.0, 0.1, 1.0, 1.0) * gl_Vertex);
         }
 
         #endif

这里通过将 乘以 ,来压扁所有的几何体.这是分量级向量乘积; 关于GLSL更多的向量和矩阵,可以看Template:GLSL Programming Unity SectionRef.)

如果shader没有编译,Unity窗体底部显示了一个错误信息并且材质变为亮粉色. 为了看到全部的错误和警告,应该在Project选中shader,从Inspector中查看信息,这里也含有行号,通过文本编辑器菜单View > Line Numbers来显示行号.

可以从Window > Console打开Console,但这里不会显示全部的错误信息并且经常不报告重要的错误.

附加材质到GameObject

编辑

我们还需要一个重要的步骤:附加新的材质到三角网格.为此,点击菜单GameObject > Create Other > Sphere来创建一个球体(是Unity预建的游戏物体). Scene中应该出现了一个球体并且Hierarchy中出现名为"Sphere"的条目(如果Scene中没出现,在Hierarchy中单击球体条目,移动(不要点击)鼠标到Scene然后按"f". 球体现在应该出现在Scene中心了.

将材质赋予球体,可以通过:

  • Project中拖放材质到Hierarchy的球体上 或
  • Project中拖放材质到Scene的球体上 或
  • Hierarchy中选择球体,定位到Inspector中的Mesh Renderer组件(点击小三角展开如果没展开),点击展开MeshRenderer的Materials设置.点击右侧点圆形图标,从下拉列表中将"Default-Diffuse"材质改变为新的材质.

无论如何,Scene中的球体的颜色应该与Inspector中材质预览的颜色一致了.改变shader(保持并切回Unity)应该改正Scene中球体的外观.

将工作成果保存到场景

编辑

这里还有一件事:你应该将你完成的工作保存到"场景"(场景通常代表的是一个关卡).选择File > Save Scene(或File > Save Scene As ...)并在项目的"Assets"目录中选一个文件名. 之后,场景文件应该出现在Project中,下次打开项目时将可用.

还有一个术语注意事项

编辑

澄清下术语可能比较好.在GLSL中,"shader"要么是顶点shader要么是片段shader.二者组合被叫做"program".

不同的书,Unity将这种程序称为"shader",在Unity中顶点shader叫做"vertex program",片段shader被叫做"fragment program".

为了解除混乱,我决定使用Unity的"shader"来称呼GLSL program,如顶点和片段shader的组合.但是我将使用GLSL的术语,"顶点"shader和"片段"shader来代替"vertex program"和"fragment program".

总结

编辑

恭喜,你已读完本教程.你已经看到的几件事情是:

  • 如何创建一个shader.
  • 在Unity如何定义一个GLSL的顶点和片段shader.
  • 如何创建一个材质并制定shader.
  • 在片段shader中如何操作输出的颜色gl_FragColor.
  • 在顶点shader中如何变换输入属性gl_Vertex.
  • 如何创建一个gameObject并指定一个材质.

实际上,这其中包含有一堆事情.

补充阅读

编辑

如果你想知道更多

Template:GLSL Programming BottomNav