glsl 基础语法

摘要:
关键词含义示例:vecn包含n个float类型vec2的向量,vec4ivecn包含n个int类型vec2向量,ivec4uvecn包含n n个uint类型uvec2向量,uvec4bvecn包含n个bool类型bvec2,bvec4创建向量我们可以使用不同的构造函数创建相应的vectors://Vec3policy=ivec3 (1,

向量(Vector)

在 GLSL 中向量一般用于储存顶点坐标、颜色或纹理坐标数据。一个向量可以包含 2 到 4 个分量(Component),分量的类型也可以是以上基础类型中的任意一个,一般情况下我们使用浮点型 vecn 就已经足够了。

关键字

含义

举例

vecn

包含 n 个 float 类型分量的向量

vec2vec4

ivecn

包含 n 个 int 类型分量的向量

ivec2ivec4

uvecn

包含 n 个 uint 类型分量的向量

uvec2uvec4

bvecn

包含 n 个 bool 类型分量的向量

bvec2bvec4

创建向量

我们可以使用不同的构造函数来创建相应的向量:

vec2 coord = vec2(0.5, 0.5); // 含有 2 个 float 类型分量的向量
ivec3 police = ivec3(1, 1, 0); // 含有 3 个 int 类型分量的向量
bvec4 hello = bvec4(true, false, true, false); // 含有 4 个 bool 类型分量的向量

只传入一个参数的情况下会自动将其他值也设为第一个参数:

vec3 three = vec3(0.1); // 等同于 vec3(0.1, 0.1, 0.1)

也可以使用一个向量作为参数传给另一个向量构造函数:

vec2 two = vec2(0.1, 0.2);
vec3 three = vec3(two, 0.3); // vec3(0.1, 0.2, 0.3)

而将“大”向量作为参数来创建“小”向量(降维)会自动抛弃多余的值:

vec4 four = vec4(0.1, 0.2, 0.3, 0.4);
vec3 three = vec3(four); // 等同于 vec3(0.1, 0.2, 0.3),抛弃了 0.4

 分量

实际上所有向量都可以使用 xyzw、rgbastpq 分量名,但是为了代码的严谨性和可读性,建议使用相应的分量名

分量名(对应第 1 - 4 个分量)

使用场景

x, y, z, w

顶点坐标向量

r, g, b, a

颜色向量

s, t, p, q

纹理坐标向量

重组

另外,你还可以使用同一组分量名的任意组合来创建一个新的向量:

vec4 coord = vec4(0.1, 0.2, 0.3, 0.4);
vec2 one = coord.xx; // vec2(0.1, 0.1)
vec2 two = coord.xy; // vec2(0.1, 0.2)
vec3 three = coord.xzw; // vec3(0.1, 0.3, 0.4)
vec4 four = coord.wzyx; // vec4(0.4, 0.3, 0.2, 0.1)
vec4 boom = coord.xyzw + coord.wzyx; // vec4(0.5, 0.5, 0.5, 0.5)
vec4 hello = vec4(coord.zyx, 0.0); // vec4(0.3, 0.2, 0.1, 0.0)

矩阵(Matrix)

矩阵最多能够支持 4 列 4 行的数据,且其元素只能够为 float 类型。

下面表格中的 nm 皆为 2 到 4 的任意数字

关键字

含义

举例

matnxn /matn

表示一个 n 列 n 行的浮点型矩阵

mat2mat3mat3x3

matnxm

表示一个 n 列 m 行的浮点型矩阵

mat2x3mat4x3

创建矩阵

使用不同的构造函数来创建相应的矩阵:

// 创建一个 2x2 的矩阵
mat2 two = mat2(0.1, 0.2, // 第一列
                 0.3, 0.4); // 第二列
0.10.3
0.20.4
// 创建一个 3x3 的矩阵
mat3 three = mat3(0.1, 0.2, 0.3, // 第一列
                  0.4, 0.5, 0.6, // 第二列
                  0.7, 0.8, 0.9); // 第三列
0.10.40.7
0.20.50.8
0.30.60.9
 

只传入一个参数的情况下会自动补零:

mat2 two = mat2(1.0); // 等同于 mat2(1.0, 0.0, 0.0, 0.0)
mat3 three = mat2x3(1.0); // 等同于 mat3(1.0, 0.0, 0.0, 0.0, 0.0, 0.0)

我们也可以向构造函数传入向量来创建矩阵:

vec2 a = vec2(1.0, 0.0);
vec2 b = vec2(0.5, 0.1);
mat2 four = mat2(a, b); // 等同于 mat2(1.0, 0.0, 0.5, 0.1)
// 创建一个 2x3 的矩阵
mat2x3 haha = mat2x3(a, 0.3,
              b, 0.2); // 等同于 mat2x3(1.0, 0.0, 0.3, 0.5, 0.1, 0.2)

降维操作会自动抛弃多余的元素,升维则会自动补零:

