WebGL 中的 "unbound" 个采样器如何运行?

How do "unbound" samplers in WebGL behave?

我发现没有绑定纹理的采样器在传递给 texture2D 时似乎 return 另一个采样器的值:

            for (int l = 0; l < Main.MaxLayers; l++)
            {
                if (layers[l] != null && layers[l].enabled)
                {
                    finalShader.SetInt("layer" + l, l);
                    layers[l].BindTexture(GL.TEXTURE0 + l);
                }
                else
                {
                    Context.activeTexture(GL.TEXTURE0 + l);
                    Context.bindTexture(GL.TEXTURE_2D, null);
                }

            }

这里我将 "layers" 绑定到我的着色器(最多 8 个)。其中一些可能未启用,事实上在我的测试中我只启用了一个,纹理槽 0 中的一个。

现在在我的 "finalShader" 中,我正在执行以下操作:

uniform sampler2D layer0;
uniform sampler2D layer1;
uniform sampler2D layer2;
uniform sampler2D layer3;
uniform sampler2D layer4;
uniform sampler2D layer5;
uniform sampler2D layer6;
uniform sampler2D layer7;
varying vec2 vTextureCoord;
void main(void) {
    gl_FragColor = texture2D(layer0, vTextureCoord)
                    +texture2D(layer1, vTextureCoord)
                    +texture2D(layer2, vTextureCoord)
                    +texture2D(layer3, vTextureCoord)
                    +texture2D(layer4, vTextureCoord)
                    +texture2D(layer5, vTextureCoord)
                    +texture2D(layer6, vTextureCoord)
                    +texture2D(layer7, vTextureCoord);
}

人们会期望所有未绑定的采样器 return vec4(0.0)。不在这里。所有采样器都给我采样器 0 的颜色值。这是预期的还是我的代码中有错误?

未绑定和无法渲染的纹理 return WebGL 中的 0,0,0,1。

在 WebGL 和未绑定或不可渲染的纹理中渲染 使用 0,0,0,1 渲染并且在许多浏览器上将在 JavaScript 控制台中生成警告帮助您找到代码中可能存在的错误。

至于你的代码,不清楚你在做什么。

首发

                finalShader.SetInt("layer" + l, l);
                layers[l].BindTexture(GL.TEXTURE0 + l);

做什么?它是否使用正确的枚举正确调用 gl.activeTexture,然后将正确的纹理绑定到活动纹理单元?

你也在为layer0layer1layer2等设置制服吗

您需要设置每个制服来告诉它使用哪个纹理单元。查看您的示例,假设您已经查找了统一位置,我猜您需要

gl.uniform1i(layer0location, 0);
gl.uniform1i(layer1location, 1);
gl.uniform1i(layer2location, 2);
gl.uniform1i(layer3location, 3);
gl.uniform1i(layer4location, 4);
gl.uniform1i(layer5location, 5);
gl.uniform1i(layer6location, 6);
gl.uniform1i(layer7location, 7);

无法渲染的纹理

无法渲染的纹理是任何未正确设置的纹理。对于 WebGL 1.0,其过滤设置为需要 MIPS 的 2 维非幂纹理。如果过滤需要 mip,或者如果任何 mip 的大小错误,或者如果它们不完全相同,那么它也是在最后一层缺少任何 mip 的纹理 format/type。或者对于立方体贴图,如果它们不是正方形并且所有面的大小都相同。

注意:这与 OpenGL 不同。在 OpenGL 中有默认纹理的概念,纹理 #0。所以绑定0,glBindTexture(GL_TEXTURE_2D,0),只是绑定纹理0。你可以像任何其他纹理一样将数据上传到纹理0。不过 WebGL 没有默认纹理。