webgl getUniformLocation returns 0
webgl getUniformLocation returns 0
简而言之,我遇到了一个问题,即通过 getUniformLocation 调用不同的制服似乎都 return 相同的值。
很难验证这一点,因为 returned Glint 对于 javascript 控制台是不透明的。但是,当查看其他人的代码示例时,我注意到您可以在其位置传递标准 javascript 数字,因此此试用代码:
const infoA = gl.getActiveUniform(program, gl.getUniformLocation(program, 'uSampler'));
const infoB = gl.getActiveUniform(program, gl.getUniformLocation(program, 'uRotationMatrix'));
const infoC = gl.getActiveUniform(program, 0);
const infoD = gl.getActiveUniform(program, 1);
infoA
和 infoB
都等于 'uRotationMatrix'
制服的 WebGLActiveInfo
对象,infoC
也是如此,但是 infoD
returns 'uSampler'
.
的信息数据
我能找到的最接近类似问题的是关于优化删除未使用的制服导致 getUniformLocation 总是 returning -1。我不相信这里是这种情况,因为两种制服都被使用并使用 Ben Vanik https://github.com/benvanik/WebGL-Inspector 的 webgl-inspector chrome 扩展,我看到程序面板中列出的两种制服的 idx 值为 0和 1. 但是我确实注意到,提供无效的统一名称不会产生任何错误,并导致 'uRotationMatrix'
(infoE
) 的信息对象的 'default' return 值;仅使用 -1
导致错误 (infoF
)。
const infoE = gl.getActiveUniform(program, gl.getUniformLocation(program, 'INVALID_NAME');
const infoF = gl.getActiveUniform(program, -1); // null
有趣的是,Safari 中的结果是相反的,即大多数调用 return 'uSampler
' 的信息对象,而只明确使用 javascript 数字,returns 'uRotationMatrix'
的信息对象
着色器在下面并且非常简单,它们和我在 return 检查相关参数时成功链接它们的程序。即
gl.getShaderParameter(shader, gl.COMPILE_STATUS);
gl.getProgramParameter(program, gl.LINK_STATUS);
顶点。
precision mediump float;
attribute vec2 aPosition;
attribute vec2 aTexCoord;
uniform mat4 uRotationMatrix;
varying vec2 fragTexCoord;
void main() {
fragTexCoord = aTexCoord;
gl_Position = uRotationMatrix * vec4(aPosition, 0.0, 1.0);
}
片段。
precision mediump float;
varying vec2 fragTexCoord;
uniform sampler2D uSampler;
void main() {
vec4 sample = texture2D(uSampler, fragTexCoord);
gl_FragColor = vec4(sample.rgb, 1.0);
}
有没有人对我应该在哪里查找问题有任何指示?
编辑:
参考确保参数类型和 return 值类型兼容,通过相关函数的 MDN 文档。
"location: A GLuint specifying the index of the uniform attribute to get. This value is returned by getUniformLocation()." Link: getActiveUniform
和
"Return value: A WebGLUniformLocation value indicating the location of the named variable, ... The WebGLUniformLocation type is compatible with the GLint type when specifying the index or location of a uniform attribute." Link: getUniformLocation
gl.getUniformLocation
不会 return -1 对于 non-existent 制服。它 returns null
这段代码毫无意义
const infoA = gl.getActiveUniform(program, gl.getUniformLocation(program, 'uSampler'));
const infoB = gl.getActiveUniform(program, gl.getUniformLocation(program, 'uRotationMatrix'));
gl.getActiveUniform
需要一个整数。 gl.getUniformLocation
returns WebGLUniformLocation
object,不是整数,不能转换成整数。充其量它被转换成 NaN
而 NaN
被转换成 0.
gl.getActiveUniform
不采用统一位置,它采用从 0 到 N - 1 的数字,其中 N 是 return 从 gl.getProgramParameter(prg, gl.ACTIVE_UNIFORMS)
编辑而来。它的目的是让你在不知道他们的名字的情况下查询制服。
const numUniforms = gl.getProgramParameter(prg, gl.ACTIVE_UNIFORMS);
for (let i = 0; i < numUniforms; ++i) {
// get the name, type, and size of a uniform
const info = gl.getActiveUniform(prg, i);
// get the location of that uinform
const loc = gl.getUniformLocation(prg, info.name);
}
请注意,WebGL 选择 gl.getUniformLocation
return WebGLUniformLocation
object 而不是 int 的原因是因为猜测这些 int 或假设它们是连续的。 OpenGL 不做这样的保证。
- 两个具有相同制服的程序可能每个制服的位置不同。
- 这些位置不是 0 和 1,它们可以是任何东西,5323 和 23424。这取决于 driver。各种 drivers return 不同的数字。
- 类似地,对于像
uniform float foo[2]
这样的统一数组,如果 foo[0]
的位置是 37,那么 不是 意味着 foo[1]
的位置是38.
出于所有这些原因,WebGL 选择包装位置。这样可以避免许多错误 and/or 检查。您不能在 WebGLUniformLocation
上进行数学运算,因此猜测位置错误会消失(您的猜测可能在本地有效,但您正在制作一个必须在其他 GPU 上 运行 的网页)。避免了错误的统一数组数学错误。同样,您不能将一个程序中的 WebGLUniformLocation
与另一个程序一起使用,这意味着可以避免假设具有相同制服的 2 个程序对这些制服具有相同的 int 位置的错误。
虽然我们讨论的是 gl.getActiveUniform
这个话题,但您应该知道它可以 return 提供非制服的信息。示例:https://jsfiddle.net/greggman/n6mzz6jv/
简而言之,我遇到了一个问题,即通过 getUniformLocation 调用不同的制服似乎都 return 相同的值。
很难验证这一点,因为 returned Glint 对于 javascript 控制台是不透明的。但是,当查看其他人的代码示例时,我注意到您可以在其位置传递标准 javascript 数字,因此此试用代码:
const infoA = gl.getActiveUniform(program, gl.getUniformLocation(program, 'uSampler'));
const infoB = gl.getActiveUniform(program, gl.getUniformLocation(program, 'uRotationMatrix'));
const infoC = gl.getActiveUniform(program, 0);
const infoD = gl.getActiveUniform(program, 1);
infoA
和 infoB
都等于 'uRotationMatrix'
制服的 WebGLActiveInfo
对象,infoC
也是如此,但是 infoD
returns 'uSampler'
.
我能找到的最接近类似问题的是关于优化删除未使用的制服导致 getUniformLocation 总是 returning -1。我不相信这里是这种情况,因为两种制服都被使用并使用 Ben Vanik https://github.com/benvanik/WebGL-Inspector 的 webgl-inspector chrome 扩展,我看到程序面板中列出的两种制服的 idx 值为 0和 1. 但是我确实注意到,提供无效的统一名称不会产生任何错误,并导致 'uRotationMatrix'
(infoE
) 的信息对象的 'default' return 值;仅使用 -1
导致错误 (infoF
)。
const infoE = gl.getActiveUniform(program, gl.getUniformLocation(program, 'INVALID_NAME');
const infoF = gl.getActiveUniform(program, -1); // null
有趣的是,Safari 中的结果是相反的,即大多数调用 return 'uSampler
' 的信息对象,而只明确使用 javascript 数字,returns 'uRotationMatrix'
着色器在下面并且非常简单,它们和我在 return 检查相关参数时成功链接它们的程序。即
gl.getShaderParameter(shader, gl.COMPILE_STATUS);
gl.getProgramParameter(program, gl.LINK_STATUS);
顶点。
precision mediump float;
attribute vec2 aPosition;
attribute vec2 aTexCoord;
uniform mat4 uRotationMatrix;
varying vec2 fragTexCoord;
void main() {
fragTexCoord = aTexCoord;
gl_Position = uRotationMatrix * vec4(aPosition, 0.0, 1.0);
}
片段。
precision mediump float;
varying vec2 fragTexCoord;
uniform sampler2D uSampler;
void main() {
vec4 sample = texture2D(uSampler, fragTexCoord);
gl_FragColor = vec4(sample.rgb, 1.0);
}
有没有人对我应该在哪里查找问题有任何指示?
编辑:
参考确保参数类型和 return 值类型兼容,通过相关函数的 MDN 文档。
"location: A GLuint specifying the index of the uniform attribute to get. This value is returned by getUniformLocation()." Link: getActiveUniform
和
"Return value: A WebGLUniformLocation value indicating the location of the named variable, ... The WebGLUniformLocation type is compatible with the GLint type when specifying the index or location of a uniform attribute." Link: getUniformLocation
gl.getUniformLocation
不会 return -1 对于 non-existent 制服。它 returns null
这段代码毫无意义
const infoA = gl.getActiveUniform(program, gl.getUniformLocation(program, 'uSampler'));
const infoB = gl.getActiveUniform(program, gl.getUniformLocation(program, 'uRotationMatrix'));
gl.getActiveUniform
需要一个整数。 gl.getUniformLocation
returns WebGLUniformLocation
object,不是整数,不能转换成整数。充其量它被转换成 NaN
而 NaN
被转换成 0.
gl.getActiveUniform
不采用统一位置,它采用从 0 到 N - 1 的数字,其中 N 是 return 从 gl.getProgramParameter(prg, gl.ACTIVE_UNIFORMS)
编辑而来。它的目的是让你在不知道他们的名字的情况下查询制服。
const numUniforms = gl.getProgramParameter(prg, gl.ACTIVE_UNIFORMS);
for (let i = 0; i < numUniforms; ++i) {
// get the name, type, and size of a uniform
const info = gl.getActiveUniform(prg, i);
// get the location of that uinform
const loc = gl.getUniformLocation(prg, info.name);
}
请注意,WebGL 选择 gl.getUniformLocation
return WebGLUniformLocation
object 而不是 int 的原因是因为猜测这些 int 或假设它们是连续的。 OpenGL 不做这样的保证。
- 两个具有相同制服的程序可能每个制服的位置不同。
- 这些位置不是 0 和 1,它们可以是任何东西,5323 和 23424。这取决于 driver。各种 drivers return 不同的数字。
- 类似地,对于像
uniform float foo[2]
这样的统一数组,如果foo[0]
的位置是 37,那么 不是 意味着foo[1]
的位置是38.
出于所有这些原因,WebGL 选择包装位置。这样可以避免许多错误 and/or 检查。您不能在 WebGLUniformLocation
上进行数学运算,因此猜测位置错误会消失(您的猜测可能在本地有效,但您正在制作一个必须在其他 GPU 上 运行 的网页)。避免了错误的统一数组数学错误。同样,您不能将一个程序中的 WebGLUniformLocation
与另一个程序一起使用,这意味着可以避免假设具有相同制服的 2 个程序对这些制服具有相同的 int 位置的错误。
虽然我们讨论的是 gl.getActiveUniform
这个话题,但您应该知道它可以 return 提供非制服的信息。示例:https://jsfiddle.net/greggman/n6mzz6jv/