欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

13 WebGL 着色器编程语言GLSL ES的精度限定字

程序员文章站 2022-07-15 12:48:21
...

GLSL ES新引入了精度限定字,目的是帮助着色器程序提高运行效率,消减内存开支。顾名思义,精度限定字用来表示每种数据具有的精度(比特数)。简而言之,高精度的程序需要更大的开销(包括更大的内存和更久的计算时间),而低精度的程序需要开销则小得多。使用精度限定字,你就能精细地控制程序在效果和性能间的平衡。然而,精度限定字是可选的,如果你不确定,可以使用下面这个适中的默认值:

#ifdef GL_ES
    precision mediump float;
#endif
由于WebGL是基于OpenGL  ES 2.0 的,WebGL程序最后有可能运行在各种各样的硬件平台上。肯定存在某些情况需要在低精度下运行程序,以提高内存使用效率,减少性能开销,以及更重要的,降低能耗,延长移动设备的电池续航能力。

注意,在低精度下,WebGL程序的裕兴结果会教教粗糙或不准确,比必须在程序效果和性能间进行平衡。

如表6.15所示,WebGL程序支持三种精度,其限定字分别为highp(高精度)、mediump(中精度)和lowp(低精度)。

13 WebGL 着色器编程语言GLSL ES的精度限定字

还有两点值得注意。首先,在某些WebGL环境中,片元着色器可能不支持highp精度,检查(其是否支持)的方法稍后再讨论;其次,数值范围和精度实际上也是与系统环境相关的,你可以使用gl.getShaderPrecisionFormat()来检查。

下面是声明变量精度的几个例子:

mediump float size;//中精度的浮点型变量
highp vec4 position;//具有高精度浮点型元素的vec4对象
lowp vec4 color;//具有低精度浮点型元素的vec4对象
为每个变量都声明精度很繁琐,我们也可以使用关键字precision来声明着色器的默认精度,这行代码必须在顶点着色器或片元着色器的顶部,其格式如下:

precision 精度限定字 类型名称;

这句代码表示,在着色器中,某种类型的变量其默认精度有精度限定字指定。也就是说,接下来所有不以精度限定字修饰的该类型变量,其精度就是默认精度。比如:

precision mediump float; //所有浮点数默认为中精度
precision highp int; //所有整型数默认为高精度
上面这段代码表示,所有float类型以及相关的vec2和mat3的变量都是中精度的,所有整型变量都是高精度的。比如,vec4类型变量的四个分量都是中精度的。

你也许已经注意到,在前几章我们并没有限定类型的精度(除了在片元着色器中对float类型做出限定)。这是因为,对于这些类型,着色器已经实现了默认的精度,只有片元着色器中的float类型没有默认精度。如表6.16所示。

13 WebGL 着色器编程语言GLSL ES的精度限定字
事实就是,片元着色器中的float类型没有默认精度,我们需要手动指定。如果我们不在片元着色器中限定float类型的精度,就会导致如下的编译错误:

failed to compile shader: ERROR: 0:1 : No prceision specified for (float).  
我们说过,WebGL是否在片元着色器中支持highp精度,取决于具体的设备。如果其支持的话,那么着色器就会定义内置宏GL_FRAGMENT_PRECISION_HIGH。(见下一节)