OpenGLES(四)glsl语法

GLSL是OpenGL着色器语言(OpenGL Shading Language)

版本说明

OpenGLES版本 GLSL版本
2.0 100
3.0 300
3.1 310
3.2 320
GLSL3.0与2.0差异
  • inout 取代 attributevarying
  • 头文件多了个 #version 300 es
  • 纹理 texture2Dtexture3D 统统改为 texture
  • 内置函数 gl_FragColorgl_FragData 删除,如果片段着色器要输出用out声明字段输出,不过保留了gl_Position
  • 可直接使用 layout 指定属性位置

数据类型

  • 基本数据类型:void、int、float、double、uint、bool
  • 容器数据类型:向量(Vector)、矩阵(Matrix)
向量

可以包含有2、3、4个分量,分量的类型可以是基础数据类型的任意一个(除过void类型),n表示向量维度,如下表:

数据类型 说明
vecn 包含n个float分量的默认向量
bvecn 包含n个bool分量的默认向量
ivecn 包含n个int分量的向量
uvecn 包含n个unsigned int分量的向量
dvecn 包含n个double分量的向量
  • 一个向量可能有特殊含义,其可以看作是空间坐标(x,y,z,w)、颜色(r,g,b,a)或纹理坐标(s,t,p,q)。
  • 向量的分量可以通过vecn.x这种方式获取,可以分别使用.x、.y、.z、.w来获取它们的第1、2、3、4个分量(或着使用颜色vecn.rgba、或者使用纹理venc.stpq)。
  • 向量可以使用上面4个字母任意组合来创建一个和分量类型相同的新向量,只要原来向量有那些分量即可,这个叫做向量重组
//如果向量构造器中只提供了一个标量参数,则向量中所有值都会设定为该参数,即color={1.0,1.0,1.0,1.0}
vec4 color = vec4(1.0);

//向量重组
vec2 someVec;
vec4 differentVec = someVec.xyxx;
vec3 anotherVec = differentVec.zyw;
vec4 otherVec = someVec.xxxx + anotherVec.yxzy;
矩阵

OpenGL的矩阵是列主顺序的

数据类型 说明
mat2 或 mat2x2 2×2的浮点数矩阵类型
mat3 或 mat3x3 3×3的浮点数矩阵类型
mat4x4 4×4的浮点矩阵
mat2x3 2列3行的浮点矩阵
mat3x2 3列2行的浮点矩阵
mat3x4 3列4行的浮点矩阵
mat4x2 4列2行的浮点矩阵
mat4x3 4列3行的浮点矩阵

输入与输出

GLSL 3.0 定义了inout 关键字专门来实现输入输出,只要一个输出变量与下一个着色器阶段的输入匹配,它就会传递下去。

顶点着色器

顶点着色器必须要有一个输入,用于接收顶点数据。每个输入变量也叫顶点属性(Vertex Attribute)。顶点属性是有上限的,它一般由硬件来决定。OpenGL确保至少有16个包含4分量的顶点属性可用,但是有些硬件或许允许更多的顶点属性,可以通过GL_MAX_VERTEX_ATTRIBS查询

#version 300 es

//顶点着色器输入(用于从顶点数据中接收数据)
//layout (location = 0) 是限定该属性的位置为 0,如果不限定,需要通过 glGetAttribLocation 查询
layout (location = 0) in vec3 aPos; 
//为片段着色器指定一个颜色输出
out vec4 vertexColor;

void main(){
	//把一个vec3作为vec4的构造器的参数
    gl_Position = vec4(aPos, 1.0);
	//把输出变量设置为暗红色
    vertexColor = vec4(0.5, 0.0, 0.0, 1.0);
}
片段着色器

片段着色器必须要有一个vec4颜色输出,因为片段着色器需要输出颜色信息来绘制。

#version 300 es
//片段着色器的输出,用于最终输出的颜色
out vec4 FragColor;
//从顶点着色器传来的输入变量(名称相同、类型相同)
in vec4 vertexColor;

void main(){
    FragColor = vertexColor;
}

限定符

uniform

uniform是一种从CPU中的应用向GPU中的着色器发送数据的方式,uniform和顶点属性有如下不同点:

  • uniform是全局的(Global)
  • 在所有着色器程序对象中都是独一无二的
  • 可以被任意着色器在任意阶段访问
  • 无论将 uniform 值设置成什么,uniform会一直保存它们的数据,直到它们被重置或更新
  • 如果声明了一个uniform却在GLSL代码中没用过,编译器会静默移除这个变量
#version 330 core
out vec4 FragColor;
// 在OpenGL程序代码中设定这个变量
uniform vec4 ourColor;
void main()
{
    FragColor = ourColor;
}

获取和设置Uniform变量

//获取 Uniform 变量的位置属性
int vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");

//设置 Uniform 变量的值,设置之前必须已经激活了Program程序(glUseProgram)
glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);

glUniform有多个不同后缀的函数(C语言不支持重载)

后缀 含义
f 函数需要一个float作为它的值
i 函数需要一个int作为它的值
ui 函数需要一个unsigned int作为它的值
3f 函数需要3个float作为它的值
fv 函数需要一个float向量/数组作为它的值
precision

设置数据类型的默认精度

//默认精度限定符放在着色器代码起始位置
precision highp float;
precision mediump int;
浮点数范围 整数范围
highp (-2^62, 2^62) (-2^16, 2^16)
mediump (-2^14, 2^14) (-2^10, 2^10)
lowp (-2, 2) (-2^8, 2^8)

函数

GLSL 中函数不能够递归调用,且必须声明返回值类型,无返回值时声明为 void。其内建函数如下:

//返回 x、y 的线性混合的,如:x⋅(1−a)+y⋅a
T mix (T x, T y, T a)
T mix (T x, T y, float a)

你可能感兴趣的:(OpenGL,android,OpenGL,glsl)