概述
GLSL 全称 OpenGL Shading Language,是用来在 OpenGL 中着色编程的语言,即开发人员写的自定义程序代码。是执行在 GPU上的,代替了固定的渲染管线的一部分,使渲染管线中不同层次具有可编程性。
GLSL 其使用 C 语言作为基础高阶着色语言,避免了使用汇编语言或硬件规格语言的复杂性。
GLSL 的变量命名方式与 C 语言类似,可使用字母,数字以及下划线,不能以数字开头。还需要注意的是,变量名不能以 gl_ 作为前缀,这个是 GLSL 保留的前缀,用于 GLSL 的内部变量。
基本数据类型
类型 | 描述 |
---|---|
void | 表示空类型,作为函数的返回类型,便是这个函数不返回值 |
bool | 布尔类型 |
int | 有符号整形 |
uint | 无符号整形 |
float | 浮点型 |
bool bDone = false;
int iValue = 42;
uint uiValue = 32u;
float fValue = 3.14159f;
向量/分量类型 | 描述 |
---|---|
vec2,vec3,vec4 | 2/3/4分量浮点向量 |
ivec2,ivec3,ivec4 | 2/3/4分量整形向量 |
uvec2,uvec3,uvec4 | 2/3/4无符号整型向量 |
bvec2,bvec3,bvec4 | 2/3/4布尔型向量 |
向量的使用
//1.声明4分量的float向量
vec4 v1;
//2.声明4分量并构成它
vec4 v2 = vec4(1,2,3,4); vec4 v3 = vec4(0,0,0,0);
//3.向量运算
//向量相加
v1 = v2 + v3;
vec4 v4 = v1;
v1 += vec4(10,10,10,10);
v1 *= 5;
//获取向量的元素,可以通过x,y,z,w来获取向量中的元素;
v1.x = 3.0f;
v1.y = 4.0f;
v1.z = 5.0f;
v1.w = 1.0f;
v1.xy = vec2(1,2);
v1.xyz = vec3(1,2,3);
//获取向量的元素,可以通过r,g,b,a 来获取向量中元素.
v2.r = 1.0f;
v2 = vec4(1.0f,1.0f,1.0f,1.0f);
//获取向量元素,可以s,t,p,q 来获取纹理坐标控制
v1.st = vec2(1.0,2.0);
v1.st = v2.st;
//不可以如下:xt不允许混合
v1.st = v2.xt;
向量数据累形还可以swizzle(调换)操作
//将颜色数据RGB顺序化BGR顺序
v1.bgra = v2.rgba;
//向量的一次性所有分量操作
v1.x = v2.x + 5.0f;
v1.xyz = v2.xyz + vec3(5.0f,4.0f,1.0f);
变量存储限定符
类型 | 描述 |
---|---|
只是普通的本地变量,外部不见,外部不可访问 | |
const | ⼀个编译常量,或者说是一个对函数来说为只读的参数 |
in/varying | 从以前阶段传递过来的变量 |
in/varying centroid | ⼀个从以前的阶段传递过来的变量,使用质⼼插值 |
out/attribute | 传递到下一个处理阶段或者在一个函数中指定一个返回值 |
out/attribute centroid | 传递到下一个处理阶段,质⼼插值 |
uniform | ⼀个从客户端代码传递过来的变量,在顶点之间不做改变 |
矩阵
矩阵只支持float类型
类型 | 描述 |
---|---|
mat2,mat2*2 | 两行两列 |
mat3,mat3*3 | 三行三列 |
mat4,mat4*4 | 四行四列 |
matx*j | j行x列 |
mat4 m1;
vec4 v2;
vec4 vOutPos ;
//矩阵可以与向量相乘,应用顶点模型/投影矩阵变化时
m1 = mat4(
1.0,1.0,1.0,1.0,
1.0,1.0,1.0,1.0,
1.0,1.0,1.0,1.0,
1.0,1.0,1.0,1.0,
)
vOutPos = v2 * m1;
m1 = mat4(1.0f);
结构体
结构体使用与C类似字段为struct
struct forStruct{
vec4 color;
float start;
float end;
}fogVar;
//初始化
fogVar = fogStruct(vec4(1.0,0.0,0.0,1.0),0.5,2.0);
//赋值给新的对象
vec4 color = fogVar.color;
float start = fogVar.start;
数组
//定义数组
float floatArray[4];
vec4 vecArray[2]; //定义了一个可以存储2个4分量数组。
//注意
//初始化
float a[4] = float[](1.0,2.0,3.0,4.0); //[]里面不填,就会算括号里面的元素个数。
vec2 c[2] = vec2[2](vec2(1.0,2.0),vec2(3.0,4.0));
函数
函数定义了3个修饰符
修饰符 | 描述 |
---|---|
in | (没有指定时,默认限定修饰符),传递进入函数中,函数不能对其进行修改 |
out | 函数返回时,可以进行修改 |
inout | 传入相应的数值,并且在函数中可以进行修改 |
vec4 myFunc(inout float myFloat, out vec4 m1, mat4 m2){
//函数中计算
}
vec4 diffuse(vec3 normal ,vec3 light, vec4 baseColor) {
return baseColor * dot(normal,light);
}
dot 是一个点乘。
控制语句
控制语句包括 if ,while,do while ,for
GLSL预定义变量
GLSL为不同的渲染阶段定义了一些特定的而变量。这些预定义的变量有特定的属性。所有的预定义变量都已gl_开头。用户定义的变量不能以此开头
顶点变量
顶点属性——指顶点的信息,OpenGL据此绘制各个图元,对于传统的顶点属性包括坐标、纹理坐标、颜色等GLSL都会设置一个内置变量与之对应,以便在需要时可以在顶点或片元着色器中直接引用,这也体现了GLSL与HLSL的一个最大的不同,HLSL里顶点的属性是通过语义来定义的,而GLSL充分考虑了OpenGL是个状态机这一事实,将顶点属性设为一个状态变量。GLSL中内置的顶点属性包括以下几个
// 顶点属性
attribute vec4 gl_Color; // 顶点颜色
attribute vec4 gl_SecondaryColor; // 辅助顶点颜色
attribute vec3 gl_Normal; // 顶点法线
attribute vec4 gl_Vertex; // 顶点物体空间坐标(未变换)
attribute vec4 gl_MultiTexCoord[0-N]; // 顶点纹理坐标(N = gl_MaxTextureCoords)
attribute float gl_FogCoord; // 顶点雾坐标
一致变量
就是常说的Uniform,这是用户向GLSL传递自己数据的最常用方法,比如光源位置等等。之所以称为一致变量,是为了与易变变量相区别。不同于顶点属性在每个顶点有其自己的值,也不同于易变变量由顶点程序向片元程序插值传递,一致变量在一个图元的绘制过程中是不会改变的,而且可以在顶点shader和片元shader间共享。这部分变量主要用来描述OpenGL的状态,可以看作OpenGL状态机的复制。GLSL内置的一致变量包括:
// 矩阵状态
uniform mat4 gl_ModelViewMatrix; // 模型视图变换矩阵
uniform mat4 gl_ProjectionMatrix; // 投影矩阵
uniform mat4 gl_ModelViewProjectionMatrix; // 模型视图投影变换矩阵(ftransform())
uniform mat3 gl_NormalMatrix; // 法向量变换到视空间矩阵
uniform mat4 gl_TextureMatrix[gl_MatTextureCoords]; // 各纹理变换矩阵
// 普通缩放因子
uniform float gl_NormalScale;
// 窗口坐标深度范围
struct gl_DepthRangeParameters
{
float near;
float far;
float diff; // far-near
};
uniform gl_DepthRangeParameters gl_DepthRange;
// 裁剪平面
uniform vec4 gl_ClipPlane[gl_MaxClipPlanes];
// 点属性
struct gl_PointParameters
{
float size;
float sizeMin;
float sizeMax;
float fadeThresholdSize;
float distanceConstantAttenuation;
float distanceLinearAttenuation;
float distanceQuadraticAttenuation;
};
uniform gl_PointParameters gl_Point;
// 材质
struct gl_MaterialParameters
{
vec4 emission; // 自身光照Ecm
vec4 ambient; // 环境光吸收系数Acm
vec4 diffuse; // 漫反射吸收系数Dcm
vec4 specular; // 镜面反射吸收系数Scm
float shininess; // Srm
};
uniform gl_MaterialParameters gl_FrontMaterial; // 正面材质
uniform gl_MaterialParameters gl_BackMaterial; // 反面材质
// 光源性质,参数性质就不解释了,和OpenGL的三种光源性质是一样的![image](https://upload-images.jianshu.io/upload_images/16249515-d9c01827b81d1002.gif?imageMogr2/auto-orient/strip)
struct gl_LightSourceParameters
{
vec4 ambient; // Acii
vec4 diffuse; // Dcii
vec4 specular; // Scii
vec4 position; // Ppii
vec4 halfVector; // Hi
vec3 spotDirection; // Sdli
float spotExponent; // Srli
float spotCutoff; // Crli
float spotCosCutoff; // cos(Crli)
float constantAttenuation; // K0
float linearAttenuation; // K1
float quadraticAttenuation; // K2
};
uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights];
struct gl_LightModelParameters
{
vec4 ambient; // Acs
};
uniform gl_LightModelParameters gl_LightModel;
// 光照和材质的派生状态
struct gl_LightModelProducts
{
vec4 sceneColor; // Ecm+Acm*Acs
};
uniform gl_LightModelProducts gl_FrontLightModelProduct;
uniform gl_LightModelProducts gl_BackLightModelProduct;
struct gl_LightProducts
{
vec4 ambient; // Acm * Acli
vec4 diffuse; // Dcm * Dcli
vec4 specular; // Scm * Scli
};
uniform gl_LightProducts gl_FrontLightProduct[gl_MaxLights];
uniform gl_LightProducts gl_BackLightProduct[gl_MaxLights];
// 纹理环境和生成
unifrom vec4 gl_TextureEnvColor[gl_MaxTextureImageUnits];
unifrom vec4 gl_EyePlaneS[gl_MaxTextureCoords];
unifrom vec4 gl_EyePlaneT[gl_MaxTextureCoords];
unifrom vec4 gl_EyePlaneR[gl_MaxTextureCoords];
unifrom vec4 gl_EyePlaneQ[gl_MaxTextureCoords];
unifrom vec4 gl_ObjectPlaneS[gl_MaxTextureCoords];
unifrom vec4 gl_ObjectPlaneT[gl_MaxTextureCoords];
unifrom vec4 gl_ObjectPlaneR[gl_MaxTextureCoords];
unifrom vec4 gl_ObjectPlaneQ[gl_MaxTextureCoords];
// 雾参数
struct gl_FogParameters
{
vec4 color;
float density;
float start;
float end;
float scale; // 1/(end-start)
};
uniform gl_FogParameters gl_Fog;
易变变量
易变变量只能在顶点shader和片元shader间传递,这期间实际上经过了一个光栅化的过程。内置的易变变量比较少,如下:
varying vec4 gl_Color;
varying vec4 gl_SecondaryColor;
varying vec4 gl_TexCoord[gl_MaxTextureCoords];
varying float gl_FogFragCoord;
内置常量
内置常量描述了显卡的渲染能力,依据各个显卡而定,这里就不一一列举了,如果想要查询的话可以用OpenGL的glGet函数获取MAX/MIN一族的常量值,这些值和内置变量的值是一致的。
常量出处