除了使用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);