我的OpenGL ES学习之路(一):GLSL着色器语言

 我的OpenGL ES学习之路(一):GLSL着色器语言

着色器语言

GLSL即 OpenGL Shading Language,着色器语言,是和GPU打交道的语言,GLSL的语法比较像C语言。

版本

OpenGL ES的顶点着色器和片段着色器的第一行声明GLSL的版本:

#version 300 es // 使用3.0版本
如果没有声明版本号,则会认为使用1.0版本,着色器的1.0版本用于OpenGL ES 2.0,从OpenGL ES 3.0 开始,规范匹配API和着色器语言的版本号,所以版本才从1.0跳到3.0。

数据类型

基本数据类型

GLSL有三种基本数据类型:float,int,bool,还有由这三种数据类型组成的数组和结构体。

float myFloat = 1.0;
float floatArray[4];
float a[4] = float[](1.0, 2.0, 3.0, 4.0);
float b[4] = float[4](1.0. 2.0, 3.0, 4.0);

向量

vec2, vec3, vec4 // 包含2/3/4个浮点数的矢量
ivec2, ivec3, ivec4 // 包含2/3/4个整数的矢量
bvec2, bvec3, bvec4 // 包含2/3/4个布尔值的矢量
vec2 c[2] = vec2[2](vec2(1.0), vec2(2.0));

矩阵

mat2(或mat2x2), mat2x3, mat2x4 // 2x2/2x3/2x4 基于浮点数的矩阵
mat3(或mat3x3), mat3x2, mat3x4 // 3x3/3x2/3x4 基于浮点数的矩阵
mat4(或mat4x4), mat4x3, mat4x2 // 4x4/4x3/4x2 基于浮点数的矩阵

GLSL不支持指针,

GLSL在类型转换方面有非常严格的规则,变量只能赋值给相同类型的其他变量或者与相同类型的变量进行运算。

float myFloat1 = 1.0;
float myFloat2 = 1; // error: invalid type conversion

同时为了解决这种类型转换,类型提供了一些可用的构造器。可以使用构造器初始化变量,并且作为不同类型的变量之间的转换手段

myFloat = float(true); // Convert from bool -> float
bool myBool = bool(1); // Convert from int -> bool

同样,向量也可以使用构造器,向量构造器的参数传递有两种基本的用法

● 如果只为向量构造器提供一个标量参数,则该值涌来设置向量的所有值
● 如果提供了多个标量或者向量参数,则向量的值从左到右使用这些参数设置

vec4 myVec4 = vec4(1.0); // {1.0, 1.0, 1.0, .10}
vec3 myVec3 = vec3(1.0, 1.0, 1.0); // {1.0, 1.0, 1.0}
vec3 temp = vec3(myVec3);
vec2 myVec2 = vec2(myVec3); // {myVec3.x, myVec3.y}
myVec4 = vec4(myVec2, myVec3); // {myVec2.x, myVec2.y, myVec3.x, myVec3.y}
float a[4] = float[](1.0, 2.0, 3.0, 4.0);
float b[]4 = float[4](1.0. 2.0, 3.0, 4.0); // 数组构造器中的参数数量必须等于数组的大小
vec2 c[2] = vec2[2](vec2(1.0), vec2(2.0));

向量和矩阵分量

向量的单独分量有两种访问形式:使用“.”运算符或者使用数组下标“[]”,根据组成的向量的分量数量,每个分量可以通过使用{x,y,z,w}, {r,g,b,a} 或者{s,t,p,q}组合访问,可以根据向量中不同的数学意义比如向量、颜色值、纹理坐标。但是不能,把这三种访问形式混合使用,比如用x表示第一个分量,用g表示第二个分量

vec3 myVec3 = vec3(1.0, 2.0, 3.0);
vec3 other;
other = myVec3.xxx; // {1.0, 1.0, 1.0}
other = myVec3.xyz; // {1.0, 2.0, 3.0}
other = myVec3.zyx; // {3.0, 2.0, 1.0}
在数组下标访问形式中,元素[0]对应x,元素[1]对应y...
同时,矩阵可以看成是由向量组成的,mat2可以看成是两个vec2组成的,mat3是由三个vec3组成的。
在矩阵中,单独一列可以用数组下标“[]”来访问,然后每一行通过上面介绍的向量的方式来访问

mat4 myMat4 = mat4(1.0)
vec4 col_0 = myMat4[0];
float m_1_1 = myMat4[1][1];
float m_2_2 = myMat4[2].z;

常量

GLSL中可以使用常量,常量是着色器语言中不变的值,在程序中不能被修改,声明常量时,需要加入const修饰符,并且常量在声明时必须初始化。

const float zero = 0.0;
const mat4 myMat = mat4(1.0);

结构

GLSL除了提供基本类型之外,还可以和C语言一样提供结构体

struct fragStruct {
vec4 color;
float start;
float end;
} fragVar; //定义了一个fragStruct的结构体类型和fragVar的结构体变量
fragVar = fragStruct( vec4(0.0, 1.0, 1.0, 1.0), // color
0.5, // start
2.0); // end
vec4 color = fragVar.color;
float start = fragVar.start;
float end = fragVar.end;

运算符

除了 == 和 != 之外,比较运算符(<, <=, >, >=)只能用于标量,要比较向量,可以使用内建函数,针对每个分量进行比较

函数

