fragment shader基本结构以#version声明开头,需匹配opengl上下文版本;输入变量(in)必须与顶点着色器输出变量名、类型一致;输出需用out vec4指定颜色缓冲区,如outcolor,并在main中赋值。

Fragment Shader 的基本结构和 GLSL 版本声明
OpenGL 要求每个片段着色器必须以 #version 开头,且版本号必须与 OpenGL 上下文兼容。常见错误是写成 #version 330 却在 OpenGL 2.1 环境下运行——这会直接导致编译失败,glGetShaderInfoLog 返回 “#version required and must be first” 或类似错误。
实际编写时需对齐上下文版本:
- OpenGL 3.3+(推荐)→ 用
#version 330 core,启用in/out语义,禁用gl_FragColor - OpenGL 2.1 → 只能用
#version 120,必须写gl_FragColor = vec4(1.0); - macOS OpenGL 4.1+ 默认不支持 compatibility profile,硬写
#version 410但没启 core profile 也会失败
别跳过这一步:先用 glGetString(GL_SHADING_LANGUAGE_VERSION) 确认驱动实际支持的 GLSL 版本,再定 #version。
输入变量怎么连到顶点着色器输出
片段着色器的 in 变量不是凭空来的,必须和顶点着色器的 out 变量名、类型、插值限定符完全一致,否则链接时静默丢弃或黑屏。常见坑是大小写不一致(如顶点里写 out vec3 vNormal,片元里写 in vec3 vnormal),或者漏掉 flat/smooth 导致插值行为不符合预期。
典型匹配写法(GLSL 330):
// 顶点着色器
out vec3 fragColor;
void main() {
fragColor = vec3(0.5, 0.0, 0.5);
}
// 片段着色器
in vec3 fragColor;
out vec4 outColor;
void main() {
outColor = vec4(fragColor, 1.0);
}
注意:out 变量名(如 outColor)是你要写入的颜色缓冲区,它不需要和顶点端任何变量对应;而 in 变量(如 fragColor)才是跨阶段传递的数据。
编译和链接时最容易卡住的三个地方
片段着色器单独编译成功 ≠ 能用。链接到程序对象时失败更隐蔽,日志往往只报“link failed”,得手动查原因。
-
glGetShaderiv(shader, GL_COMPILE_STATUS, &result)必须检查,不能只看是否非零——要读glGetShaderInfoLog才知道具体哪行错 - 忘记调用
glAttachShader(program, fragmentShader)就直接glLinkProgram→ 链接成功但渲染黑屏(因为没附着任何 shader) - 输出变量名不匹配:GLSL 330 要求
out vec4 outColor,但误写成out vec4 FragColor,链接时不报错,但 OpenGL 不认这个输出,结果是未定义颜色(常为黑色或随机内存值)
调试建议:先写最简片段着色器(只输出纯红色),确认管线通了,再逐步加功能。
纹理采样为什么返回全黑
片段着色器里调 texture(sampler2D, uv) 返回 (0,0,0,0),大概率不是 shader 写错了,而是绑定问题:
- 没调
glActiveTexture(GL_TEXTURE0)+glBindTexture(GL_TEXTURE_2D, texID),或绑定时机在glUseProgram之后 - uniform
sampler2D没正确设置:用glGetUniformLocation拿到 location 后,必须用glUniform1i(loc, 0)把纹理单元号传进去(不是纹理 ID) - UV 坐标超出 [0,1] 且纹理没设 wrap mode(默认是
GL_REPEAT,但若设成GL_CLAMP_TO_EDGE又传了负 UV,就采样边缘色)
验证方法:把 texture(...) 换成 vec4(uv.x, uv.y, 0.0, 1.0),看是否显示渐变——能显示说明采样逻辑通,问题在纹理绑定或参数。
真正麻烦的是跨平台差异:Windows NVIDIA 驱动有时容忍小错误(比如漏 out 变量),但 Intel 集显或 macOS 会直接拒编译。写的时候就得按最严标准来,别依赖“本地能跑”。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











