前言
GLSL是一种针对图形处理器的编程语言,它是OpenGL着色器语言的一部分,用于编写着色器程序。着色器程序是一种运行在图形处理器上的程序,主要用于控制渲染流程中各个阶段的处理。
1. 简介
GLSL是OpenGL着色器语言的简称,它是一种面向图形处理器编程的语言,主要用于编写着色器程序。着色器程序是一种运行在图形处理器上的程序,用于控制渲染流程中各个阶段的处理。GLSL语言结构类似于C语言,支持向量、矩阵、函数等基本数据类型和操作符,同时也支持控制结构、循环结构、条件结构等基本的程序结构。
2. 着色器类型
在GLSL中,有两种着色器程序:顶点着色器和片元着色器。
顶点着色器用于对顶点进行处理,主要用于对每个顶点的位置、颜色等属性进行计算和变换,从而生成对应的片元着色器需要的信息。片元着色器用于对每个像素进行处理,主要用于对每个像素的颜色进行计算和渲染,从而生成最终的图像。
关键字(变量类型) | 数据传递 | 声明变量 |
---|---|---|
attribute | javascript——>顶点着色器 | 声明顶点数据变量(位置、颜色、法向量,和有关的数据) |
uniform | javascript——>顶点、片元着色器 | 声明非顶点数据变量(灯光,雾,和阴影贴图相关) |
varying | 顶点着色器——>片元着色器 | 声明需要插值计算的顶点变量 |
声明特定用途的变量:attribute
和uniform
关键字的目的主要是为了javascript语言可以通过相关的WebGL API把一些数据传递给着色器,如果一个着色器中一个变量,着色器代码中变量不通过attribute
或uniform
声明标识,该变量是不能从javascript代码中获得相应的数据。
-
attribute
关键字通常用来声明与顶点数据相关的变量,比如顶点位置坐标数据、顶点颜色数据、顶点法向量数据,attribute
关键字只能在顶点着色器中声明变量使用,注意attribute
关键字声明顶点变量代码位于主函数main
之外。 -
uniform
关键字用于传递一个光源的位置数据、一个光源的方向数据、一个光源的颜色数据、一个用于顶点变换的模型矩阵、一个用于顶点变换的视图矩阵,uniform
关键字既可以在顶点着色器中使用,也可以在片元着色器中使用。 -
同时在顶点着色器和片元着色器中执行
varying vec4 v_color;
,就可以在片元着色器中获得顶点颜色插值计算以后的数据,最后再顶点着色器中执行v_color = a_color;
即可,varying
类型变量主要是为了完成顶点着色器和片元着色器之间的数据传递和插值计算。
内置变量 | 含义 | 值数据类型 |
---|---|---|
gl_PointSize | 点渲染模式,方形点区域渲染像素大小 | float |
gl_Position | 顶点位置坐标 | vec4 |
gl_FragColor | 片元颜色值 | vec4 |
gl_FragCoord | 片元坐标,单位像素 | vec2 |
gl_PointCoord | 点渲染模式对应点像素坐标 | vec2 |
sampler2D | 从纹理图像提取像素值 |
- gl_PointSize:
gl.drawArrays()
绘制模式是点模式gl.POINTS
的时候,会用到内置变量gl_PointSize
gl_Position
:最终传入片元着色器要使用的顶点位置坐标gl_Position=vec4(x,y,z,1.0)
- 顶点经过片元着色器片元化以后,得到一个个片元,或者说像素点,然后通过内置变量
gl_FragColor
给每一个片元设置颜色值。
// 根据片元位置设置渐变色
void main() {
gl_FragColor = vec4(gl_FragCoord.x/500.0*1.0,1.0,0.0,1.0);
}
---------------------------------------
// 接收插值后的纹理坐标
varying vec2 v_TexCoord;
// 纹理图片像素数据
uniform sampler2D u_Sampler;
void main() {
// 采集纹素,逐片元赋值像素值
gl_FragColor = texture2D(u_Sampler,v_TexCoord);
}
gl_PointCoord
与gl_FragCoord
(与Canvas坐标相同)表示的像素坐标含义不同,如图所示:
3. 着色器语法
GLSL语法类似于C语言,支持向量、矩阵、函数等基本数据类型和操作符,同时也支持控制结构、循环结构、条件结构等基本的程序结构。下面是一些常见的GLSL语法:
3.1 声明变量
在GLSL中,变量需要先进行声明才能使用,声明方式与C语言相似,如下:
//声明一个整型变量
int a;
//声明一个浮点型变量
float b;
//声明一个vec3类型的变量
vec3 c;
3.2 数据类型
GLSL中的数据类型和大部分编程语言中的数据类型类似,但是还有一些特有的类型。
- 基础类型:int,uint,float,double,bool
- 向量类型:vec2,vec3,vec4,bvec2,bvec3,bvec4,ivec2,ivec3,ivec4,uvec2,uvec3,uvec4,dvec2,dvec3,dvec4
- 矩阵类型:mat2,mat3,mat4
- 数组类型:数组可以包含任意基础类型、向量类型、矩阵类型
- 结构体类型:结构体可以包含任意基础类型、向量类型、矩阵类型、数组类型和其他结构体类型
向量类型和矩阵类型是GLSL中比较特殊的类型。向量类型表示了一个N维的向量,可以用来表示顶点的坐标、法向量、颜色等属性。矩阵类型表示了一个MxN的矩阵,可以用来表示变换矩阵、投影矩阵等。
3.3 函数
GLSL中的函数和大部分编程语言中的函数类似,可以用来封装一些常用的操作,以便在多个地方重复使用。GLSL中的函数可以接受任意类型的参数,包括基础类型、向量类型、矩阵类型、数组类型和结构体类型。
GLSL中的函数分为两种类型:内置函数和自定义函数。内置函数是GLSL提供的函数,可以直接在着色器中使用。自定义函数是由用户自己编写的函数,需要在着色器中定义和调用。
3.4 着色器之间的通信
在OpenGL中,顶点着色器、片段着色器和几何着色器之间可以进行数据传递。具体来说,顶点着色器可以将数据输出到几何着色器,几何着色器可以将数据输出到片段着色器。这些数据被称为顶点属性、几何属性和片段属性。
顶点属性是顶点着色器输出的数据,可以包含顶点的位置、法向量、纹理坐标等属性。顶点属性可以通过顶点数组来传递给顶点着色器。
几何属性是几何着色器输出的数据,可以包含几何图元的类型、顶点坐标、颜色等属性。几何属性可以通过GLSL内置变量gl_Position来传递给下一个着色器。
片段属性是片段着色器输入的数据,可以包含片段的坐标、颜色、深度值等属性。片段属性可以通过varying变量来传递给片段着色器。
3.5 常见的GLSL内置变量和函数
sin(x)
: 正弦函数。cos(x)
: 余弦函数。tan(x)
: 正切函数。asin(x)
: 反正弦函数。acos(x)
: 反余弦函数。atan(y, x)
: 反正切函数,返回角度。pow(x, y)
: 计算幂。sqrt(x)
: 计算平方根。length(x)
: 返回向量的长度。normalize(x)
: 返回长度为1的向量。dot(x, y)
: 计算点积。cross(x, y)
: 计算叉积。
第一个GLSL程序
准备工作 VSCode + glsl-canvas插件,该插件可以直接运行我们编写着色器代码。 插件用法:按
Ctrl + P
, 输入>show glslCanvas
即运行 下面是一个简单的GLSL程序:
precision mediump float;
uniform vec2 u_resolution;
void main () {
vec2 uv = gl_FragCoord.xy / u_resolution;
gl_FragColor = vec4(uv, 0.0, 1.0);
}
运行效果如下: