目录
10.19 着色器中的不变性
10.20 循环声明
10.21 着色器之间的交叉链接
10.22 声明的可见性
10.23 语言版本
10.24 采样器
10.19 着色器中的不变性
如何指定着色器中的不变性?
编译器可能决定重新计算值而不是将其存储在寄存器中。 新值可能与原始值不完全相同。
选项1:禁止此行为。
选项2:对变量使用不变性限定符来控制它。 这与桌面一致。
A:着色器中的值在变体中是默认值。 不变性限定符或pragma可用于使它们不变。
常量表达式应该是不变的吗?在以下示例中,未定义文字表达式是否应始终计算为相同值。
precision mediump int;
precision mediump float;
const int size = int(ceil(4.0/3.0 – 0.333333));
int a[size];
for (int i=0; i<int(ceil(4.0/3.0 – 0.333333)); i++) {a [i] = i;}
实现通常必须能够在编译时评估常量表达式,因为它们可用于声明数组的大小。与C中可用的数学库相比,硬件可能计算出不太准确的值。然而,无论它们是否是常量表达式的一部分,诸如正弦和余弦的函数都将返回类似的结果。这表明实现可能只想在硬件上计算这些功能。但是,即使有全局不变性,编译时计算和运行时计算也必须完全匹配。
A:是的,常量表达式必须是不变的。
10.20 循环声明
在while语句中允许变量声明的目的是什么?
while (bool b = f()) {...}
布尔b将始终为真,直到它被销毁。它在C ++中很有用,因为整数被隐式转换为布尔值。
A:保持此行为。 如果将隐式类型转换添加到将来的版本,则需要.
10.21 着色器之间的交叉链接
片段着色器是否允许调用顶点着色器中定义的函数,反之亦然?
A:不,不需要这种行为.
10.22 声明的可见性
声明应在什么时候生效?
int x=1;
{
int x=2, y=x; // case A
int z=z; // case B
}
选项1:名称应在标识符后面立即可见。 以上两种情况都是合法的。 在情况A中,y被初始化为值2.这与c ++一致。 对于情况B,用例是初始化变量以指向其自身,例如 void * p =&p; 这与GLSL ES无关。
选项2:名称应在初始化程序(如果存在)后可见,否则紧跟在标识符之后。 在情况A中,y被初始化为2.情况B是错误(假设没有先前的z声明)。
选项3:声明后应显示名称。 在情况A中,y被初始化为1.如果z没有事先声明,则情况B是错误。
A:选项2.声明在初始化程序之后可见(如果存在),否则在标识符之后。
10.23 语言版本
此版本(gles 2.0)的语言基于桌面GLSL的1.10版。 但是,它包含许多版本1.20但不是1.10的功能。 __VERSION__应该返回110或120还是其他什么?
选项1:它应返回110. GL_ES已定义,因此桌面版本不存在歧义。
选项2:它应返回115以指示它位于桌面版本1.10和1.20之间。 不,这是错误的,ES简化了许多领域的语言,并在其他领域增加了功能。
选项3:语言足够独立,应该有一个独立的编号方案。
__VERSION__应返回100。
A:__ VERSION__应该返回100。
10.24 采样器
取样器应该被允许作为l值吗? 规范已经允许等效行为:
当前规格:
uniform sampler2D sampler[8];
int index = f(...);
vec4 tex = texture2D(sampler[index], xy); // allowed
使用采样器类型的分配:
uniform sampler2D s;
s = g(...);
vec4 tex = texture2D(s, xy); // not allowed
A:保持当前的规格。 ES2.0不强制支持对采样器阵列进行动态索引(在限制部分中指定)。
Android,OpenGL ES,图形学