Opengl es 在WebGL2中,布局限定符如何优于GetAttriblLocation?
随着我对WebGL2的进一步了解,我在着色器中遇到了这种新语法,您可以通过在vec4 a_位置中的Opengl es 在WebGL2中,布局限定符如何优于GetAttriblLocation?,opengl-es,webgl,webgl2,Opengl Es,Webgl,Webgl2,随着我对WebGL2的进一步了解,我在着色器中遇到了这种新语法,您可以通过在vec4 a_位置中的layout(location=0)在着色器内部设置location。这与使用传统的gl.getAttriblLocation('a_Position')获取属性位置相比如何。我想是更快吧?还有其他原因吗?另外,将位置设置为整数更好,还是也可以使用字符串更好?这里有两种想法 手动将位置指定给属性 在GLSL与JavaScript中分配属性位置 为什么要分配位置? 因为你已经知道了位置,所以你不必去查
layout(location=0)在着色器内部设置location
代码>。这与使用传统的gl.getAttriblLocation('a_Position')获取属性
位置相比如何代码>。我想是更快吧?还有其他原因吗?另外,将位置设置为整数更好,还是也可以使用字符串更好?这里有两种想法
手动将位置指定给属性
在GLSL与JavaScript中分配属性位置
为什么要分配位置?
因为你已经知道了位置,所以你不必去查它
您希望确保两个或多个着色器程序使用相同的位置,以便它们可以使用相同的属性。这也意味着单个顶点阵列可以与两个着色器一起使用。如果未指定属性位置,则着色器可能会对同一数据使用不同的属性。换句话说,shaderprogram1可能使用属性3表示位置,shaderprogram2可能使用属性1表示位置
为什么要在GLSL中分配位置而不是在JavaScript中分配位置?
您可以在GLSL ES 3.0(而不是GLSL ES 1.0)中指定这样的位置
您还可以像这样在JavaScript中分配一个位置
// **BEFORE** calling gl.linkProgram
gl.bindAttribLocation(program, 0, "a_Position");
在我看来,用JavaScript做这件事似乎比较枯燥(不要重复)。事实上,如果您使用一致的命名,那么在调用gl.linkProgram
之前,您可能只需绑定常用名称的位置,就可以为所有着色器设置所有位置。使用JavaScript进行此操作的另一个次要优势是它与GLSL ES 1.0和WebGL1兼容
我有一种感觉,虽然在GLSL中这样做更常见。这对我来说很糟糕,因为如果您遇到冲突,您可能需要编辑10或100个着色器。例如,您从
layout (location=0) in vec4 a_Position;
layout (location=1) in vec2 a_Texcoord;
稍后在另一个没有texcoord但有法线的着色器中,您可以执行此操作
layout (location=0) in vec4 a_Position;
layout (location=1) in vec3 a_Normal;
然后,很久以后,您添加了一个着色器,该着色器需要所有3个
layout (location=0) in vec4 a_Position;
layout (location=1) in vec2 a_Texcoord;
layout (location=2) in vec3 a_Normal;
如果希望能够使用具有相同数据的所有3个着色器,则必须编辑前2个着色器。如果您使用JavaScript方式,就不必编辑任何着色器
当然,另一种方法是生成常见的着色器。然后,您可以注入位置
const someShader = `
layout (location=$POSITION_LOC) in vec4 a_Position;
layout (location=$NORMAL_LOC) in vec2 a_Texcoord;
layout (location=$TEXCOORD_LOC) in vec3 a_Normal;
...
`;
const substitutions = {
POSITION_LOC: 0,
NORMAL_LOC: 1,
TEXCOORD_LOC: 2,
};
const subRE = /\$([A-Z0-9_]+)/ig;
function replaceStuff(subs, str) {
return str.replace(subRE, (match, group0) => {
return subs[group0];
});
}
...
gl.shaderSource(prog, replaceStuff(substitutions, someShader));
或者注入预处理器宏来定义它们
const commonHeader = `
#define A_POSITION_LOC 0
#define A_NORMAL_LOC 1
#define A_TEXCOORD_LOC 2
`;
const someShader = `
layout (location=A_POSITION_LOC) in vec4 a_Position;
layout (location=A_NORMAL_LOC) in vec2 a_Texcoord;
layout (location=A_TEXCOORD_LOC) in vec3 a_Normal;
...
`;
gl.shaderSource(prog, commonHeader + someShader);
速度快吗?是的,但可能不会太多,不调用gl.getAttribLocation
比调用它快,但通常应在初始时间只调用gl.getAttribLocation
,这样不会影响渲染速度,并且在设置顶点数组时通常只在初始时间使用位置
将位置设置为整数更好,还是也可以使用字符串更好
位置是整数。您正在手动选择要使用的属性索引。如上所述,您可以使用替换、着色器生成、预处理器宏等。。。将某些类型的字符串转换为整数,但它们最终必须是整数,并且必须在GPU支持的属性数量范围内。不能选择像9127这样的任意整数。只有0到N-1,其中N是由gl.getParameter(MAX\u VERTEX\u ATTRIBS)
返回的值。注:在WebGL2中,N总是>=16,这是一个非常好的答案。感谢一票给出如此详细的答案。
const commonHeader = `
#define A_POSITION_LOC 0
#define A_NORMAL_LOC 1
#define A_TEXCOORD_LOC 2
`;
const someShader = `
layout (location=A_POSITION_LOC) in vec4 a_Position;
layout (location=A_NORMAL_LOC) in vec2 a_Texcoord;
layout (location=A_TEXCOORD_LOC) in vec3 a_Normal;
...
`;
gl.shaderSource(prog, commonHeader + someShader);