一:着色器语言概述
OpenGL ES 着色语言是一种高级的图形编程语言,起源自于C语言,同时具有RenderMan 以及其他着色语言的一些优良特性,易于被开发人员掌握。、
与传统的编程语言有很大不同的是,器提供了更加丰富的原生类型,入向量、矩阵等。主要有以下特征:
1.OpenGL ES 着色语言是一种高级的过程语言(注意 ,不是面向对象)。
2.对顶点着色器、片元着色器使用的是同样的语言,不做区分。
3.基于C/C++的语法即流程控制。
4.完美支持向量与矩阵的各种操作。
5.通过类型限定符来管理输入与输出。
6.拥有大量的内置函数来提供丰富的功能。
二:着色语言基础:
OpenGL ES 着色语言虽然基于C/C++语法的语言,但又有很大的不同,主要是不支持double,byte,short,long,并取消了C中的union,enum。unsigned以及位运算。
2.1 数据类型的概述:
2.1.1 标量 :也叫无向量,只有大小而没有方向,如质量、密度、体积、时间、温度等等,直接运算。有三种标量类型:
bool --布尔型
1 bool b; //声明一个布尔型的变量
int --整形
1 int a = 15; //十进制
2 int b = 036; //0 开头的是八进制,代表十进制的是30
3 int c = 0x3D; //0x开头的是十六进制,代表的是十进制的58
float --浮点型
1 float f //声明一个float 型的变量
2 float g=2.0; //在声明变量的同时为变量赋初值
3 float h,j; //同时声明多个变量
4 float j, k = 2.56, l ; // 声明多个变量的时候。可以为其中的某些变量赋初值
注意:不需要在数值后面加 f 。
2.1.2 向量:向量可以看成是用同样类型的标量组成的,也有3种类型:int float bool 。每个向量可由 2个、3个、4个相同的标量组成。具体如下:
各向量类型及说明
向量类型
| 说明 |
向量类型
|
说明
|
vec2
|
包含2个浮点数的向量
|
ivec4
|
包含4个整数的向量
|
vec3
|
包含3个浮点数的向量
|
bvec2
|
包含2个布尔型向量
|
vec4
|
包含4个浮点数的向量
|
bvec3
|
包含3个布尔型向量
|
ivec2
|
包含2个整数的向量
|
bvec4
|
包含4个布尔型向量
|
ivec3
|
包含3个整数的向量
|
|
|
1 vec2 v2; //声明一个vec2 类型的向量
1 vec3 v3; //声明一个vec3类型的向量
1 vec4 v4; //声明一个vec4 类型的向量
向量在着色器代码的开发中有十分重要的作用,可以非常方便的存储以及操作颜色、位置、纹理坐标。语法是“<向量名>.<分量名>
如: 向量看做是颜色的时候,可以试用 r, g,b,a 4个分量名分别代表 红、绿、蓝、透明度:
1 aColor . r = 0.6; //给向量aColor
的红色通道分量赋值
2 aColor . g = 0.6; //给向量aColor 的绿色通道分量赋值
同理,如果是看做位置的时候可以用 x,y,z,w 代表 X轴Y轴Z轴记忆向量的模。
1 aPosition.x = 67.2 ; //给向量aPosition 的X轴分量赋值
2 aPosition.y = 67.2 ; //给向量aPosition 的Y轴分量赋值
向量看做是纹理坐标时,可用 s,t,p,q 代表纹理的不用分量
1.aTexCoor.s = 0.65; //给向量aTexCoor的s分量赋值
2.aTexCoor.t= 0.65; //给向量aTexCoor的t分量赋值
1 aColor
[0] = 0.6; //给向量aColor 的红色通道分量赋值
2 aPosition[2] = 48.0; //给向量aPosition 的Z轴分量赋值
2 aPosition[2] = 48.0; //给向量aPosition 的Z轴分量赋值
3 aTexCoor[1] = 0.34; //给向量aTexCoor的t分量赋值
2.1.3 矩阵
用于3D场景中的移位、旋转、缩放等变换
矩阵的类型及说明
矩阵类型
| 说明 |
mat2
|
2*2的浮点数矩阵
|
mat3
|
3*3的浮点数矩阵
|
mat4
|
4*4的浮点数矩阵
|
基本语法:
1 mat2 m2; //声明一个mat2 类型的矩阵
2 mat3 m3; //声明一个mat3 类型的矩阵
3 mat4 m4; //声明一个mat4 类型的矩阵
矩阵可以看做是几个列向量组成的,例如 mat3 其实是3个vec3 组成。
2.1.4 采样器
采样器是着色语言中不同于C语言的一种特殊的基本数据类型,是专门用来进行纹理采样的相关操作,一般情况下,一个采样器变量代表一副或一套纹理贴图。
采样器类型 | 说明 |
sampler2D |
用于访问二维纹理
|
sampler3D
|
用于访问三维纹理
|
samplerCube
|
用于访问立方贴图纹理
|
注意:采样器不能在着色器中初始化,一般用uniform1限定符来修饰,从宿主语言(如java)接受传递着色器的值
2.1.5 结构体
struct info{
vec3 color;
vec3 position;
vec2 textureCoor;
}
info CubeInfo; //就可以声明一个info类型的变量CubeInfo
2.1.6 数组
2.1.7 空类型
void main()
{// .........................}
数据类型的基本使用:
1>初始化
2>
属性变量、一致变量以及易变变量在声明的时候一定不能初始化
如:
1 attribute float angleSpan;
2 uniform int k;
3 varying vec3 position;
2.2 运算符
2.3限定符
4种限定符及说明
限定符
|
说明
|
attribute
|
一般用于每个顶点都各不相同的量,如顶点位置、颜色等;
|
uniform
|
一般用于对同一组顶点组成的单个3D物体中所有顶点都相同的量,如当前的光源位置
|
varying |
用于从顶点着色器传递到片元着色器的量
|
const
|
用于声明常量
|
如:
1 uniform mat4 uMVPMatrix;
2 attribute vec3 aPosition;
3 varrying vec4 aaColor;
4 const int lightsCount = 4;
2.4程序的基本结构
一般有3大部分组成,主要有:全局变量的声明、自定义函数、main函数。
下面是顶点着色器的程序:
1 uniform mat4 uMVPMatrix; //总变换矩阵
2 attribute vec3 aPosition; //顶点位置
3 attribute vec2 aTexCoor; // 顶点纹理坐标
4 varrying vec2 vTextureCoord; //用于传递给片元着色器的变量
5 void positionShift() //根据总变化矩阵计算此次绘制顶点位置的方法
6 {
7 gl_Position = uMVPMatrix * vec4(aPosition,1);
8 }
9 void main() //主函数
10 {
11 positionShift(); //根据总变换矩阵计算此次绘制此顶点位置
12 vTextureCoord = aTexCoor;//将接受到的纹理坐标传递给片元着色器
13 }
注意:着色器程序中要求被调用的函数必须在调用之前声明。
2.4特殊的内建变量
分为输入与输出变量,输入变量负责将渲染管线中固定功能部分产生的信息传递进着色器,输出变量负责将着色器产生的信息传递给渲染管线中固定功能部分。
2.4.1 顶点着色器中的内建变量
顶点着色器中的内建变量主要是输出变量,包括gl_Position(vrc4)、gl_PointSize(默认为1) 等。
2.4.2 片元着色器中的内建变量
片元着色器中的内建变量分为输入变量和输出变量。
1> 内建输入变量
gl_FragCoord (vec4类型):包含有当前片元相对于窗口位置的坐标值x、y、z与1/w
gl_FrontFacing(bool类型):判断片元是否是在光栅阶段生成此片元的对应图元的正面,值为true和false。
2>内建输出变量
gl_FragColor(vec4类型):
gl_FragData(vec4类型的数组):
2.5着色语言的内置函数
按照设计目的有3个类别:
1> 提供独特的硬件功能的访问接口
2>简单的数学函数
3>一些复杂的函数
2.5.1 角度转换与三角函数
内置函数签名
|
说明
|
genType radians(genType degrees)
| 此函数功能为将角度转换为弧度,即返回值 result = (x/180)*degrees ,degrees 参数表示需要转换的角度 |
genType degrees(genType radians)
|
此函数功能为将弧度转换为角度,即返回值 result = (180/π)*radians,radians参数表示需要转换的角度
|
genType sin(genType angle)
| 此函数为标准的正弦函数,返回值范围为[-1,1],radians为正弦函数的参数,单位为弧度 |
|
|
|
|
|
|
|
|
2.5.2指数函数
2.5.3常见函数
abs 、sign、floor、ceil、fract、min、max、clamp、step、shoothstep
2.5.4 几何函数
dot、cross、reflect、refract、
2.5.5 矩阵函数
mat matrixCompMult(mat x, mat y): 此函数按各个部分将矩阵x与矩阵y相乘,即返回值result[i][j]是x[i][j]与y[i][j]标量的乘积
2.5.6 向量关系函数
bvec lessThan(vec x,vex y)
2.5.7 纹理采样函数
纹理采样函数是用来根据指定的纹理坐标从采样器对应的纹理中进行采样,返回值类型是vec4,代表采样得到的颜色值。
纹理采样函数
内置函数签名
|
说明
|
vec4 texture2D(sampler2D sampler,vec2 coord,[float bias])
vec4 texture2DProj(sampler2D sampler,vec3 coord,[float bias])
vec4 texture2DProj(sampler2D sampler,vec4coord,[float bias])
vec4 texture2DLod(sampler2D sampler,vec2 coord,float lod)
vec4 texture2DProjLod(sampler2D sampler,vec3 coord,float lod)
vec4 texture2DProjLod(sampler2D sampler,vec4coord,float lod)
| 此系列函数功能为使用二维纹理坐标coord 在由sample参数指定的2D纹理中执行纹理采样,对于带Proj后缀的函数,会将纹理坐标(coord.s,coord.t)除以coord的最后一个部分(coord.q).对于类型为vec4的coord,忽略其他三部分(coord.p) |
vec4 textureCube(samplerCube sampler,vec3 coord)
vec4 textureCube(samplerCube sampler,vec3 coord,float bias)
vec4 textureCubeLod(samplerCube sampler,vec3 coord,float lod)
|
|
vec4 texture3D(sampler3D sampler,vec3 coord,[float bias])
vec4 texture3DProj(sampler3D sampler,vec4coord,[float bias])
vec4 texture3DLod(sampler3D sampler,vec3coord,float lod)
vec4
texture3DProjLod(sampler3D sampler,vec4coord,float lod)
|
|
注:1。bias参数 含有bias参数的纹理采样函数只能在片元着色器中调用,且此参数仅对sampler为mipmap类型的纹理时才有意义。
2.Lod后缀 。仅能作用于顶点着色器。Lod是level of detail 的缩写。仅对sampler 为mipmap类型的纹理才有意义。
3.texture3D 系列:
部分厂家进行了扩展:
1 #extension GL_OES_texture_3d:enable //打开扩展后还需要硬件支持才可以真正使用
2.5.8 微分函数
仅能作用于片元着色器,并且还没纳入OpenGL ES 2.0 的正式标准。
1 #extension GL_OES_standard_derivatives:enable //打开扩展后还需要硬件支持才可以真正使用