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中点击Create选Material. Project中将出现一个名字为"New Material"的材质.(可以如shader那样重命名.) 通过单击来选中新材质,如果没选中的话. Inspector中将出现材质的细节.通过下面的操作将shader附加到材质上.
- Project中拖放shader到材质上或
- Project中选择材质,然后在Inspector中Shader下拉列表中选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并指定一个材质.
实际上,这其中包含有一堆事情.
补充阅读
编辑如果你想知道更多
- 关于通常的顶点和片段shader,你应该看看Template:GLSL Programming Unity SectionRef里的说明.
- 关于顶点变换,如
gl_ModelViewProjectionMatrix
,你应该看看Template:GLSL Programming Unity SectionRef. - 关于GLSL的向量(如
vec4
)和矩阵,你应该看看Template:GLSL Programming Unity SectionRef. - 关于如何应用顶点变换如
gl_ModelViewProjectionMatrix
,你应该看看Template:GLSL Programming Unity SectionRef. - 关于Unity的ShaderLab语言特定的shader,你应该看看Unity's ShaderLab reference.