glsl语法

 

一、基础类型

  • void 空类型
  • bool 布尔类型 true,false
  • int 带符号的整数 signed integer
  • float 带符号的浮点数 floating scalar
  • vec2, vec3, vec4 n维浮点数向量
  • bvec2, bvec3, bvec4 n维布尔向量
  • ivec2, ivec3, ivec4 n维整数向量
  • mat2, mat3, mat4 2x2, 3x3, 4x4 浮点数矩阵
  • sampler1D 用于内建的纹理函数中引用指定的1D纹理的句柄。只可以作为一致变量或者函数参数使用
  • sampler2D 2D纹理句柄
  • sampler3D 三维纹理句柄
  • samplerCube cube map纹理句柄
  • sampler1DShadow 一维深度纹理句柄
  • sampler2DShadow 二维深度纹理句柄

 

二、数组和结构体

  • float foo[3] glsl只支持1维数组
  • struct type-name{} 类似c语言中的 结构体
//一般类型
float pSize = 10.0;
float pSize1;
pSize1=10.0;
...

//复合类型
vec4 color = vec4(0.0, 1.0, 0.0, 1.0);
vec4 color1;
color1 =vec4(0.0, 1.0, 0.0, 1.0);
...

//结构
struct light {
    float intensity;
    vec3 position;
};
light lightVar = light(3.0, vec3(1.0, 2.0, 3.0));

//数组
const float c[3] = float[3](5.0, 7.2, 1.1);

 

三、运算符

  • () a*(b+c)
  • [] () . ++ – 数组下标[],方法参数fun(arg1,arg2,arg3),属性访问a.b,自增/减后缀a++ a–
  • ++ – + - ! 自增/减前缀++a –a,正负号(一般正号不写)a ,-a,取反!false
  • * / 乘除数学运算
  • + - 加减数学运算
  • < > <= >= 关系运算符
  • == != 相等性运算符
  • && 逻辑与
  • ^^ 逻辑排他或(用处基本等于!=)
  • || 逻辑或
  • ? : 三目运算符
  • = += -= *= /= 赋值与复合赋值
  • , 顺序分配运算

四、变量限定符

  • none (默认的可省略)本地变量,可读可写,函数的输入参数既是这种类型
  • varying 主要负责在vertex 和 fragment 之间传递变量
  • const 常量值必须在声明时初始化。它是只读的不可修改的。
  • attribute 只能存在于vertex shader中,一般用于保存顶点或法线数据,它可以在数据缓冲区中读取数据。表示只读的顶点数据,只用在顶点着色器中。数据来自当前的顶点状态或者顶点数组。它必须是全局范围声明的,不能在函数内部。一个attribute可以是浮点数类型的标量,向量,或者矩阵。不可以是数组或者结构体
  • uniform 一致变量。在着色器执行期间一致变量的值是不变的。与const常量不同的是,这个值在编译时期是未知的是由着色器外部初始化的。一致变量在顶点着色器和片段着色器之间是共享的。它也只能在全局范围进行声明。
  • varying 顶点着色器的输出。例如颜色或者纹理坐标,(插值后的数据)作为片段着色器的只读输入数据。必须是全局范围声明的全局变量。可以是浮点数类型的标量,向量,矩阵。不能是数组或者结构体。
  • centorid varying 在没有多重采样的情况下,与varying是一样的意思。在多重采样时,centorid varying在光栅化的图形内部进行求值而不是在片段中心的固定位置求值。
  • invariant (不变量)用于表示顶点着色器的输出和任何匹配片段着色器的输入,在不同的着色器中计算产生的值必须是一致的。所有的数据流和控制流,写入一个invariant变量的是一致的。编译器为了保证结果是完全一致的,需要放弃那些可能会导致不一致值的潜在的优化。除非必要,不要使用这个修饰符。在多通道渲染中避免z-fighting可能会使用到。
//顶点着色器
varying vec4 v_Color;
void main(){ 
    ...
    v_Color = vec4(1.,1.,1.,1);
}

//片元着色器
...
varying vec4 v_Color;
void main() {
  gl_FragColor = v_Color;
}
...

 

五、函数参数限定符

  • < none: default > 默认使用 in 限定符

  • in 复制到函数中在函数中可读写

  • out 用在函数的参数中,表示该参数是输出参数,值是会改变的。

  • inout 用在函数的参数,表示这个参数即是输入参数也是输出参数。

 

