GLSL语法知识汇总

这篇博客全面概述了GLSL的基础知识,包括变量类型、运算符、语句、函数、OpenGL状态值的使用、纹理访问以及顶点和片断着色器的细节。重点介绍了向量和矩阵的操作,以及在着色器中如何访问和操作纹理图像。
摘要由CSDN通过智能技术生成

一、基础类型和限定符

1.GLSL基础变量类型:

(1)Float;// IEEE浮点值
(2)int ;
(3)uint;
(4)bool;
(5)sampler; 采样器,作为访问纹理图像的不透明句柄。
OGL实现可能并不严格地实现这些类型,例如整数也可以存储在浮点寄存器中,最大整数也不一定是2^15。

2.变量的作用域

变量可以在使用时候声明,类似C++,不像C(c语言要求在函数开头声明所有使用到的类型)。
在函数外部声明的变量具有全局作用域,他们在着色器程序的所有函数中均可见(program中,也就是shader对象源代码在链接后可以共享该全局变量)。
函数内部的变量作用域和C++相同。

3.变量的初始化和转换

变量声明时候就可以初始化。可以指定为八进制,十进制,十六进制常量。u或U无符号。3E-7等价于3*10^-7, -3E-7等价于-3*10^-7的科学计数法。
例如:
int i, numParticles = 100;
float force, g = -9.8;
bool falling = true;

变量的转换,没有隐式类型转换,要求比C++还要严格,不同类型的转换到要使用类似该类型的构造函数一样的语法。
例如:
float scale = 10.0;
int ten = int(scale);

4.聚合类型(向量和矩阵类型)

GLSL支持每种基本类型的二维,三维,四维向量和矩阵(默认是列主序矩阵)。
float 的 vec2 vec3 vec4; mat2, mat3, mat4, mat2x2, mat2x3, mat3x4, mat4x4,mat4x2等各维。
int类型对应增加前缀i, 如ivec3。
uint类型对应增加前缀u, 如uvec3.
bool类型对应增加前缀b, 如bvec3.
mat3x4含义是3列4行,也就是行主序的mat4x3的写法一样。其实转置矩阵就是本来行主序的矩阵,用列主序类写,当然向量也要用列序来写,这样:v' = v*M; v'^T = (v*M)^T= M^T * v^T;
列式矩阵用v'^T描述向量的结果,其实坐标系意义上都是x,y,z,w所以都是一样的。
在行式矩阵中4D空间引入主要是包含平移的变换也放到矩阵中和透视除法,为了平移时候矩阵最后一列总是( 0,0,0,1)向量; 透视除法时候,主要是因为透视时候存在对结果每个元素统一的除法,可以放到向量第四维去,然后约定向量结果中如果最后一位不是1那么需要除以w,所以一般传入向量w=1。
列式矩阵中4D空间存在也是一样的,只是矩阵最后一列改为最后一行,最后一行平移变为了最后一列。向量最后一列改为了最后一行。全部矩阵向量都用列式表示,右乘矩阵(所以D3D中基于父坐标系表示子坐标系位置的M缩放*M旋转*M平移代数变换顺序,到OGL中就变成了基于local coordinate的M平移^T*M旋转^T*M缩放^T, ^T刚好是列式矩阵;模型到视口的变换,
OGL中也变成了M视口^T * M模型^T),右乘向量实现变换,结果为列式向量即可。
在CG语法中v*M时候,v会转换为行向量,乘积结果等于列式的M^T*v。
例如,世界坐标系中计算法向量:
// the same as mul(transpose(_World2Object), float4(input.normal, 0.0)) but fast.
float3 normalDir = normalize(mul(normalObjectDir, _World2Object).xyz);

向量的使用

向量的构造
vec3 velocity = vec3(0.0, 2.0, 3.0);
向量类型转换:
ivec3 = ivec3(velocity);
向量的截短和拉长:
vec4 color;
vec3 rgb = vec3(color);
vec4 white = vec4(rgb, 1.0);
访问和赋值向量中的元素:
1)通过名称
float r = color.r;
color.r = 1.0f;
2)通过下标
float r = color[0];
color[0] = 1.0f;
3)搅拌式
vec3 luminance = color.rrr;
vec4 color2 = color.abgr;

矩阵的使用

矩阵的初始化:
可以用向量初始化,或单个值指定,但是OGL是列主序矩阵,所以先填充的是第一列。
mat3 m =mat3 (1.0, 0.0, 0.0,
0.0, 1.0, 2.0,
0.0, 0.0, 1.0);
vec3 colum1 = (1.0, 0.0, 0.0);
vec3 colum2 = (1.0, 0.0, 0.0);
vec3 colum3 = (1.0, 0.0, 0.0);
mat3 m = mat3(colum1, colum2, colum3);
mat4 m = mat4(colum1, 1.0,
colum2, 2.0,
colum3, 1.0);
矩阵的访问和赋值:
通过下标形式访问和赋值矩阵的一个向量或者一个元素:
mat4 m = mat4(1.0);
vec4 = m[0]; //矩阵的第一列
float yScale = m[1][1];// 矩阵的第二列,第二行

6.结构

结构定义一组类型不一样的数据作为一个组,方便数据的记录和传递;定义一个结构后会定义一个新的类型,并隐式定义一个构造函数,可以通过这个构造函数来给结构赋值,通过.成员名来访问结构中的数据。
struct Particle( float lifetime, vec3 position, vec3 velocity);
Particle p = Particle(3.0, pos, vel);

7.数组

GLSL中可以定义任何类型的数组,包括结构体,从0到n-1, 但是只能是一维的,不能是二维及以上的。数组的声明:
可以指明大小也可以不指明大小,使用的时候指明大小,数组可以作为函数参数和返回值使用。
float coeff[3];// 等价于float[3] coeff;
int coeff[];
定义时候的初始化:
float coeff[3] = float[3](2.3, 1.0, 3.0);
可以用数组的下标来访问数组元素。
数组长度可以用默认内建.length()得到n大小;
for(int i = 0; i < coeff.length(); i++)
{
coeff[i] *= 1.0f;
}

8.布局限定符layout

顶点着色器输出和片段着色器输入不能使用布局限定符(顶点输入和片段输出中才有,输出的index是用于MRT指定的,默认是0)。
layout(location = 0)表示该变量在顶点属性中的位置为0.
对应顶点属性数组中0:
// 设置(设置或解析)数据到顶点属性的指定位置内
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, vVertices);
// 激活GPU内部顶点属性的指定位置
glEnableVertexAttribArray(0);
"#version 300 es                         "
"layout(location = 0) in vec4 vPosition;  "
"void main()                              
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值