ES着色器语言,OpenGL编制程序语言

By admin in 4858美高梅 on 2019年4月20日

一、前言

一、前言

本章首要内容:
(1)数据、变量和变量类型。
(2)矢量、矩阵、结构体、数组、采样器(纹理)
(3)运算、程序流、函数
(4)attribute、uniform和varying变量
(5)精度限定词
(6)预管理和指令

前言

       近期重头痛胸闷,妈蛋好优伤,请假了三天,汽车驾驶员培训学校也没去,差不多僵硬!今日一而再WebGL的学习。

       近日重尿少涩痛,妈蛋好优伤,请假了三天,汽车驾驶员培训学校也没去,简直僵硬!前几天后续WebGL的学习。

  1. WebGL并不补助GLSL ES 1.00的具备天性。实际上,它辅助的是一.00本子的1个子集,当中只包含WebGL供给的那个大旨本性。

  2. GLEL
    ES编程语言是在OpenGL着色器语言(GLSL)的根底上,删除和简化1部分后产生的,下跌了硬件消耗,裁减了品质开销。

  3. 基础:
    (1)程序式大大小小写敏感
    (二)每三个说话都应有以2个英文分号结束

  4. 进行顺序
    从main函数开端实践。
    着色器程序有且仅有二个main()函数,而且该函数无法经受别的参数。
    main函数前的void关键字表示这一个函数不回去任何值。

  5. 注释
    单行注释: // int kp = 4玖陆;
    多行注释: /* haha */

  6. 数码值类型(数值和布尔值)
    GLSL支持三种多少值类型
    (1)数值类型:整数(未有小数点)和浮点数(有小数点)
    (2)布尔值类型:true 和 false
    不帮忙字符串类型

  7. 变量
    规则:
    (一)只囊括a-z,A-Z,0-九和下划线_
    (2)变量名的首字母无法是数字
    (3)不可能是根本字和保留字,但是变量名的壹某些能够是它们
    (4)不能以gl_webgl_,或_webgl_起来,那一个前缀已经被OpenGL
    ES保留了

4858美高梅 1

 

 

4858美高梅 2

近日在研究OpenGL
被各样面生的名词虐成狗,所以记录下来一些就学知识点供就学和参考.

二、正文

二、正文

GLSL ES关键字

GLSL是什么?

       A. GLSL辅助二种多少值类型:

       A. GLSL协助二种多少值类型:

4858美高梅 3