六、精度限定

  • 一般在片元着色器(fragment shader)最开始的地方加上 precision mediump float; 便设定了默认的精度.这样所有没有显式表明精度的变量都会按照设定好的默认精度来处理.
lowp float color;
varying mediump vec2 Coord;
lowp ivec2 foo(lowp mat3);
highp mat4 m;
invariant varying lowp float color; // invariant > storage > precision

void doubleSize(const in lowp float s){ //storage > parameter > precision
    float s1=s;
}

 

七、预编译指令

  • #define #undef #if #ifdef #ifndef #else
    #elif #endif #error #pragma #extension #version #line

  • 内置的宏

    • _LINE_ : 当前源码中的行号.
    • _VERSION_ : 一个整数,指示当前的glsl版本 比如 100 ps: 100 = v1.00
    • GL_ES : 如果当前是在 OPGL ES 环境中运行则 GL_ES 被设置成1,一般用来检查当前环境是不是 OPENGL ES.
    • GL_FRAGMENT_PRECISION_HIGH : 如果当前系统glsl的片元着色器支持高浮点精度,则设置为1.一般用于检查着色器精度.
#ifdef GL_ES //
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#endif

 

八、内置变量

顶点着色器内置变量
  • gl_Color vec4 输入属性-表示顶点的主颜色
  • gl_SecondaryColor vec4 输入属性-表示顶点的辅助颜色
  • gl_Normal vec3 输入属性-表示顶点的法线值
  • gl_Vertex vec4 输入属性-表示物体空间的顶点位置
  • gl_MultiTexCoordn vec4 输入属性-表示顶点的第n个纹理的坐标
  • gl_FogCoord float 输入属性-表示顶点的雾坐标
  • gl_Position vec4 输出属性-变换后的顶点的位置,用于后面的固定的裁剪等操作。所有的顶点着色器都必须写这个值。
  • gl_ClipVertex vec4 输出坐标,用于用户裁剪平面的裁剪
  • gl_PointSize float 点的大小
  • gl_FrontColor vec4 正面的主颜色的varying输出
  • gl_BackColor vec4 背面主颜色的varying输出
  • gl_FrontSecondaryColor vec4 正面的辅助颜色的varying输出
  • gl_BackSecondaryColor vec4 背面的辅助颜色的varying输出
  • gl_TexCoord[] vec4 纹理坐标的数组varying输出
  • gl_FogFragCoord float 雾坐标的varying输出

 

顶点着色器内置变量
  • gl_Color vec4 包含主颜色的插值只读输入
  • gl_SecondaryColor vec4 包含辅助颜色的插值只读输入
  • gl_TexCoord[] vec4 包含纹理坐标数组的插值只读输入
  • gl_FogFragCoord float 包含雾坐标的插值只读输入
  • gl_FragCoord vec4 只读输入,窗口的x,y,z和1/w
  • gl_FrontFacing bool 只读输入,如果是窗口正面图元的一部分,则这个值为true
  • gl_PointCoord vec2 点精灵的二维空间坐标范围在(0.0, 0.0)到(1.0, 1.0)之间,仅用于点图元和点精灵开启的情况下。
  • gl_FragData[] vec4 使用glDrawBuffers输出的数据数组。不能与gl_FragColor结合使用。
  • gl_FragColor vec4 输出的颜色用于随后的像素操作
  • gl_FragDepth float 输出的深度用于随后的像素操作,如果这个值没有被写,则使用固定功能管线的深度值代替

 

九、内置常量

 

十、内置函数库

通用函数

  • T abs(T x) 返回x的绝对值
  • T sign(T x) 比较x与0的值,大于,等于,小于 分别返回 1.0 ,0.0,-1.0
  • T floor(T x) 返回<=x的最大整数
  • T ceil(T x) 返回>=等于x的最小整数
  • T fract(T x) 获取x的小数部分
  • T mod(T x, T y)
  • T mod(T x, float y) 取x,y的余数
  • T min(T x, T y)
  • T min(T x, float y) 取x,y的最小值
  • T max(T x, T y)
  • T max(T x, float y) 取x,y的最大值
  • T clamp(T x, T minVal, T maxVal)
  • T clamp(T x, float minVal,float maxVal) min(max(x, minVal), maxVal),返回值被限定在 minVal,maxVal之间
  • T mix(T x, T y, T a)
  • T mix(T x, T y, float a) 取x,y的线性混合,x*(1-a)+y*a
  • T step(T edge, T x)
  • T step(float edge, T x) 如果 x
  • T smoothstep(T edge0, T edge1, T x)
  • T smoothstep(float edge0,float edge1, T x) 如果xedge1返回1.0, 否则返回Hermite插值

 

