Version: 2021.3
使用采样器状态
着色器示例

Unity 中的 GLSL

除了编写 HLSL 着色器程序,还可以在 Unity 中编写原始 OpenGL 着色语言 (GLSL) 着色器程序。

注意:在常规工作流程中,不建议或不需要这样做;Unity 会在需要时将您的 HLSL 交叉编译为优化的 GLSL。仅建议将原始 GLSL 用于测试或支持使用 GLSL 的平台上的项目。

GLSL 代码片段

GLSLPROGRAMENDGLSL 关键字之间编写 GLSL 程序代码片段。

在 GLSL 中,所有着色器函数入口点都必须名为 main()。Unity 加载 GLSL 着色器时,会为顶点程序加载一次源代码(使用 VERTEX 预处理器定义),然后为片元程序再加载一次(使用 FRAGMENT 预处理器定义)。所以,在 GLSL 代码片段中将顶点程序和片元程序部分分开的方法是在它们周围加上 #ifdef VERTEX ..#endif 和 #ifdef FRAGMENT ..#endif`。每个 GLSL 代码片段必须同时包含顶点程序和片元程序。

标准 include 文件与 Cg/HLSL 着色器的 include 文件匹配;只是它们的扩展名为 .glslinc

UnityCG.glslinc

顶点着色器输入来自预定义的 GLSL 变量(gl_Vertexgl_MultiTexCoord0 等等)或者是用户定义的属性。通常,只有切线矢量才需要用户定义的属性:

attribute vec4 Tangent;

从顶点程序到片元程序的数据是通过 varying 变量传递的,例如:

varying vec3 lightDir; // 顶点着色器负责计算,由片元着色器使用

外部 OES 纹理

Unity 在着色器编译期间会进行某些预处理;例如,根据图形 API(GlES3 或 GLCore),texture2D/texture2DProj 函数可能会替换为 texture/textureProj。一些扩展不支持新约定,最明显的就是 GL_OES_EGL_image_external

如果希望在 GLSL 着色器中采样外部纹理,请使用 textureExternal/textureProjExternal 调用,而不是 texture2D/texture2DProj

示例:

gl_FragData[0] = textureExternal(_MainTex, uv);
使用采样器状态
着色器示例