OpenGL ES着色器语言之变量和数据类型(二)(官方文档第四章)

4.5精度和精度修饰符

4.5.1范围和精度

用于存储和展示浮点数、整数变量的范围和精度依赖于数值的源(varying,uniform,纹理查找,等等),是不是顶点或者片元着色器,还有其他一些底层实现的细节。最低存储需要通过精度修饰符来声明。典型地,精度操作必须要保留变量包含的精度存储。仅有的例外是需要大量复杂计算的内建函数,如atan(),返回值的精度低于声明的精度。

强烈建议顶点语言提供一种匹配IEEE单精度浮点数或更高精度的浮点数的浮点范围和精度。这就需要顶点语言提供浮点变量的范围至少是(-2^62,  2^62),精度至少是65536。

顶点语言必须提供一种至少16位,加上一个符号位的整数精度。

片元语言提供与顶点着色器相同的浮点数范围和精度是很有必要的,但不是必须的。这就需要片元语言提供的浮点数的范围至少是(-16384,+16384),精度至少是1024。

片元语言必须提供一种至少10为,加上一个符号位的整数精度。

4.5.2精度修饰符

任何浮点数或者整数声明前面都可以添加如下精度修饰符:

举例:

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

精度修饰符声明了底层实现存储这些变量必须要使用的最小范围和精度。实现可能会使用比要求更大的范围和精度,但绝对不会比要求少。

一下是精度修饰符要求的最低范围和精度:

Floating Point Magnitude Range是非零值量级的范围。对于Floating Point Precision,relative意思是任何度量的值的精度都是相对于这个值的。对于所有的精度级别,0必须被精确的表示出来。任何不能提供着色器存储变量所声明的精度的实现都会引起一个编译或链接错误。

对于高精度和中级精度,整型范围必须可以准确地转化成相应的相同精度修饰符所表示的float型。这样的话,highp int 可以被转换成highp float, mediump int 可以被转换成mediump float,但是lowp int 不能转换成相应的lowp float。

顶点语言要求编译和链接任何lowp, mediump和highp应用都不能出现错误。

片元语言要求编译和链接任何lowp, mediump应用都不能出现错误。但是highp支持是可选的。

字符常量和布尔型没有精度修饰符.当浮点数和整数构造器不含带有精度修饰符的参数时也不需要精度修饰符。

在这段文档中,操作包含运算符,内建函数和构造器,操作数包含函数参数和构造器参数。

对于精度没有定义的常量表达式或子表达式,评估的精度结果是所有操作数中的最高精度(mediump或者highp) 。带评估的常量表达式必须是固定不变的,并且在编译期进行。

另外,对于没有精度修饰符的操作数,精度将来自于其他操作数。如果所有的操作数都没有精度,那么接着看使用计算结果的其他表达式。这个操作是递归的,直到找到一个有精度的操作符为止。如果必要,这个操作也包含赋值运算的左值,初始化声明的变量,函数形参,函数返回值.如果这样依然不能决定精度,如果组成表达式的所有操作数都没有精度,如果结果没有被赋值,也没有当作参数传进函数,那么将使用默认或更大的类型.当这种情况出现在片元着色器中,默认的精度必须被定义.

比如:

uniform highp float h1;

highp float h2 = 2.3*4.7;操作和结果都是高精度

mediump float m;

m = 3.7*h1*h2;//所有操作都是高精度

h2 = m * h1;//操作是高精度

m = h2 - h1;//操作是高精度

h2 = m + m;//加法和结果都是mediump精度

void f(highp p);

f(3.3);//3.3将作为高精度值传入函数

4.5.3默认精度修饰符

precision precision-qualifier type;

precision可以用来确定默认精度修饰符。type可以是int或float或采样器类型,precision-qualifier可以是lowp, mediump, 或者highp。任何其他类型和修饰符都会引起错误。如果type是float类型,那么该精度(precision-qualifier)将适用于所有无精度修饰符的浮点数声明(标量,向量,矩阵)。如果type是int类型,那么该精度(precision-qualifier)将适用于所有无精度修饰符的整型数声明(标量,向量)。包括全局变量声明,函数返回值声明,函数参数声明,和本地变量声明等。没有声明精度修饰符的变量将使用和它最近的precision语句中的精度。

在顶点语言中有如下预定义的全局默认精度语句:

precision highp float;

precision highp int;

precision lowp sampler2D;

precision lowp samplerCube;

在片元语言中有如下预定义的全局默认精度语句:

precision mediump int;

precision lowp sampler2D;

precision lowp samplerCube;