// 伪代码
mat3x3(mat4x4); // 保留参数的前 3 列前 3 行的元素
mat2x3(mat4x2); // 保留参数的前 2 列前 2 行的元素,第 3 行补零
 

获取元素

可以通过 [] 操作符来获取矩阵的某个元素(下标从 0 开始):

mat3 three = mat3(0.1, 0.2, 0.3, // 第一列
                  0.4, 0.5, 0.6, // 第二列
                  0.7, 0.8, 0.9); // 第三列
float el = three[0][2]; // 获取第一列第三行的元素:0.3

也可以通过分量名来获取元素:

float el = three[0].z; // 同上,获取第一列第三行的元素:0.3

 采样器(Sampler)

 在 GLSL 中我们需要通过采样器来获取纹理的信息。采样器只能在 Shader 外部的宿主语言中通过 OpenGL 的 API 来进行赋值。

 采样器的类型较多,这里只列出了常见的几个

关键字

含义

smapler2D

用来访问 2D 纹理的句柄

sampler3D

用来访问 3D 纹理的句柄

samplerCube

用来访问立方体映射纹理的句柄

sampler2DArray

用来访问 2D 纹理数组的句柄

剩下不常用的还有 samplerCubeShadowsampler2DShadowsampler2DArrayShadowisampler2Disampler3DisamplerCubeisampler2DArrayusampler2Dusampler3DusamplerCubeusampler2DArray

采样器必须使用 uniform 关键字来修饰,内置的 texture 函数获取颜色:

uniform sampler2D myTexture;
// 通过内置的 texture 函数获取 myTexture 纹理 uv_0 坐标处的颜色
vec4 color = texture(myTexture, uv_0);

结构体(Structure)

 GLSL 允许你使用 struct 关键字来自定义一个新的类型,新的自定义类型可以包含其他已经定义的类型:

// 定义一个名为 circle 的类型,包含一个浮点型成员和一个四维向量成员
struct circle {
    float radius;
    vec4 color;
};
// 创建一个 circle 类型的变量
circle myCircle;
// 单独给 radius 赋值
myCircle.radius = 0.5;

原文链接:https://mp.weixin.qq.com/s/mgyjYWiD9NOCHhNFSfoGJg

免责声明:文章转载自《glsl 基础语法》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇穆里尼奥之皮洛斯式胜利初学安卓开发随笔之 Menu、toast 用法、活动的四种启动模式 以及 一个方便的Base活动类使用方法下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

SAP-ABAP程序开发规范

SAP--ABAP程序开发规范 1  范围 本标准规定了SAP S/4 系统程序开发过程中术语定义、命名规则、程序结构、测试方法和请求管理。 本标准适用于SAP S/4 系统的ABAP语言开发的程序。 2  规范性引用文件 下列文件对于本文件的应用是必不可少的。凡是注日期的引用文件,仅所注日期的版本适用于本文件。凡是不注日期的引用文件,其最新版本(包括所有...

.mtl文件格式解析

最近在导入下载的.OBJ文件,有时会出现只有模型而没有材质渲染的情况。难道材质要自己一点一点重新赋予?抓狂……我知道.OBJ文件用来存储模型信息,观察第一行代码,可以看到材质库文件为mtllib ####.mtl刚开始打开.mtl文件时,根本不明白其中存储的什么信息。百度了一下,发现有一篇前人翻译的.mtl文件格式的文章感谢新浪博主 牛魔公主 ——————...

[C]x字符转义序列

概述       x转义的定义是这样的 转义符 字符值 输出结果 xh[h...] 具有此十六进制码的字符 输出此字符 问题      看似x后面可以接受1或n个十六进制的字符,但是如果你把一个超过ff分十六进制数赋值给一个char变量,会得到一个"Out of range"的提示; #include <stdio.h> #incl...

unity sprite怎么获取切割后的图

学习了一段时间的unity,对里面的组件有一个大致的了解,但是具体操作来说还不是很熟悉,今天看了一片关于unity sprite怎么获取切割后的图的文章,感觉还不错。 假设有一张png/tga图集,导入到Unity,放置目录"Assets/Resources/UI"(UI文件夹可替换成其他的,重要的是要在"Assets/Resources/"路径下),默认...

C++的隐式类型转换

C++是一种复杂的语言,其中有许多“好玩”的特性,学习C++的过程就像在海边捡一颗颗石头,只要坚持不懈,也许一颗颗小石头也能建起你自己小小的城堡。 废话完后,讲讲自己捡到的石头:隐式类型转换  学习出处:《Effective C++》 lostmouse大人翻译 class TestInt{ public:    int GetData()const{...

Java 泛型(一)作用和使用

泛型的使用 : https://www.cnblogs.com/jpfss/p/9928747.html   在没有使用泛型的情况下,如果要实现参数“任意化”,通常会定义成Object类型来接受,然后强制类型转换使用;   而强制类型转换有明显的缺点,就是必须要知道实际参数的具体类型的情况才可以进行转换,同时在强制转换的过程中,编译器不会报错提示的,只有在...