
关于
为 Web 和游戏引擎编写高效 GLSL 着色器(顶点/片段)的专家指南,涵盖语法、Uniforms 和常见效果。
name: shader-programming-glsl description: "编写高效 GLSL 着色器(顶点/片段)的专家指南,适用于 Web 和游戏引擎,涵盖语法、uniform 变量和常见效果。" risk: safe source: community date_added: "2026-02-27"
Shader 编程 GLSL
概述
使用 GLSL(OpenGL Shading Language)编写 GPU 着色器的综合指南。学习语法、uniform 变量、varying 变量以及关键数学概念,如 swizzling 和向量运算,用于视觉效果开发。
何时使用此技能
- 在 WebGL、Three.js 或游戏引擎中创建自定义视觉效果时使用。
- 优化图形渲染性能时使用。
- 实现后处理效果(模糊、泛光、色彩校正)时使用。
- 在 GPU 上程序化生成纹理或几何体时使用。
分步指南
1. 结构:顶点着色器 vs. 片段着色器
理解渲染管线:
- 顶点着色器:将 3D 坐标转换为 2D 屏幕空间(
gl_Position)。 - 片段着色器:为单个像素着色(
gl_FragColor)。
// Vertex Shader (basic)
attribute vec3 position;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
void main() {
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
// Fragment Shader (basic)
uniform vec3 color;
void main() {
gl_FragColor = vec4(color, 1.0);
}
2. Uniform 和 Varying 变量
uniform:对所有顶点/片段恒定的数据(从 CPU 传入)。varying:从顶点着色器插值传递到片段着色器的数据。
// Passing UV coordinates
varying vec2 vUv;
// In Vertex Shader
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
// In Fragment Shader
void main() {
// Gradient based on UV
gl_FragColor = vec4(vUv.x, vUv.y, 1.0, 1.0);
}
3. Swizzling 与向量数学
自由访问向量分量:vec4 color = vec4(1.0, 0.5, 0.0, 1.0);
color.rgb->vec3(1.0, 0.5, 0.0)color.zyx->vec3(0.0, 0.5, 1.0)(重新排序)
示例
示例 1:简单光线步进(SDF 球体)
float sdSphere(vec3 p, float s) {
return length(p) - s;
}
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
vec2 uv = (fragCoord - 0.5 * iResolution.xy) / iResolution.y;
vec3 ro = vec3(0.0, 0.0, -3.0); // Ray Origin
vec3 rd = normalize(vec3(uv, 1.0)); // Ray Direction
float t = 0.0;
for(int i = 0; i < 64; i++) {
vec3 p = ro + rd * t;
float d = sdSphere(p, 1.0); // Sphere radius 1.0
if(d < 0.001) break;
t += d;
}
vec3 col = vec3(0.0);
if(t < 10.0) {
vec3 p = ro + rd * t;
vec3 normal = normalize(p);
col = normal * 0.5 + 0.5; // Color by normal
}
fragColor = vec4(col, 1.0);
}
最佳实践
- 推荐:使用
mix()进行线性插值,而非手动计算。 - 推荐:使用
step()和smoothstep()进行阈值处理和柔和边缘(避免if分支)。 - 推荐:将数据打包到向量(
vec4)中以减少内存访问。 - 避免:尽量不要在循环内使用大量分支(
if-else),这会影响 GPU 并行性能。 - 避免:不要在着色器内计算常量值;在 CPU 端预计算后通过 uniform 传入。
故障排除
问题: 着色器编译成功但屏幕全黑。
解决方案: 检查 gl_Position.w 是否正确(通常为 1.0)。检查 uniform 是否确实从宿主应用程序中设置。验证 UV 坐标是否在 [0, 1] 范围内。
限制
- 仅在任务明确匹配上述描述范围时使用此技能。
- 不要将输出视为特定环境验证、测试或专家审查的替代品。
- 如果缺少必要的输入、权限、安全边界或成功标准,请停下来寻求澄清。
兼容工具
Claude CodeCursor
标签
AI与机器学习