GLSL(OpenGL Shading Language)
是OpenGL的着色器语言,纯粹的和GPU打交道的计算机语言.能够领会为C的变种专门针对OpenGL编制程序,不协助指针等等一些C的个性等.
(名词解释:着色器

  1. 整数型(int)与浮点型(float),没小数点的就是整数,反之则是浮点数;
  2. 帮衬布尔值类型(bool);
  3. GLSL
    ES不协助字符串类型
  4. 改变情势:转变类型(被转换类型),如:int(float)
  1. 整数型(int)与浮点型(float),没小数点的就是整数,反之则是浮点数;
  2. 扶助布尔值类型(bool);
  3. GLSL
    ES不帮助字符串类型
  4. 改动格局:调换类型(被撤换类型),如:int(float)

GLSL ES保留字

GPU是102线程并行Computer,GLSL直接面向单指令流多数据流模型的四线程计算。

 

 

  1. GLSL ES是强类型语言
    (一)GLSL ES要求切切实实指明变量的数据类型: <类型>
    <变量名>
    如: vec4 a_Position
    (贰)定义函数时,必须钦点函数的重回值
    (三)在开展赋值操作(=)的时候,等号左右两侧的数据类型也务必1致,不然就会出错

  2. 中央类型

GLSL编写的着色器函数是对每种数据同时实施的。

       B. []
运算符

       B. []
运算符

4858美高梅 4

各类终端都会由顶点着色器中的算法管理,各种像素也都会由
局部着色器中的算法管理。

      
[]运算符通过数组下标来访问矢量或矩阵的要素,例:

      
[]运算符通过数组下标来访问矢量或矩阵的元素,例:

GLSL的骨干项目

初学者在编写自身的着色器时,须要思索到SIMD的产出本性,并用并行计算的笔触来考虑难点那正是GLSL.

       float m23 = m4[1][2];
m肆的第3列中的第二个因素

       float m23 = m4[1][2];
m4的第3列中的第一个因素

为变量内定项目有利于WebGL系统一检查查代码错误,进步程序的运营功效。
如: float klimt // 浮点数变量

我们最广泛的用法是在 极端着色器里转换所须求的值,然后传给
片断着色器用.

 

 

  1. ES着色器语言,OpenGL编制程序语言。赋值和类型转变
    = 用于赋值,赋值时要力保左边变量的门类和右手的值类型一致

GLSL能做什么样

       C.
变量限定词

       C.
变量限定词

日以逼真的材料 – 金属,岩石,木头,油漆等

  1. const 该变量值无法被退换;

  2. attribute只可以出现在终点着色器且只好被声称为全局变量;

  3. uniform能够在极限或片元着色器中,且必须是全局变量,其为只读而且在同名时能被共享;
  4. varying必须是全局变量,功能正是从顶点着色器向片元着色器传输数据,必须在二种着色器中申明同名,同品种的varying变量。
  1. const 该变量值无法被改成;

  2. attribute只可以出现在顶峰着色器且不得不被声称为全局变量;

  3. uniform能够在终点或片元着色器中,且务必是全局变量,其为只读而且在同名时能被共享;
  4. varying必须是全局变量,功用正是从顶点着色器向片元着色器传输数据,必须在两种着色器中宣称同名,同种类的varying变量。
float f2 = 8.0;

稳步逼真的光照效果 – 区域光和软阴影

 

 

能够动用内置函数举行类型调换,如:

非实际材料 – 美术效果,钢笔画,摄影和对插画才具的优孟衣冠

       D.
精度限定词

       D.
精度限定词

float f3 = float(8);

针对纹理内部存款和储蓄器的新用处

  1. highp 高精度 (-2^62,2^62)
    2^-16;

  2. mediump 中精度 (-2^14,2^14)
    2^-10;

  3. lowp 低精度 (-2,2)
    2^-8
  1. highp 高精度 (-2^62,2^62)
    2^-16;

  2. mediump 中精度 (-2^14,2^14)
    2^-10;

  3. lowp 低精度 (-2,2)
    2^-8

4858美高梅 5

更少的纹路访问

4858美高梅 6

4858美高梅 7

类型调换内置函数

图形处理 – 选用,边缘钝化遮蔽和复杂性混合

 

 

  1. 运算符

动画片效果 – 关键帧插值,粒子系统

 

 

4858美高梅 8

用户可编制程序的反走样方法

三、结尾

三、结尾

核心项目标运算符

GLSL注意

       前一周随着看《WebGL编制程序指南》,牢固学习进度。

       下一周跟着看《WebGL编制程序指南》,牢固学习进程。

说明:

GLSL支持函数重载(就是父类定义方法,子类复写该方法叫重载)

[1]
在伸开逻辑与(&&)运算时,唯有首先个表明式的总计值为true时才会一个钱打二拾七个结第三个表明式。同样,在进展逻辑或(||)运算时,只有首先个表达式的值为false时才会测度第三个表明式。

GLSL不设有数据类型的自发性晋级(便是不帮忙项目自动进化转变 eg:float 转
double),类型必须严酷保持1致.

[2]
逻辑异或(^^)运算的含义是:唯有当左右四个表明式中有且仅有二个为true时,运算结果才是true,否则为false。

GLSL不扶助指针,字符串,字符,它基本上是1种处理数字数据的语言

  1. 矢量和矩阵
    (一)矢量和矩阵类型的变量都包涵多少个要素,各种成分是四个数值(整型数、浮点数和布尔值)
    矢量将这个因素排成1列,可以用来代表顶点坐标或颜色值等,而矩阵将成分划分成行和列,能够用来代表调换矩阵。

GLSL不帮助联合、枚举类型、结构体位字段(>> or <<
左右移)及按位运算符(| or &那种按位与)
(正是干掉麻烦的C操作
让那个更单纯的管理图片数据利用)

4858美高梅 9

GLSL的数据类型

6-6.png

GLSL有二种为主数据类型:

(二)赋值和结构
(a) =
等号用于赋值,如:vec4 position = vec4(1.0, 2.0, 3.0, 4.0);
(b)构造函数:专门创立钦赐项目标变量的函数,构造函数的称号和其创立的变量类型名称总是同样的。

float

(三)矩阵构造函数
(a)想矩阵构造函数中传来矩阵的每1个成分的数值来布局矩阵,注意传入值的顺序必须是列主序的

int

4858美高梅 10

double

(b)向矩阵构造函数中传来二个或七个矢量,遵照列主序使用矢量里的成分值来组织矩阵。

由float、int、double组成的array[]依旧结构体

// 使用两个vec2对象来创建mat2对象
vec2 v2_1 = vec2(1.0, 3.0);
vec2 v2_2 = vec2(2.0, 2.0);
mat2 m2_1 = mat2(v2_1, v2_2);   // 1.0  2.0
                                //  3.0  4.0

// 使用一个vec4对象来创建mat2对象
vec4 v4 = vec4(1.0, 3.0, 2.0, 4.0);
mat2 m2_2 = mat2(v4);     // 1.0  2.0
                          //  3.0  4.0

42// 十进制

(c)向矩阵构造函数中出阿奴矢量和数值,根据列主序动用矢量里的元素值和一贯传入的数值来布局矩阵

042// 八进制

// 使用两个浮点数和一个vec2对象来创建mat2对象
mat2 m2 = mat2(1.0, 3.0, v2_2);      // 1.0  2.0
                                     //  3.0  4.0

0x二A// 十陆进制

(d)向矩阵构造函数中流传单个数值,这样将生成二个对角线元宵素都是该数值,其余因素为0.0的矩阵

留意:GLSL不援助指针,GLSL把向量和矩阵作为主旨数据类型

mat4 m4 = mat4(1.0);    // 1.0  0.0  0.0  0.0
                        // 0.0  1.0  0.0  0.0
                        // 0.0  0.0  1.0  0.0
                        // 0.0  0.0  0.0  1.0

向量:有伊始地方有方向的线条,也称作
矢量(不要被这几个名词吓到,作者回想这些向量是本人高中二年级的时候数学学的东西).

与矢量构造函数类似,假如传入的数值的数额超过一,有未有高达矩阵元素的多少,就会出错

矢量

mat4 m4 = mat4(1.0, 2.0, 3.0);    // 错误。mat4对象需要16个元素

矢量能够和标量乃至矩阵做加减乘除(必须遵循一定规则才能够 不然报错)

(叁)访问成分
为了访问矢量或矩阵中的成分,能够应用.[]运算符
(a).运算符

vec二, vec叁, vec四 //包罗2/百分之七十五个浮点数的矢量

4858美高梅 11

ivec二, ivec3, ivec四 //包罗2/四分之三个整数的矢量(整形数 前面带i 代表integer)

分量名

bvec2, bvec3, bvec四 //包涵2/百分之七十五个布尔值的矢量

别的方便的x,r或s分量都会回去第三个轻重,y,g,t分量都会重临首个轻重。
如:

上面这个是一种GLSL的数据类型, 能够简简单单领悟为 vec+数字 就意味着
是一个数组里面放多少个要素(应该都是 vec二~vec四时期,没见过
vec5以上和vec二之下,好像那就象征几维坐标系),暗许成分是float浮点类型,前边带i代表integer整形,b代表bool.

vec3 v3 = vec3(1.0, 2.0, 3.0);    // 将v3设为(1.0, 2.0, 3.0)
float f;

f = v3.x;  // 设f为 1.0
f = v3.y;  // 设f为 2.0
f = v3.z;  // 设f为 3.0

f = v3.r;  // 设f为 1.0
f = v3.s;  // 设f为 1.0

vec如何评释使用?

将(同1个成团的)四个轻重名联合置于点运算符后,就足以从矢量中而且收收取几个轻重。那些进程乘坐混合(swizzling)
如: v2 = v3.xz
此刻的多少个轻重必须属于同2个聚焦,比方说,你不能动用v叁.was

vec三 v; //申明三个维度浮点型向量v

(b)[]运算符
矩阵中的成分从下标0起来按部就班列主序读取。
限制:[]中只可以冒出的索引值必须是常量索引值

v[1] = 3.0;
//给向量v的第二个因素赋值(数组从0发轫,下标为一正是首个要素)

常量索引值概念如下:
(a)整型字面量(0或壹)
(b)用 const 修饰的全局变量或部分变量。不包罗函数参数。
(c)循环索引
(d)由前述三条中的项整合的表达式

//下边三种等价

const int index = 0  // const 关键字表示变量是只读的
vec4 v4a = m4[index]  // 同m4[0]相同

vec3 v = vec三; //数组是连接的积存空间 也正是任何成分默许被这一个0.陆值填充

小心,你无法选用未经const修饰的变量作为索引值,因为它不是三个常量索引值(除非它是循环索引)。

vec3 v = vec3(0.6,0.6,0.6);

int index1 = 0
vec4 v4c = m4[index2]    // 错误:index不是常量索引

在意:
除了用索引格局外,还是能够用选取运算符的点子来选用向量.择运算符是对于向量的逐1要素约定俗成的称呼,用三个大写拉丁字母来代表。依据向量表示对象的意义差别,能够动用以下采取运算符:

(4)运算符
对于矢量和矩阵,只好够接Nabi较运算符中的==
!=,不得以动用><>=<=
借使想要比较矢量和矩阵的分寸,应该是用内置函数,举个例子lessThan()
壹旦你想逐分量相比,能够运用内置的函数equal()notEqual()

代表顶点能够用

4858美高梅 12

代表颜色能够用

矢量和矩阵可用的运算符

表示纹理坐标用

  1. 矢量和浮点数的演算

两种任选壹种都同一,作用莫不相异的. 也便是说,若是v是2个向量,那么:

4858美高梅 13

v[0]

(壹) 矢量运算

v.x

4858美高梅 14

v.r

(贰) 矩阵和浮点数的运算

v.s

4858美高梅 15

都指的是向量v的第二个因素。

(3)矩阵右乘矢量

例如:

4858美高梅 16

//用构造函数的秘技宣示并先河化四维浮点型

(4) 矩阵左乘矢量

vec4v1 =vec4(1.0,2.0,3.0,4.0);

4858美高梅 17

vec4v2;

(五)矩阵与矩阵相乘

v二.xy=v一.yz;//将v1的第四个和第多个要素复制到v二的率先个和第壹个要素

4858美高梅 18

v2.z=二.0;//给v二的第多少个元素赋值

  1. 结构体
    (一)结构体:用户自定义的种类,使用主要字
    struct,将已存在的种类聚合到一齐,就能够定义为结构体。如:

v2.xy=v一.yx;//将v一的头七个因素沟通,再复制到v二的头多少个要素中

矩阵

struct light {    //  定义结构体light
  vec4 color;    // 光的颜色
  vec4 position;    // 广元位置
} 
light 11, 12;    // 声明了light类型的变量11和12

矩阵以下种类皆以mat开端

也能够在概念结构体的还要证明该协会体类型类型的变量,如:

mat2 代表2×2的矩阵

struct light {    //  定义结构体和定义变量同时进行
  vec4 color;    // 光的颜色
  vec4 position;    // 广元位置
} 11;    // 该结构体类型的变量11

mat3 代表3×3的矩阵

(2)赋值和结构
结构体有标准的构造函数,其名目与构造体名1致。构造函数的参数的次第必须与组织体定义中的成员相继壹致。

mat4 代表4×4的矩阵

4858美高梅 19

瞩目:矩阵是按列顺序组织的,先列后行

组织体构造函数的使用办法

如下代码:

(三)访问成员
在结构体变量名后跟点运算符(.),然后再加上成员名,就足以访问变量的积极分子。如:

mat四m;//注解四维浮点型方阵m

vec4 color = 11.color;
vec3 position = 11.position;

m[2][3]=二.0;//给方阵的第一列、第伍行成分赋值

  1. 数组
    (1)
    ELSL ES
    只支持1维数组,而且数组对象不协助pop()和push()等操作,制造数组时也不必要接纳new运算符。
    声称数组,只必要在变量名后加上中括号和数主管度,如:

// 下边二种等价,伊始化矩阵对角

mat2m =mat2

float floatArray[4];    // 声明含有4个浮点数元素的数组
vec4 vec4Array[2];    //  声明含有两个vec4对象的数组

mat2m =mat2(1.0,0.0,0.0,1.0);

数组的长度必须是大于0的整型常量表明式,定义如下:
(a)整型字面量(如0或一)
(b)用const限定字修饰的全局变量或局地变量,不包含函数参数
(c)由前述两条中的项组成的表达式

取样器

举例:

纹理查找需求制定哪个纹理可能纹理单元将制定查找.

int size = 4;
vec4 vec4Array[size];    // 错误。如果第一行为const int size = 4;则不会报错

sampler1D// 访问1个1维纹理

小心,你不得以用const限定字来修饰数组本人。

sampler二D// 访问二个2维纹理

唯有整型常量表明式和uniform变量能够被用作数组的索引值。
数组无法在申明时被1遍性地开首化,而必须显式地对各样成分实行初阶化。如:

sampler3D// 访问多个三维纹理

vec4Array[0] = vec4(4.0, 3.0, 6.0, 1.0);
vec4Array[1] = vec4(3.0, 2.0, 0.0, 1.0);

samplerCube// 访问3个立方贴图纹理

数组自己只支持[]运算符,但数组的成分能够到场其自作者类型帮忙的放4运算。如:

sampler1DShadow// 访问三个带比较的一维深度纹理

// 将floatArray的第二个参数乘以3.14
float f = floatArray[1] * 3.14;
// 将vec4Array的第一个参数乘以vec4(1.0, 2.0, 3.0 ,4.0)
vec4 v4 = vec4Array[0] * vec4(1.0, 2.0, 3.0 ,4.0);

sampler二DShadow// 访问三个带相比的二维深度纹理

  1. 取样器(纹理)
    总得经过取样器(sampler)类型变量访问纹理。
    有二种基本类型的取样器类型:sampler2DsamplerCube
    取样器变量只可以是uniform变量,只怕须求拜访纹理的函数,如texture2D()函数的参数,如:

uniformsampler2Dgrass;

vcc2 coord =vec2;

uniform sampler2D u_Sampler;

vec4color =texture2D(grass, coord);

唯有纹理单元编号可以给取样器变量,而且必须利用gl.uniformli()来开始展览赋值。

假如三个着色器在程序里结合八个文理, 能够行使取样器数组.

除了===!=,取样器变量不能当做操作数参预运算。

constinttex_nums =4;

取样器变量受到着色器援救的纹理单元的最大数目限制。

uniformsampler2Dtextures[tex_nums];

4858美高梅 20

for(inti =0; i < tex_nums; ++i) {

着色器中取样器类型变量的蝇头数量

sampler2Dtex = textures[i];

mediump是2个精度限定字

// todo …

  1. 运算符优先级

}

4858美高梅 21

结构体

  1. 程序流程序调整制:分支和巡回
    (1)if 和 if-else

这是绝无仅有的用户能用的自定义类型

![](https://upload-images.jianshu.io/upload_images/3779867-870270bebbb99ae1.png)

if语句格式

struct light

如:

{

if (distance < 0.5) {
  gl_fragColor = vec4(1.0, 0.0, 0.0, 1.0);
} else {
  gl_fragColor = vec4(0.0, 1.0, 0.0, 1.0);
}

vec3position;

(2)for语句

vec3color;

4858美高梅 22

};

for语句格式

light ceiling_light;

如:

数组

for (int i = 0; i < 3; i++) {
  sum += i;
}

数组索引是从0伊始的,而且从不指针概念

小心:循环变量i只可以在早先化表达中定义,条件表达式可感觉空,假诺那样做,空的尺码表明式重回true

// 创制3个13个要素的数组

for语句的别样限制:
(a)只同意有多个循环变量,循环变量只好是intfloat类型。
(b)循环表明式必须是以下的款型:i++,i--,i+=常量表达式或i-=常量表达式
(c)条件表达式必须是循环变量与整型常量的可比
(d)在循环体内,循环变量不可被赋值
那个限制的留存是为了使编写翻译器就可见对for循环进行内联合展览会开

vec4points[10];

(3)continue、break和discard语句
(a)continue终止包蕴该语句的最内层循环和施行循环表达式(递增/递减循环变量),然后试行下三次巡回
(b)break中止包括该语句的最内层循环,并不在继续实行循环。

// 创造三个不点名大小的数组

如:

vec4points[];

// continue case
for (int i = 0; i < 10; i++) {
  if (i == 8) {
    continue;    // 跳过循环体余下的部分,继续下次循环
  }
  // 当i==8时,不会执行到这里
}

// break case
for (int i = 0; i < 10; i++) {
  if (i == 8) {
    break;    // 跳出for循环
  }
  // 当i>=8时,不会执行这里
}
// 当i==8时,执行这里

points[2] =vec四;// points未来大小为叁

至于discard,它不得不在片元着色器中央银行使,表示抛弃当前片元直接管理下一片元。

points[7] =vec4;// points未来高低为八

  1. 函数
    (1)

void

4858美高梅 23

不得不用来注解函数重返值

函数语句格式

类型转变

可以未有return语句,不过回去类型必须是void
也能够将协和定义的结构体钦点为回到类型,但是结构体的分子中不可能有数组。

总得分明地进行类型调换,不会自行类型升高

示例:

floatf =2.3;

// RGBA颜色值转为亮度值函数
float luma(vec4, color) {
  return 0.2126 * color.r +  0.7162 * color.g +  0.0722 * color.b;
}

// 调用
attribute vec4 a_Color    // 传了(r, g, b, a)的值
void main() {
  ...
  float brightness = luma(a_Color);
  ...
}

boolb =bool;// b is true

注意,尽管调用函数时传出的参数类型与性命函数时钦赐的参数类型分裂样,就会出错。
如:

限定符

float square(float value) {
  return value * value;
}

void main() {
  ...
  float x2 = square(10);   // 错误。应用10.0
  ...
}

GLSL中有6个限定符(variable
qualifiers)可供使用,它们限定了被标志的变量无法被更换的”范围”.

因为函数声明时的参数是float类型,而调用时却传来了int类型的值。

const

(二)标准证明
设若函数定义在其调用之后,那么大家务必在举办调用在此以前先表明该函数的专门的学问。
行业内部会先行告诉WebGL系统函数的参数、参数类型、重临值等等
如:

attribute

float luma(vec4, color);   // 规范声明
main() {
  ...
  float brightness = luma(a_Color);  // luma在定义之前就被调用了
  ...
}

float luma(vec4, color) {
  return 0.2126 * color.r +  0.7162 * color.g +  0.0722 * color.b;
}

uniform

(3)参数限定词
GLSL ES中,可以为参数内定限定自,以调控参数的一举一动。
咱们得以将函数参数定义成:
(a)传递给函数的
(b)就要在函数中被复制的
(c)既是传递给函数的,也是快要在函数中被赋值的。
中间(b)和(c)都有点类似于C语言中的指针

varying

4858美高梅 24

const: 和C++里差不离,定义不可变常量

(四)内置函数

意味着限定的变量在编写翻译时不可被修改.

4858美高梅 25

attribute:是应用程序传给顶点着色器用的

  1. 全局变量和部分变量
    attribute、varying和uniform变量都必须注明为全局变量

不允许注脚时开头化

(一)存款和储蓄限定字
在GLSL
ES中,大家日常利用attributevaryinguniform限定字来修饰变量,如下图所示。别的,有时也会选拔const限定字,它表示着色器中的有个别变量是永远的常量。

attribute限定符标识的是1种全局变量,该变量在顶峰着色器中是只读(read-only)的,该变量被当做从OpenGL应用程序向终极着色器中传递参数,因此该限定符仅能用来顶点着色器.

4858美高梅 26

attribute变量是只可以在vertex shader中动用的变量

(2)const变量
const变量写在品种在此之前,表明的还要务必对它实行初步化,申明之后就不可能再去改换它们的值了。
如:

它无法在fragment shader中宣示attribute变量,

const int a = 3232

也不可能被fragment shader中选拔)

(3)Attributr变量
只好冒出在极端着色器中,只可以被声称为全局变量,被用来表示逐顶点的音信。
终极着色器中可见容纳的attribute变量的最大数额与装备有关,你能够由此走访内置的大局常量来博取最大数量的值。
只是无论是设备怎么样,帮衬WebGL的景况都协理至少8个attribute变量。

在application中,一般用函数glBindAttribLocation()来绑定每一个attribute变量的地方,然后用函数

4858美高梅 27

glVertexAttribPointer()为各样attribute变量赋值。

(4)uniform变量
可以用在巅峰着色器和片元着色器中,且务必是全局变量
uniform变量只读,能够是除了数组或结构体之外的自由档期的顺序。
假设在顶峰着色器和片元着色器中宣示了同名的uniform变量,那么它就会被三种着色器共享。
uniform变量包涵了一如既往(非逐顶点/逐片元的,各顶点或各片元公用)的数量,JS应该向其传递此类数据。
比方说,调换矩阵就不是逐确定地点的,而是有着终端共用的,所以它在着色器中是uniform变量。

以下是例证:

uniform mat4 u_ViewMatrix

uniform mat4 u_matViewProjection;

(5)varying变量
必须是全局变量
从极限着色器向片元着色器传输数据。
非得在二种着色器中生命同名、同品种的varying变量

attribute vec4 a_position;

varying vec2 v_TexCoord
varying vec4 v_Color

attribute vec2 a_texCoord0;

varying变量只可以是以下体系:floatvec2vec3vec4mat2mat3mat4
极端着色器中赋给varying变量的值并不是平素传给了片元着色器的varying变量,那在那之中发生了光栅化的长河:依据绘制的图样,对前者(顶点着色器varying变量)举行内插,然后再传递个后者(片元着色器varying变量)
幸亏因为varying变量要求被内插,所以我们需求限制它的数据类型

varying vec2 v_texCoord;

配备至少援救7个varying变量

void main

  1. 精度限定字
    扶持着色器程序提升运行成效,削减内部存款和储蓄器开支。
    可选,不鲜明精度能够应用合适的私下认可值:

{

gl_Position = u_matViewProjection * a_position;

#ifdef GL_ES
precision mediump float;
#endif

v_texCoord = a_texCoord0;

WebGL中帮忙的三种精度

}

4858美高梅 28

uniform:一般是应用程序用于设定顶点着色器和片断着色器相关开头化值.不容许证明时先导化.uniform限定符标志的是一种全局变量,该变量对于三个图元(primitive)来讲是不可改换的
它能够从OpenGL应用程序中吸收传递来的参数

注意:
(一)在好几WebGL情形中,片元着色器或然不帮助highp精度
(二)数值范围和精度实际上也是与系统遭受互为表里,可以动用gl.getShaderPrecisionFormet()来检查

uniform变量 外部程序传递给shader的变量.

如:

函数glUniform**()函数赋值的.

mediump float size;  //  中精度浮点型变量
highp vec4 position;  //  具有高精度浮点型的vec4对象
lowp vec4 color;  //  具有低精度浮点型的vec4对象

shader 中是只读变量,不能够被 shader 修改.

宣示着色器的暗许精度,那行代码必须在终端着色器或片元着色器的顶部:
precision 精度限定自 品种名称
意味着接下去全部不以精度限定自修饰的该类型标量,其精度正是暗中同意精度,如:

uniform变量一般用来表示:转换矩阵,质地,光照参数和颜色等音信。

precision mediump float;

uniform mat4 viewProjMatrix; //投影+视图矩阵

4858美高梅 29

uniform mat肆 viewMatrix; //视图矩阵

6-27.png

uniform vec三 lightPosition; //光源地方

只有片元着色器中的float类型没有暗许精度,大家需求手动钦命。

varying:用于传递顶点着色器的值给片断着色器.它提供了从巅峰着色器向部分着色器传递数据的艺术,varying限定符能够在巅峰着色器中定义变量,然后再传递给光栅化器,光栅化器对数码插值后,再将各种片段的值交给片段着色器.

  1. 预处理指令
    用来在真正编译以前对代码举行预管理,#开始

varying变量是vertex和fragment shader之间做多少传递用的。

4858美高梅 30

貌似vertex shader修改varying变量的值,

6-28.png

下一场fragment shader使用该varying变量的值。

#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;  //  支持高精度,限定浮点型为高精度

#else
precision mediump float;  //  不支持高精度,限定浮点型为中精度
#endif
#endif

于是varying变量在vertex和fragment shader二者之间的声

能够只是用#version number来钦赐着色器使用的GLSL ES版本

明必须是一模同样的。

能够承受的本子包蕴100(GLSL ES 一.00)和拾一(GLSL ES
壹.0一)。要是不应用#version命令,暗中认可版本为100

application不能够选择此变量。

钦点版本代码:

以下是例证:

#version 101

// Vertex shaderuniform

#version 指令必须在着色器顶部,在它在此以前只好有注释和空域。

mat4 u_matViewProjection;

attribute vec4 a_position;

attribute vec2 a_texCoord0;

varying vec2 v_texCoord; // Varying in vertex shader

void main

{

gl_Position = u_matViewProjection * a_position;

v_texCoord = a_texCoord0;

}

// Fragment shaderprecision

mediump float;

varying vec2 v_texCoord; // Varying in fragment shader

uniform sampler2D s_baseMap;

uniform sampler2D s_lightMap;

void main()

{

vec4 baseColor;

vec4 lightColor;

baseColor = texture2D(s_baseMap, v_texCoord);

lightColor = texture2D(s_lightMap, v_texCoord);

gl_FragColor = baseColor * (lightColor + 0.25);

}

只顾:以上那二种范围符很要紧

限制性

不可能在if-else中扬言变量

用以决断的原则必须是bool类型(if,while,for…)

操作符后四个参数必须类型一样

不支持switch语句

vec4toonify(infloatintensify)

{

vec4color;

color =vec4(0.8,0.8,0.8,0.8)

returncolor;

}

discard

discard关键字可防止止有个别更新帧缓冲区,当流动调查节蒙受那么些至关心保养要字时,正在处理的1部分就会被标识为丢.

一经不明了什么叫标志为丢 可以参考一下UIView的绘图进度

函数

4858美高梅 ,函数名能够通过参数类型重载,可是和再次回到值类型非亲非故

具备参数必须完全协作,参数不会自行

函数不可能被递归调用

函数重回值无法是数组

函数参数标记符

in: 进复制到函数中,但不回来的参数

out: 不将参数复制到函数中,但回到参数

inout: 复制到函数中并赶回

错落操作

通过在选用器后列出各分量名,就足以选拔那一个分量

vec4v4;

v4.rgba;// 得到vec4

v4.rgb;// 得到vec3

v4.b;// 得到float

v4.xy;// 得到vec2

v四.xgba;// 错误!分量名不是同壹类

v肆.wxyz;// 打乱原有分量顺序

v肆.xxyy;// 重复分量

终极推荐1个GLSL编辑调节和测试工具OpenGL Shader Builder(Graphics Tools.dmg)

全文完

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有