WebGL - 纹理未正确显示

时间:2014-12-17 11:24:24

标签: javascript textures webgl

在webglacademy第5教程中创建纹理(http://www.webglacademy.com/#5)之后,重点是在立方体对象上加载纹理,有点工作。

查看结果 - enter image description here

任何人都可以告诉我为什么纹理看起来像这样,而它应该完全适合立方体?

在这里演示 - http://kgpk.esy.es/WebGL/(按住鼠标按钮并拖动以移动立方体;鼠标滚轮可放大/缩小)

使用的纹理 - http://kgpk.esy.es/WebGL/texture.png

代码 - http://kgpk.esy.es/WebGL/WEBGL.js(纹理加载到f_IniatializeTextures函数[第209行],它使用f_GetTexture函数[第255行]加载纹理,并在f_Animate函数中将纹理投入流中[第427行]

可以在函数f_InitializeShaders [第215行]

中找到顶点和片段
        base.m_ShaderVertex = [
            "attribute vec3 position;", // The position of the point.
            "uniform mat4 Pmatrix;",    // Projection matrix.
            "uniform mat4 Vmatrix;",    // Movement matrix from object reference to view reference.
            "uniform mat4 Mmatrix;",    // Movement matrix.
            "attribute vec2 uv;",
            "varying vec2 vUV;",

            "void main(void) {",
                "gl_Position = Pmatrix * Vmatrix * Mmatrix * vec4(position, 1.0);",
                "vUV = uv;", // Set color.
            "}"
        ].join("\n");

        base.m_ShaderFragment = [
            "precision mediump float;",
            "uniform sampler2D sampler;",
            "varying vec2 vUV;",

            "void main(void) {",
                "gl_FragColor = texture2D(sampler, vUV);", // Assign the color to pixel with total opaque.
            "}"
        ].join("\n"); 

感谢。

1 个答案:

答案 0 :(得分:2)

您的顶点缓冲区未正确设置。只需按照教程代码:

var cube_vertex=[
-1,-1,-1,    0,0,
1,-1,-1,     1,0,
1, 1,-1,     1,1,
-1, 1,-1,    0,1,

-1,-1, 1,    0,0,
1,-1, 1,     1,0,
1, 1, 1,     1,1,
-1, 1, 1,    0,1,

-1,-1,-1,    0,0,
-1, 1,-1,    1,0,
-1, 1, 1,    1,1,
-1,-1, 1,    0,1,

1,-1,-1,     0,0,
1, 1,-1,     1,0,
1, 1, 1,     1,1,
1,-1, 1,     0,1,

-1,-1,-1,    0,0,
-1,-1, 1,    1,0,
1,-1, 1,     1,1,
1,-1,-1,     0,1,

-1, 1,-1,    0,0,
-1, 1, 1,    1,0,
1, 1, 1,     1,1,
1, 1,-1,     0,1

];

每行中的前3/5值用于顶点的位置,其他两个值用于其UV坐标。你有一些额外的紫外线值会让其他人感到困惑。

这段代码负责处理缓冲区内的偏移量(最后一个参数):

GL.vertexAttribPointer(_position, 3, GL.FLOAT, false, 4*(3+2), 0) ;
GL.vertexAttribPointer(_uv,       2, GL.FLOAT, false, 4*(3+2), 3*4) ;

编辑:

来自webGL spec

void vertexAttribPointer(GLuint indx,GLint size,GLenum type,GLboolean normalized,GLsizei stride,GLintptr offset)

将当前绑定到ARRAY_BUFFER目标的WebGLBuffer对象分配给传递索引处的顶点属性。大小是每个属性的组件数。步幅和偏移量以字节为单位。传递的步幅和偏移量必须适合传递的类型和大小,否则将生成INVALID_OPERATION错误;请参阅缓冲偏移和步幅要求。如果offset为负,则将生成INVALID_VALUE错误。如果没有WebGL缓冲区绑定到ARRAY_BUFFER目标,则会生成INVALID_OPERATION错误。在WebGL中,支持的最大步幅为255;请参阅顶点属性数据步骤。

将多个属性打包到同一个缓冲区时,会使用最后两个参数,如示例所示。 Stride(末尾的第二个参数)告诉你每个顶点有多少字节数据,即5个值,每个值4个字节= 20。 偏移量告诉您绑定到某个VBO的每个顶点值内的字节偏移量是多少。 在您的示例中,您可以看到:

[pos] [pos] [pos] [uv] [uv]
[4B ] [4B ] [4B ] [4B] [4B]
[   12B         ] [  8B   ]

所以你希望位置在缓冲区中的每个20 * i + 0字节上,并且你的UV在缓冲区中的每20 * i + 3 * 4字节上。这就是0和3 * 4的来源。