片元语言没有默认的浮点数精度修饰符。因此,对于浮点数,浮点数向量和矩阵变量声明,要么声明必须包含一个精度修饰符,要不默认的精度修饰符在之前已经被声明过了。

4.5.4可用的精度修饰符

内建宏GL_FRAGMENT_PRECISION_HIGH在支持highp精度的片元语言中是定义过的,但在不支持的系统中是未定义的。一旦定义以后,在顶点和片元语言中都可以使用。

#defien GL_FRAGMENT_PRECISION_HIGH 1;

4.6变异和invariant修饰符

在这部分中,变异是指在不同的着色器中的相同语句返回不同的值的可能性.举个例子,两个顶点着色器都使用相同的表达式来设置gl_Position,并且当着色器执行时传进表达式的值也是一样的.完全有可能,由于两个着色器独立的编译环境,当着色器运行时赋给gl_Position的值不一定会相同.在这个例子中,会引起多路算法的几何对齐问题.

通常,着色器之间的这种变异是允许的.如果想避免这种变异的发生,变量可以使用invariant来声明.

4.6.1invariant修饰符

   为确保一个特定的输出变量是不变的,可以使用invariant修饰符.它可以修饰之前已经定义过的变量,如:

invariant gl_Position;

也可以用在变量的声明当中:

invariant varying mediump vec3 Color;

仅如下变量可以声明为invariant:

(1)顶点着色器中内建的特定输出变量

(2)顶点着色器中输出varying变量

(3)片元着色器中特定的输入变量

(4)片元着色器中的输入varying变量

(5)片元着色器中内建的输出变量

invariant后面还可以跟一个用逗号隔开的之前声明的标识符列表.

为了确保两个着色器中特定的输出变量不发生变异.还应遵循以下规则:

(1)顶点和片元着色器中的输出变量都声明为invariant

(2)相同的值必须输入到赋给输出变量的表达式或控制流的所有着色器输入变量.

(3)输出变量上的任何纹理函数调用在使用纹理格式,纹理像素值和纹理过滤时都需要设置成相同的方式.

(4)所有的输入变量都以相同的方式操作.

初始时,默认的所有输出变量被允许变异.如果想强制所有输出变量都不可变,那么在着色器所有的变量声明之前使用

#pragma STDGL invariant(all)

4.6.2着色器中的不变体

当一个值被存到一个变量中,我们通常假设它是一个常量,除非显示的去更改它的值.然而,在优化处理期间,编译期可能会重新计算一个值而不是将它存到寄存器中.因为操作的精度没有被完全指定(如,低精度的操作会被转成中等精度或高精度),重新计算的值有可能就和原来的值不一致.

在着色器中变体是允许的.如果要避免变体,可以使用invariant修饰符或invariant pragma.

precision mediump;

vec4 col;

vec2 a = ...;

........

col = texture2D(tex, a);//此时a的值假设为a1

..............

col = texture2D(tex, a);//此时a的值假设为a2,但是有可能a1不等于a2

如果强制成常量,可以使用:

#pragma STDGL invariant(all)

例子二:

vec2 m = ...;

vec2 n = ...;

vec2 a = m + n;

vec2 b = m + n;//没法保证a和b完全相等

4.6.3常量表达式的不变体

常量表达式必须要保证是不变体.一个特定的表达式在相同的还是不同的着色器中都必须有相同的结果.这包括同一个表达式出现在同一个顶点和片元着色器中,或出现在不同的顶点和片元着色器中.

如果满足以下条件,常量表达式必须得出相同的值:

(1)表达式的输入值相同

(2)执行的操作相同并且顺序也相同

(3)所有操作均以相同的精度执行

4.6.4不变体和链接装置

在顶点和片元着色器中声明的不变体varying变量必须要匹配.对于内建的特定变量,当且仅当gl_Position被声明为invariant时,gl_FragCoord才可以被声明为invariant.同样的,当且仅当gl_PositionSize被声明为invariant时,gl_PointCoord才可以被声明为invariant.将gl_FrontFacing声明为invariant是错误的.gl_FrontFacing的不变体和gl_Position的不变体是一样的.

4.7修饰顺序

当需要使用多个修饰时,它们必须遵循严格的顺序:

(1)invariant-qualifier   storage-qualifier   precision-qualifier

(2)storage-qualifier    parameter-qualifier    precision-qualifier

 

