[英]How are layout qualifiers better than getAttribLocation in WebGL2?
随着我对 WebGL2 的了解越来越多,我在着色器中遇到了这种新语法,您可以通过以下方式在着色器中设置location
: layout (location=0) in vec4 a_Position;
. 这与使用传统的gl.getAttribLocation('a_Position');
获取attribute
位置相比如何gl.getAttribLocation('a_Position');
. 我认为它更快? 还有其他原因吗? 另外,将位置设置为整数会更好还是也可以使用字符串?
这里有两个想法混为一谈
您可以在 GLSL ES 3.0(不是 GLSL ES 1.0)中分配这样的位置
layout (location=0) in vec4 a_Position;
你也可以像这样在 JavaScript 中分配一个位置
// **BEFORE** calling gl.linkProgram
gl.bindAttribLocation(program, 0, "a_Position");
在我的脑海里,用 JavaScript 做这件事似乎更 DRY(不要重复自己)。 事实上,如果您使用一致的命名,那么您可能只需在调用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_VERTEX_ATTRIBS)
返回的值。 注意 N 在 WebGL2 中总是 >= 16
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.