第2.2章:GLSL基础语法
GLSL(OpenGL Shading Language)是专为图形计算设计的着色器语言,它包含针对向量和矩阵操作的特性,使渲染管线具有可编程性。本章将详细介绍在Cocos Creator Shader开发中常用的GLSL语法知识。
🎯 学习目标
通过本章学习,你将掌握:
- GLSL变量类型和数据结构
- 控制流程语句的使用
- 函数定义和调用方法
- 存储限定符的作用和用法
- 精度限定符的设置和优化
- 预处理宏定义的高级技巧
📊 变量和数据类型
基本数据类型
GLSL支持多种数据类型,每种都有其特定的用途和默认值:
变量类型 | 说明 | 默认值 | Cocos Shader可选项 |
---|
bool | 布尔型标志 | false | ✓ |
int/ivec2/ivec3/ivec4 | 整型向量(1-4维) | 0/[0,0]/[0,0,0]/[0,0,0,0] | ✓ |
float/vec2/vec3/vec4 | 浮点型向量(1-4维) | 0.0/[0,0]/[0,0,0]/[0,0,0,0] | ✓ |
sampler2D | 2D纹理采样器 | default | black, grey, white, normal, default |
samplerCube | 立方体纹理采样器 | default-cube | black-cube, white-cube, default-cube |
mat2/mat3/mat4 | 矩阵(2x2/3x3/4x4) | 单位矩阵 | ✓ |
标量操作
标量的构造和操作与C语言类似:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| float timeValue = 1.0; float speed = 2.5;
int count = 10; int maxItems = 100;
bool isVisible = true; bool hasTexture = false;
float result = timeValue * speed + 1.0; bool condition = count < maxItems;
|
向量操作详解
向量是GLSL中最重要的数据类型,支持多种构造和访问方式。
向量构造
1 2 3 4 5 6 7 8 9 10 11 12
| vec4 color1 = vec4(1.0); vec3 position = vec3(0.5);
vec4 color2 = vec4(1.0, 0.5, 0.2, 1.0); vec3 velocity = vec3(1.0, -2.0, 0.0);
vec2 uv = vec2(0.5, 0.8); vec4 color3 = vec4(color2.rgb, 0.5); vec4 transform = vec4(uv, 0.0, 1.0);
|
向量分量访问
GLSL提供多种向量分量访问方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| vec4 color = vec4(1.0, 0.5, 0.2, 1.0);
float red = color.r; float alpha = color.a;
float x = color.x; float w = color.w;
vec3 rgb = color.rgb; vec3 bgr = color.bgr; vec2 rg = color.rg; vec4 rgba = color.rgba;
vec3 rrr = color.rrr; vec2 xy = color.xy;
color.rgb = vec3(0.8, 0.6, 0.4); color.xy = vec2(0.0, 1.0);
|
矩阵操作详解
矩阵在3D变换中至关重要,GLSL提供完整的矩阵支持:
矩阵构造
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| mat4 identity = mat4(1.0);
mat3 transform = mat3( 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 );
vec3 col1 = vec3(1.0, 0.0, 0.0); vec3 col2 = vec3(0.0, 1.0, 0.0); vec3 col3 = vec3(0.0, 0.0, 1.0); mat3 matrix = mat3(col1, col2, col3);
|
矩阵访问和操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| mat4 transform = mat4(1.0);
vec4 firstColumn = transform[0]; vec4 secondColumn = transform[1];
float element = transform[0][0]; transform[1][1] = 2.0;
mat4 modelMatrix = mat4(1.0); mat4 viewMatrix = mat4(1.0); mat4 mvpMatrix = projectionMatrix * viewMatrix * modelMatrix;
vec4 position = vec4(1.0, 2.0, 3.0, 1.0); vec4 transformedPos = mvpMatrix * position;
|
⚠️ 重要提醒:为避免内存对齐问题,引擎要求使用Uniform限定符的矩阵必须是4阶矩阵(mat4),2阶和3阶矩阵不能作为Uniform变量使用。
结构体定义
结构体允许组合不同类型的数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| struct Material { vec3 diffuse; vec3 specular; float shininess; sampler2D diffuseMap; };
struct Light { vec3 position; vec3 color; float intensity; float range; };
Material material = Material( vec3(0.8, 0.6, 0.4), vec3(1.0, 1.0, 1.0), 32.0, mainTexture );
vec3 materialColor = material.diffuse; float gloss = material.shininess;
|
数组操作
GLSL的数组使用有特定规则:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| float weights[4]; vec3 positions[8]; mat4 boneMatrices[64];
for(int i = 0; i < 4; i++) { weights[i] = 0.25; }
const int MAX_LIGHTS = 8; Light lights[MAX_LIGHTS];
for(int i = 0; i < MAX_LIGHTS; i++) { if(lights[i].intensity > 0.0) { } }
|
🔄 控制流程语句
条件语句
GLSL支持标准的条件控制结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| float lightIntensity = 0.8; vec3 finalColor;
if(lightIntensity > 0.5) { finalColor = vec3(1.0, 1.0, 0.0); } else if(lightIntensity > 0.2) { finalColor = vec3(0.5, 0.5, 0.0); } else { finalColor = vec3(0.0, 0.0, 0.0); }
vec3 resultColor = (lightIntensity > 0.5) ? vec3(1.0) : vec3(0.0);
float threshold = step(0.5, lightIntensity); vec3 optimizedColor = mix(vec3(0.0), vec3(1.0), threshold);
|
循环语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| vec3 accumColor = vec3(0.0); for(int i = 0; i < 4; i++) { accumColor += texture(inputTexture, uv + offset[i]).rgb; } accumColor /= 4.0;
int counter = 0; float value = 1.0; while(value > 0.01 && counter < 10) { value *= 0.5; counter++; }
int iteration = 0; do { iteration++; } while(iteration < maxIterations);
|
⚠️ 性能提示:在片元着色器中避免使用过多循环,特别是嵌套循环,这会严重影响GPU性能。
分支控制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| for(int i = 0; i < MAX_SAMPLES; i++) { vec4 sample = texture(inputTexture, sampleUV[i]); if(sample.a < 0.01) { break; } }
vec3 totalColor = vec3(0.0); int validSamples = 0; for(int i = 0; i < SAMPLE_COUNT; i++) { vec4 sample = texture(inputTexture, sampleUV[i]); if(sample.a < 0.1) { continue; } totalColor += sample.rgb; validSamples++; }
vec4 frag() { vec4 texColor = texture(mainTexture, v_uv); if(texColor.a < alphaThreshold) { discard; } return texColor; }
|
🎭 函数定义与调用
函数定义语法