OpenGL ES着色器语言之变量和数据类型(二)(官方文档第四章)相关推荐

  1. OpenGL ES着色器语言之变量和数据类型

    所有变量和函数在使用前必须声明.变量和函数名是标识符. 没有默认类型,所有变量和函数声明必须包含一个声明类型以及可选的修饰符.变量在声明的时候首先要标明类型,后边可以跟多个变量,之间用逗号隔开.很多情 ...

  2. OpenGL ES着色器语言之语句和结构体(官方文档第六章)内建变量(官方文档第七、八章)...

    OpenGL ES着色器语言之语句和结构体(官方文档第六章) OpenGL ES着色器语言的程序块基本构成如下: 语句和声明 函数定义 选择(if-else) 迭代(for, while, do-wh ...

  3. OpenGL ES着色器语言(GLSL ES)规范 ——下篇

    文章目录 前言 分支和循环 if.if-else for continue.break.discard 着色器内置变量 函数 函数定义 规范声明 webgl内置函数 存储限定字 const attri ...

  4. iOS OpenGl ES着色器

    首先创建两个文件分别为simple.frag和simple.vert simple.frag内容 const char* SimpleFragmentShader = STRINGIFY(varyin ...

  5. 【清单】语言、框架及库的官方文档、examples、tutorials

    spark:Quick Start tensorflow: 官方文档中文版:介绍 | TensorFlow 官方文档中文版 tutorials:Get Started with TensorFlow

  6. GLSL三种基本类型(着色器语言三种变量)

    着色器语言和C语言一样,通过一个表示特定数据类型的关键词声明一个变量,比如int num;通过int关键字声明一个整数型变量num,不过着色器语言还提供了三个关键字attribute.uniform和 ...

  7. OpenGLES2.0着色器语言glsl

    OpenGLES2.0中是强制使用可编程的渲染管线的,使用的是glsl着色器语言,因为着色器语言是使用的GPU,即图形处理单元,而不是CPU,这样可以使CPU从繁重的几何计算和像素的处理中解脱出来了. ...

  8. OpenGL:着色器shader

    参考资料:https://learnopengl-cn.github.io/01%20Getting%20started/05%20Shaders/ 着色器基本描述 首先看一个着色器 #version ...

  9. 可编程渲染管线与着色器语言

    Programming pipeline & shading language 大家好,今天想给大家介绍一下可编程渲染管线和着色器语言的相关基础知识,使想上手SHADER编程的童鞋们可以快速揭 ...

最新文章

  1. 在CentOS 6.3 64bit上安装最新版tsar并监控ATS 5.3
  2. Java相当于C#中的#region
  3. 无法更改密码的解决办法--passwd: User not known
  4. mysql查询case when_【原创】关于MySQL高级查询–case when
  5. 时隙aloha协议仿真程序_工控ModbusTCP/IP协议仿真环境搭建
  6. python下载图片到文件夹_python实现解析markdown文档中的图片,并且保存到本地~
  7. 计算机出现黑屏问题方法派出,电脑重装系统开机常见黑屏问题的解决方法
  8. SVN 客户端的安装与配置
  9. 计算机中用于描述音乐乐曲并,计算机中用于描述音乐乐曲并由声卡合成出音乐来的语言(规范)为。...
  10. 网络存储技术 (HUAWEI)
  11. python好用的软件_新手写Python程序有什么推荐好用编辑器
  12. 特征值与特征向量及其应用
  13. 云计算安全知识CCSK V4 知多少
  14. C语言格式化输出函数printf详解——C语言基础知识
  15. 短信接口安全防护策略
  16. 关于unity easy touch 再次进入场景后报错问题
  17. Keras.metrics中的accuracy总结
  18. 四大基本反应类型的关系_中学化学中的四种基本反应类型,氧化还原反应和物质的变化!...
  19. 女孩起名取名字:聪明美丽、好听委婉的女孩名字
  20. 【赛题解读】2021 CCF BDCI 基于飞桨实现花样滑冰选手骨骼点动作识别

热门文章

  1. php是硬件还是软件,计算机操作系统是管理计算机硬件和软件的什么
  2. 计算机显示器工作原理与维修,新型电脑显示器的原理与维修
  3. ios 代码设置控件宽高比_iOS基于代码按比例约束方法进行屏幕适配
  4. python发布_python如何发布模块
  5. php get 分页,PHP_codeigniter实现get分页的方法,本文实例讲述了codeigniter实现ge - phpStudy...
  6. pytorch nn.Conv1d
  7. python `__str__`
  8. 编程语言对比 引用数据类型-字典
  9. 电脑尺寸大小在哪里看_科技资讯:电脑弹出本地计算机上的服务启动后停止的提示在哪里看...
  10. 微型计算机天逸510s光驱,主机届的小钢炮,性能最强NAS——天逸510S Mini