OpenGL ES 3. 着色器 shader 语言 二

大家好,接着上节继续为大家介绍OpenGL ES 3.x 着色器语言:shader language  。

8、运算符

优先级(越小越高)运算符说明结合性
1()聚组:a*(b+c)N/A
2[] () . ++ --数组下标__[],方法参数__fun(arg1,arg2,arg3),属性访问__a.b__,自增/减后缀__a++ a--__L - R
3++ -- + - !自增/减前缀__++a --a__,正负号(一般正号不写)a ,-a,取反__!false__R - L
4* /乘除数学运算L - R
5+ -加减数学运算L - R
7< > <= >=关系运算符L - R
8== !=相等性运算符L - R
12&&逻辑与L - R
13^^逻辑排他或(用处基本等于!=)L - R
14||逻辑或L - R
15__? :__三目运算符L - R
16= += -= *= /=赋值与复合赋值L - R
17,顺序分配运算L - R

 

左值:表示一个储存位置,可以是变量,也可以是表达式,但表达式最后的结果必须是一个储存位置。

右值:表示一个值, 可以是一个变量或者表达式再或者纯粹的值。

操作符的优先级:决定含有多个操作符的表达式的求值顺序,每个操作的优先级不同。

操作符的结合性:决定相同优先级的操作符是从左到右计算,还是从右到左计算。

 

9、函数参数限定符

函数的参数默认是以拷贝的形式传递的,也就是值传递,任何传递给函数参数的变量,其值都会被复制一份,然后再交给函数内部进行处理.。我们可以为参数添加限定符来达到传递引用的目的,OpenGL提供的参数限定符如下:

限定符说明
< none: default >默认使用 in 限定符
in复制到函数中在函数中可读写
out返回时从函数中复制出来
inout复制到函数中并在返回时复制出来

 

10、函数示例

注意:GLSL中的函数不能递归

vec4 getPosition(){ 
    vec4 v4 = vec4(0.,0.,0.,1.);
    return v4;
}

void doubleSize(inout float size){
    size= size*2.0  ;
}
void main() {
    float psize= 10.0;
    doubleSize(psize);
    gl_Position = getPosition();
    gl_PointSize = psize;
}

 

11、精度限定

GLSL在进行光栅化着色的时候,会产生大量的浮点数运算,这些运算可能是当前设备所不能承受的,所以GLSL提供了3种浮点数精度,我们可以根据不同的设备来使用合适的精度。

在变量前面加上 highp mediump lowp 即可完成对该变量的精度声明。

lowp float color;
mediump vec2 Coord;
lowp ivec2 foo(lowp mat3);
highp mat4 m;

我们一般在片元着色器(fragment shader)最开始的地方加上 precision mediump float; 便设定了默认的精度,这样所有没有显式表明精度的变量都会按照设定好的默认精度来处理。

可以设置变量的默认精度,如果变量声明时没有使用精度限定符,将会拥有该类型的默认精度,默认精度可以在顶点或者片段着色器的开头指定:

precision highp float;
precision mediump int;

同时,在顶点着色器中,如果没有指定默认精度,int 和 float 值的默认精度都是highp,但是在片段着色器中,float没有默认的精度,每个着色器必须声明一个默认的float精度,或者为float变量手动指定精度。

12、变量修饰符  

修饰符说明
none默认类型
const声明变量或函数的参数为只读类型
uniform在运行时shader无法改变uniform变量,一般用来放置程序传递给shader的变换矩阵,材质,光照参数等等
in出入着色器的变量
out着色器传出的变量

const:

和C语言类似,被const限定符修饰的变量初始化后不可变,除了局部变量,函数参数也可以使用const修饰符。但要注意的是结构变量可以用const修饰, 但结构中的字段不行。

const变量必须在声明时就初始化 const vec3 v3 = vec3(0.,0.,0.)。

局部变量只能使用const限定符。函数参数只能使用const限定符。

uniform:

uniform变量是全局只读的,在整个shader执行完毕前其值不会改变,他可以和任意基本类型变量组合,一般我们使用uniform变量来放置:外部程序传递来的环境数据(如点光源位置,模型的变换矩阵等等) ,这些数据在运行中显然是不需要被改变的。

 

13、流程控制

主要有for、while、do while、if else 等。

for (l = 0; l < numLights; l++)
{
    if (!lightExists[l]);
        continue;
    color += light[l];
}
...

while (i < num)
{
    sum += color[i];
    i++;
}
...

do{
    color += light[lightNum];
    lightNum--;
}while (lightNum > 0)


...

if (true)
    discard;
else
    ……

 

14、内建变量

在 vertex Shader 中:

output 类型的内置变量:

变量说明单位
highp vec4 gl_Position;gl_Position 放置顶点坐标信息vec4
mediump float gl_PointSize;gl_PointSize 需要绘制点的大小,(只在gl.POINTS模式下有效)float

在 fragment Shader 中:

input 类型的内置变量:

变量说明单位
mediump vec4 gl_FragCoord;片元在framebuffer画面的相对位置vec4
bool gl_FrontFacing;标志当前图元是不是正面图元的一部分bool
mediump vec2 gl_PointCoord;经过插值计算后的纹理坐标,点的范围是0.0到1.0vec2

output 类型的内置变量:

变量说明单位
mediump vec4 fragColor;设置当前片点的颜色vec4 RGBA color
mediump vec4 fragData[n]设置当前片点的颜色,使用glDrawBuffers数据数组vec4 RGBA color

 

15、着色器程序的基本结构

#version 300 es
uniform mat4 uMVPMatrix;
layout (location = 3) in vec3 aPosition;
layout (location = 2) in vec4 aColor;
out vec4 vColor;
void positionShift(){ 
  ……
}
void main(){
  positionShift(); 
  vColor = aColor; 
}

 

最后,欢迎大家一起交流学习:微信:liaosy666 ; QQ:2209115372 。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值