Open GL - GLSL着色器语言

2018/5/15 posted in  OpenGL

GLSL(OpenGL Shading Language) 是一个以C语言为基础的高阶着色语言

作用

可用于 OpenGL 可编程管线
能够让你对OpenGL渲染其中的一些着色环节来自定义(如顶点着色器,片元着色器)
类似UIVIewController的自定义控件

固定管线
相当于已经封装了的高级API,让你通过传递参数来实现效果

自定义环节

  • 顶点着色器: 处理每个顶点,确定位置以及变换
  • 片元着色器: 片元

GLSL 数据类型

  • void – 用于没有返回值的函式
  • bool – 条件类型,其值可以是真或假
  • int – 带负号整数
  • float – 浮点数
  • vec2 – 2 个浮点数组成的向量
  • vec3 – 3 个浮点数组成的向量
  • vec4 – 4 个浮点数组成的向量
  • bvec2 – 2 个布尔组成的向量
  • bvec3 – 3 个布尔组成的向量
  • bvec4 – 4 个布尔组成的向量
  • ivec2 – 2 个整数组成的向量
  • ivec3 – 3 个整数组成的向量
  • ivec4 – 4 个整数组成的向量
  • mat2 – 浮点数的 2X2 矩阵
  • mat3 – 浮点数的 3X3 矩阵
  • mat4 – 浮点数的 4X4 矩阵
  • sampler1D – 用来存取一维纹理的句柄(handle)(或:操作,作名词解。)
  • sampler2D – 用来存取二维纹理的句柄
  • sampler3D – 用来存取三维纹理的句柄
  • samplerCube – 用来存取立方映射纹理的句柄
  • sampler1Dshadow – 用来存取一维深度纹理的句柄
  • sampler2Dshadow – 用来存取二维深度纹理的句柄

存储修饰符

1. 常量修饰符 const

1. 任何使用const声明的变量在其所属的着色器中均是只读的。
2. const 用来修饰任何基本数据类型
3. const 不能用来修饰包含数组的数组、结构体

2. Attribute

1. 用于修饰声明通过OpenGL ES 应用程序传递顶点着色器的变量值,在其他任何非顶点着⾊器的着色器程序中声明attribute变量是错误的

3. Uniform

1. ⽤来修饰那些被整个图元在被处理过程中保持不变的全局变量
2. 所有uniform变量都是只读的
3. uniform修饰符可以和任意基本数据类型一起使用,或者包含基本数据类型元素的数组和结构体

4. Varying

1. varying变量提供了顶点着⾊器,⽚元着色器和二者通讯控制模块之间的接口
2. 顶点着⾊器计算每个顶点的值(颜⾊,纹理坐标等)并将它们写到 varying 变量中。顶点着⾊器也会从 varying 变量中读值,获取和它写入相同的值
3. ⽚元着⾊器会读取varying变量的值,并且被读取的值将会作为插值器,作为图元中片元位置的一个功能信息。varying 变量对于⽚元着⾊器来说是只读的。

精度修饰符

highp: 浮点数的范围 (-262 - 262) ,整型范围 (-216 - 216)
mediump:浮点数的范围 (-214 - 214), 整型范围 (-210 - 210)
lowp: 浮点数的范围 (-2,2), 整型范围(-28 - 28)

官方的shader范例:

Vertex Shader:

uniform mat4 mvp_matrix; //透视矩阵 * 视图矩阵 * 模型变换矩阵
uniform mat3 normal_matrix; //法线变换矩阵(用于物体变换后法线跟着变换)
uniform vec3 ec_light_dir; //光照方向
attribute vec4 a_vertex; // 顶点坐标
attribute vec3 a_normal; //顶点法线
attribute vec2 a_texcoord; //纹理坐标
varying float v_diffuse; //法线与入射光的夹角
varying vec2 v_texcoord; //2d纹理坐标
void main(void)
{
 //归一化法线
 vec3 ec_normal = normalize(normal_matrix * a_normal);
 //v_diffuse 是法线与光照的夹角.根据向量点乘法则,当两向量长度为1是 乘积即cosθ值
 v_diffuse = max(dot(ec_light_dir, ec_normal), 0.0);
 v_texcoord = a_texcoord;
 gl_Position = mvp_matrix * a_vertex;
}

Fragment Shader:

precision mediump float;
uniform sampler2D t_reflectance;
uniform vec4 i_ambient;
varying float v_diffuse;
varying vec2 v_texcoord;
void main (void)
{
 vec4 color = texture2D(t_reflectance, v_texcoord);
 //这里分解开来是 color*vec3(1,1,1)*v_diffuse + color*i_ambient
 //色*光*夹角cos + 色*环境光
 gl_FragColor = color*(vec4(v_diffuse) + i_ambient);
}

目录