目录
10 常见问题
10.1 顶点着色器精度
Q:最小精度应该是(相当于)float 24还是float 32?
A:最小精度为float 24.将鼓励底层实现使用float 32。
10.2片段着色器精度
Q:最小精度应该是(相当于)float 16还是float 24?
需要float 24来完成大多数依赖纹理查找的情况。
float 24对于低端硬件来说太昂贵了。
在进行简单的混色操作时,即使是float16也很昂贵。能用低精度尽量使用低精度。
很明显,该标准必须满足不同细分市场的需求。能够指定何时可以使用降低的精度值也是有利的。
A:将有3个精度可用,大致对应于float32,float16和int10。 片段着色器中的最高精度是可选的。
10.3 精度限定符
Q:是否应将精度指定为float16,float24等? 这将有助于移植性。 它意味着不同的类型而不是提示。 它将要求所有实现使用相同或类似的算法,并缩小更新范围。
A:不,精度不应指定格式。 标准化算术不是(图像)的要求。
Q:整数有精度限定符吗? 许多实现中整数被假设将映射到浮点硬件。 这只允许10位整数用于mediump浮点数。
A:是的,整数具有精度限定符。 将指定整数的精度,以便可以使用相应的浮点精度来实现它们。
Q:如何定义整数的包装行为? 如果应用程序依赖于一个实现的包装,则可能会导致可移植性问题。
选项:标准应指定包装或截断。
A:这应该是未定义的。 实施成本太高。 规范应明确规定不能依赖任何包装或截断行为。
Q:顶点着色器中是否提供精度限定符?
A:是的。 它可能对某些实现很有用,并使语言保持一致。
Q:应该有默认精度吗? 将默认顶点着色器精度指定为当前指定的highp是有意义的。 关于片段着色器的默认精度应该是什么没有达成一致。
A:顶点着色器为highp,片段着色器没有默认精度。
Q:是否应该有一个与float32相当的精度? 桌面实现已经支持这一点。
A:保留superp以便可能包含在GLSL ES的未来版本中。
Q:如果不同的精度会产生不同的类型,例如 需要在它们之间进行显式转
选项1:不,它们只是提示。 但如果实现可以忽略它,暗示高精度是没有意义的。
选项2:是的,它们是不同的类型。 但这引入了复杂性。
A:highp必须意味着至少使用高精度,对于mediump和lowp也是如此,因此精度限定符不仅仅是提示。就着色语言而言,由于它不会影响行为,所以他们可以被视为提示或具有隐式类型转换的不同类型。在任何情况下,实现都可以自由地以高精度或更高精度计算所有内容。
Q:解析函数调用时是否应考虑精度?
A:不,它们应该更多的被视为提示。 函数声明不能基于精度重载。
Q:如何在表达式中传播精度?
选项1:仅考虑操作的输入。 对于没有定义精度的操作数,精度的确定从表达式树的叶节点开始,然后进入根,直到找到精度。如有必要,还应当考虑赋值中的左值。常量表达式必须是不变的,并且期望它们将在编译时进行评估。因此,必须以目标支持的最高精度(lowp或highp)或更高精度对它们进行评估。
选项2:始终考虑表达式的目标。 编译器应该能够解决如何避免丢失精度。
A:选项1.这使开发人员可以更轻松地指定复杂表达式中使用的精度。
Q:如果表达式中没有精度怎么办?
选项1:将其保留为未定义。
选项2:使用默认精度。
A:使用默认精度。 如果未定义(在片段着色器中),则会报错。
Q:统一变量的精度限定符需要匹配吗?
选项1:是的。
统一变量被定义为在顶点和片段处理器中使用相同的存储,并且可以以这种方式实现。
如果在顶点和片段着色器中都使用了统一变量,那么如果精度不同,应该警告开发人员。 (一些高端的芯片有做处理,及时两边的着色器没有使用同样的精度限定符,也不会报错,但是低端的芯片就会报错,所以最好是申明成一样的以便适配)
精确度的转换绝不应该是隐含的。
选项2:不。
两个着色器都可以使用统一变量,但两者都可能没有相同的精度,因此有理由允许它们不同。
在顶点和片段着色器中使用相同的均匀将始终要求在顶点着色器中指定精度(因为默认精度为highp)。 这对开发人员来说是不必要的负担。
A:是的,制服的精确限定符必须匹配。
Q:易变变量的精确限定符是否需要匹配?
选项1:是的。易变变量由顶点着色器写入并由片段着色器读取,因此不存在精度不同的情况。
选项2:不,顶点着色器写入的变化不应被视为与片段着色器读取的变量相同(可能没有共享存储)。因此,可以指定它们具有不同的精度。
A:易变变量的精度限定符不需要匹配。
Q:片段着色器中的highp是扩展还是选项? 是否需要使用#extension启用?
如果着色器可移植性存在问题,可以在着色器中使用宏来选择高精度或中等精度。 要求使用#extension似乎是不必要的。
A:片段着色器highp是一个选项,不由#extension来启用。
lowp int
规范声明应使用等效浮点精度表示整数值。lowp float的范围为+/- 2.0,而lowp int的范围为+/- 256。如果需要将lowp float转换为lowp int,则会出现问题。直接转换,即lowp int = int(lowp float)在转换之前几乎失去所有精度和乘法,例如 lowp int = int(lowp float * 256)导致溢出,因此导致未定义的结果。保持精度的唯一方法是首先转换为mediump浮点数。
选项1:保持此行为。 接受将lowp float转换为low int会失去精度,因此无用。
选项2:通过将其范围设置为+/-1使lowp int与mediump和highp int一致。
选项3:重新定义lowp float到lowp int的转换以包括8位左移。 然后,lowp int到lowp float的转换包含一个8位右移。
选项4:选项1,但添加内置函数以在两种格式之间进行转换。
选项5:将lowp float重新定义为真正的浮点格式。 然后它将等效于具有10位尾数和3位无符号指数的浮点值。
解决:选项1转换将失去大部分精度。
内置纹理功能的精确度。
Q:大多数内置函数都采用单个参数,返回值的精度与参数的精度相同是合理的。纹理函数采用采样器和坐标参数。返回值应完全独立于坐标的精度。 那么如何指定返回值的精度?
A:允许采样器类型采用精度限定符。 纹理函数的返回值与sampler参数的精度具有相同的精度。
Q:采样器类型的默认精度应该是多少?
A:所有采样器类型的默认精度应为lowp。
版权:https://blog.csdn.net/flycatdeng/article/details/88146590