三角函数

  • T radians(T degrees) 角度转弧度
  • T degrees(T radians) 弧度转角度
  • T sin(T angle) 正弦函数,角度是弧度
  • T cos(T angle) 余弦函数,角度是弧度
  • T tan(T angle) 正切函数,角度是弧度
  • T asin(T x) 反正弦函数,返回值是弧度
  • T acos(T x) 反余弦函数,返回值是弧度
  • T atan(T y, T x)
  • T atan(T y_over_x) 反正切函数,返回值是弧度

 

指数函数

  • T pow(T x, T y) 返回x的y次幂 xy
  • T exp(T x) 返回x的自然指数幂 ex
  • T log(T x) 返回x的自然对数 ln
  • T exp2(T x) 返回2的x次幂 2x
  • T log2(T x) 返回2为底的对数 log2
  • T sqrt(T x) 开根号 √x
  • T inversesqrt(T x) 先开根号,在取倒数,就是 1/√x

 

几何函数

  • float length(T x) 返回矢量x的长度
  • float distance(T p0, T p1) 返回p0 p1两点的距离
  • float dot(T x, T y) 返回x y的点积
  • vec3 cross(vec3 x, vec3 y) 返回x y的叉积
  • T normalize(T x) 对x进行归一化,保持向量方向不变但长度变为1
  • T faceforward(T N, T I, T Nref) 根据 矢量 N 与Nref 调整法向量
  • T reflect(T I, T N) 返回 I - 2 * dot(N,I) * N, 结果是入射矢量 I 关于法向量N的 镜面反射矢量
  • T refract(T I, T N, float eta) 返回入射矢量I关于法向量N的折射矢量,折射率为eta

 

向量函数

  • bvec lessThan(T x, T y) 逐分量比较x < y,将结果写入bvec对应位置
  • bvec lessThanEqual(T x, T y) 逐分量比较 x <= y,将结果写入bvec对应位置
  • bvec greaterThan(T x, T y) 逐分量比较 x > y,将结果写入bvec对应位置
  • bvec greaterThanEqual(T x, T y) 逐分量比较 x >= y,将结果写入bvec对应位置
  • bvec equal(T x, T y)
  • bvec equal(bvec x, bvec y) 逐分量比较 x == y,将结果写入bvec对应位置
  • bvec notEqual(T x, T y)
  • bvec notEqual(bvec x, bvec y) 逐分量比较 x!= y,将结果写入bvec对应位置
  • bool any(bvec x) 如果x的任意一个分量是true,则结果为true
  • bool all(bvec x) 如果x的所有分量是true,则结果为true
  • bvec not(bvec x) bool矢量的逐分量取反

 

纹理查询函数

  • 只在vertex shader中可用
vec4 texture2DLod(sampler2D sampler, vec2 coord, float lod);
vec4 texture2DProjLod(sampler2D sampler, vec3 coord, float lod);
vec4 texture2DProjLod(sampler2D sampler, vec4 coord, float lod);
vec4 textureCubeLod(samplerCube sampler, vec3 coord, float lod);
  • 只在fragment shader中可用
vec4 texture2D(sampler2D sampler, vec2 coord, float bias);
vec4 texture2DProj(sampler2D sampler, vec3 coord, float bias);
vec4 texture2DProj(sampler2D sampler, vec4 coord, float bias);
vec4 textureCube(samplerCube sampler, vec3 coord, float bias);
  • 在 vertex shader 与 fragment shader 中都可用
vec4 texture2D(sampler2D sampler, vec2 coord);
vec4 texture2DProj(sampler2D sampler, vec3 coord);
vec4 texture2DProj(sampler2D sampler, vec4 coord);
vec4 textureCube(samplerCube sampler, vec3 coord);

 

十一、范例

  • 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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值