函数的声明和C语言的一样,函数的使用必须要先提供函数原型声明。还有一点跟C语言的差别很大:函数参数的传递方式,GLSL对函数的传参提供特殊的修饰符,定义函数是否可以修改可变参数

我的OpenGL ES学习之路(一):GLSL着色器语言

内建函数

GLSL中最强大的功能之一就是提供的内建函数,比如用dot来计算两个向量的点乘,用pow来计算标量的幂次

控制流语句

GLSL可以使用if-else的控制逻辑,还可以使用while和do-while循环

if(color.a < 0.5) {
color *= color.a;
} else {
color = vec4(1.0);
}

精度限定符

用户喜欢...

机器学习更接近你身边的微控制器

机器学习(ML)是人工智能(AI)的一个分支,多年来一直在电子系统中应用。但是,直到现在,实施ML所需的处理能力大部分都被限制在基于云计算的活动中。然而,这种情况即将发生变化,随...


梳理 Opengl ES 3.0 (一)宏观着眼

Opengl ES 可以理解为是在嵌入式设备上工作的一层用于处理图形显示的软件,是Opengl 的缩水版本。 下图是它的工作流程示意图: 注意图中手机左边的EGL Layer Opengl ES是跨平台(即可支持不同操...


机器学习中如何选择分类器

在机器学习中,分类器作用是在标记好类别的训练数据基础上判断一个新的观察样本所属的类别。分类器依据学习的方式可以分为非监督学习和监督学习。 非监督学习顾名思义指的是给予分...


你的深度学习应用可能存在安全风险!

导语:深度学习框架和应用中存在许多漏洞,其中15个漏洞拥有CVE编号。漏洞的类型有堆溢出、数字溢出、Use-After-Free漏洞等。 360安全实验室(肖奇学 、Deyue Zhang)、佐治亚大学(李康)和弗...


虚幻引擎学习之路:渲染模块之全局光照明

之前为大家分别介绍了Unreal 4引擎中渲染模块的光照系统、材质系统和相机图像后处理,在本篇文章中,我们将为大家介绍渲染模块的全局光照明这部分内容。 在此,特别感谢Unreal中国团队对...


虚幻引擎学习之路:动画模块之基础篇

之前我们陆续为大家详细介绍了Unreal 4引擎的渲染模块(包括光照系统、材质系统、相机后处理和全局光照明),接下来我们将讲解动画模块的基础功能。 动画模块是游戏引擎中的重要部分,...


深度学习中消失的梯度

了解深度学习的同学可能知道,目前深度学习面临的一个问题就是在网络训练的过程中存在梯度消失问题(vanishing gradient problem),或者更广义地来讲就是不稳定梯度问题。那么到底什么是梯...


学习OpenGL ES之物理引擎

前言 本文将介绍3D物理引擎Bullet的基本使用方式以及如何将之前的OpenGL渲染代码和Bullet相结合,制造一个符合物理运动规则的虚拟3D场景。下面是效果图。 Bullet Bullet是一个开源的物理引擎,...


机器学习方法:从线性模型到神经网络

发现模式 一个模型实际上都是一个从输入到输出的函数,我们希望用这些模型发现数据中的模式,发现数据中存在的函数依赖,当然前提是数据中本身就存在这样的函数依赖。数据集有很多...


专家教你利用深度学习检测恶意代码

当前,恶意软件的检测已经成为全社会关注的网络安全焦点,因为许多时候,单个恶意软件就足以导致数百万美元的损失。目前的反病毒和恶意软件检测产品,一般采用的是基于特征的方法,...


AI医疗2.0时代已到,用深度学习助推人工智能落地

最近市场又被人工智能医疗刷屏了。刷屏的原因就是人工智能继战胜了国际各位围棋棋手之后,又有了一个新的突破,这个突破就是在医疗领域。今年11月,国家医学考试中心发布了“2017年国...


虚幻引擎学习之路:渲染模块之材质系统

接上文:虚幻引擎学习之路:渲染模块之光照系统 在本篇文章中,我们继续介绍渲染模块的另一重要部分:材质系统。 虚幻引擎学习之路:材质系统 材质描述了场景中物体与光照进行交互的...


前途光明的机器学习将走向何方?这里有 5 个关于它的未来预测

机器学习目前是 IT 领域最热门的话题之一,这是因为它在看似无限的应用场景中都能发挥自身的作用。从检测欺诈网站到自动驾驶汽车,再到识别你的“金牌会员”身份以进行价格预测等等...


学习OpenGL ES之教你实现SkyBox

不知道大家是否还记得基于CubeMap的反射效果里介绍的CubeMap,本文将使用CubeMap来制作3D游戏中的一个经典技术,天空盒(SkyBox)。老规矩,先来看下效果图。效果中的地形模型在前面的文章中...


机器学习作用于信息安全的五大顶级案例

通俗讲,机器学习就是“(计算机)无需显式编程即可学习的能力”。跨海量数据集应用数学技术,机器学习算法可建立起行为模型,并基于新输入的数据,用这些模型做出对未来的预测。视...


学习OpenGL ES之教你制作迷雾

前言 本文将为大家介绍一种常见的3D技术-雾(fog)。雾可以让你看不清远处的物体,除了模拟真实环境中的雾效果以外,还可以用来遮挡修饰远处细节精度比较低的模型,让它们看起来没那...