前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Shader 入门:GLSL ES(运算符和限定符)

Shader 入门:GLSL ES(运算符和限定符)

作者头像
陈皮皮
发布2020-07-10 17:08:03
2.7K0
发布2020-07-10 17:08:03
举报
文章被收录于专栏:菜鸟小栈菜鸟小栈

正文

运算符(Operators)

使用括号包裹的内容优先级最高!

优先级

操作符

描述

1

++ --

后置自增、自减

2

++ --

前置自增、自减

2

+ - ~ !

一元运算

3

* % /

乘、取余、除

4

+ -

加、减

5

<< >>

位运算

6

< > <= >= == !=

关系运算

7

& ^ |

位与、位异或、位同或

8

&& ^^ ||

逻辑与、逻辑异或、逻辑同或

9

?:

三目运算

10

=

赋值

10

+= -= *= /= %= <<= >>= &= ^= |=

算术赋值

限定符(Qualifiers)

储存限定符(Storage Qualifiers)

声明变量时可以在类型前面添加一个储存限定符。

限定词

含义

无(默认)

用于局部作用域。

const

声明为只读的常量。

in

从上一阶段输入到当前着色器。

out

从当前着色器输出到下一阶段。

uniform

在着色器、OpenGL ES 和程序之间共享的变量。

const

使用 const 限定符修饰的变量即为常量,常量一但定义就不可再修改。

适用于标量、向量、矩阵、数组和结构体,但不适用于采样器:

// 声明定义常量
const int age = 18;
const vec4 color = vec4(0.5, 0.5, 0.5, 0.5);

// 也可以用于限定函数的参数
void doSomething(const float param) {
    param = 0.1; // Error! 不可!
    // ...
}
in

in 限定符常用于接收从上一阶段输出的变量:

in vec3 a_position; // 接收一个顶点坐标向量
in vec2 a_uv0; // 接收一个纹理坐标向量
in vec4 a_color; // 接受一个颜色向量
out

out 限定符常用于将当前着色器中的变量输出到下一阶段:

out vec2 v_uv0; // 输出一个纹理坐标向量
out vec4 v_color; // 输出一个颜色向量
uniform

使用 uniform 限定符来表示一个统一且只读的全局变量,该变量为所有着色器所共用。

注意:声明了却没有使用的 uniform 变量会在编译时被静默移除!

uniform sampler2D texture;

另外 uniform 变量只能在程序中使用 OpenGL ES 的一系列 glUniform API 进行赋值:

// 程序代码
int location = glGetUniformLocation(shaderProgram, "color"); // 查找 color 的位置(索引)
glUniform4f(location, 0.0f, 0.1f, 0.0f, 1.0f); // 给 color 赋值

// 着色器代码
uniform vec4 color; // vec4(0.0, 0.1, 0.0, 1.0)

参数限定符(Parameter Qualifiers)

函数的参数也可以使用限定符。

和 in
 的作用一致。

使用示例:

// in
void doo(in float param) { ... } // 和普通不加限定词的参数一样

// out
void foo(out int param) {
    param = 666;
}
int a; // 声明了但是没有初始化
foo(a); // a = 666
 
// inout
void goo(inout int param) {
    param = param++;
}
int b = 1;
goo(b); // b = 2

精度限定符(Precision Qualifiers)

浮点数、整数和采样器类型声明可以添加精度限定词来设置精度范围(精度控制可以扩展至向量和矩阵)。

精度限定符不适用于常量、布尔类型和构造函数!

满足顶点语言的最低要求(使用 highp
 可以获得最大的范围和精度,但是也有可能会降低运行速度)。
// 变量声明
lowp float a;
mediump vec2 p;
highp mat4 m;

// 函数声明(返回值和参数)也适用
highp float foo(highp param);
默认精度限定符(Default Precision Qualifiers)

我们可以用 precision 关键字来声明指定类型的默认精度:

// 声明方式
precision 精度限定符 类型;

// 示例:声明 float 类型的默认精度为 highp
precision highp float;

「未主动声明精度」的情况下,在顶点着色器中有以下默认精度声明:

precision highp float;
precision highp int;
precision lowp sampler2D;
precision lowp samplerCube;

而在片段着色器中有以下默认精度声明:

precision mediump int;
precision lowp sampler2D;
precision lowp samplerCube;

在片段着色器中浮点类型、浮点向量和浮点矩阵都没有默认的精度,所以使用时就必须声明其精度,或者事先声明默认精度!

另外,上面没有提到的类型都没有默认精度!

相关资料

「OpenGL ES Registry(OpenGL ES 资料页)」 https://www.khronos.org/registry/OpenGL/index_es.php

「OpenGL ES 3 Quick Reference Card(OpenGL ES 3 快速参考卡片)」 https://www.khronos.org/files/opengles3-quick-reference-card.pdf

「GLSL ES Specification 3.00(GLSL ES 规范 3.0)」 https://www.khronos.org/registry/OpenGL/specs/es/3.0/GLSL_ES_Specification_3.00.pdf

「OpenGL ES 3.0 Online Reference Pages(OpenGL ES 3.0 在线参考页)」 https://www.khronos.org/registry/OpenGL-Refpages/es3.0/

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 菜鸟小栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 正文
    • 运算符(Operators)
      • 限定符(Qualifiers)
        • 储存限定符(Storage Qualifiers)
        • 参数限定符(Parameter Qualifiers)
        • 精度限定符(Precision Qualifiers)
    • 相关资料
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档