除了使用Cg/HSL 着色器程序以外, OpenGL 着色器语言(GLSL)着色器可以直接书写shader。
然而,使用原生的GLSL只推荐作为测试使用,或者你清晰的知道你的目标平台是 Mac OS X,OpenGL ES移动设备,或者是Linux。在所有常见情况下,Unity会将 Cg/HLSL语言编译为优化过的GLSL语言。
GLSL 片段
GLSL程序片段写在GLSLPROGRAM和ENDGLSL关键字之间。
在GLSL中,所有着色器功能入口被叫做main()。当unity加载GLSL着色器,它会为顶点程序加载一次 标记了VERTEX 预处理指令的资源,对片段程序再加载一次标记了FRAGMENT预处理指令的资源。所以在GLSL片段中分离 顶点和片段程序的方式是用 #ifdef VERTEX……#endif 和#ifdef FRAGMENT …… #endif来分别包含vertex程序和fragment程序。
标准包含文件已经向Cg/HLSL着色器提供了这些指令,它们知识有一个 .glslinc 扩展
UnityCG.glslinc
顶点着色器的输入从预定义的GLSL变量中获取(gl_Vertex,gl_MultiTexCoord0,……)或者使用用户定义的特性。通常只有切线向量需要用户自定义:
attribute vec4 Tangent;
顶点程序传到片段程序的数据是通过 varying 变量传输的,比如:
varying vec3 lightDir; // vertex shader computes this, fragment shader uses this External OES textures
外部的OES 贴图
Unity在shader编译时做了一些预处理;比如,基于图形API(GLES3,GLCore)时,texture2D/texture2DProj 函数可能被texture/textureProj取代。有一些扩展不支持新的转换,特别注意这里面的: GL_OES_EGL_image_external
如果你想要在GLSL着色器中采样 外部的贴图,使用 textureExternal/textureProjExternal 来取代texture2D/texture2DProj,例子:
gl_FragData[0] = textureExternal(_MainTex, uv);