首页 > 解决方案 > 错误:WebGL 警告:texImage2D:所需上传的数据比可用数据多:(加载带有三角形网格数据和法线的纹理时)

问题描述

当我加载 2 个纹理时,我可能搞砸了。我收到此错误:“WebGL 警告:texImage2D:所需上传的数据比可用数据多:(需要 0 行加 246 像素,可用 0 行加 244 像素)”

屏幕上什么也没有。我有 2 个纹理,一个带有网格的顶点,另一个带有法线。我将发布我尝试加载纹理的方式:

const uLSr = gl.getUniformLocation(P, 'uMeshData');
const uNormData = gl.getUniformLocation(P, 'uNormData');

const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);

 const verts = [
         ...
         4.910892,0.000000,4.910892,
        -4.910892,0.000000,-4.910892,
        -4.910892,0.000000,4.910892,
        4.910892,0.000000,4.910892,
        4.910892,0.000000,-4.910892,
        ...
];

const vertsNorm = [
        ...
        0.0000,-1.0000,0.0000,
        0.4253,-0.8506,0.3090,
        -0.1625,-0.8506,0.5000,
        0.7236,-0.4472,0.5257,
        0.4253,-0.8506,0.3090,
        ...
];

const meshVerts = new Float32Array(verts);
    const vertsLenght = meshVerts.length / 3;
    gl.uniform1i(uLvertices, vertsLenght);

gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB32F, vertsLenght, 1, 0, gl.RGB, gl.FLOAT, meshVerts);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);


const textureNorm = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, textureNorm);

const meshNorm = new Float32Array(vertsNorm);
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
//vertsLength is the same cause normal and vertices have the same length
//foreachone normal there is one single vertex
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB32F, vertsLenght, 1, 0, gl.RGB, gl.FLOAT, meshNorm);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);

然后在绘图函数中我这样称呼它们:

gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, textureNorm);
gl.uniform1i(uLSr, 0);
gl.uniform1i(uNormData, 1);

然后在着色器中我尝试像这样解压它们:

for (int i = 6; i < vertsCount; i += 3) {

    a = texelFetch(uMeshData, ivec2(i, 0), 0);
    b = texelFetchOffset(uMeshData, ivec2(i, 0), 0, ivec2(1, 0));
    c = texelFetchOffset(uMeshData, ivec2(i, 0), 0, ivec2(2, 0));

    aN = texelFetch(uNormData, ivec2(i, 0), 0);
    bN = texelFetchOffset(uNormData, ivec2(i, 0), 0, ivec2(1, 0));
    cN = texelFetchOffset(uNormData, ivec2(i, 0), 0, ivec2(2, 0));

    triangleNormal = (aN.xyz + bN.xyz + cN.xyz) / 3.;

    vec3 uvt;
    vec3 intersect;
    float z;
    bool isHit = hitTriangleSecond(R_.orig, R_.dir, a.xyz, b.xyz, c.xyz, uvt, triangleNormal, intersect, z);;
    if (isHit) {

        if (z<mindist && z > 0.001) {
            hitPos1 = intersect;

            mindist = z;
            weHitSomething = true;
            material.type = DIEL;
            material.albedo = vec3(.8, .3, .4);
            normal = triangleNormal;
            hitPos = hitPos1;            
        }
    }      
} 

如果我注释我计算表面法线的行,然后用我从纹理中得到的法线替换它,我得到一个白页。所以我认为我在加载纹理时做错了。还是在我计算三角形面法线的 HitTriandglSecond 函数中?

在下面我用一个最小的例子发布到 jsfiddle 的链接(它的长期原因是我放置了一个平面和一个三角形球体的顶点和法线): jsfiddle 示例的链接

标签: javascriptopengl-estextureswebgl2

解决方案


gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB32F, vertsLenght, 1, 0, gl.RGB, gl.FLOAT, meshNorm);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);

我发现了错误。

它是 vertsLength 变量,我为第二个纹理创建了一个新变量,以重用 vertsLength 似乎没有工作的原因。

const normLength = meshNorm.length /3;
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB32F, normLength, 1, 0, gl.RGB, gl.FLOAT, meshNorm);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);

推荐阅读